fix(attribution): hide unattributed chip when a task has no responsible member (MUL-4765)

The Human Attribution work (MUL-4302) showed a yellow "No responsible member"
warning chip in the execution log and working-status surfaces whenever a task
had no resolved responsible member. An unassigned run is a normal state, not
something to flag, so the badge variant now renders nothing in that case —
matching the avatar variant, which already stayed silent. Removes the now-dead
`unattributed` locale string across all bundles.

Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
J
2026-07-15 03:22:51 +08:00
parent 4fac8d772f
commit 52ecda8df7
6 changed files with 13 additions and 23 deletions

View File

@@ -62,7 +62,7 @@ describe("AttributionBadge", () => {
expect(screen.getByText("on behalf of someone")).toBeInTheDocument();
});
it("renders an unattributed chip when no responsible member resolved", () => {
it("renders nothing when no responsible member resolved (MUL-4765)", () => {
const attribution: TaskAttribution = {
source: "unattributed",
precise: false,
@@ -71,8 +71,9 @@ describe("AttributionBadge", () => {
<AttributionBadge attribution={attribution} />,
);
expect(screen.getByText("No responsible member")).toBeInTheDocument();
expect(container.querySelector(".text-warning")).not.toBeNull();
// An unassigned run is a normal state, not a warning — the badge stays silent
// rather than showing a "No responsible member" chip.
expect(container).toBeEmptyDOMElement();
});
it("degrades gracefully for an unknown source label", () => {

View File

@@ -26,9 +26,10 @@ function initialsOf(name: string): string {
* the "on behalf of <member>" provenance, with the resolution source and a
* distinct warning tone for degraded (non-precise) attribution.
*
* Two shapes:
* - `variant="badge"` (default): the full "on behalf of <name>" chip, with an
* explicit "unattributed" chip when no responsible member resolved.
* Two shapes, both silent when no responsible member resolved (MUL-4765):
* - `variant="badge"` (default): the full "on behalf of <name>" chip. Renders
* nothing when there's no accountable member, so an unassigned run reads as
* plain rather than a warning.
* - `variant="avatar"`: just the accountable member's avatar, with the name +
* source in a hover tooltip. Compact enough for a dense task row. Renders
* nothing when there's no accountable member — an avatar-only surface has
@@ -132,19 +133,11 @@ export function AttributionBadge({
);
}
if (!initiator) {
return (
<Badge
variant="outline"
className={cn("max-w-40 min-w-0 gap-1 font-normal text-warning", className)}
title={sourceLabel}
>
<span className="min-w-0 truncate">
{t(($) => $.execution_log.attribution.unattributed)}
</span>
</Badge>
);
}
// No resolved responsible member: render nothing rather than a warning chip.
// An empty accountable member is a normal state (e.g. an unassigned task), not
// something to flag — so the badge variant stays silent, matching the avatar
// variant above (MUL-4765).
if (!initiator) return null;
const name = initiator.name || t(($) => $.execution_log.attribution.someone);
return (

View File

@@ -407,7 +407,6 @@
"attribution": {
"on_behalf_of": "on behalf of {{name}}",
"someone": "someone",
"unattributed": "No responsible member",
"source_direct_human": "Direct member action",
"source_delegation": "Delegated from another run",
"source_comment_source": "From a comment thread",

View File

@@ -389,7 +389,6 @@
"attribution": {
"on_behalf_of": "{{name}} の代理として",
"someone": "あるメンバー",
"unattributed": "責任メンバーなし",
"source_direct_human": "メンバーの直接操作",
"source_delegation": "別の実行から委任",
"source_comment_source": "コメントスレッドから",

View File

@@ -389,7 +389,6 @@
"attribution": {
"on_behalf_of": "{{name}} 님을 대신하여",
"someone": "어떤 멤버",
"unattributed": "책임 멤버 없음",
"source_direct_human": "멤버 직접 작업",
"source_delegation": "다른 실행에서 위임됨",
"source_comment_source": "댓글 스레드에서",

View File

@@ -389,7 +389,6 @@
"attribution": {
"on_behalf_of": "代表 {{name}}",
"someone": "某位成员",
"unattributed": "无责任成员",
"source_direct_human": "成员直接操作",
"source_delegation": "由其他运行委托",
"source_comment_source": "来自评论线程",