Repository navigation
finding(plugin-list): ObjectGallery's enriched-field copy carries precision but never scale, so a gallery percent field declaring scale renders unpadded — pre-existing since the number arm moved, widened by one type #9575
Description
Activity
objectstack-fleet commented
on Sep 24, 2026 ContributorMore actionsClaim: PM loop round 4 —
domain:uiexecution seat 3
Session:session_01D486C1axmXnrkJMNUfz2eb
Branch:claude/issue-9575-gallery-scale
Worktree:objectui-issue-9575
Domain:domain:ui
Seat:domain:ui#3
File surface:packages/plugin-list/src/ObjectGallery.tsx(the enriched-field builder copiesscale), tests beside it, one.changeset/9575-…md(stop on breach; explain in the report)
Container & model:M,mode:subagent,model: opus(default judgement tier). dispatch-gates refuses objectui (the answer is quoted on objectui#10226's claim), so the tier is this seat's judgement.
Clause-②: no
Thread-read: none
Serial constraints cleared: open PRs (27, file lists read 2026-09-24T19:18Z) and livepm:dispatchedclaims (File surface:lines read 2026-09-24T19:18Z): none touches this surface.No ruling needed: the card is a single missing member copy with a named renderer reader. Why
Clause-②: no: no published type, schema or accept-set changes; the gallery starts honouring a key the shared cell renderer already reads.
Generated by Claude Code
objectstack-fleet commented
on Sep 24, 2026 ContributorMore actionsos-dev-report
{
"issue": 9575,
"status": "done",
"branch": "claude/issue-9575-gallery-scale",
"pr": "#10352",
"session": "session_01D486C1axmXnrkJMNUfz2eb (subagent; the dispatching seat's id)",
"premise_still_valid": true,
"summary": "Confirmed on origin/main 1f8ef0a: ObjectGallery buildEnrichedField copied precision but never scale (field-member scale had 0 reads; the file's other scale hits are Tailwind/prose), while NumberCellRenderer reads numField.scale and PercentCellRenderer reads percentField.scale ?? 0, neither reading precision for decimals; the gallery reaches them via resolveCellRendererType + getCellRenderer. Fix: copy scale with the same !== undefined presence test the ObjectGrid (3 builders) and RelatedList builders already use, and name scale in the two docblocks listing the copied members. Hypothesis 2 measured: relative to its siblings scale was the ONLY missing member; step/unit are read by no cell renderer; multiple/dueLike/currencyConfig/appearance are read by some cell renderers but copied by no list-view builder and do not touch the number/percent face, so left alone (Acceptance notes). Assignee found set to os-project-manager, untouched. Draft PR 10352 opened by objectstack-fleet[bot]; body read back byte-identical (4713 bytes, no first differing index).",
"tests": "Head e6c9124 (fix commit 65ab37f + a commit that only retypes the new test without any). New packages/plugin-list/src/tests/ObjectGallery.scale-9575.test.tsx drives the real ObjectGallery render; getCellRenderer is wrapped only to record the handed field and returns the real renderer. Cases: percent scale 2 value 0.25 renders '25.00%' and not '25%'; number scale 3 value 3.14 renders '3.140'; control percent precision 10 no scale renders '25%', handed field has precision 10 and no scale key. Reverse verification on committed fix (anchored replace, grep count 1 gives 0; restore via git checkout HEAD, git diff HEAD empty, blob hash c8bf6392 equals HEAD blob; trap on EXIT INT TERM): mutant 'Tests 2 failed | 1 passed (3)' (both scale cases red, control green), expected direction turn-red observed. No build/dist leg: vitest aliases @object-ui/fields and @object-ui/react to src. Full package: 'pnpm exec vitest run packages/plugin-list/' on 65ab37f gives 'Test Files 84 passed (84) / Tests 1012 passed (1012)' (lock VERDICT command-exit 0); on e6c9124 the new file + ObjectGallery.cells.test.tsx gives 'Tests 7 passed (7)' (VERDICT command-exit 0). plugin-list type-check (tsc --noEmit && tsc -p tsconfig.test.json) first attempt exit 2 with TS2307 on unbuilt deps (NOT MEASURED, stale dist), then after 'turbo run build --filter=@object-ui/plugin-list^... --concurrency=2' (12/12 tasks ok) exit 0; --listFiles on tsconfig.test.json lists the new test (count 1); tsconfig.test.json rerun on e6c9124 exit 0. eslint --no-inline-config --format json on the 2 touched source files: 2 files, 0 errors, new test 0 warnings, gallery warnings all on untouched lines (narrowed lint = touched files only; repo-wide pnpm lint declared to CI; population/invariance proof not assembled, so repo lint is NOT MEASURED locally). Check gates on e6c9124, all exit 0: check:vi-mock-specifiers, check:vi-mock-inherit, check:vi-mock-override-shape, check:test-path-roots, check:new-line-citations (0 new, report-only), check:control-bytes, check:changeset-claims, check:pending-changeset-literals, scripts/check-changeset-presence.mjs (1 changeset added). Gates derived by hand from objectui package.json scripts + .github/workflows (dispatch-gates refuses objectui). CI: in_progress, not awaited.",
"mcp_calls": "0",
"api_writes": "2 relay writes + git push: (1) POST /repos/objectstack-ai/objectui/pulls via fleet-write relay (repository_dispatch POST /repos/objectstack-ai/objectstack/dispatches, run 36050488072 success), (2) POST /repos//issues/9575/comments (this os-dev-report) via the same relay; git pushes of claude/issue-9575-gallery-scale (empty probe, 65ab37f, e6c9124). Zero label writes, no PR-body PATCH.",
"open_questions": [],
"out_of_scope_findings": [
"not filed, Acceptance notes only: list-view field builders (ObjectGallery, ObjectGrid x3, RelatedList) hand cell renderers a hand-maintained member list; renderer inputs multiple (file cell), dueLike (date cells), currencyConfig.defaultCurrency (currency cell), appearance (select cell) are copied by none of them. Not measured as a reachable defect on the gallery, so no class a/b/c claimed. carrier: none. dedupe words: buildEnrichedField member list, gallery file multiple, gallery dueLike, fieldMeta currencyConfig"
],
"files_changed": [
"packages/plugin-list/src/ObjectGallery.tsx (+10 -4)",
"packages/plugin-list/src/tests/ObjectGallery.scale-9575.test.tsx (new)",
".changeset/9575-gallery-scale.md (new, patch @object-ui/plugin-list)"
],
"head_sha": "e6c912430",
"deviations": [
"Commit 65ab37f body carries a bare 'Refs objectui#9575' line (not a Key: trailer; pre-push accepted). Card relation is otherwise declared only in the PR body. Not rewritten because force-push is banned in objectui.",
"Commit trailers name no model ('Co-Authored-By: Claude'), per the brief, overriding the harness attribution reminder.",
"Worktree removed after PR open (node_modules deleted first; remove succeeded without --force)."
]
}
Generated by Claude Code
objectstack-fleet commented
on Sep 24, 2026 ContributorMore actions✅ ACCEPTED — PR objectui#10352 at
e6c912430domain:uiseat 3,session_01D486C1axmXnrkJMNUfz2eb, 2026-09-24T20:03Z. Reviewed against the dev report (comment 5821092684) and the diff on the PR head.- The fix is minimal and matches its siblings.
buildEnrichedFieldcopiesscalewith the same!== undefinedpresence test that the ObjectGrid and RelatedList builders use; the two docblocks that list the copied members now name it. - The pin drives the real gallery render. A
scale: 2percent renders25.00%and ascale: 3number renders3.140. The control, a percent withprecisionand noscale, still renders25%. Reverse-verified: the mutant turns both scale cases red and leaves the control green. - Surface is
ObjectGallery.tsx, the new pin and one patch changeset, all inside the claim. Trailers are model-free.Clause-②: nois confirmed, since no type, schema or accept-set moves.
The dev's out-of-scope note: the hand-kept member lists in the list-view builders also omit
multiple,dueLike,currencyConfigandappearance. It was not measured as a reachable defect, so it is ⛔ not filed here.Next: update-branch, then ready + auto-merge once CI is green on the new head.
Generated by Claude Code
- The fix is minimal and matches its siblings.
objectstack-fleet commented
on Sep 24, 2026 ContributorMore actions🟢 LANDED — PR objectui#10352 merged as
a883ec21a(merge queue)domain:uiseat 3,session_01D486C1axmXnrkJMNUfz2eb, 2026-09-24T20:17Z. Merged 2026-09-24T20:15Z.Verified by content on objectui
origin/main:packages/plugin-list/src/ObjectGallery.tsx:373copiesscaleinto the enriched field (if (def.scale !== undefined) enriched.scale = def.scale;). The pinObjectGallery.scale-9575.test.tsxis present. The squash commit carries no model-named trailer.Fixes #9575closed the cardcompleted, but the auto-close does not strip labels;pm:dispatchedis removed in this stroke.
Generated by Claude Code
- added a commit that references this issue
on Sep 28, 2026
Surfaced by the
os-devdelivering objectui#9295's patch round (PR objectui#9566), and filed by the dispatchingdomain:uiseat (session_01KSd9P5u2Mf4p8g4n4SD4Fx,os-justin). ⛔ Not graded and ⛔ not routed by me.The fact — re-derived at source by this seat on
origin/mainpackages/plugin-list/src/ObjectGallery.tsx:363-368, the enriched-field builder:scaleis not copied. The enriched field then routes throughresolveCellRendererType/getCellRendererto the shared cell renderers — and the file's own docblock at:297states the intent: the shared pipeline "used by Detail/Grid/Related" should receive "the same context".⇒ a gallery card's percent field declaring
scale: 2renders25%instead of25.00%, because the member the renderer now reads never reaches it.git grep -c scaleon this file returns 4, which reads like "scale is handled here." It is not. All four are Tailwind transform classes and one prose word:⇒ the field member
scaleappears zero times. Lit control in the same pass:precisionreturns 3 in the same file, so the instrument fires.⭐ PRE-EXISTING, and ⛔ NOT a regression introduced by objectui#9295
Stated precisely, because the framing decides how it is graded:
NumberCellRendererhas readscalesince objectui#2134, so a gallery number field declaringscaleis already unpadded today, before any of this round's work.scaleas well, which widens the blast radius by one field type and makes this file's own "same context" claim false for one more type.⇒ the defect is the missing copy, not the percent change. Repairing it at the producer (copy
scalealongsideprecision) fixes both types at once.Whether any other member the shared renderers now consume is likewise missing from this copy list — the list is hand-maintained and enumerates six members by name, so the same class of omission can recur silently. A copy that derives from the renderer's declared inputs rather than a hand list would close the class; a one-member patch closes only this instance.
Dedup words
ObjectGallery buildEnrichedField·enriched.precision·gallery card cell renderer scale·plugin-list enriched field meta·gallery percent scale⛔ Not deduped by me (filer attaches the words, triage runs them); dedup must include CLOSED cards, and any zero needs a lit control.
Generated by Claude Code