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 }}
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Repository navigation
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
finding(components): an action:bar inline action authored with component: 'action:menu' or 'action:group' renders nothing — the action vanishes from the toolbar and a ?runAction= deep link to it runs nothing #10345
Ruled: 5825579152 · letter A (menu/group = placement on the bar) · 2026-09-25T02:17Z
Filing-gate category: ① a product defect with named sites and a reproduction. Reader: triage first (route and grade), then the domain:ui execution seat that claims it. The sites: packages/components/src/renderers/action/action-bar.tsx (the inline member dispatch) and the action:menu / action:group renderers.
Filed by the domain:ui#4 execution seat (session_01BP8CMtACxTdLjqR6rhd33C) from the os-dev-report of objectui#10274 (PR objectui#10342). The dev measured it; ⛔ it is filed bare, not graded here.
The defect
action:bar renders each inline action with the renderer its component names (action.component || 'action:button', then ComponentRegistry.get), and spreads the single action onto that renderer's schema. The spec's ActionSchema.component enum offers 'action:menu' and 'action:group', and the metadata-admin ActionDefaultInspector offers them as "Menu item" and "Button group". Both renderers read schema.actions, which a single action does not carry, and return null (action-menu.tsx: if (actions.length === 0) return null;). So:
the action disappears from the toolbar with no error and no author diagnostic;
a ?runAction= deep link to it is armed and consumed by the host, then runs nothing.
Reproduction (the dev's probe at PR head 3b6341b, not committed)
The setup is one action:bar with an unflagged control action plus one member flagged autoTrigger, with the member's component varied:
member component
executions
buttons rendered
action:button
1
Control, Member
action:icon (after PR objectui#10342)
1
Control, Member
action:menu
0
Control
action:group
0
Control
⚠️ These readings are the dev's, relayed by the seat, ⛔ not re-run by the seat.
Grading notes (for triage, not a grade)
Authorable today through a spec enum member and a designer option, and the failure is silent.
The fix direction is open. The bar could render a single-action member of these kinds as a button; the spec could refuse component: 'action:menu' | 'action:group' on a single action; or the renderers could accept a single action. That may be a small decision.
Seam: spec:ActionSchema.component ('action:menu' | 'action:group') → renderer:action:bar inline member dispatch → action:menu / action:group (read schema.actions, absent on a single action ⇒ null)
Dedupe
REST page walk over the 1000 most recently updated objectui items, pattern (action:menu|action:group) … (inline|member|bar) … (null|nothing|vanish|renders no) / action:bar … component … (menu|group) ⇒ 0 hits. Control pattern action:icon … autoTrigger ⇒ objectui#10274, the must-hit control, which did hit.
Dedupe words: component action:menu bar member renders nothing · action:group inline member vanishes · action:bar component override · autoTrigger menu member
Triage: lands in @object-ui/components ⇒ domain:ui, bug, priority:p2, needs-user-decision (finding removed — graded); rationale: @objectstack/spec's ActionSchema.component enum offers 'action:menu' ("Dropdown menu") and 'action:group' ("Button Group") and the metadata-admin inspector offers both, but action:bar hands a SINGLE action to renderers that read schema.actions and return null, so the action silently vanishes and a ?runAction= deep link runs nothing; the repair turns on what those two values MEAN for a single action (overflow placement, a one-button menu/group, or refusal in the spec), which is a contract-meaning call for the maintainer.
spec:ActionSchema.component 是 z.enum(['action:button', 'action:icon', 'action:menu' /* Dropdown menu */, 'action:group' /* Button Group */]),描述为「Visual component override」。上方注释写着「Defaults to 'button' or 'menu_item' based on location, but can be overridden」。
渲染:action-bar.tsx 本身已经有一个溢出菜单(「Render a single overflow menu … at most ONE "More" button per bar」),用的正是 ComponentRegistry.get('action:menu'),传进去的是 actions: combinedOverflow。
Ruling: batch #224 item 1 · letter A (a single action's action:menu / action:group is a PLACEMENT) · maintainer 「批 #224 同意」 (chat, director seat summon #29, session_01EcrTi7s5oDYPHS4Pi7h31d) 2026-09-25T02:15Z
Director seat, summon #29. Presented with recommendation A (fallback C); the maintainer agreed. Thread re-read to its last comment (5820756170) in this act.
Ruled: A. On an action:bar, a single action's component is read as where it goes, which is the spec's own comment: "Defaults to 'button' or 'menu_item' based on location, but can be overridden".
action:menu puts the action into the bar's existing single overflow menu (the one "More" button).
action:group renders it in a button group with its adjacent action:group members.
The dispatch lives in action-bar.tsx. ⛔ No contract change, and ⛔ the menu and group renderers are not taught to accept a single action (B).
The silent vanish is gone: every member renders somewhere, and a ?runAction= deep link to it runs.
Pins: the card's four-row probe (button, icon, menu, group), with run count and rendered placement for each, plus the deep-link case.
What counts as "adjacent" for action:group is the dev's to measure and state in the PR.
Execution: needs-user-decision → pm:queue in this stroke. Serial after objectui#10274 / PR #10342 (it also edits action-bar.tsx). priority:p2, bug and domain:ui stand.
packages/components/src/renderers/action/action-bar.tsx: the inline member dispatch and its docblock. It reads a single action's component: 'action:menu' as a place in the bar's one overflow menu, and 'action:group' as a place in a button group with its adjacent action:group members.
Tests beside it under packages/components/src/renderers/action/__tests__/.
One .changeset/10345-…md.
Stop on breach; explain in the report. Per the ruling, the action:menu / action:group renderers are ⛔ not taught to accept a single action, and no contract moves.
Container & model: M, mode:subagent, model: opus — executes ruling 5825579152 (letter A)
Clause-②: no
Thread-read: 5825579152
Serial constraints cleared:
The predecessor, objectui#10274's PR objectui#10342 (the last holder of action-bar.tsx), merged 2026-09-24T19:34Z.
The open-PR file lists read 2026-09-25T02:44Z show one hit, draft PR objectui#8941 (lucide bump). It edits one line of the docblock usage example in action-bar.tsx (the trash-2 icon), so it is hunk-disjoint from the member dispatch; this claim leaves that example line alone.
The live pm:dispatched claims of the other seats, read 2026-09-25T02:43Z, name no file under packages/components/src/renderers/action/.
Clause-②: no. The spec's ActionSchema.component enum already accepts both values; the bar starts honouring them as placement, as the spec's own comment says. No declared key, schema, export or accept set moves.
{
"issue": 10345,
"status": "done",
"branch": "claude/issue-10345-action-bar-menu-group-placement",
"pr": "https://github.com/objectstack-ai/objectui/pull/10470",
"session": "session_01BP8CMtACxTdLjqR6rhd33C — the dispatching seat's session; this subagent run carries the parent's id (the commit Claude-Session trailers and the fleet-write route derived from CLAUDE_CODE_REMOTE_SESSION_ID both name it)",
"premise_still_valid": true,
"summary": "Ruling A is carried entirely inside action-bar.tsx. A member authored component 'action:menu' is taken out before the maxVisible split and placed in the bar's one existing overflow menu. A member authored 'action:group' renders inline through the action:button renderer, inside the existing custom ButtonGroup primitive (role=group), shared with the adjacent action:group members of the drawn inline row; the docblock's opening paragraph now says this, and the trash-2 example line is untouched. A2 measured: action-group.tsx draws its own InlineActionButton, which consumes no autoTrigger and gates visible fail-soft, so routing grouped members through that renderer would leave the deep link dead. Having the bar draw the group, with action:button members, is the compliant route inside the file surface; no needs_decision fork was needed, action-menu.tsx and action-group.tsx are untouched, and no contract moved. A1 held (the menu's existing ActionAutoTrigger runs a menu-placed member's deep link). A3: menu-placed members do not count toward maxVisible. A4: the overflow order is the spilled actions, then the menu-placed ones, each in bar order, then the separator and the system actions (page:header's relative order). A5 is pinned for both placements. One pending changeset sentence was corrected (see tests). The coordinator's resume note said no branch existed; in fact the empty-branch probe push had landed at 0348bc9f1 before the 429 cut, and the work continued on it.",
"tests": "All readings are at HEAD da122c4cf. (1) New suite action-bar-member-placement-10345.test.tsx: 21/21 passed. It holds the card's four-row probe (button, icon, menu and group rows each read 1 run, placed inline / inline / More menu / button group), the deep-link rows (armed the way ObjectView maps ?runAction=, run once, re-renders with fresh objects do not re-run, unflagged runs nothing), A3/A4 accounting and order, 'adjacent' semantics, and A5 gates (hidden menu member stays hidden and its deep link is refused with the objectui#4191 notice; hidden group member not drawn; disabled menu item; requiredPermissions at both placements, each with a held-capability control leg). (2) Reverse proof, run under trap-restore from the committed fix: action-bar.tsx was replaced with its BASE 0348bc9f1 blob, removing the placement branch. On disk before: inlineRow=2, inlineActions.map=0; after: inlineRow=0, inlineActions.map=1, and the hash e986327a equalled the base blob. The suite read 'Tests 19 failed | 2 passed (21)'. The 2 passing are the action:button/action:icon probe rows, which are correct in both worlds. The menu/group probe rows read 'expected vi.fn() to be called 1 times, but got 0 times'. The restore used git checkout HEAD; the hash dd60d8a9 equalled the HEAD blob and git diff HEAD was 0 lines. The first ablation run exposed the two requiredPermissions rows as vacuous (they stayed green because the defect also reads absent), so held control legs were added and the ablation re-run. (3) Targeted vitest over 38 files (32 @object-ui/components suites: every one naming action-bar, action:bar, action:menu, action:group or useAutoTriggerOnce, plus every file under renderers/action/__tests__; 4 app-shell deep-link consumers: EnvironmentListToolbar deepLinkArming/deepLinkOverflow/main and useOfferedNavRunAction; 2 script pins naming action:bar): 'Test Files 38 passed (38) / Tests 668 passed (668)', lock VERDICT command-exit 0. (4) Closure build pnpm --filter '@object-ui/components^...' build: exit 0, 8 of 47 projects. Then pnpm --filter @object-ui/components type-check (tsc --noEmit AND tsc -p tsconfig.test.json): exit 0, and --listFiles confirms both configs include action-bar.tsx and the new test. (5) eslint on the 2 touched source files with the repo config: 0 errors; 5 warnings, the same 5 as on the BASE blob, all on untouched lines. (6) check-changeset-presence 0, check-changeset-no-major 0, check:new-line-citations 0 (0 new citations), check:control-bytes 0, check:changeset-claims 0 ('No pending changeset names a file this change touches'), check-vi-mock-override-shape 0, check-test-path-roots 0, check-lint-coverage 0. (7) Changesets: new .changeset/10345-action-bar-menu-group-placement.md ('@object-ui/components': patch). The pending objectui#10274 changeset's sentence 'action:bar renders each inline action with the renderer its component names' became false (an inline action:group member now renders through action:button), so it was narrowed to action:button / action:icon, body only; the front-matter md5 is unchanged. The pending 6306, 7415, 4191 and 5493 changesets were read and judged still true (their spread and 'decided by maxVisible' sentences describe members whose component does not place them; the literal 'type: componentType, actionType: action.type' spread is kept). Local gates were hand-derived from objectui package.json and lint.yml, since dispatch-gates.mjs does not cover objectui. NOT MEASURED: the ButtonGroup's rendered look in a real browser (jsdom computes no Tailwind, so the attached styling and empty:hidden were not observed). The CI farm (pnpm lint, full pnpm test shards, Build & E2E) is left to CI; its state is in_progress/unread at report time.",
"mcp_calls": "0 — no MCP GitHub tools called",
"api_writes": "2 — both via the fleet-write relay as objectstack-fleet[bot] (each one repository_dispatch POST /repos/objectstack-ai/objectstack/dispatches): (1) pr_create, i.e. POST /repos/objectstack-ai/objectui/pulls, draft=true, opening #10470, relay run 36092791117 concluded success; (2) this os-dev-report comment, POST /repos/objectstack-ai/objectui/issues/10345/comments via post-stamped.mjs. Plus git push (not REST): the empty-branch probe, then three pushes of the branch. No label writes (objectui labels are path-synced by labeler.yml and the dispatch named none). No PR body PATCH.",
"open_questions": [],
"out_of_scope_findings": [
"carrier: 承接者:无 · noted, not filed (dormant, zero producer) — action:group's own leaves (InlineActionButton, DropdownActionItem in action-group.tsx) consume no autoTrigger, while auto-trigger.ts states 'every renderer that can receive an action consumes it'. No host sends a flagged action into a standalone action:group today; the ?runAction= host (ObjectView, EnvironmentListToolbar) composes an action:bar. Recorded in PR #10470 Acceptance notes.",
"carrier: 承接者:无 · noted, not filed (pre-existing observation) — an overflow whose every entry is hidden by its own visible still renders an empty More trigger; this was already true for spilled actions before this change. Recorded in PR #10470 Acceptance notes."
]
}
✅ ACCEPT: objectui#10470 at da122c4, landing now (ready → merge queue)
domain:ui seat #4, session_01BP8CMtACxTdLjqR6rhd33C. I read the dev report 5826498127 and checked it against the diff, the tree and CI. The contract-review record is on the PR. This executes ruling 5825579152 (letter A): on an action:bar, a single action's component is its PLACEMENT.
The member leaves the row candidates before the maxVisible cut and joins the bar's one existing overflow menu, after the spilled actions and before the separator and system actions (page:header's relative order). It spends no inline slot, and an overflow holding only such members still draws exactly one More button. Its deep link runs through the menu's existing per-action ActionAutoTrigger (A1)
action:group
Consecutive action:group members of the drawn inline row (after ordering, the maxVisible cut and menu placement) render through the action:button renderer inside the repo's ButtonGroup primitive (role="group"). [G1, G2, Plain, G3] gives two groups. A group tail cut by maxVisible lands in the More menu as plain items. That is the dev's measured reading of "adjacent", as the ruling left it
why not the action:group renderer
Its leaves consume no autoTrigger and gate visible fail-soft, so routing members there would leave the ruling's deep-link requirement unmet. Fixing that means editing action-group.tsx, outside the claim. The bar-drawn group is the in-surface compliant route: the reviewer judged it within the ruling's letter, not a quiet fork. ⛔ action-menu.tsx and action-group.tsx are untouched, and no contract moved
gates
requiredPermissions, visible (fail-closed) and disabled gate a relocated member exactly as they gate an inline one (A5)
unchanged bars
A bar with no menu or group member renders the same element tree: the same slices, keys, spread and data
pins
21 cases on the real registered renderers under a real ActionProvider, with no module mocks. Reverting the file to base gives 19 red and 2 green (the button and icon rows, correct in both worlds). The two requiredPermissions rows carry held-capability control legs, so they are not vacuous
surface
The claim's three items, plus .changeset/10274-action-icon-auto-trigger.md: body only, frontmatter sha256 identical at base and head. Ratified here. Its sentence "action:bar renders each inline action with the renderer its component names" was true at base and becomes false with this PR, because an inline action:group member now renders through action:button. Correcting it in the same PR is what .claude/agents/os-dev.md requires. The trash-2 example line is byte-identical, which keeps it hunk-disjoint from draft PR objectui#8941
changesets
Every sentence is true at head. patch on @object-ui/components. The pending 6306, 7415, 4191 and 5493 changesets stay true
Clause-②
no. Both enum values were already legal and now render. No export or accepted set moves
boundary
Fixes #10345 is the only closing keyword, and there are no model identifiers
CI
43 check-runs on da122c4: 40 success, 3 skipped by design, 0 red
The look differs. A bar-drawn group is the ButtonGroup primitive, an attached segmented control. A standalone action:group renders a gapped row. The ruling's "a button group" is met by the repo primitive of that name. The rendered look and the all-members-hidden empty:hidden collapse were not observed in a real browser (jsdom).
An overflow whose every entry is hidden by its own visible still shows an empty More trigger. This was already true for spilled actions, and a menu-placed member can now reach it too. Dropped: pre-existing, and a hidden entry's gate is doing its job.
action-icon.tsx and action-icon-autotrigger.test.tsx keep a comment saying the bar renders an inline member with the renderer its component names. It is still true for action:icon members, but it reads more general than it is. Dropped: comment wording only.
Activity
objectstack-fleet commentedon Sep 24, 2026
分诊首次定级:
priority:p2·bug·domain:ui·needs-user-decision—— 工具栏里把一个动作的显示方式设成「下拉菜单」或「按钮组」,这个动作就从工具栏上消失了,深链接也执行不了;设计器里明明提供这两个选项,而「单个动作设成菜单是什么意思」需要维护者定Path:
packages/components/src/renderers/action/action-bar.tsx(按action.component || 'action:button'取渲染器,把单个动作铺进它的 schema)→action-menu.tsx(if (actions.length === 0) return null;)/action:groupTriage: lands in
@object-ui/components⇒domain:ui,bug,priority:p2,needs-user-decision(findingremoved — graded); rationale:@objectstack/spec'sActionSchema.componentenum offers'action:menu'("Dropdown menu") and'action:group'("Button Group") and the metadata-admin inspector offers both, butaction:barhands a SINGLE action to renderers that readschema.actionsand returnnull, so the action silently vanishes and a?runAction=deep link runs nothing; the repair turns on what those two values MEAN for a single action (overflow placement, a one-button menu/group, or refusal in the spec), which is a contract-meaning call for the maintainer.分诊席 #6015,2026-09-24T19:26Z。⛔ 不认领、不派发。本席读完了卡面(本卡尚无评论),并在 objectui
origin/main1f8ef0a8和 objectstackorigin/mainb81da66df7上核对。本席核对
ActionSchema.component是z.enum(['action:button', 'action:icon', 'action:menu' /* Dropdown menu */, 'action:group' /* Button Group */]),描述为「Visual component override」。上方注释写着「Defaults to 'button' or 'menu_item' based on location, but can be overridden」。action-bar.tsx本身已经有一个溢出菜单(「Render a single overflow menu … at most ONE "More" button per bar」),用的正是ComponentRegistry.get('action:menu'),传进去的是actions: combinedOverflow。action:menu/action:group成员执行 0 次、不渲染按钮)是 finding(components):action:iconnever consumesautoTrigger— a?runAction=deep link to an icon-rendered toolbar action is armed, consumed, and does nothing (the #4162 signature on a third renderer) #10274 的开发在 PR fix(components): action:icon consumes autoTrigger through the shared hook (objectui#10274) #10342 的 head 上测的,本席没有重跑。需要维护者决定:单个动作的
component: 'action:menu' | 'action:group'是什么意思action:menu表示把这个动作放进工具栏已有的「更多」下拉菜单;action:group表示把它和相邻动作渲染成一个按钮组。action-bar.tsx的分发逻辑,不改契约。⇒ 不管选哪个,今天的「静默消失」都必须消除。
定级说明
p2:设计器里可选、spec 里合法,结果动作静默消失,深链接也什么都不执行。不给 p1:不涉及数据或权限,只有专门选了这两个值才会触发。
裁决后的执行要点
action-bar.tsx正被 finding(components):action:iconnever consumesautoTrigger— a?runAction=deep link to an icon-rendered toolbar action is armed, consumed, and does nothing (the #4162 signature on a third renderer) #10274 的 PR fix(components): action:icon consumes autoTrigger through the shared hook (objectui#10274) #10342 修改(action:icon成员),⛔ 排在它后面,或者在它落地之后再动手。?runAction=指向这类成员时,必须能执行。Generated by Claude Code
objectstack-fleet commentedon Sep 25, 2026
Ruling: batch #224 item 1 · letter A (a single action's
action:menu/action:groupis a PLACEMENT) · maintainer 「批 #224 同意」 (chat, director seat summon #29,session_01EcrTi7s5oDYPHS4Pi7h31d) 2026-09-25T02:15ZDirector seat, summon #29. Presented with recommendation A (fallback C); the maintainer agreed. Thread re-read to its last comment (5820756170) in this act.
Ruled: A. On an
action:bar, a single action'scomponentis read as where it goes, which is the spec's own comment: "Defaults to 'button' or 'menu_item' based on location, but can be overridden".action:menuputs the action into the bar's existing single overflow menu (the one "More" button).action:grouprenders it in a button group with its adjacentaction:groupmembers.action-bar.tsx. ⛔ No contract change, and ⛔ the menu and group renderers are not taught to accept a single action (B).?runAction=deep link to it runs.action:groupis the dev's to measure and state in the PR.Execution:
needs-user-decision→pm:queuein this stroke. Serial after objectui#10274 / PR #10342 (it also editsaction-bar.tsx).priority:p2,buganddomain:uistand.Generated by Claude Code
objectstack-fleet commentedon Sep 25, 2026
Claim: PM loop round 1 —
domain:uiexecution seat 4Session:
session_01BP8CMtACxTdLjqR6rhd33CBranch:
claude/issue-10345-action-bar-menu-group-placementWorktree:
objectui-issue-10345Domain:
domain:uiSeat:
domain:ui#4File surface:
packages/components/src/renderers/action/action-bar.tsx: the inline member dispatch and its docblock. It reads a single action'scomponent: 'action:menu'as a place in the bar's one overflow menu, and'action:group'as a place in a button group with its adjacentaction:groupmembers.packages/components/src/renderers/action/__tests__/..changeset/10345-…md.Stop on breach; explain in the report. Per the ruling, the
action:menu/action:grouprenderers are ⛔ not taught to accept a single action, and no contract moves.Container & model:
M,mode:subagent,model: opus— executes ruling5825579152(letter A)Clause-②: no
Thread-read: 5825579152
Serial constraints cleared:
action-bar.tsx), merged 2026-09-24T19:34Z.action-bar.tsx(thetrash-2icon), so it is hunk-disjoint from the member dispatch; this claim leaves that example line alone.pm:dispatchedclaims of the other seats, read 2026-09-25T02:43Z, name no file underpackages/components/src/renderers/action/.Clause-②: no. The spec'sActionSchema.componentenum already accepts both values; the bar starts honouring them as placement, as the spec's own comment says. No declared key, schema, export or accept set moves.Generated by Claude Code
objectstack-fleet commentedon Sep 25, 2026
os-dev-report
{ "issue": 10345, "status": "done", "branch": "claude/issue-10345-action-bar-menu-group-placement", "pr": "https://github.com/objectstack-ai/objectui/pull/10470", "session": "session_01BP8CMtACxTdLjqR6rhd33C — the dispatching seat's session; this subagent run carries the parent's id (the commit Claude-Session trailers and the fleet-write route derived from CLAUDE_CODE_REMOTE_SESSION_ID both name it)", "premise_still_valid": true, "summary": "Ruling A is carried entirely inside action-bar.tsx. A member authored component 'action:menu' is taken out before the maxVisible split and placed in the bar's one existing overflow menu. A member authored 'action:group' renders inline through the action:button renderer, inside the existing custom ButtonGroup primitive (role=group), shared with the adjacent action:group members of the drawn inline row; the docblock's opening paragraph now says this, and the trash-2 example line is untouched. A2 measured: action-group.tsx draws its own InlineActionButton, which consumes no autoTrigger and gates visible fail-soft, so routing grouped members through that renderer would leave the deep link dead. Having the bar draw the group, with action:button members, is the compliant route inside the file surface; no needs_decision fork was needed, action-menu.tsx and action-group.tsx are untouched, and no contract moved. A1 held (the menu's existing ActionAutoTrigger runs a menu-placed member's deep link). A3: menu-placed members do not count toward maxVisible. A4: the overflow order is the spilled actions, then the menu-placed ones, each in bar order, then the separator and the system actions (page:header's relative order). A5 is pinned for both placements. One pending changeset sentence was corrected (see tests). The coordinator's resume note said no branch existed; in fact the empty-branch probe push had landed at 0348bc9f1 before the 429 cut, and the work continued on it.", "tests": "All readings are at HEAD da122c4cf. (1) New suite action-bar-member-placement-10345.test.tsx: 21/21 passed. It holds the card's four-row probe (button, icon, menu and group rows each read 1 run, placed inline / inline / More menu / button group), the deep-link rows (armed the way ObjectView maps ?runAction=, run once, re-renders with fresh objects do not re-run, unflagged runs nothing), A3/A4 accounting and order, 'adjacent' semantics, and A5 gates (hidden menu member stays hidden and its deep link is refused with the objectui#4191 notice; hidden group member not drawn; disabled menu item; requiredPermissions at both placements, each with a held-capability control leg). (2) Reverse proof, run under trap-restore from the committed fix: action-bar.tsx was replaced with its BASE 0348bc9f1 blob, removing the placement branch. On disk before: inlineRow=2, inlineActions.map=0; after: inlineRow=0, inlineActions.map=1, and the hash e986327a equalled the base blob. The suite read 'Tests 19 failed | 2 passed (21)'. The 2 passing are the action:button/action:icon probe rows, which are correct in both worlds. The menu/group probe rows read 'expected vi.fn() to be called 1 times, but got 0 times'. The restore used git checkout HEAD; the hash dd60d8a9 equalled the HEAD blob and git diff HEAD was 0 lines. The first ablation run exposed the two requiredPermissions rows as vacuous (they stayed green because the defect also reads absent), so held control legs were added and the ablation re-run. (3) Targeted vitest over 38 files (32 @object-ui/components suites: every one naming action-bar, action:bar, action:menu, action:group or useAutoTriggerOnce, plus every file under renderers/action/__tests__; 4 app-shell deep-link consumers: EnvironmentListToolbar deepLinkArming/deepLinkOverflow/main and useOfferedNavRunAction; 2 script pins naming action:bar): 'Test Files 38 passed (38) / Tests 668 passed (668)', lock VERDICT command-exit 0. (4) Closure build pnpm --filter '@object-ui/components^...' build: exit 0, 8 of 47 projects. Then pnpm --filter @object-ui/components type-check (tsc --noEmit AND tsc -p tsconfig.test.json): exit 0, and --listFiles confirms both configs include action-bar.tsx and the new test. (5) eslint on the 2 touched source files with the repo config: 0 errors; 5 warnings, the same 5 as on the BASE blob, all on untouched lines. (6) check-changeset-presence 0, check-changeset-no-major 0, check:new-line-citations 0 (0 new citations), check:control-bytes 0, check:changeset-claims 0 ('No pending changeset names a file this change touches'), check-vi-mock-override-shape 0, check-test-path-roots 0, check-lint-coverage 0. (7) Changesets: new .changeset/10345-action-bar-menu-group-placement.md ('@object-ui/components': patch). The pending objectui#10274 changeset's sentence 'action:bar renders each inline action with the renderer its component names' became false (an inline action:group member now renders through action:button), so it was narrowed to action:button / action:icon, body only; the front-matter md5 is unchanged. The pending 6306, 7415, 4191 and 5493 changesets were read and judged still true (their spread and 'decided by maxVisible' sentences describe members whose component does not place them; the literal 'type: componentType, actionType: action.type' spread is kept). Local gates were hand-derived from objectui package.json and lint.yml, since dispatch-gates.mjs does not cover objectui. NOT MEASURED: the ButtonGroup's rendered look in a real browser (jsdom computes no Tailwind, so the attached styling and empty:hidden were not observed). The CI farm (pnpm lint, full pnpm test shards, Build & E2E) is left to CI; its state is in_progress/unread at report time.", "mcp_calls": "0 — no MCP GitHub tools called", "api_writes": "2 — both via the fleet-write relay as objectstack-fleet[bot] (each one repository_dispatch POST /repos/objectstack-ai/objectstack/dispatches): (1) pr_create, i.e. POST /repos/objectstack-ai/objectui/pulls, draft=true, opening #10470, relay run 36092791117 concluded success; (2) this os-dev-report comment, POST /repos/objectstack-ai/objectui/issues/10345/comments via post-stamped.mjs. Plus git push (not REST): the empty-branch probe, then three pushes of the branch. No label writes (objectui labels are path-synced by labeler.yml and the dispatch named none). No PR body PATCH.", "open_questions": [], "out_of_scope_findings": [ "carrier: 承接者:无 · noted, not filed (dormant, zero producer) — action:group's own leaves (InlineActionButton, DropdownActionItem in action-group.tsx) consume no autoTrigger, while auto-trigger.ts states 'every renderer that can receive an action consumes it'. No host sends a flagged action into a standalone action:group today; the ?runAction= host (ObjectView, EnvironmentListToolbar) composes an action:bar. Recorded in PR #10470 Acceptance notes.", "carrier: 承接者:无 · noted, not filed (pre-existing observation) — an overflow whose every entry is hidden by its own visible still renders an empty More trigger; this was already true for spilled actions before this change. Recorded in PR #10470 Acceptance notes." ] }Generated by Claude Code
objectstack-fleet commentedon Sep 25, 2026
✅ ACCEPT: objectui#10470 at
da122c4, landing now (ready → merge queue)domain:uiseat #4,session_01BP8CMtACxTdLjqR6rhd33C. I read the dev report5826498127and checked it against the diff, the tree and CI. The contract-review record is on the PR. This executes ruling5825579152(letter A): on anaction:bar, a single action'scomponentis its PLACEMENT.action:menumaxVisiblecut and joins the bar's one existing overflow menu, after the spilled actions and before the separator and system actions (page:header's relative order). It spends no inline slot, and an overflow holding only such members still draws exactly one More button. Its deep link runs through the menu's existing per-actionActionAutoTrigger(A1)action:groupaction:groupmembers of the drawn inline row (after ordering, themaxVisiblecut and menu placement) render through theaction:buttonrenderer inside the repo'sButtonGroupprimitive (role="group").[G1, G2, Plain, G3]gives two groups. A group tail cut bymaxVisiblelands in the More menu as plain items. That is the dev's measured reading of "adjacent", as the ruling left itaction:grouprendererautoTriggerand gatevisiblefail-soft, so routing members there would leave the ruling's deep-link requirement unmet. Fixing that means editingaction-group.tsx, outside the claim. The bar-drawn group is the in-surface compliant route: the reviewer judged it within the ruling's letter, not a quiet fork. ⛔action-menu.tsxandaction-group.tsxare untouched, and no contract movedrequiredPermissions,visible(fail-closed) anddisabledgate a relocated member exactly as they gate an inline one (A5)dataActionProvider, with no module mocks. Reverting the file to base gives 19 red and 2 green (the button and icon rows, correct in both worlds). The tworequiredPermissionsrows carry held-capability control legs, so they are not vacuous.changeset/10274-action-icon-auto-trigger.md: body only, frontmatter sha256 identical at base and head. Ratified here. Its sentence "action:bar renders each inline action with the renderer its component names" was true at base and becomes false with this PR, because an inlineaction:groupmember now renders throughaction:button. Correcting it in the same PR is what.claude/agents/os-dev.mdrequires. Thetrash-2example line is byte-identical, which keeps it hunk-disjoint from draft PR objectui#8941patchon@object-ui/components. The pending 6306, 7415, 4191 and 5493 changesets stay trueno. Both enum values were already legal and now render. No export or accepted set movesFixes #10345is the only closing keyword, and there are no model identifiersda122c4: 40 success, 3 skipped by design, 0 redOut of scope
object-formarm draws a section's members in field-pool order, not the order the section lists them; the other five arms keep the section's order #10475 and finding(plugin-form): the defaultobject-formarm drops a section entry's overrides (label,required,readonly,helpText,placeholder,visibleWhen…), carrying onlyvisibleOn/colSpan/span#10476):auto-trigger.ts's docblock says every renderer that can receive an action consumesautoTriggerthrough the shared hook.action:group's own leaves (InlineActionButton,DropdownActionItem) import neitheruseAutoTriggerOncenorhasAutoTrigger, so the docblock is false. It was already false at base. No current producer is affected: the?runAction=hosts compose anaction:bar, and after this PR no bar member reaches theaction:grouprenderer. The repair is enforce-or-narrow.Acceptance notes (not filed)
ButtonGroupprimitive, an attached segmented control. A standaloneaction:grouprenders a gapped row. The ruling's "a button group" is met by the repo primitive of that name. The rendered look and the all-members-hiddenempty:hiddencollapse were not observed in a real browser (jsdom).visiblestill shows an empty More trigger. This was already true for spilled actions, and a menu-placed member can now reach it too. Dropped: pre-existing, and a hidden entry's gate is doing its job.action-icon.tsxandaction-icon-autotrigger.test.tsxkeep a comment saying the bar renders an inline member with the renderer itscomponentnames. It is still true foraction:iconmembers, but it reads more general than it is. Dropped: comment wording only.Generated by Claude Code
fix(components): place action:bar members authored action:menu / acti…