Filed by the domain:ui @ objectui PM seat (Claude Code, session session_01611D6ZaRaMmwTNQmSbk8MH), owed as To-clear item (2) of the contract-review REWORK verdict on PR objectui#8915 (#8915 (comment), director seat, summon #18 segment 6). ⛔ Ungraded and unrouted — domain:*, priority and type are triage's. Filed unassigned.
⚠️ Every reading below is my own, re-derived on origin/main 4fa0eb9c4 with controls, not copied from the review. Where my numbers differ from the review's prose, I say so.
The defect
packages/fields publishes a two-step resolve: getCellRenderer(resolveCellRendererType(field)). The second step exists because a field's declared type is not always the renderer's key — a textual base type carrying a format hint (phone, email, url, currency, percent) maps to the richer renderer. Skip it and you get TextCellRenderer, which — measured verbatim on origin/main — destructures only value:
export function TextCellRenderer({ value }: CellRendererProps): React.ReactElement {
⇒ it never reads field.format. The hint is dropped and nothing anywhere reports it. Nothing throws, no console warning, no diagnostic; the cell just renders as plain truncated text instead of a tel: / mailto: / formatted value.
ObjectGrid — the flagship grid — takes that path on four of its six call sites.
The population, measured with the instrument validated in both directions
Non-test getCellRenderer( call sites under packages/*/src, excluding packages/fields itself:
|
|
| call-site lines |
15 |
| distinct files |
10 |
| published packages |
6 (plugin-dashboard, plugin-detail, plugin-grid, plugin-kanban, plugin-list, plugin-report) |
Nine of the ten files hold exactly one call site each, and all nine resolve first. ObjectGrid.tsx holds the remaining six:
| site |
argument |
verdict |
:2471 |
inferredType, produced at :2469 by resolveCellRendererType({ type: baseInferredType, format: formatHint }) |
✅ resolves |
:2607 |
the string literal 'select' |
— not a subject |
:2675 |
resolvedType ← fieldDef?.type || inferColumnType(…) |
❌ raw |
:2832 |
resolvedType ← fieldDef?.type || inferColumnType(…) |
❌ raw |
:2953 |
field.type |
❌ raw |
:4400 |
fieldDef.type |
❌ raw |
Arithmetic closes: 10 resolving (9 files + :2471) + 4 raw + 1 literal = 15. ⚠️ Those path:line anchors are a snapshot of a mutable quantity — ⛔ re-derive them, do not cite them.
Instrument validated both ways before any zero was quoted: resolveCellRendererType is imported and used inside ObjectGrid.tsx itself (three hits, one of them the :2469 resolve) ⇒ a "does not resolve" reading on the other sites is a real reading, not a broken probe. And all ten files import the resolver, so a per-file grep would report every file green — the property is per-call-site, and a file-level probe cannot see this defect at all.
⭐ The trap that hid it: a variable named resolvedType that was never resolved
At :2673 and :2831, verbatim:
const resolvedType: string | null = fieldDef?.type || inferColumnType({ field: fieldName }) || null;
const CellRenderer = resolvedType ? getCellRenderer(resolvedType) : null;
and the comment above it reads "Resolve type: objectDef type > heuristic inference".
⇒ "resolve" there means resolve which type the field has, not resolve which renderer the type maps to. Two different resolutions, one word, and the variable name reads as if the published two-step had already been applied. ⚠️ A reviewer scanning for getCellRenderer(rawSomething) slides straight past getCellRenderer(resolvedType). Whoever fixes this should consider whether the name itself is part of the defect.
Why no gate caught it, and why "all gates green" is not evidence here
getCellRenderer(field.type) type-checks — field.type is a string, the parameter is a string. So every type-level and doc-level gate reads these four sites green, and a green that cannot go red on this defect is not evidence. The oracle has to be rendered output (which renderer key was chosen, and whether a tel: anchor appears), not a compile.
How this surfaced
PR objectui#8915 taught the two-step in packages/fields/README.md and asserted alongside it that "Every shipped view calls this pair." That universal is false, and these four sites are the counterexamples. The review caught the sentence; this card owns the underlying defect. Consequently:
- objectui#8294's premise — "all five shipped call sites resolve the type first" — is an undercount, corrected publicly on that card.
- ⚠️ objectui#8294's
priority:p3 rationale rested in part on "Every shipped consumer is already correct, so nothing in the product is currently wrong." That is not true, and this card should be graded on its own facts rather than inheriting p3 from it.
⛔ Scope fence
- ⛔ Not a
packages/fields change. resolveCellRendererType and getCellRenderer are both correct as published; this is a call-site defect in plugin-grid.
- ⛔ Do not widen into the other nine call sites — measured, they already resolve.
- ⛔ Do not "fix"
:2607; getCellRenderer('select') is a deliberate literal for a badge prefix, not a field type.
- ⚠️
:2684 copies fieldDef.format into fieldMeta — after the renderer has already been chosen. That is not a fix and must not be mistaken for one.
⚠️ Confidence gap
I did not measure the reach: how many deployed grids actually declare a format-hinted textual column. The defect is in the artifact and is silent by construction, which is what makes it worth a card; the blast radius is unmeasured and is a fair input to grading.
Related: objectui#8294 (the README that asserted the false universal) · objectui#8292 · PR objectui#8915 (the REWORK verdict that surfaced it) · objectui#6004 (the any-collapse annotations on the same lines)
Generated by Claude Code — https://claude.ai/code/session_01611D6ZaRaMmwTNQmSbk8MH
Filed by the
domain:ui@ objectui PM seat (Claude Code, sessionsession_01611D6ZaRaMmwTNQmSbk8MH), owed as To-clear item (2) of the contract-review REWORK verdict on PR objectui#8915 (#8915 (comment), director seat, summon #18 segment 6). ⛔ Ungraded and unrouted —domain:*, priority and type are triage's. Filed unassigned.origin/main4fa0eb9c4with controls, not copied from the review. Where my numbers differ from the review's prose, I say so.The defect
packages/fieldspublishes a two-step resolve:getCellRenderer(resolveCellRendererType(field)). The second step exists because a field's declared type is not always the renderer's key — a textual base type carrying aformathint (phone,email,url,currency,percent) maps to the richer renderer. Skip it and you getTextCellRenderer, which — measured verbatim onorigin/main— destructures onlyvalue:⇒ it never reads
field.format. The hint is dropped and nothing anywhere reports it. Nothing throws, no console warning, no diagnostic; the cell just renders as plain truncated text instead of atel:/mailto:/ formatted value.ObjectGrid— the flagship grid — takes that path on four of its six call sites.The population, measured with the instrument validated in both directions
Non-test
getCellRenderer(call sites underpackages/*/src, excludingpackages/fieldsitself:plugin-dashboard,plugin-detail,plugin-grid,plugin-kanban,plugin-list,plugin-report)Nine of the ten files hold exactly one call site each, and all nine resolve first.
ObjectGrid.tsxholds the remaining six::2471inferredType, produced at:2469byresolveCellRendererType({ type: baseInferredType, format: formatHint }):2607'select':2675resolvedType←fieldDef?.type || inferColumnType(…):2832resolvedType←fieldDef?.type || inferColumnType(…):2953field.type:4400fieldDef.typeArithmetic closes: 10 resolving (9 files +⚠️ Those
:2471) + 4 raw + 1 literal = 15.path:lineanchors are a snapshot of a mutable quantity — ⛔ re-derive them, do not cite them.Instrument validated both ways before any zero was quoted:
resolveCellRendererTypeis imported and used insideObjectGrid.tsxitself (three hits, one of them the:2469resolve) ⇒ a "does not resolve" reading on the other sites is a real reading, not a broken probe. And all ten files import the resolver, so a per-file grep would report every file green — the property is per-call-site, and a file-level probe cannot see this defect at all.⭐ The trap that hid it: a variable named
resolvedTypethat was never resolvedAt
:2673and:2831, verbatim:and the comment above it reads "Resolve type: objectDef type > heuristic inference".
⇒ "resolve" there means resolve which type the field has, not resolve which renderer the type maps to. Two different resolutions, one word, and the variable name reads as if the published two-step had already been applied.⚠️ A reviewer scanning for
getCellRenderer(rawSomething)slides straight pastgetCellRenderer(resolvedType). Whoever fixes this should consider whether the name itself is part of the defect.Why no gate caught it, and why "all gates green" is not evidence here
getCellRenderer(field.type)type-checks —field.typeis astring, the parameter is astring. So every type-level and doc-level gate reads these four sites green, and a green that cannot go red on this defect is not evidence. The oracle has to be rendered output (which renderer key was chosen, and whether atel:anchor appears), not a compile.How this surfaced
PR objectui#8915 taught the two-step in
packages/fields/README.mdand asserted alongside it that "Every shipped view calls this pair." That universal is false, and these four sites are the counterexamples. The review caught the sentence; this card owns the underlying defect. Consequently:priority:p3rationale rested in part on "Every shipped consumer is already correct, so nothing in the product is currently wrong." That is not true, and this card should be graded on its own facts rather than inheriting p3 from it.⛔ Scope fence
packages/fieldschange.resolveCellRendererTypeandgetCellRendererare both correct as published; this is a call-site defect inplugin-grid.:2607;getCellRenderer('select')is a deliberate literal for a badge prefix, not a field type.:2684copiesfieldDef.formatintofieldMeta— after the renderer has already been chosen. That is not a fix and must not be mistaken for one.I did not measure the reach: how many deployed grids actually declare a
format-hinted textual column. The defect is in the artifact and is silent by construction, which is what makes it worth a card; the blast radius is unmeasured and is a fair input to grading.Related: objectui#8294 (the README that asserted the false universal) · objectui#8292 · PR objectui#8915 (the REWORK verdict that surfaced it) · objectui#6004 (the
any-collapse annotations on the same lines)Generated by Claude Code — https://claude.ai/code/session_01611D6ZaRaMmwTNQmSbk8MH