Skip to content

A standalone ViewItem RECORD's nested config.sort / config.searchableFields is judged by neither list-view field rule — the same runtime-door gap #9313 closed for the flattened overlay, one member over #10001

Description

@os-elon

Recorded while implementing #9313 (the flattened-overlay rung). Not claimed.

What is measured

ViewMetadataSchema member 1 (ViewItemWireSchema) is the standalone ViewItem record — { name, object, viewKind: 'list', config: { …ListView } } — and it is a hot wire shape: objectui's updateView GETs the stored item and PUTs { ...current, ...partial }, which for a standalone record carries viewKind + config (the trace is in view.zod.ts's #5074 note). Its sort and searchableFields live one level down, inside config.

Neither validateSortableFields nor validateSearchableFields walks that rung. After #9313 the walks read objects[].listViews.*, views[].list / views[].listViews.*, and the flattened overlay's top level (views[].sort when viewKind: 'list' and no nested config) — the config guard on the self rung deliberately excludes the record shape, so a record write carrying config.sort: [{ field: '<typo>' }] publishes through the runtime gate in silence, then answers 400 INVALID_SORT on the view's first fetch (#6994 / #7095), every load.

Pinned rather than latent: runtime-gate.view-writes.test.ts carries the boundary marker — a ViewItem RECORD's nested config.sort is not judged here — recorded scope, not a rung that fell off.

Why it was not fixed in the #9313 PR

The #9313 claim fences scope to the flattened overlay ("Scope is validateSearchableFields + validateSortableFields reaching a top-level flattened list-view overlay through the runtime door"), and the record rung fails the bounded in-place-fix bar on the verification axis: it widens the refusal surface onto a second wire shape, which owes its own refusal tests and its own corpus replay of record-shaped bodies (the #4716 false-positive budget, unchanged).

Shape of the fix

A config rung in both walks (the two rules are deliberate twins — mirror them): when a views[] entry carries viewKind: 'list' and a record-shaped config, judge config.sort / config.searchableFields against listViewObject(config) ?? entry.object, path views[i].config.sort[…]. The runtime dispatch is already in place (#9313 widened the suite entry and the two members to view), so this is walk-only — plus the record-shaped corpus replay before it ships.

Refs

#9313 (the overlay half, with the dispatch widening and the member-surface pin), #5074 (the updateView merge trace), #7741 (the overlay binding pair), #6994 / #7095 (the runtime refusals both rules mirror), #4716 (the false-positive budget).


Generated by Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions