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
Recorded while implementing #9313 (the flattened-overlay rung). Not claimed.
What is measured
ViewMetadataSchemamember 1 (ViewItemWireSchema) is the standalone ViewItem record —{ name, object, viewKind: 'list', config: { …ListView } }— and it is a hot wire shape: objectui'supdateViewGETs the stored item and PUTs{ ...current, ...partial }, which for a standalone record carriesviewKind+config(the trace is inview.zod.ts's #5074 note). ItssortandsearchableFieldslive one level down, insideconfig.Neither
validateSortableFieldsnorvalidateSearchableFieldswalks that rung. After #9313 the walks readobjects[].listViews.*,views[].list/views[].listViews.*, and the flattened overlay's top level (views[].sortwhenviewKind: 'list'and no nestedconfig) — theconfigguard on the self rung deliberately excludes the record shape, so a record write carryingconfig.sort: [{ field: '<typo>' }]publishes through the runtime gate in silence, then answers400 INVALID_SORTon the view's first fetch (#6994 / #7095), every load.Pinned rather than latent:
runtime-gate.view-writes.test.tscarries 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+validateSortableFieldsreaching 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
configrung in both walks (the two rules are deliberate twins — mirror them): when aviews[]entry carriesviewKind: 'list'and a record-shapedconfig, judgeconfig.sort/config.searchableFieldsagainstlistViewObject(config) ?? entry.object, pathviews[i].config.sort[…]. The runtime dispatch is already in place (#9313 widened the suite entry and the two members toview), 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
updateViewmerge trace), #7741 (the overlay binding pair), #6994 / #7095 (the runtime refusals both rules mirror), #4716 (the false-positive budget).Generated by Claude Code