Filing-gate category: ② a runtime path that answers wrong: stored data is lost on a normal click, with a named landing site. Reader: triage first (grade and route). Filed by domain:ui seat 2, session_014mXUNuFomfj24w7s1pZzhN, from the dev's out-of-scope finding on PR objectui#11017 (objectui#10899). ⛔ Not graded here.
What the code does (objectui main, packages/app-shell/src/views/RecordDetailView.tsx)
sys_comment.reactions stores { emoji: userIds[] } as a JSON string.
- A reaction click writes the row's whole reaction set back through
dataSource.update('sys_comment', …).
- The panel does not have the user-id lists, only
{ emoji, count, reacted }, so the write rebuilds each list as the signed-in user (when reacted), padded with the literal '__other__' up to count. PR objectui#11017 moves that code verbatim into storedReactionShape, whose comment calls it "an over-simplification for single-user pilot installs, to be replaced by a proper backend reaction endpoint in M11".
- On re-read,
reacted is userIds.includes(currentUser.id).
What goes wrong (measured by the dev, one-off probe at PR objectui#11017's 27df953e3e)
- The row is seeded with
{"👍": ["u2", "u3"]}.
u1 adds ❤️. The stored value becomes {"👍": ["__other__", "__other__"], "❤️": ["u1"]}.
u1 then adds 👍. It becomes {"👍": ["u1", "__other__", "__other__"], "❤️": ["u1"]}.
u2's own 👍 no longer reads as theirs (measured). Derived from the toggle code and not probed: u2's next 👍 click counts as a new reaction (count + 1) instead of taking theirs back.
- Any click by anyone on any emoji of that comment erases every other user's ids on every emoji.
Reach
- Every record page's discussion panel, on any tenant with more than one person reacting.
- The count survives, but who reacted is lost on the first click by someone else.
Direction (for triage to grade)
- A. A server-side toggle: one write that adds or removes the caller's id for one emoji, such as an action or an endpoint on
sys_comment. The client sends (commentId, emoji) and never the whole set. This is the "reaction endpoint" the code comment names. It needs a producer card in objectstack.
- B. Client-side, keep the stored lists: read the row's stored
reactions JSON, change only the caller's id in the one emoji, and write that. This is still last-writer-wins between two users, but no longer erases ids.
- The dedupe search found no existing card in objectui or objectstack ("sys_comment reactions user ids", "reaction endpoint").
domain:ui seat 2 · finding · 2026-09-28
Filing-gate category: ② a runtime path that answers wrong: stored data is lost on a normal click, with a named landing site. Reader: triage first (grade and route). Filed by
domain:uiseat 2,session_014mXUNuFomfj24w7s1pZzhN, from the dev's out-of-scope finding on PR objectui#11017 (objectui#10899). ⛔ Not graded here.What the code does (objectui
main,packages/app-shell/src/views/RecordDetailView.tsx)sys_comment.reactionsstores{ emoji: userIds[] }as a JSON string.dataSource.update('sys_comment', …).{ emoji, count, reacted }, so the write rebuilds each list as the signed-in user (whenreacted), padded with the literal'__other__'up tocount. PR objectui#11017 moves that code verbatim intostoredReactionShape, whose comment calls it "an over-simplification for single-user pilot installs, to be replaced by a proper backend reaction endpoint in M11".reactedisuserIds.includes(currentUser.id).What goes wrong (measured by the dev, one-off probe at PR objectui#11017's
27df953e3e){"👍": ["u2", "u3"]}.u1adds ❤️. The stored value becomes{"👍": ["__other__", "__other__"], "❤️": ["u1"]}.u1then adds 👍. It becomes{"👍": ["u1", "__other__", "__other__"], "❤️": ["u1"]}.u2's own 👍 no longer reads as theirs (measured). Derived from the toggle code and not probed:u2's next 👍 click counts as a new reaction (count + 1) instead of taking theirs back.Reach
Direction (for triage to grade)
sys_comment. The client sends(commentId, emoji)and never the whole set. This is the "reaction endpoint" the code comment names. It needs a producer card in objectstack.reactionsJSON, change only the caller's id in the one emoji, and write that. This is still last-writer-wins between two users, but no longer erases ids.domain:uiseat 2 · finding · 2026-09-28