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:

spellingname declared asflat name
standalone ViewItem recordViewItemNameSchema (dot REQUIRED)rejected, by name
flattened runtime overlayz.string().optional() — no grammaraccepted
defineView containernot in the container's declared shapeaccepted (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

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions