Skip to content

No doc states that a stored view row's name grammar depends on the BODY SPELLING — dot-required for ViewItem records, unconstrained for flattened overlays and containers #13134

Description

@os-trump

Observation-class finding, surfaced by the #12384 census (PR #13133). Filed unassigned; not fixed there — #12384's ruling authorized a name correction on two teaching sites, not new contract prose.

The measurement

ViewMetadataSchema is a union over the persisted view body spellings, and they do not share a name grammar. Measured against the built schema (packages/spec/dist), not read off source:

=== the stored `view` body spellings, each with a FLAT name ===
RECORD    flat  {name,object,viewKind,config}          -> REJECT
      invalid_format @ ["name"]: View item name must be a dotted snake_case qualified name, e.g. "crm_lead.pipeline".
RECORD    dotted {name,object,viewKind,config}         -> ACCEPT   [positive control]
OVERLAY   flat  {name,object,viewKind,...rawConfig}    -> ACCEPT
CONTAINER flat  {name,list}                            -> ACCEPT

Sources:

  • packages/spec/src/ui/view.zod.tsviewItemBaseShape() declares name: ViewItemNameSchema, which pins QUALIFIED_ITEM_NAME_PATTERN (dot REQUIRED, identifiers.zod.ts:137).
  • same file — flattenedViewOverlayFields() declares name: z.string().optional(), carrying no grammar at all.
  • ADR-0017 §3.2 dual-read — the aggregated container is registered under the bare object key, so its name is flat by design.

So all three of these are true simultaneously, and no page says so:

spelling name declared as flat name
standalone ViewItem record ViewItemNameSchema (dot REQUIRED) rejected, by name
flattened runtime overlay z.string().optional() — no grammar accepted
defineView container not in the container's declared shape accepted (bare object key)

Why it is worth recording

The two failure directions are symmetric, and the docs currently prevent neither:

  1. An author who reads only ViewItemNameSchema (or, after PR docs(kernel): teach the dot-qualified view item name in metadata-service.mdx #13133, only metadata-service.mdx's now-dotted examples) concludes the dot is mandatory for every view row — and it is not; the overlay and container spellings accept flat names, and in-tree fixtures use them (case_grid, cases, shared_grid, org_grid, overdue_grid, myapp_case_grid, and the container row crm_lead).
  2. An author who reads a flat-named overlay fixture concludes flat is fine generally, then writes a standalone ViewItem record and gets a rejection on the one field the fixture told them to fill.

This is the AI-authoring axis specifically: the grammar is decided by a body shape the author never names explicitly, so the failure is not discoverable from the key being written. Declaring the per-spelling rule in the view contract docs makes it a stated contract instead of something recoverable only by reading three schema factories.

Not proposed here

No schema change. The schemas are internally consistent and the flat-named rows parse clean — this is a documentation gap, not a contract conflict. Which page should carry the rule (content/docs/kernel/contracts/metadata-service.mdx, the view reference, or ADR-0017) is a spec-seat call.

Fixture hygiene, same census, much smaller

packages/spec/src/conversions/view-spelling-walk.test.ts:429 carries a record-shaped body with a flat name ({ name: 'clean', object: 'crm_lead', viewKind: 'list', config: {...} }). It is a copy-on-write identity probe for the conversion walker and never reaches the parse door, so it is not wrong today — but it is the one in-tree record-shaped fixture whose name ViewMetadataSchema would reject, and a future author copying it as a template would inherit the defect.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions