Repository navigation
Conversation
… character reportLabel cut a subagent, command, monitor or delegated task label at 79 UTF-16 code units before adding an ellipsis. When an emoji straddled the cut, the label kept only its high surrogate, so the notice the thread shows when that work finishes or asks a question ended in a replacement character before the ellipsis. Each notice is stored with the thread, so the broken character stayed for good. The cut now steps back one unit when it would land between a high and a low surrogate, the same check pingdotgg#29163 and pingdotgg#29563 added to thread titles. Bug: a background work notice ends in a broken character when an emoji sits at the label cut
ApprovabilityVerdict: Approved at Macroscope's review found this PR approvable — Notification labels now avoid cutting a Unicode surrogate pair before the ellipsis. The change is limited to summary formatting and preserves existing length limits and task behavior. You can add or adjust custom eligibility rules. Learn more. |
|
No actionable comments were generated in the recent review. Walkthrough
Merge Risk:
|
|
Note Written by Verified in a real dev environmentverified unchanged head the agent ran the same bounded background command in both builds, with the emoji crossing the 79-code-unit cut. it ended its turn before the command completed. main persisted a lone high surrogate and rendered before, main (cropped to the expanded notice): after, pr head, matching command and crop: nearby behavior: opening and closing the notice detail works. short labels retain their emoji. a second background command failed with exit 7 and produced a failed notice; another completed with exit 0 and produced a finished notice. both woke the real parent agent, which acknowledged the exit codes. read-only sqlite inspection of the server-persisted notices: blacksmith validation passed: Not verifiednative ios/android work logs and desktop shells were not exercised on this linux browser pass. other provider adapters, delegated-task question wakes, subagent notices, remote/relay and tunnel connections were not exercised. this verifies new command notices; previously persisted notices retain their original text. provider transport returned transient 429s, then recovered; each tested background command completed and delivered its notice. |


Problem
When background work finishes and its label is 80 UTF-16 code units or longer with an emoji straddling the cut, the parent thread's notice quotes the label with only the emoji's high surrogate, so it ends in a replacement character (�) before the
…, as inCommand "…then: �…" finished. It should end on the last whole character before the emoji, as #29163 and #29563 do for thread titles.Change
The quoted label comes from
reportLabelinpackages/provider-core/src/server/notification.ts, which cuts the label's first line at 79 UTF-16 code units and adds…. When the cut would land between a high and a low surrogate, it now steps back one unit. That is the check #29563 added tot3 thread starttitles and #29163 added tocreate_threadstitles. The 80-unit limit, the…suffix and every notice's wording are unchanged.Every notice summary is written into the thread's stored events when it happens: the Claude, Codex, ACP and Muse adapter notices, the delegated-task completion notices and the delegated-task question wake. A notice already written keeps its broken character; this PR fixes the notices written after it.
Where it shows:
Bashwithrun_in_background. The row truncates its text with CSS, so the broken end shows when the window fits the label. A notice that names a child thread (a subagent or a delegated task) renders as a link row with the child thread's own title instead, so it shows the summary only when the child thread cannot be resolved.Scope and approval
This is a very small, focused fix for an obvious bug. It is the defect #29563 ("t3 thread start titles no longer end in a broken character") and #29163 ("create_threads titles no longer end in a broken character") fixed in thread titles, still present in the label every background work notice quotes. It applies their check and changes no other behaviour, setting or contract.
Overlap check, by
reportLabel,backgroundWorkNotificationand by file. No open PR changesnotification.tsor its test. #29007 editsDelegatedTaskQuestionReactor.ts, which callsreportLabel, but leaves that call as it is. #29906 (subagentProjection.ts) and #29647 (RestartBackgroundNote.ts) fix the same kind of cut in other files and do not touch this one. #24611 changes the sharedtruncate, which this function does not call.Verification
packages/provider-core/src/server/notification.test.tsgets one assertion in its existingnames one piece of work and the thread of a subagentcase. It reports a command labelled with 78as followed by😀, so the emoji sits on the cut.On
mainwith only the test commit (da7f4b8), frompackages/provider-core,vp test run src/server/notification.test.ts:With the fix:
vp test run src/server/notification.test.tsinpackages/provider-core: 4 tests passed.vp run check:changedfrom the repo root: format, lint, knip, typecheck (26 packages) and tests (3 files) all pass.In a running dev build (web, Windows, Claude Haiku as the agent): the agent ran
Bashwithrun_in_background, commandsleep 20, and the description "Rename the config loader so it reads the new paths before the old ones, then: 🚀 ship it", whose first 78 UTF-16 code units come before the emoji, then ended its turn. When the command finished, the server wrote the notice. The before run usedmain'snotification.ts, the after run this branch's, each on a fresh server start. The stored summaries endedthen: \ud83d…" finishedandthen: …" finished.main)The captures are the preview panel's visible area (952 by 702), not the full window.
What I could not check: the mobile work log on a device, and the delegated-task question wake. Like #29163 and #29563, the cut works per code point, so it can still split a grapheme cluster such as a flag, a skin-tone modifier or a ZWJ sequence; it never leaves a lone surrogate.
Bug: a background work notice ends in a broken character when an emoji sits at the label cut
This was written with Claude Opus 5.5 in Claude Code, driven from T3 Code.