plugin-security: a member cannot react to another user's comment — reactions are stored on the author's sys_comment row, and the created_by update floor refuses the write (403) #22500
Description
Activity
objectstack-fleet commented
on Oct 9, 2026 ContributorAuthorMore actionsTriage: first grade,
bug·priority:p2·domain:services·area:records,pm:blockedon the decision card #22505Triage seat (objectstack-wide, seat post #6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-09T15:54Z. ⛔ Not a claim, ⛔ not a dispatch.-
Why p2: members cannot react to anyone else's comment at all. The console offers the button on every comment, the click fails with 403, and an external app's guide promises the feature.
-
Why a decision, not a direction. The floor is deliberate: only the author updates a
sys_commentrow (plugin-security, with a moderation alternate). Each fix either loosens that floor, which is the maintainer's call, or changesreactions' published storage shape, which goes to the decision box. Filed as [Decision] comment reactions: members cannot react to another user's comment (the author-only update floor refuses it). Store each reaction as the reactor's own record, add one narrow reaction action, or open the floor for the column #22505:- A: each reaction is the reactor's own record;
- B: one narrow reaction action;
- C: a column exception to the floor;
- D: no member reactions.
The recommendation is A, with B as the fallback. ⛔ C loosens a security floor, and ⛔ D deletes a published capability.
-
⛔ The author-only edit of a comment's text stays under every option, as this card says.
-
Blocked-by: [Decision] comment reactions: members cannot react to another user's comment (the author-only update floor refuses it). Store each reaction as the reactor's own record, add one narrow reaction action, or open the floor for the column #22505 (now in this body). This card closes through the PR that executes the ruling.
-
- addedarea:recordsBusiness objects, records, the views that show data, usable forms, searchBusiness objects, records, the views that show data, usable forms, searchbugSomething isn't workingSomething isn't workingpriority:p2Medium: important, M3Medium: important, M3
on Oct 9, 2026 objectstack-fleet commented
on Oct 10, 2026 ContributorAuthorMore actionsBlocker moved ·
domain:servicesseat 1 (#6021) ·session_013j5gkUCpqQiti4GgPqqmnt· 2026-10-10T01:17Z- The decision is made. [Decision] comment reactions: members cannot react to another user's comment (the author-only update floor refuses it). Store each reaction as the reactor's own record, add one narrow reaction action, or open the floor for the column #22505 was ruled A, amended (
6091550406, supplement6091621568). A reaction becomes the reactor's ownsys_comment_reactionrecord.sys_comment.reactionsretires, with no aggregate and no data migration. The author-only floor onsys_commentstays. - The card this one waits on now is the platform card that executes the ruling, Comment reactions (ruling A amended on #22505): a reaction is the reactor's own
sys_comment_reactionrecord, andsys_comment.reactionsretires with no aggregate and no data migration #22566. This body'sBlocked-by:line was rewritten in this act, from [Decision] comment reactions: members cannot react to another user's comment (the author-only update floor refuses it). Store each reaction as the reactor's own record, add one narrow reaction action, or open the floor for the column #22505 to Comment reactions (ruling A amended on #22505): a reaction is the reactor's ownsys_comment_reactionrecord, andsys_comment.reactionsretires with no aggregate and no data migration #22566. The state stayspm:blocked. - The objectui half is the chatter's write and read of reaction records. It is asked of triage on [Decision] comment reactions: members cannot react to another user's comment (the author-only update floor refuses it). Store each reaction as the reactor's own record, add one narrow reaction action, or open the floor for the column #22505.
- Closing: this card closes on the PRs that execute the ruling (the record's Execution line). The member-visible fix needs both halves.
Generated by Claude Code
- The decision is made. [Decision] comment reactions: members cannot react to another user's comment (the author-only update floor refuses it). Store each reaction as the reactor's own record, add one narrow reaction action, or open the floor for the column #22505 was ruled A, amended (
objectstack-fleet commented
on Oct 10, 2026 ContributorAuthorMore actionsBlocker moved, and a hand-off for the application grant ·
domain:servicesseat 1 (#6021) ·session_013j5gkUCpqQiti4GgPqqmnt· 2026-10-10T06:25Z#22566 landed (PR #22603,
29a163f571onmain). A comment reaction is now its reactor's ownsys_comment_reactionrecord, one row per comment, emoji and user. A member reacts to any comment they can read, and deletes only their own reaction. The author-only edit rule onsys_commentis unchanged.This card stays
pm:blocked. Line 1 now readsBlocked-by: objectstack-ai/objectui#12078. The console's chatter still writessys_comment.reactionsuntil that card moves it to the new records. The column itself retires in #22573, after the console pin carries objectui#12078.Hand-off to the
repo:hotcrmseat (this session cannot write to hotcrm). The platform'severyonebaseline grants nothing on the new object, by the maintainer's ruling recorded onmember_default(seat answer6093553917on #22566, open to the maintainer's veto). An application that shows reactions grantssys_comment_reactionread, create and delete in the same permission set that grantssys_comment(objectstack-ai/hotcrm#2043 is where hotcrm grantssys_comment). The platform's own-record rule (owner_only_deletes) keeps a delete to the reactor, so the app's delete bit does not let a member remove another member's reaction. Without the grant, a member's first reaction answers a loud403, not a silent half-feature. The grant needs a hotcrm release that consumes the@objectstack/plugin-auditversion carrying #22566.
Generated by Claude Code
objectstack-fleet commented
on Oct 10, 2026 ContributorAuthorMore actionsUnlock scan: objectstack-ai/objectui#12078 closed (objectui
de302c7315), but the console pin does not carry it yet.pm:blocked→pm:on-holdTriage seat (objectstack-wide, seat post #6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-10T10:55Z. ⛔ Not a claim, ⛔ not a dispatch.Blocked-by: none
- What landed: objectui
mainde302c7315. The chatter reads and writes reactions as the member's ownsys_comment_reactionrecords (objectui PR [finding]CLAIM_COMMENT_MARKERneeds a colon, so 24 of 54 livepm:dispatchedclaims are invisible — H2 reports them as claimless and H20/H27 cannot see them at all #12090). - What has not happened yet: this repo's
.objectui-shais20c6d351ad(2026-10-09T22:57Z), which does not containde302c7315. The console this repo serves still writessys_comment.reactions. - Restart-when: objectstack's
.objectui-shacarries objectuide302c7315. Then:- this defect is fixed in the served console, and the card closes
completedafter one reading onmain: a member reacts to another member's comment; - the application grant noted in
6094633923(hotcrm'ssys_comment_reactionread, create and delete) stays with therepo:hotcrmseat.
- this defect is fixed in the served console, and the card closes
- What landed: objectui
Blocked-by: objectstack-ai/objectui#12078
Filing gate: ① product defect with reach measured. Class (a), user-visible. reach: REST
PATCH /api/v1/data/sys_comment/:idwith{ reactions }, and the console's reaction button on every comment. Measured on@objectstack/*17.7.0 by the dev of objectstack-ai/hotcrm#2029 (report6083534286there) on a freshobjectstack devbox, personana.rep(sales_rep+na_sales_team), withsys_commentread, create and edit granted (objectstack-ai/hotcrm#2043).Who acts on it: the objectstack triage seat routes it. Filed by the
repo:hotcrmseat,session_018Mk4tab2eCyY41UTWK7y7V. ⛔ Not a claim. hotcrm has nothing to change for it: its guidecontent/docs/guides/files-and-commentssays "React to a comment with an emoji", which becomes true for members when this is fixed (hotcrm AGENTS.md §2: wait, no workaround).What happens
sys_comment.reactions({ emoji: userIds[] }, the shape finding(plugin-audit):sys_comment.reactionsis described as "JSON array of emoji reaction objects", but its one reader and writer stores{ emoji: userIds[] }#20558 settled).sys_commentupdate floor lets only the row's author update it (created_by;plugin-security, deliberately, per its own comment). So a member's reaction click on someone else's comment is an update of another user's row, and is refused.Measured (17.7.0)
na.rep→PATCH sys_comment/ID{ reactions }on the admin's comment → 403PERMISSION_DENIED, on an account the rep can edit and on a quote and a contract they can read. The server logs "not permitted to update this sys_comment record (row-level security)".So a non-admin member can react only to their own comments; reacting is a social action on other people's comments, so in practice members cannot react at all.
Seam
spec:sys_comment.reactions(a column of the author's row) →runtime:plugin-securitysys_commentupdate floor →renderer:objectuichatter reaction click. The fix's shape (a narrow reaction write path, a separate reaction record, or a column-scoped exception to the floor) is the platform's to decide; ⛔ the author-only edit of a comment's text is correct and must stay.Duplicate check
Semantic issue search (MCP, this container's REST
/searchis refused): objectstack "sys_comment reactions non-author…" → #4630 (closed, comment authorization, which introduced the floor); "reactions column on sys_comment cannot be updated by other users" → #20558 (closed, the stored shape), #4630, #4756 (closed, unrelated columns); objectui "comment emoji reaction permission denied…" → objectui#11019 (closed, a click rewriting other users' ids). None is this defect.Dedupe words: sys_comment reactions 403 · react to comment permission · reactions created_by floor · chatter reaction non-author
Generated by Claude Code