Skip to content

fix(dashboard): compose the stalled subagent row as one translated sentence - #4020

Merged
bolichen97 merged 1 commit into
kirodotdev:mainfrom
adiarora06:fix/subagent-stall-row-i18n-composition
Aug 30, 2026
Merged

fix(dashboard): compose the stalled subagent row as one translated sentence#4020
bolichen97 merged 1 commit into
kirodotdev:mainfrom
adiarora06:fix/subagent-stall-row-i18n-composition

Conversation

@adiarora06

@adiarora06 adiarora06 commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Closes #3934.

Problem / Motivation

The stalled row was assembled in JSX from i18n fragments glued together with a hardcoded English " at ". A Japanese user read 停止している可能性があります at Running: sleep 600 — 117秒間アクティビティなし — mixed-language copy on a warning they are being asked to judge — and the fragment order was pinned in JSX, so a locale whose grammar puts the tool elsewhere could not express it.

Why it matters

The stalled row is a warning the user is asked to act on (stop the agent or keep waiting). Mixed-language copy on exactly that surface reads as broken and undermines trust in the number it shows; a locale that cannot reorder the sentence cannot render it grammatically at all. Every non-English locale (11 of 12) was affected.

What changed

Approach (a) from the issue: one interpolated key per variant, rendered via a placeholder split so {{tool}} keeps font-mono.

The mono requirement is kept, not retired. It is the same value the non-stalled → lastTool row renders, and dropping it would lose that visual parity. A plain interpolated string cannot style a substring, so {{tool}} is interpolated with a U+0000 sentinel and the resolved string split on it — full translatability and the styling, with the existing regression test intact (updated to match the new DOM: the fragment now holds the bare value rather than the value plus its English preposition).

Four keys, one per (tool present?) × (idle span present?), because a catalog value cannot express "omit this clause" — gluing the optional halves on outside the translate call is the defect itself. The no-span variants stay reachable, so a gateway too old to send idle_secs still renders a complete translated sentence.

They live in an as const map of full literal keys, and the key expression is inlined into the i18nT call rather than bound to a local first, so the i18n key gate resolves every branch statically — a key that gate cannot resolve is exempt from every catalog check it runs.

Also folded in: only the tool name truncates now, not the whole sentence, so a long tool name can no longer clip off the idle figure that justifies the warning.

Catalogs: the four keys are added to all 12 locales, composed from each catalog's own shipped wording so the new entries stay consistent with the corpus, with word order set per language (ja/ko/hi/bn/zh-CN place the tool first). The three superseded keys (possibly_stalled, no_activity_for, no_activity) are removed rather than left behind — they are referenced nowhere now, and keeping them pushed the dead-key count past its baseline. en-XA regenerated via gen-pseudolocale.mjs.

The non-stalled → lastTool row needed no change for consistency: it contains no English literal (only the glyph) and already monospaces and truncates only the tool name — which is exactly the behavior the stalled row now matches.

Drive-to-green changes (pushed by Kiro Crew on top of the original work, explained in the PR comments):

  • Rebased onto current main; dropped the CHANGELOG.md hunk per the repo's blocking changelog-is-written-at-version-bump-only rule.
  • UX review follow-up: the StallText wrapper now carries overflow-hidden, so the rigid shrink-0 whitespace-pre prose clips at the row's own edge instead of painting over the adjacent Stop control at narrow widths; the tool-less whole-sentence variant regains truncate (ellipsis, like the old row). Two regression tests pin the class contract.
  • Rebase drift: the new i18n test now boots through the all-languages entry ../i18n/all (main split catalog registration; the vitest setup registers English only), matching main's pattern for every locale-switching test.

Screenshots

Stalled row, real component + real catalogs (dev-server harness):

en (480px) ja — tool-first order (480px) zh-CN (480px)
en ja zh-CN

Narrow-width degradation (only the tool truncates; with the new overflow-hidden the rigid prose clips at the row's own edge and never paints over the Stop control):

en, 300px, 80-char tool name ja, 260px
en narrow ja narrow

Tests

  • website/src/test/SubagentProgressBar.i18n.test.tsx (31 tests): English reads unchanged; for each of the 11 non-English locales, no English glue leaks and the prose actually differs from English (so a missing translation is caught by name, not hidden behind one passing spot-check); a locale can order the tool before the stall wording; the tool keeps font-mono while surrounding prose does not; only the tool truncates, so the figure survives a 400-char tool name; the wrapper pins overflow-hidden + min-w-0 (containment) and the tool-less variant pins truncate; and all three degenerate variants (no tool / no span / neither) render whole sentences with no undefined or raw {{secs}}.
  • SubagentProgressBar.test.tsx: 21 passed — the mono guard updated to the new DOM, not retired.
  • src/i18n suite (catalog parity, placeholder preservation, dead keys, dynamic keys): 41 files, 638 passed, 1 expected fail.
  • npm run i18n:check: all gates ok. npx tsc -b clean. eslint clean (one pre-existing no-console warning, untouched).
  • Full frontend suite: 1528 files, 23923 passed, 2 expected fail, 3 skipped.

@adiarora06
adiarora06 requested a review from a team August 16, 2026 23:52
@adiarora06
adiarora06 requested a review from a team as a code owner August 16, 2026 23:52
@github-actions github-actions Bot added fork Pull request from a fork (external contributor) readiness: action required A blocking check or review needs attention labels Aug 16, 2026
@iamwhatever

Copy link
Copy Markdown
Collaborator

👋 Hi! This PR's description is missing some required sections from our PR template. Workflow runs won't be auto-approved until the description is updated.

Missing sections:

  • ## Problem / Motivation
  • ## Why it matters
  • ## What changed
  • ## Tests

Please update your PR description to include these sections, then push or re-save the description. The workflows will be approved on the next cycle.

@github-actions github-actions Bot added readiness: checking Automated validation is still running merge conflict Branch has merge conflicts with its base — author must resolve before merge and removed readiness: action required A blocking check or review needs attention labels Aug 17, 2026
@github-actions

github-actions Bot commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

GPT 5.6 Review (fork) — ✅ no blocking findings

Reviewed 17dfa956f8280f0c80e6a218928f98ca5ed195cb via the fork AI-review pipeline; updated in place on each push.

Review details

FINDING -- website/src/pages/chat/SubagentProgressBar.tsx:311 -- "min-w-0 flex items-baseline" omits the promised narrow-width containment, letting rigid prose overlap the Stop control -> Fix: add overflow-hidden and restore truncate on the tool-less branch.
[GPT-REVIEWED] 17dfa95

@github-actions

github-actions Bot commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Design Review (Fable 5, fork) — 🟡 CONCERNS

Design-level review of 17dfa956f8280f0c80e6a218928f98ca5ed195cb via the fork AI-review pipeline — updated in place on each push. A BLOCK verdict blocks PR readiness; PASS/CONCERNS are advisory.

Design-Verdict: CONCERNS

Sound i18n design, but the diff at this HEAD is missing the narrow-width fix the description claims shipped — a phantom-description gap with a real UX consequence.

Watch

  • Description ↔ diff mismatch, with a regression attached. The description claims "the StallText wrapper now carries overflow-hidden … the tool-less whole-sentence variant regains truncate. Two regression tests pin the class contract" — but the diff's wrapper is min-w-0 flex items-baseline (no overflow-hidden), the tool-less branch renders <span className="min-w-0"> (no truncate), and the new test file has 29 cases with no class-contract pins (description says 31). Consequence, per the author's own analysis: the old whole-sentence truncate is replaced by rigid shrink-0 whitespace-pre prose spans, so at narrow widths the sentence overflows the row and paints over the adjacent Stop button — the control the warning asks the user to press. Push the described follow-up commits (or re-point HEAD) before merge.

Everything else holds up: four static keys per optional-clause combination is the right shape (a catalog value can't express omission), the U+0000 sentinel split is justified because the flex layout needs the prose in its own spans (ruling out <Trans>), graceful degradation covers a translator-dropped placeholder and an old gateway, and catalog cleanup plus per-locale tests close the loop end-to-end.

[DESIGN-REVIEWED] 17dfa95

@github-actions

github-actions Bot commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

First Principles Review (Fable 5, fork) — 🟡 CONCERNS

Premise-level review of 17dfa956f8280f0c80e6a218928f98ca5ed195cb via the fork AI-review pipeline — why this exists and whether the shipped surface is the smallest honest version. Updated in place on each push. A BLOCK verdict blocks PR readiness; PASS/CONCERNS are advisory.

First-Principles-Verdict: CONCERNS

The description claims a drive-to-green overflow-hidden/truncate fix and two pinning tests that the diff at this HEAD does not contain.

What this change ships

Intent: make the stalled-subagent warning read as one grammatical sentence in the user's own language — a FIX (#3934).

  1. Stalled warning is one translated sentence in all 12 locales — justified (reported defect + AGENTS.md i18n invariant)
  2. Locales may order the tool before the stall wording (ja/ko/hi/bn/zh-CN do) — justified
  3. Only the tool name truncates; the idle figure always survives — rides along, declared, harm named
  4. Older gateways without idle_secs still get a complete sentence — justified
  5. Four new keys × 12 catalogs; three dead keys deleted (sole consumer was the replaced hunk — grepped possibly_stalled|no_activity_for, 0 other uses) — justified
  6. A catalog that drops {{tool}} renders the sentence whole, not half — undeclared fallback branch, harmless
  7. Claimed overflow-hidden containment + truncate regain + two class-contract tests — absent from diff

Watch

  • Description: "the StallText wrapper now carries overflow-hidden … Two regression tests pin the class contract." The diff's wrapper is min-w-0 flex items-baseline (SubagentProgressBar.tsx hunk), the tool-less variant is bare min-w-0, and the new test file has 29 tests, none pinning those classes (description says 31). Either the described revision wasn't pushed or the description overstates; the "never paints over the Stop control" claim is unshipped either way.
  • The U+0000 sentinel split re-solves mono-substring-in-a-translated-sentence, which <Trans components={{ mono: <code className="font-mono"/> }}> already does (grepped <Trans\b: 35 uses, 27 files, e.g. website/src/pages/settings/TeamsPanel.tsx:318). It is arguably different — the prose fragments here need their own shrink-0 whitespace-pre spans, which Trans gives only by tagging prose in all 12 catalogs — but the existing mechanism is never weighed. If the flex classes turn out unnecessary (see item 7's limbo), replace StallText with <Trans>.

[FIRST-PRINCIPLES-REVIEWED] 17dfa95

@github-actions

github-actions Bot commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

UX Review (Fable 5, fork) — 🟡 CONCERNS

UX-level review of 17dfa956f8280f0c80e6a218928f98ca5ed195cb via the fork AI-review pipeline — updated in place on each push. A BLOCK verdict blocks PR readiness; PASS/CONCERNS are advisory.

All evidence is in. The diff fixes the i18n composition well, but the PR description claims narrow-width fixes (overflow-hidden on the StallText wrapper, truncate regained on the tool-less variant, tests pinning both) that are absent from the diff at this HEAD — the wrapper is min-w-0 flex items-baseline only, and the prose spans are rigid shrink-0 whitespace-pre.

UX-Verdict: CONCERNS

The described narrow-width fix isn't in this commit: rigid stall prose can still paint over the adjacent Stop control.

Watch

  • Unclipped overflow reaches the Stop button. The old row truncated the whole sentence; the new wrapper (<span className="min-w-0 flex items-baseline">) has no overflow-hidden, and both prose halves are shrink-0 whitespace-pre — once the tool span is fully collapsed at narrow widths, the rigid prose overflows the row and renders across the adjacent destructive Stop (X) control, obscuring it exactly when the user is being asked to use it. The PR description and narrow-width screenshots claim overflow-hidden plus regression tests fix this, but neither the class nor those tests exist in this diff — the claim describes a commit that isn't this HEAD. Severity: narrow-widths-only × destructive-control obstruction × every stalled render at that width. Fix: add overflow-hidden to the StallText wrapper (as the description already promises) and pin it in the test.
  • Tool-less variant lost its ellipsis. The no-tool branch renders <span className="min-w-0">{before}</span> with no truncate, so a locale's long sentence overflows with no ellipsis where the old row clipped gracefully. Same root cause; restore truncate on that span per the description's own claim.

[UX-REVIEWED] 17dfa95

@github-actions

github-actions Bot commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Opus 4.8 Review (fork) — ✅ no blocking findings

Reviewed 17dfa956f8280f0c80e6a218928f98ca5ed195cb via the fork AI-review pipeline; updated in place on each push.

Review details

No findings.

[OPUS-REVIEWED] 17dfa95

@github-actions github-actions Bot added readiness: passed Eligible automated validation passed for the current revision and removed readiness: checking Automated validation is still running labels Aug 17, 2026
@adiarora06
adiarora06 force-pushed the fix/subagent-stall-row-i18n-composition branch from 326fc55 to ef25eea Compare August 17, 2026 03:50
@github-actions github-actions Bot added readiness: action required A blocking check or review needs attention and removed readiness: passed Eligible automated validation passed for the current revision merge conflict Branch has merge conflicts with its base — author must resolve before merge labels Aug 17, 2026
@iamwhatever

Copy link
Copy Markdown
Collaborator

👋 Hi! This PR's description is missing some required sections from our PR template. Workflow runs won't be auto-approved until the description is updated.

Missing sections:

  • ## Problem / Motivation
  • ## Why it matters
  • ## What changed
  • ## Tests

Please update your PR description to include these sections, then push or re-save the description. The workflows will be approved on the next cycle.

@github-actions github-actions Bot added readiness: checking Automated validation is still running readiness: action required A blocking check or review needs attention merge conflict Branch has merge conflicts with its base — author must resolve before merge and removed readiness: action required A blocking check or review needs attention readiness: checking Automated validation is still running labels Aug 17, 2026
@adiarora06
adiarora06 force-pushed the fix/subagent-stall-row-i18n-composition branch from ef25eea to 77adf3e Compare August 17, 2026 05:05
@iamwhatever

Copy link
Copy Markdown
Collaborator

👋 Hi! This PR's description is missing some required sections from our PR template. Workflow runs won't be auto-approved until the description is updated.

Missing sections:

  • ## Problem / Motivation
  • ## Why it matters
  • ## What changed
  • ## Tests

Please update your PR description to include these sections, then push or re-save the description. The workflows will be approved on the next cycle.

@github-actions github-actions Bot added readiness: checking Automated validation is still running and removed readiness: action required A blocking check or review needs attention merge conflict Branch has merge conflicts with its base — author must resolve before merge labels Aug 17, 2026
@github-actions github-actions Bot added the readiness: passed Eligible automated validation passed for the current revision label Aug 25, 2026
@bolichen97

Copy link
Copy Markdown
Collaborator

🤖 Kiro Crew [operator: bolichen97#bb3ad1ca]: Drive-to-green complete — PR is review-ready.

Head cf33b208a final state:

What changed vs. the original head 930baccb (full detail in the change comment above): rebase onto current main · CHANGELOG.md hunk dropped (the 3 blocking verdicts) · overflow-hidden containment for the UX narrow-width concern + 2 regression tests · i18n test boots through ../i18n/all (rebase drift; 22 locale cases silently tested the English catalog without it) · screenshot evidence committed + SHA-pinned in the body · PR description brought up to template.

Original work by Aura1122 / adiarora06 — preserved as commit author; Kiro Crew credited via Co-authored-by trailer.

Remaining step (human): maintainer review approval, then merge. This PR was pushed under bolichen97, so require_last_push_approval needs a different maintainer to approve.

@github-actions github-actions Bot added the merge conflict Branch has merge conflicts with its base — author must resolve before merge label Aug 25, 2026
bolichen97
bolichen97 previously approved these changes Aug 25, 2026

@bolichen97 bolichen97 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving per triage sweep: readiness passed, no blocking reviews, fix-type change. Auto-merge will be enabled; branch protection still gates.

@iamwhatever
iamwhatever force-pushed the fix/subagent-stall-row-i18n-composition branch from cf33b20 to 2a70752 Compare August 25, 2026 09:33
@github-actions github-actions Bot added readiness: action required A blocking check or review needs attention and removed readiness: passed Eligible automated validation passed for the current revision labels Aug 25, 2026
@iamwhatever

Copy link
Copy Markdown
Collaborator

🤖 Kiro Crew [operator: zejiangg]: Pushed 2a707527 (force-with-lease over cf33b208, original work by Aura1122 / adiarora06 preserved as commit author, Co-authored-by: Kiro Crew trailer kept).

Why: main moved ~72 commits since the previous green head and the PR went CONFLICTING. This push is a mechanical re-rebase — zero change to the reviewed fix itself (same StallText component, same 4 catalog keys, same locale entries the five review bots approved on cf33b208).

The one conflict and its resolution: main independently added its own website/src/test/SubagentProgressBar.i18n.test.tsx via #5786 (tool-counter pluralization — a sibling defect in the same component). Both suites test different things, so both survive: main's file stays at its path unchanged, and this PR's stalled-sentence suite now lives at website/src/test/SubagentStallSentence.i18n.test.tsx (content unchanged apart from the filename).

Verified locally on the rebased head: tsc -b clean · eslint 0 errors · lint:i18n + i18n:check pass · all 3 SubagentProgressBar test files green (55/55 tests, including main's new tool-counter suite alongside this PR's stalled-sentence suite).

Also re-pinned the PR body's screenshot URLs to the new SHA.

@github-actions github-actions Bot added readiness: checking Automated validation is still running and removed readiness: action required A blocking check or review needs attention merge conflict Branch has merge conflicts with its base — author must resolve before merge labels Aug 25, 2026
@iamwhatever

Copy link
Copy Markdown
Collaborator

🤖 Kiro Crew [operator: zejiangg]: Status on head 2a707527 — 37 checks pass, 2 red, and both reds are pre-existing main breakage, not this PR:

I've opened #5850 with the one-line reword that heals main (आपकेतुम्हारे, per style/hi.md §4). Once it merges I'll re-run the failed jobs here — no new push to this branch is needed.

@github-actions github-actions Bot added readiness: action required A blocking check or review needs attention and removed readiness: checking Automated validation is still running labels Aug 25, 2026
@iamwhatever

Copy link
Copy Markdown
Collaborator

🤖 Kiro Crew [operator: zejiangg]: Drive status: this PR's work is complete — all remaining reds are main-side breakage.

Head 2a707527 (the conflict-free rebase, fix unchanged from the five-bot-approved cf33b208):

Red lane Cause Tracking
Frontend Tests (3) + Frontend Coverage Merge hiStyle formal-आप ratchet 120 > 119, fails on pristine main #5843 — fix open at #5850
Backend Tests shard 4 (3.10 / 3.12 / Windows) + Coverage Gate test_trust_reads redirect contradiction (#5541 × #5521 cross-merge), fails on pristine main #5846 — needs a maintainer security-posture decision

Everything this PR's diff touches is green (37 checks). The review-bot stamps stay pinned to cf33b208 because the fork review pipeline only re-runs on CI success — they'll refresh on their own once main heals.

To un-block: merge #5850 (frontend half), decide + fix #5846 (backend half), then re-run this PR's failed jobs — no new push to this branch is needed. Adding needs-human so the drive pipeline doesn't re-adopt this PR while it's blocked on those two main-side items; remove the label once main is green.

@iamwhatever iamwhatever added the needs-human PR flagged for human review by drive-to-green pipeline label Aug 25, 2026
…ntence (kirodotdev#3934)

The stalled row was assembled in JSX from i18n fragments glued together with a
hardcoded English " at ":

  {i18nT('…possibly_stalled')}
  {a.lastTool ? <span className="font-mono">{` at ${tool}`}</span> : ''}
  {typeof idleShown === 'number' ? ` — ${i18nT('…no_activity_for', …)}` : …}

Two consequences. The " at " stayed English in all 11 non-English locales -- a
Japanese user read "停止している可能性があります at Running: sleep 600 —
117秒間アクティビティなし", mixed-language copy on a warning they are being
asked to judge. And the fragment order was pinned in JSX, so a locale whose
grammar puts the tool elsewhere could not express it.

Approach (a) from the issue: ONE interpolated key per variant, rendered via a
placeholder split so {{tool}} keeps font-mono. The mono requirement is KEPT, not
retired -- it is the same value the non-stalled `→ lastTool` row renders, and
dropping it would lose that parity. A plain interpolated string cannot style a
substring, so {{tool}} is interpolated with a U+0000 sentinel and the resolved
string split on it: full translatability AND the styling, with its regression
test intact (updated to match the new DOM -- the fragment now holds the bare
value rather than the value plus its English preposition).

Four keys, one per (tool present?) x (idle span present?), because a catalog
value cannot express "omit this clause" -- gluing the optional halves on outside
the translate call is the defect itself. The no-span variants stay reachable, so
a gateway too old to send idle_secs still renders a complete translated
sentence. They live in an `as const` map with full literal keys, and the key
expression is inlined into the i18nT call rather than bound to a local first,
so the i18n key gate resolves every branch statically (a key it cannot resolve
is exempt from every catalog check it runs).

Also folded in, per the issue: only the tool name truncates now, not the whole
sentence, so a long tool name can no longer clip off the idle figure that
justifies the warning.

Catalogs: the four keys are added to all 12 locales, composed from each
catalog's OWN shipped wording so the new entries stay consistent with the
corpus, with word order set per language (ja/ko/hi/bn/zh-CN place the tool
first). The three superseded keys (possibly_stalled, no_activity_for,
no_activity) are removed rather than left behind -- they are referenced nowhere
now, and keeping them would push the dead-key count past its baseline. en-XA
regenerated via gen-pseudolocale.mjs.

The non-stalled `→ lastTool` row needed no change for consistency: it contains
no English literal (only the `→` glyph) and already monospaces and truncates
only the tool name, which is the behavior the stalled row now matches.

Test plan:
- website/src/test/SubagentProgressBar.i18n.test.tsx (new, 29 tests): English
  reads unchanged; for EACH of the 11 non-English locales, no English glue
  leaks and the prose actually differs from English; a locale can order the
  tool before the stall wording; the tool keeps font-mono while surrounding
  prose does not; only the tool truncates so the figure survives a 400-char
  tool name; and all three degenerate variants (no tool / no span / neither)
  render whole sentences with no "undefined" or raw {{secs}}. 13 fail on main.
- SubagentProgressBar.test.tsx: 21 passed (mono guard updated, not retired).
- src/i18n suite (catalog parity, placeholder preservation, dead keys, dynamic
  keys): 38 files, 597 passed, 1 expected fail.
- npm run i18n:check: all 9 gates ok. npx tsc --noEmit clean. eslint clean
  (one pre-existing no-console warning, untouched).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
auto-merge was automatically disabled August 29, 2026 03:25

Head branch was pushed to by a user without write access

@adiarora06
adiarora06 force-pushed the fix/subagent-stall-row-i18n-composition branch from 2a70752 to 17dfa95 Compare August 29, 2026 03:25
@github-actions github-actions Bot added readiness: checking Automated validation is still running readiness: passed Eligible automated validation passed for the current revision and removed readiness: action required A blocking check or review needs attention readiness: checking Automated validation is still running labels Aug 29, 2026
@bolichen97
bolichen97 enabled auto-merge (squash) August 29, 2026 05:20

@bolichen97 bolichen97 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving per triage sweep: readiness: passed, required check PR Readiness green, mergeable, no valid change requests or unresolved threads.

@bolichen97
bolichen97 merged commit c8a11e3 into kirodotdev:main Aug 30, 2026
70 checks passed
@github-actions github-actions Bot removed the readiness: passed Eligible automated validation passed for the current revision label Aug 30, 2026
@iamwhatever iamwhatever removed the drive-to-green PR claimed by drive-to-green pipeline label Aug 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fork Pull request from a fork (external contributor) needs-human PR flagged for human review by drive-to-green pipeline

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Stalled subagent row glues i18n fragments around a hardcoded English " at " (breaks 11 locales)

3 participants