You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Repository navigation
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
[finding] ObjectGrid's legacy defaultFilters leg still reaches $filter without the toFilterNode hop #4082
Observation-class finding, recorded from the objectui#4041 implementation (PR #4081) so it is not rediscovered. Unassigned, and no pm:queue — I did not measure a live producer, so I am not claiming a user hits this today. Filed plainly; let triage grade it.
The fact
packages/plugin-grid/src/ObjectGrid.tsx, the query assembly, after PR #4081:
if (schemaFilter !== undefined) {
params.$filter = schemaFilter; // lowered through toFilterNode at the read point
} else if (schema.defaultFilters) {
// Legacy support
params.$filter = schema.defaultFilters; // byte-for-byte, no lowering
}
objectui#4041 converged the declaredfilter key onto the repo's single lowering hop (toFilterNode, "the last hop before the wire"). The legacy defaultFilters fallback beside it was deliberately left untouched as out of scope for that card — it is a different key, undeclared in the block's inputs, and widening #4041 to it would have been scope creep on a ruled card.
But the hazard toFilterNode exists to close applies to it verbatim. defaultFilters is the MongoDB-style Record< string, any > shape (plugin-list's buildEffectiveFilter names it as exactly that: "its last fallback is table.defaultFilters, declared Record< string, any >"). isFilterAST is false for a plain object, so such a value sent raw is the 400 INVALID_FILTER shape objectui#3431 measured against a real backend. toFilterNode already handles this case — it routes objects through convertFiltersToAST — so the fix, if wanted, is a one-line reuse of the sink rather than new logic.
Why I am not asserting impact
Two reasons to let triage decide rather than grade it myself:
No measured producer.defaultFilters is not in object-grid's registered inputs, so an author writing it gets unknown-prop from the save gate (a warning, not a rejection — sdui-parser/src/validate.ts pushes severity: 'warning'). Whether any host injects it onto an object-grid node was not measured.
The sibling path already lowers. Where ObjectView feeds a list, the value goes through buildEffectiveFilter, which does call toFilterNode. So the un-lowered leg may be dormant in practice — which is precisely the "dormant code / unexercised drift" class rather than a live defect.
Severity judged at filing time is unreliable in both directions, so this is recorded as observed rather than argued up or down.
objectui#3431 — the real-backend measurement of 400 INVALID_FILTER for a non-AST $filter.
objectui#2890 — the broader ListView legacy-vocabulary migration (scope A lists filters → filter); this finding is a narrower runtime fact about a different key and is not covered there.
Why held rather than promoted: the card's own two reasons stand up — no measured producer (defaultFilters is not in object-grid's registered inputs; authoring it draws a save-gate warning), and the ObjectView→list sibling path already lowers via buildEffectiveFilter. That is the dormant-code / unexercised-drift class the finding state exists for. Real hazard (a plain object sent raw is [finding] 已保存视图的 ViewFilterRule[] 被原样当 FilterNode 送进 $filter,未在客户端折成 AST #3431's measured 400 INVALID_FILTER), but nothing reaches it today on any path that was measured.
Held on the card's own two reasons: no measured producer of defaultFilters in shipped metadata, and the leg was deliberately scoped out of the ruled object-grid 的 inputs 声明 filters(复数),渲染器只读 filter(单数):按已发布词汇写筛选条件静默无效 #4041 convergence. The one-line toFilterNode hop remains the obvious fix whenever that block is next open (grade together with the sibling legacy defaultSort leg at :676-677, same shape).
Findings round — held (finding kept), premise re-verified.
Re-checked @ objectui origin/mainb42558a: the un-lowered legacy leg is live in packages/plugin-grid/src/ObjectGrid.tsx (} else if (schema.defaultFilters) { // Legacy support → params.$filter = schema.defaultFilters, immediately after the lowered declared-filter branch). Held on the card's own standing reasons: no measured producer of defaultFilters in shipped metadata, and the exit (lower it, or retire the legacy key) is a small contract call best taken with a producer in hand.
Findings triage (re-verify @ origin/mainf812de6): HOLD — the legacy leg is intact: packages/plugin-grid/src/ObjectGrid.tsx:655-657 still assigns params.$filter = schema.defaultFilters directly, without the toFilterNode hop the primary path takes. Still dormant-by-usage; converges with the family's eventual $filter normalization sweep. finding stands.
Findings cadence re-check @ origin/main90e792e: HOLD (finding stays). The legacy leg is still live — packages/plugin-grid/src/ObjectGrid.tsx:655-657 still assigns params.$filter = schema.defaultFilters; with no toFilterNode hop. Dormant until a schema authors defaultFilters; nothing a user hits today.
Findings centralized round, batch 2 (triage seat, 2026-08-17): state transition finding → pm:on-hold per the 2026-08-13 status-semantics ruling. Standing grade unchanged and absorbed: the un-lowered legacy defaultFilters leg is dormant (no measured producer; not in registered inputs; sibling path lowers), and the exit — one-line toFilterNode reuse vs retiring the legacy key — is best taken with a producer in hand or inside the #2890 legacy-vocabulary migration. Grade together with the sibling legacy defaultSort leg (same shape, same file).
Restart-when: closed #2890, or a dispatched card's file surface includes packages/plugin-grid/src/ObjectGrid.tsx. Trigger file: packages/plugin-grid/src/ObjectGrid.tsx.
Hold released → pm:queue (triage seat, session session_014qTKTqjme5Fp5BH9iRmy6t, rider-clause audit): the file-surface leg of the Restart-when fired FIVE times — PRs #5333, #5241, #5192, #5147, #4965 all touched packages/plugin-grid/src/ObjectGrid.tsx after the hold — and the un-lowered leg is still live on origin/main (lines 1109–1114: params.$filter = schema.defaultFilters with no toFilterNode hop). The other leg (#2890) is still open, but one fired leg releases. Dispatch it as its own small card rather than waiting for a rider nobody carries. Release double-checks passed (no merged PR references this card).
Activity
os-zhuang commentedon Aug 10, 2026
Findings triage: held —
findingstays.origin/main@9154d9e): the un-lowered leg is live exactly as filed —packages/plugin-grid/src/ObjectGrid.tsx:647-648(// Legacy support→params.$filter = schema.defaultFilterswith notoFilterNodehop). PR fix(plugin-grid): object-grid publishes the filter key it reads —filter, singular (#4041) #4081 (the object-grid 的 inputs 声明filters(复数),渲染器只读filter(单数):按已发布词汇写筛选条件静默无效 #4041 convergence that deliberately left this leg alone) is merged.defaultFiltersis not inobject-grid's registeredinputs; authoring it draws a save-gate warning), and theObjectView→list sibling path already lowers viabuildEffectiveFilter. That is the dormant-code / unexercised-drift class thefindingstate exists for. Real hazard (a plain object sent raw is [finding] 已保存视图的 ViewFilterRule[] 被原样当 FilterNode 送进 $filter,未在客户端折成 AST #3431's measured400 INVALID_FILTER), but nothing reaches it today on any path that was measured.defaultFiltersonto anobject-gridnode, or (b) Migrate the remaining ListView legacy vocabulary to spec-canonical keys, and audit ObjectView/DetailView (#2231 phases 4–5) #2890 scope-A work touching this file — fold it in or promote then.filters(复数),渲染器只读filter(单数):按已发布词汇写筛选条件静默无效 #4041/PR fix(plugin-grid): object-grid publishes the filter key it reads —filter, singular (#4041) #4081 scope-disjoint by that card's ruling; Migrate the remaining ListView legacy vocabulary to spec-canonical keys, and audit ObjectView/DetailView (#2231 phases 4–5) #2890 lists the vocabulary migration but not this runtime fact; no twin.本评论来自分诊座位 Routine(#5474 试点),不构成认领。
Generated by Claude Code
claude commentedon Aug 10, 2026
Findings round — held (
findingkept), premise re-verified.origin/maine638531: the un-lowered legacy leg is live atpackages/plugin-grid/src/ObjectGrid.tsx:655-657(// Legacy support→params.$filter = schema.defaultFilters, notoFilterNodehop), beside the converged declared-filterpath from PR fix(plugin-grid): object-grid publishes the filter key it reads —filter, singular (#4041) #4081.defaultFiltersin shipped metadata, and the leg was deliberately scoped out of the ruled object-grid 的 inputs 声明filters(复数),渲染器只读filter(单数):按已发布词汇写筛选条件静默无效 #4041 convergence. The one-linetoFilterNodehop remains the obvious fix whenever that block is next open (grade together with the sibling legacydefaultSortleg at:676-677, same shape).本评论来自分诊座位 Routine(#5474 试点),不构成认领。
Generated by Claude Code
os-zhuang commentedon Aug 11, 2026
Findings round — held (
findingkept), premise re-verified.Re-checked @ objectui
origin/mainb42558a: the un-lowered legacy leg is live inpackages/plugin-grid/src/ObjectGrid.tsx(} else if (schema.defaultFilters) { // Legacy support → params.$filter = schema.defaultFilters, immediately after the lowered declared-filterbranch). Held on the card's own standing reasons: no measured producer ofdefaultFiltersin shipped metadata, and the exit (lower it, or retire the legacy key) is a small contract call best taken with a producer in hand.本评论来自分诊座位 Routine(#5474 试点),不构成认领。
Generated by Claude Code
os-zhuang commentedon Aug 11, 2026
Findings triage (re-verify @
origin/mainf812de6): HOLD — the legacy leg is intact:packages/plugin-grid/src/ObjectGrid.tsx:655-657still assignsparams.$filter = schema.defaultFiltersdirectly, without thetoFilterNodehop the primary path takes. Still dormant-by-usage; converges with the family's eventual$filternormalization sweep.findingstands.本评论来自分诊座位 Routine(#5474 试点),不构成认领。
Generated by Claude Code
claude commentedon Aug 11, 2026
Findings cadence re-check @
origin/main90e792e: HOLD (findingstays). The legacy leg is still live —packages/plugin-grid/src/ObjectGrid.tsx:655-657still assignsparams.$filter = schema.defaultFilters;with notoFilterNodehop. Dormant until a schema authorsdefaultFilters; nothing a user hits today.本评论来自分诊座位 Routine(#5474 试点),不构成认领。
Generated by Claude Code
os-zhuang commentedon Aug 17, 2026
Findings centralized round, batch 2 (triage seat, 2026-08-17): state transition
finding→pm:on-holdper the 2026-08-13 status-semantics ruling. Standing grade unchanged and absorbed: the un-lowered legacydefaultFiltersleg is dormant (no measured producer; not in registeredinputs; sibling path lowers), and the exit — one-linetoFilterNodereuse vs retiring the legacy key — is best taken with a producer in hand or inside the #2890 legacy-vocabulary migration. Grade together with the sibling legacydefaultSortleg (same shape, same file).Restart-when: closed #2890, or a dispatched card's file surface includes
packages/plugin-grid/src/ObjectGrid.tsx. Trigger file:packages/plugin-grid/src/ObjectGrid.tsx.Generated by Claude Code
os-zhuang commentedon Aug 19, 2026
Hold released →
pm:queue(triage seat, sessionsession_014qTKTqjme5Fp5BH9iRmy6t, rider-clause audit): the file-surface leg of the Restart-when fired FIVE times — PRs #5333, #5241, #5192, #5147, #4965 all touchedpackages/plugin-grid/src/ObjectGrid.tsxafter the hold — and the un-lowered leg is still live on origin/main (lines 1109–1114:params.$filter = schema.defaultFilterswith notoFilterNodehop). The other leg (#2890) is still open, but one fired leg releases. Dispatch it as its own small card rather than waiting for a rider nobody carries. Release double-checks passed (no merged PR references this card).Generated by Claude Code
docs(changeset,plugin-view): drop unregistered spec version literals;…
refactor(plugin-view,plugin-grid,types): retire table.defaultSort / o…