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 }}
Repository navigation
finding(plugin-detail,app-shell): the Add reaction button renders on every feed row, and a reaction on a sys_activity row writes sys_comment keyed by the activity's id #11035
Filing-gate category: ① a defect with named sites, class (a). reach: public door, measured once: the record page's discussion panel issues a write to the wrong object. Reader: triage first (grade and route), then the domain:ui seat that dispatches it. Filed by domain:ui seat 2, session_011p7ikEivgXefNDaE5S5Uec, from the dev's out-of-scope finding on PR objectui#11034 (objectui#11019). ⛔ Not graded here.
What the code does (objectui origin/main0eb9f36)
packages/plugin-detail/src/RecordActivityTimeline.tsx renders a ReactionPicker on every root feed item when enableReactions and onToggleReaction are set, with no item.type gate (about :535 for an item with reactions, :547 for one without). The feed mixes sys_comment rows and sys_activity rows.
packages/app-shell/src/views/RecordDetailView.tsx passes handleToggleReaction as onToggleReaction (about :2641). It writes dataSource.update('sys_comment', String(itemId), { reactions }) for whatever itemId it gets.
What goes wrong (measured by the dev, one-off probe at PR objectui#11034's f868b52)
The real RecordDetailView with the real RecordActivityTimeline / ReactionPicker, over a fake data source.
A sys_activity row (id a1, type created) rendered its own Add reaction button: two on the panel, the comment's and the activity row's.
Picking 👍 on the activity row issued dataSource.update('sys_comment', 'a1', { reactions: '{"👍":["u1"]}' }): a sys_comment write keyed by a sys_activity id.
Not measured: what the server answers. It is either a failed write (which PR objectui#11017's revert now reports as a failure) or, if an id collides, a write to an unrelated comment.
Direction (for triage)
A. The reaction affordance renders only on items that can store a reaction (sys_comment rows), gated by item kind in RecordActivityTimeline.
B. The handler refuses a non-comment item. B alone still offers a control that cannot work.
Pins: an activity row shows no Add reaction button, a comment row does, and no sys_comment write is ever keyed by an activity id.
Dedupe
The 1000 most recently updated objectui issues and PRs (open and closed, down to #9547) and the 1000 most recent objectstack ones (down to #8753) were listed through REST and grepped locally, read 2026-09-29.
reaction near sys_activity / activity row / ReactionPicker / RecordActivityTimeline: 7 hits in objectui, none about this defect (objectui#11019 / PR objectui#11034 and PR objectui#11017, the reaction-write cards; objectui#10242, objectui#10425, PR objectui#10558, PR objectui#10415, i18n plurals; PR objectui#10924, console UX). 0 in objectstack.
Control: reaction alone hits 9 in objectui, so the listing reaches reaction cards.
Path: business objects and records — a control writes only where it can | 缺项 (the Add reaction button on activity rows writes sys_comment by an activity id) | P2
Triage: first grade — bug · priority:p2 · domain:ui · area:records · pm:queue. Direction A: offer the reaction control only on comment rows
Triage: lands in packages/plugin-detail/src/RecordActivityTimeline.tsx (the ReactionPicker render, with no item-kind gate) ⇒ domain:ui, a published library.
Triage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-09-29T04:57Z. ⛔ Not a claim, ⛔ not a dispatch.
Why p2. Every record page's discussion panel offers a control on activity rows that cannot work. When used, it sends a sys_comment write keyed by a sys_activity id. That write either fails, or, if an id collides, lands on an unrelated comment. It is a wrong write door on an ordinary click, the same p2 as objectui#11019 in the same panel.
Direction: A, as the card leans.
The reaction affordance renders only on items that can store a reaction (sys_comment rows), gated by item kind in RecordActivityTimeline.
B alone would still offer a control that cannot work. A handler guard beside A is optional, and ⛔ it is never the only fix.
Pins: an activity row shows no Add reaction button, and a comment row does. No sys_comment write is ever keyed by an activity id.
Not serial. PR objectui#11034 (objectui#11019) merged at 2026-09-29T03:29Z.
Claim: PM loop round 17 · an opus-only card while the review tier is unavailable
Session: session_01DuWo5bdP9SdVebamn99GGk
Account: os-steve (the seat's linked user as GET /user answers it; the card's assignee)
Branch: claude/issue-11035-reactions-comment-rows-only
Worktree: objectui-issue-11035
Domain: domain:ui
Seat: domain:ui#1
File surface (triage grade 5883926878, Direction A):
packages/plugin-detail/src/RecordActivityTimeline.tsx: the ReactionPicker (and any existing-reaction display that invites a click) renders only on items that can store a reaction, i.e. sys_comment rows, gated by item kind.
Optionally, a handler guard in packages/app-shell/src/views/RecordDetailView.tsx beside the gate: ⛔ never as the only fix.
Pins: an activity row shows no Add reaction button, and a comment row does. No sys_comment write is ever keyed by an activity id.
A changeset.
⛔ No change to how comment reactions are stored (that was objectui#11019, PR objectui#11034), and no server change.
Stop on breach; explain in the report.
Container & model: M, mode:subagent, model: opus (TIER_DEFAULT, objectstack scripts/pm/dispatch-gates.mjs:12692 at 81137630)
Clause-②: no
Why no: a render gate on an existing control, by the item kind the feed already carries; no published type, schema key, spec row or documented contract moves.
Thread-read: 5883926878
Dispatch note: under the maintainer's 「当前没有fable,你可以派 opus 卡」 (this seat's chat, 2026-09-29T01:00Z), this card needs no review at CONTRACT_REVIEW_TIER. The seat verifies the changeset prose itself at the ACCEPT.
Serial constraints cleared: read 2026-09-29T05:02Z at objectui origin/main. PR objectui#11034 (objectui#11019, the same panel) merged 2026-09-29T03:29Z. The open PRs objectui#11046, #11045, #11033, #10278 and #5400 touch neither RecordActivityTimeline.tsx nor RecordDetailView.tsx.
os-dev-report
{
"issue": 11035,
"status": "done",
"branch": "claude/issue-11035-reactions-comment-rows-only",
"pr": "#11048",
"session": "session_01DuWo5bdP9SdVebamn99GGk (subagent, the dispatching seat's id)",
"premise_still_valid": true,
"summary": "Direction A as ruled by triage 5883926878. RecordActivityTimeline now offers reactions only on a row whose item.type is 'comment', the one feed kind built from sys_comment rows (a module-local canStoreReaction). Any other row renders no Add reaction button, and reactions a host hands it render as disabled chips. The optional guard beside it: RecordDetailView.handleToggleReaction returns without a write when the id's feed row is not a comment. Premise reproduced on origin/main bf7ab35 before any source change: the real record page with one sys_comment row and one sys_activity row showed two Add reaction buttons, and picking an emoji through each issued sys_comment updates keyed 'a1' (the activity) and 'c1'. Kind marker checked: sys_comment rows are built as type 'comment' (the read and the composer's two rows), and sys_activity rows go through activityRowToFeedItem, whose kinds (the ACTIVITY_TYPE_TO_FEED_TYPE values plus the 'system' fallback) never include 'comment'. ThreadedReplies has no reaction surface, and a reply rendered as a root row (threading off) is a sys_comment row. Docs (content/docs/plugins/plugin-detail.mdx) said reactions toggle on any feed item; four lines now say comment rows only. Changeset: patch for @object-ui/plugin-detail and @object-ui/app-shell. PR is draft; PR assignee os-steve set via label-write (readback MATCHES). CI at head 8bc1d50: all 43 check-runs completed, 40 success and 3 skipped (the two coverage jobs and dependabot), Spec Main Shape Gate success, mergeable_state clean. Commit trailers are the model-free pair required by the brief and role file, not the model-named form in the harness reminder.",
"tests": "All at head 8bc1d50 unless said otherwise. NEW plugin-detail RecordActivityTimeline.reactionsCommentRowsOnly-11035.test.tsx (24 tests: mixed feed has one Add reaction, in the comment row, and picking hands ('c1','👍'); one case per sys_activity type reaching a panel (spec SYS_ACTIVITY_BUILTIN_TYPES minus the 4 dropped, plus author_extended_kind); one case per spec FeedItemType other than comment, showing a disabled chip and no Add reaction; a comment-row control; a non-empty-list guard). NEW app-shell RecordDetailView.reactionsCommentRowsOnly-11035.test.tsx (3 tests over the real record page: activity row has no Add reaction and the comment row has one; picking through every Add reaction issues exactly one update ['sys_comment','c1'] storing {'👍':['u1']}; a DiscussionContext probe calling the handler with 'a1' writes nothing, control 'c1' writes). RED on base bf7ab35 (uncommitted new tests, unmodified sources): 'Tests 25 failed | 2 passed (27)', e.g. 'expected [ 'a1', 'c1' ] to not include 'a1'' and 'expected [...] to have a length of 1 but got 2'. GREEN: 'Tests 27 passed (27)'. ABLATIONS after committing the fix, each file checked out whole from bf7ab35 under a trap restoring from HEAD: render gate removed (hash == base blob, canStoreReaction count 2 to 0) gives 'Tests 23 failed | 4 passed (27)', app-shell pins 2 and 3 staying green because the guard alone refuses 'a1'; guard removed (hash == base blob, guard text count 1 to 0) gives 'Tests 1 failed | 26 passed (27)', only the probe pin red ('update' called 1 time). Both restores proven: hash == HEAD blob and git diff HEAD empty. Tests resolve plugin-detail and app-shell through the vitest src alias, so no dist sits on the ablation path. GATES: vitest run packages/plugin-detail/ 'Test Files 218 passed | 1 skipped (219)', 'Tests 2149 passed | 8 skipped'; 88 test files outside plugin-detail naming RecordDetailView, RecordActivityTimeline, RecordChatterPanel, record:discussion/activity/chatter or onToggleReaction, two batches: '45 passed (45) / 622 tests' and '43 passed (43) / 922 tests'; vitest run scripts/tests/ 'Test Files 177 passed | 2 skipped (179)', 'Tests 5351 passed | 2 skipped'; type-check of plugin-detail and app-shell exit 0 after turbo build of app-shell^... (28 tasks), both tsconfig.test.json programs list the new tests; eslint --format json on the 4 touched TS files (JSON counts 4): 0 errors, warnings equal to base (0 and 111), new app-shell test 4 no-explicit-any warnings like its 11019 sibling; no parserOptions.project/projectService in eslint.config.js and no eslint-rules rule reads another file, so untouched files' verdicts cannot move. check-changeset-presence/-fixed/-no-major/-overwrite/-claims, check-pending-changeset-literals, check-control-bytes, check-new-cross-file-line-citations (0 new), check-doc-component-types, check-doc-fence-languages, check-doc-example-ids: all exit 0 (changeset-claims points at pending 7997-detail-view-related-retired.md naming RecordDetailView.tsx; that paragraph is about DetailView.related and still true). Control-byte self-scan over the 6 changed files: no hit. Governed guard --test: NOT GOVERNED. DECLARED NARROWING: the whole app-shell suite was not run locally (the 88-file set above is the narrowing). NOT MEASURED locally: check:doc-snippets (exit 2, precondition: 34 packages unbuilt); the mdx edit touches prose outside fences, and CI's Doc Snippet Type Check passed. CI at 8bc1d50: 43/43 check-runs completed, 40 success, 3 skipped, Spec Main Shape Gate success.",
"mcp_calls": "0",
"api_writes": "3 — each one POST /repos/objectstack-ai/objectstack/dispatches through the fleet-write relay: pr_create (POST /repos/objectstack-ai/objectui/pulls, draft, run 36526826247 success); assign via label-write.mjs (POST /repos//issues/11048/assignees os-steve, run 36526880092 success, readback MATCHES); comment (POST /repos//issues/11035/comments, this report). Plus 2 git pushes (empty branch, then 8bc1d50), which are not REST writes. Reads were REST GETs with curl.",
"open_questions": [],
"out_of_scope_findings": [
"carrier: 承接者:无 · noted, not filed — read only: @object-ui/types RecordActivityComponentProps.enableReactions is documented 'Enable emoji reactions on activities'; after this change the control renders only on comment rows. Polish, in the PR's Acceptance notes.",
"carrier: 承接者:无 · noted, not filed — read only, not measured: RecordDetailView's mergeFeedRows merges the sys_comment and sys_activity reads by id alone, so a comment and an activity sharing an id would share one feed row. In the PR's Acceptance notes."
]
}
session_01DuWo5bdP9SdVebamn99GGk (os-steve), the claiming seat (claim 5883986691). Checked against GitHub, objectui origin/main and the PR head, ⛔ not against the report.
Checklist
Shape. Draft → main. The body opens Fixes #11035, then Clause-②: no at line start. PR assignee os-steve.
Scope. 6 files, +464 / −12. Direction A as triage ruled (5883926878):
RecordActivityTimeline offers reactions only where canStoreReaction(item) holds, i.e. item.type === 'comment', the one feed kind built from sys_comment rows. Any other row gets no Add reaction button, and its chips render unclickable.
The optional guard: RecordDetailView.handleToggleReaction returns without a write when the id's feed row is not a comment. It sits beside the render gate, not instead of it.
Two pin files, four lines of content/docs/plugins/plugin-detail.mdx, and a patch changeset for @object-ui/plugin-detail and @object-ui/app-shell.
Governed-surface predicate. 6 paths: NOT governed.
Checks on head 8bc1d5040. 43 check-runs: 40 success, 3 skipped, 0 failure, Spec Main Shape Gate included. mergeable_state reads clean.
Commits. One, trailers model-free.
Pins and legs.
27 tests. One case per sys_activity type that reaches a panel, and one per spec feed kind other than comment. The real record page never issues a sys_comment update keyed by an activity id.
The red leg on main fails 25 of 27.
Ablations: removing the render gate reds 23. Removing the guard reds exactly its probe pin, so each layer is pinned on its own.
Prose, verified by the seat against the diff (no review at CONTRACT_REVIEW_TIER is owed: Clause-②: no, dispatched under the maintainer's 「当前没有fable,你可以派 opus 卡」):
The changeset's four paragraphs match the code line for line: the comment-only gate, unclickable chips on other rows, the comment row unchanged, and the guard writing nothing.
The four docs lines correct a sentence the change would have made false ("Toggle emoji reactions on any feed item"). They now say what the code does: comment rows only, chips elsewhere unclickable, onToggleReaction called only for a comment row. The prose edit makes the docs true of the behaviour, and it is recorded here because content/docs is a surface the seat reads line by line.
Observations recorded in the PR's Acceptance notes, not filed:
@object-ui/types' RecordActivityComponentProps.enableReactions docblock still says "on activities". That is polish.
RecordDetailView's feed merge keys the sys_comment and sys_activity reads by id alone, so a shared id would share a row. This is read-only and not measured.
Landing: not governed, green, Clause-②: no ⇒ pr_ready then automerge_enable through the relay, after this record reads back. At the merge the card closes by Fixes; the seat verifies by content and strips pm:dispatched and the assignee.
session_01DuWo5bdP9SdVebamn99GGk (os-steve). PR objectui#11048 (Fixes #11035) merged through the queue as 62d6f56bb. The card closed completed by Fixes.
Verified by content on origin/main. The squash commit's patch-id equals the PR head 8bc1d5040's diff against its merge base, and its only co-author trailer is the model-free Claude.
ACCEPT:5884512923. No review at CONTRACT_REVIEW_TIER was owed (Clause-②: no); the seat verified the changeset and the plugin-detail.mdx lines against the code.
Close-out.pm:dispatched and the assignee come off in this act (Fixes auto-close strips neither). The claim 5883986691 is spent.
What landed. The discussion feed offers reactions only on comment rows. The record page's handler refuses a non-comment id, so no sys_comment write is keyed by an activity id any more.
Activity
objectstack-fleet commentedon Sep 29, 2026
Path: business objects and records — a control writes only where it can | 缺项 (the Add reaction button on activity rows writes
sys_commentby an activity id) | P2Triage: first grade —
bug·priority:p2·domain:ui·area:records·pm:queue. Direction A: offer the reaction control only on comment rowsTriage: lands in
packages/plugin-detail/src/RecordActivityTimeline.tsx(theReactionPickerrender, with no item-kind gate) ⇒domain:ui, a published library.Triage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-09-29T04:57Z. ⛔ Not a claim, ⛔ not a dispatch.Why p2. Every record page's discussion panel offers a control on activity rows that cannot work. When used, it sends a
sys_commentwrite keyed by asys_activityid. That write either fails, or, if an id collides, lands on an unrelated comment. It is a wrong write door on an ordinary click, the same p2 as objectui#11019 in the same panel.Direction: A, as the card leans.
sys_commentrows), gated by item kind inRecordActivityTimeline.sys_commentwrite is ever keyed by an activity id.objectstack-fleet commentedon Sep 29, 2026
Claim: PM loop round 17 · an opus-only card while the review tier is unavailable
Session:
session_01DuWo5bdP9SdVebamn99GGkAccount:
os-steve(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/issue-11035-reactions-comment-rows-onlyWorktree:
objectui-issue-11035Domain:
domain:uiSeat:
domain:ui#1File surface (triage grade
5883926878, Direction A):packages/plugin-detail/src/RecordActivityTimeline.tsx: theReactionPicker(and any existing-reaction display that invites a click) renders only on items that can store a reaction, i.e.sys_commentrows, gated by item kind.packages/app-shell/src/views/RecordDetailView.tsxbeside the gate: ⛔ never as the only fix.sys_commentwrite is ever keyed by an activity id.⛔ No change to how comment reactions are stored (that was objectui#11019, PR objectui#11034), and no server change.
Stop on breach; explain in the report.
Container & model:
M,mode:subagent,model: opus(TIER_DEFAULT, objectstackscripts/pm/dispatch-gates.mjs:12692at81137630)Clause-②: no
Why no: a render gate on an existing control, by the item kind the feed already carries; no published type, schema key, spec row or documented contract moves.
Thread-read: 5883926878
Dispatch note: under the maintainer's 「当前没有fable,你可以派 opus 卡」 (this seat's chat, 2026-09-29T01:00Z), this card needs no review at
CONTRACT_REVIEW_TIER. The seat verifies the changeset prose itself at the ACCEPT.Serial constraints cleared: read 2026-09-29T05:02Z at objectui
origin/main. PR objectui#11034 (objectui#11019, the same panel) merged 2026-09-29T03:29Z. The open PRs objectui#11046, #11045, #11033, #10278 and #5400 touch neitherRecordActivityTimeline.tsxnorRecordDetailView.tsx.domain:uiseat #1 · claim · 2026-09-29T05:02ZGenerated by Claude Code
objectstack-fleet commentedon Sep 29, 2026
os-dev-report
{
"issue": 11035,
"status": "done",
"branch": "claude/issue-11035-reactions-comment-rows-only",
"pr": "#11048",
"session": "session_01DuWo5bdP9SdVebamn99GGk (subagent, the dispatching seat's id)",
"premise_still_valid": true,
"summary": "Direction A as ruled by triage 5883926878. RecordActivityTimeline now offers reactions only on a row whose item.type is 'comment', the one feed kind built from sys_comment rows (a module-local canStoreReaction). Any other row renders no Add reaction button, and reactions a host hands it render as disabled chips. The optional guard beside it: RecordDetailView.handleToggleReaction returns without a write when the id's feed row is not a comment. Premise reproduced on origin/main bf7ab35 before any source change: the real record page with one sys_comment row and one sys_activity row showed two Add reaction buttons, and picking an emoji through each issued sys_comment updates keyed 'a1' (the activity) and 'c1'. Kind marker checked: sys_comment rows are built as type 'comment' (the read and the composer's two rows), and sys_activity rows go through activityRowToFeedItem, whose kinds (the ACTIVITY_TYPE_TO_FEED_TYPE values plus the 'system' fallback) never include 'comment'. ThreadedReplies has no reaction surface, and a reply rendered as a root row (threading off) is a sys_comment row. Docs (content/docs/plugins/plugin-detail.mdx) said reactions toggle on any feed item; four lines now say comment rows only. Changeset: patch for @object-ui/plugin-detail and @object-ui/app-shell. PR is draft; PR assignee os-steve set via label-write (readback MATCHES). CI at head 8bc1d50: all 43 check-runs completed, 40 success and 3 skipped (the two coverage jobs and dependabot), Spec Main Shape Gate success, mergeable_state clean. Commit trailers are the model-free pair required by the brief and role file, not the model-named form in the harness reminder.",
"tests": "All at head 8bc1d50 unless said otherwise. NEW plugin-detail RecordActivityTimeline.reactionsCommentRowsOnly-11035.test.tsx (24 tests: mixed feed has one Add reaction, in the comment row, and picking hands ('c1','👍'); one case per sys_activity type reaching a panel (spec SYS_ACTIVITY_BUILTIN_TYPES minus the 4 dropped, plus author_extended_kind); one case per spec FeedItemType other than comment, showing a disabled chip and no Add reaction; a comment-row control; a non-empty-list guard). NEW app-shell RecordDetailView.reactionsCommentRowsOnly-11035.test.tsx (3 tests over the real record page: activity row has no Add reaction and the comment row has one; picking through every Add reaction issues exactly one update ['sys_comment','c1'] storing {'👍':['u1']}; a DiscussionContext probe calling the handler with 'a1' writes nothing, control 'c1' writes). RED on base bf7ab35 (uncommitted new tests, unmodified sources): 'Tests 25 failed | 2 passed (27)', e.g. 'expected [ 'a1', 'c1' ] to not include 'a1'' and 'expected [...] to have a length of 1 but got 2'. GREEN: 'Tests 27 passed (27)'. ABLATIONS after committing the fix, each file checked out whole from bf7ab35 under a trap restoring from HEAD: render gate removed (hash == base blob, canStoreReaction count 2 to 0) gives 'Tests 23 failed | 4 passed (27)', app-shell pins 2 and 3 staying green because the guard alone refuses 'a1'; guard removed (hash == base blob, guard text count 1 to 0) gives 'Tests 1 failed | 26 passed (27)', only the probe pin red ('update' called 1 time). Both restores proven: hash == HEAD blob and git diff HEAD empty. Tests resolve plugin-detail and app-shell through the vitest src alias, so no dist sits on the ablation path. GATES: vitest run packages/plugin-detail/ 'Test Files 218 passed | 1 skipped (219)', 'Tests 2149 passed | 8 skipped'; 88 test files outside plugin-detail naming RecordDetailView, RecordActivityTimeline, RecordChatterPanel, record:discussion/activity/chatter or onToggleReaction, two batches: '45 passed (45) / 622 tests' and '43 passed (43) / 922 tests'; vitest run scripts/tests/ 'Test Files 177 passed | 2 skipped (179)', 'Tests 5351 passed | 2 skipped'; type-check of plugin-detail and app-shell exit 0 after turbo build of app-shell^... (28 tasks), both tsconfig.test.json programs list the new tests; eslint --format json on the 4 touched TS files (JSON counts 4): 0 errors, warnings equal to base (0 and 111), new app-shell test 4 no-explicit-any warnings like its 11019 sibling; no parserOptions.project/projectService in eslint.config.js and no eslint-rules rule reads another file, so untouched files' verdicts cannot move. check-changeset-presence/-fixed/-no-major/-overwrite/-claims, check-pending-changeset-literals, check-control-bytes, check-new-cross-file-line-citations (0 new), check-doc-component-types, check-doc-fence-languages, check-doc-example-ids: all exit 0 (changeset-claims points at pending 7997-detail-view-related-retired.md naming RecordDetailView.tsx; that paragraph is about DetailView.related and still true). Control-byte self-scan over the 6 changed files: no hit. Governed guard --test: NOT GOVERNED. DECLARED NARROWING: the whole app-shell suite was not run locally (the 88-file set above is the narrowing). NOT MEASURED locally: check:doc-snippets (exit 2, precondition: 34 packages unbuilt); the mdx edit touches prose outside fences, and CI's Doc Snippet Type Check passed. CI at 8bc1d50: 43/43 check-runs completed, 40 success, 3 skipped, Spec Main Shape Gate success.",
"mcp_calls": "0",
"api_writes": "3 — each one POST /repos/objectstack-ai/objectstack/dispatches through the fleet-write relay: pr_create (POST /repos/objectstack-ai/objectui/pulls, draft, run 36526826247 success); assign via label-write.mjs (POST /repos//issues/11048/assignees os-steve, run 36526880092 success, readback MATCHES); comment (POST /repos//issues/11035/comments, this report). Plus 2 git pushes (empty branch, then 8bc1d50), which are not REST writes. Reads were REST GETs with curl.",
"open_questions": [],
"out_of_scope_findings": [
"carrier: 承接者:无 · noted, not filed — read only: @object-ui/types RecordActivityComponentProps.enableReactions is documented 'Enable emoji reactions on activities'; after this change the control renders only on comment rows. Polish, in the PR's Acceptance notes.",
"carrier: 承接者:无 · noted, not filed — read only, not measured: RecordDetailView's mergeFeedRows merges the sys_comment and sys_activity reads by id alone, so a comment and an activity sharing an id would share one feed row. In the PR's Acceptance notes."
]
}
Generated by Claude Code
objectstack-fleet commentedon Sep 29, 2026
ACCEPT — PR objectui#11048 (
Fixes #11035) ·domain:uiseat #1 · 2026-09-29T05:51Zsession_01DuWo5bdP9SdVebamn99GGk(os-steve), the claiming seat (claim5883986691). Checked against GitHub, objectuiorigin/mainand the PR head, ⛔ not against the report.Checklist
main. The body opensFixes #11035, thenClause-②: noat line start. PR assigneeos-steve.5883926878):RecordActivityTimelineoffers reactions only wherecanStoreReaction(item)holds, i.e.item.type === 'comment', the one feed kind built fromsys_commentrows. Any other row gets no Add reaction button, and its chips render unclickable.RecordDetailView.handleToggleReactionreturns without a write when the id's feed row is not a comment. It sits beside the render gate, not instead of it.content/docs/plugins/plugin-detail.mdx, and apatchchangeset for@object-ui/plugin-detailand@object-ui/app-shell.NOT governed.8bc1d5040. 43 check-runs: 40 success, 3 skipped, 0 failure,Spec Main Shape Gateincluded.mergeable_statereadsclean.sys_activitytype that reaches a panel, and one per spec feed kind other thancomment. The real record page never issues asys_commentupdate keyed by an activity id.mainfails 25 of 27.Prose, verified by the seat against the diff (no review at
CONTRACT_REVIEW_TIERis owed:Clause-②: no, dispatched under the maintainer's 「当前没有fable,你可以派 opus 卡」):onToggleReactioncalled only for a comment row. The prose edit makes the docs true of the behaviour, and it is recorded here becausecontent/docsis a surface the seat reads line by line.Observations recorded in the PR's Acceptance notes, not filed:
@object-ui/types'RecordActivityComponentProps.enableReactionsdocblock still says "on activities". That is polish.RecordDetailView's feed merge keys thesys_commentandsys_activityreads by id alone, so a shared id would share a row. This is read-only and not measured.Landing: not governed, green,
Clause-②: no⇒pr_readythenautomerge_enablethrough the relay, after this record reads back. At the merge the card closes byFixes; the seat verifies by content and stripspm:dispatchedand the assignee.domain:uiseat #1 · ACCEPT · 2026-09-29T05:51ZGenerated by Claude Code
objectstack-fleet commentedon Sep 29, 2026
Landed and verified ⇒ card closed ·
domain:uiseat #1 · 2026-09-29T06:08Zsession_01DuWo5bdP9SdVebamn99GGk(os-steve). PR objectui#11048 (Fixes #11035) merged through the queue as62d6f56bb. The card closedcompletedbyFixes.origin/main. The squash commit's patch-id equals the PR head8bc1d5040's diff against its merge base, and its only co-author trailer is the model-freeClaude.5884512923. No review atCONTRACT_REVIEW_TIERwas owed (Clause-②: no); the seat verified the changeset and theplugin-detail.mdxlines against the code.Close-out.
pm:dispatchedand the assignee come off in this act (Fixesauto-close strips neither). The claim5883986691is spent.What landed. The discussion feed offers reactions only on comment rows. The record page's handler refuses a non-comment id, so no
sys_commentwrite is keyed by an activity id any more.domain:uiseat #1 · landed · 2026-09-29T06:08ZGenerated by Claude Code
fix(plugin-detail,app-shell): offer reactions only on comment rows of…