What the chat cannot say
cloud#1838 asks for phase semantics while the build agent verifies a change it just applied — 「正在校验…」 in the SSE stream or on the tool cards, so the user is not staring at an unlabelled spinner. The cloud side of that card landed a mechanical bound on the self-check loop, but the COPY half cannot be produced from cloud at all, because both channels that reach the chat are objectui-owned:
packages/plugin-chatbot/src/mapMessages.ts — extractBuildProgress reads the reconciled data-build-progress part and coerces anything it does not recognise: const phase = d.phase === 'data' || d.phase === 'done' ? d.phase : 'structure'. A runtime that emitted phase: 'verify' would render as 「Building your app…」 with a spinner — actively wrong, since the build is finished and the app is being checked.packages/plugin-chatbot/src/ChatbotEnhanced.tsx — the panel's strings are hardcoded English (Building ${appLabel}…, adding sample data, Built ${appLabel}), and each tool card is titled humanizeToolName(tool.toolName), i.e. derived from the English tool id. Nothing in the tool result or the stream can change either.
So a Chinese user watching a confirmed change get verified sees an English spinner label plus a column of English tool names, and no statement that verification is what is happening.
Suggested shape
Two small, independent pieces:
- Admit a
verify phase in extractBuildProgress and give it its own line in the progress panel (localized like the rest of the console), so a runtime can announce the phase it is in. The reconciled-single-part mechanism already exists; only the accepted vocabulary and one label are missing. - Localize the panel's three hardcoded strings through the console's own i18n, since they are the only untranslated text in an otherwise localized surface.
Measured on the local rig (2026-09-03, cloud branch claude/issue-1838-bounded-post-apply-verification): after 「确认,就按这个方案建」 the confirm turn spent 111 seconds and 9 tool calls verifying and re-seeding AFTER apply_blueprint returned, with the panel still reading 「Building your app…」 the whole time.
Filed from cloud#1838, which fixed the loop's LENGTH; this is the part of that card that must be built here. No cloud change is blocked on it.
What the chat cannot say
cloud#1838 asks for phase semantics while the build agent verifies a change it just applied — 「正在校验…」 in the SSE stream or on the tool cards, so the user is not staring at an unlabelled spinner. The cloud side of that card landed a mechanical bound on the self-check loop, but the COPY half cannot be produced from cloud at all, because both channels that reach the chat are objectui-owned:
packages/plugin-chatbot/src/mapMessages.ts—extractBuildProgressreads the reconcileddata-build-progresspart and coerces anything it does not recognise:const phase = d.phase === 'data' || d.phase === 'done' ? d.phase : 'structure'. A runtime that emittedphase: 'verify'would render as 「Building your app…」 with a spinner — actively wrong, since the build is finished and the app is being checked.packages/plugin-chatbot/src/ChatbotEnhanced.tsx— the panel's strings are hardcoded English (Building ${appLabel}…,adding sample data,Built ${appLabel}), and each tool card is titledhumanizeToolName(tool.toolName), i.e. derived from the English tool id. Nothing in the tool result or the stream can change either.So a Chinese user watching a confirmed change get verified sees an English spinner label plus a column of English tool names, and no statement that verification is what is happening.
Suggested shape
Two small, independent pieces:
verifyphase inextractBuildProgressand give it its own line in the progress panel (localized like the rest of the console), so a runtime can announce the phase it is in. The reconciled-single-part mechanism already exists; only the accepted vocabulary and one label are missing.Measured on the local rig (2026-09-03, cloud branch
claude/issue-1838-bounded-post-apply-verification): after 「确认,就按这个方案建」 the confirm turn spent 111 seconds and 9 tool calls verifying and re-seeding AFTERapply_blueprintreturned, with the panel still reading 「Building your app…」 the whole time.Filed from cloud#1838, which fixed the loop's LENGTH; this is the part of that card that must be built here. No cloud change is blocked on it.