Skip to content

fix(i18n,app-shell): the maker's first sentence promises only what ADR-0112 v1 builds (#8329) - #8439

Merged
hotlong merged 2 commits into
mainfrom
fix/ai-build-empty-description-v1-boundary-8329
Sep 8, 2026
Merged

fix(i18n,app-shell): the maker's first sentence promises only what ADR-0112 v1 builds (#8329)#8439
hotlong merged 2 commits into
mainfrom
fix/ai-build-empty-description-v1-boundary-8329

Conversation

@hotlong

@hotlong hotlong commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Closes #8329

What was wrong

The AI build surface's empty state — the first sentence a new user reads on that page, sitting above the start chips — opened with:

Describe an app or workflow in plain language — I draft the objects, screens and automations, then you review and publish.

Workflows and automations are exactly what ADR-0112 v1 refuses (no flows, actions or schedules), so a user who took the sentence at its word was turned down.

This is the last member of a family whose other three were already fixed:

Surface Card Status
Five from-scratch start chips cloud#1984 / objectui#7710
Four edit-mode start chips objectui#7709
Model's own closing suggestions cloud#2020 / cloud#2022
The static line above all of them this PR

What changed

Two strings, both on the build agent's surface (agentEmptyState() in AiChatPage.tsx):

  • console.ai.empty.build.description — "an app or workflow … objects, screens and automations" → "an app … objects, screens and sample data"
  • console.ai.empty.editApp.description — "… view or automation" → "… view or dashboard"

The second one is not in the issue body — I found it while tracing the render site. It is the same isBuildAgent() branch (edit mode, ?package=), so it makes the same promise on the same surface.

⚠️ All ten packs, not just en/zh

The issue says "只有 en 与 zh 有这条,其余 8 个语言包走回退". That is not the case — every one of the ten packs shipped its own translated violation (ar/de/es/fr/ja/ko/pt/ru too). A two-language fix would have left eight languages reading the old promise.

The hardcoded defaultValue fallbacks in AiChatPage.tsx are updated alongside, since a stale fallback silently reinstates the sentence for any pack that loses the key.

Deliberately NOT changed

The boundary is v1 AI authoring, not the word "automation". The platform's manual automation paths are real and stay as they are:

String Why it stays
home.build.subtitle ("design objects, forms, automations and interfaces") Its card navigates to /studio — manual authoring, which genuinely does author flows
engine.studio.landing.description Studio's own landing copy, same manual path
dataImport.optRunAutomations ("Run automations & triggers") Import wizard running existing automations at runtime
packagedAutomation.* Setup › Packaged automation — operational surface for flows installed packages ship
marketplace automation category Taxonomy label
approvals / flowRunner.* groups Real runtime features
auth.layout.subhead ("…data management, workflows, and analytics") Login-page platform positioning
console.ai.* approv hits (toolAwaitingApproval, planApprove*) The user approving the AI's plan — not the AI building an approval

Tests

New packages/i18n/src/__tests__/makerEmptyState-v1-scope-8329.test.ts, built on the 7709 suite's shape (54 tests):

  1. Every pack defines both descriptions and both titles, non-empty.
  2. Neither description in any pack hits that pack's own banned vocabulary — an English-only scan would have declared the five non-Latin packs clean without reading a character of them.
  3. Non-vacuity control: each pack's banned list is re-run against the two sentences that pack actually retired, and must flag both.
  4. A "didn't revert to its own old string" guard, and positive assertions that the replacement names v1 capabilities.

Verified the guard actually bites: reinstating the old zh string fails 3 tests (expected [ '自动', '流程' ] to deeply equal []).

Verification

  • packages/i18n/1090 passed
  • packages/app-shell/6261 passed, 1 skipped (649 files)
  • @object-ui/i18n type-check clean; app-shell builds clean (tsc passes)
  • eslint on changed files: 0 errors
  • End-to-end through the real i18n runtime: resolved console.ai.empty.{build,editApp}.description via createI18n({lng}) + changeLanguage() for all ten locales and read back each translated string — not just a read of the pack objects.

⚠️ Not done: a browser screenshot. The card's acceptance asks for one from a running environment; this seat verified through the i18n runtime and the component's unit tests instead. If the screenshot is required to close, it still needs to be taken.

Revert note

When ADR-0112 v2 re-adds flows and actions, both sentences come back — same line of the roadmap as the chips. Recorded in the comment beside the keys in en.ts and in the test's RETIRED map (which holds every pack's original wording).

🤖 Generated with Claude Code

…R-0112 v1 builds (#8329)

The build surface's empty state opened with "Describe an app or workflow in
plain language — I draft the objects, screens and automations, …". Workflows
and automations are exactly what ADR-0112 v1 refuses: it has no flows, actions
or schedules, so a user who took that sentence at its word was turned down.

This is the last member of a family whose other three were already fixed —
the five from-scratch start chips (cloud#1984 / objectui#7710), the four
edit-mode chips (objectui#7709) and the model's own closing suggestions
(cloud#2020 / cloud#2022). The chips were audited and the model's prose was
audited; the static line ABOVE them, which is the first thing a new user
reads on the page, was not.

Two strings, both on the build agent's surface:

  console.ai.empty.build.description    — "an app or workflow … objects,
    screens and automations" → "an app … objects, screens and sample data"
  console.ai.empty.editApp.description  — "… view or automation" →
    "… view or dashboard"

Both are changed in ALL TEN packs, not just en/zh: every pack shipped its own
translated violation, so a two-language fix would have left eight users
reading the old promise. The hardcoded `defaultValue` fallbacks in
AiChatPage.tsx are updated with them, since a stale fallback silently
reinstates the sentence for any pack that loses the key.

Deliberately NOT touched — the platform's manual automation surfaces are real
and the boundary is v1 AI AUTHORING, not the word "automation":
`home.build.subtitle` (its card opens /studio, which genuinely authors flows),
`engine.studio.landing.description`, `dataImport.optRunAutomations`,
`packagedAutomation.*`, the marketplace `automation` category, and the
approvals / flow-runner groups.

Guarded by makerEmptyState-v1-scope-8329.test.ts, built on the 7709 suite's
shape: every pack scanned with its OWN banned vocabulary (an English-only scan
would have declared the five non-Latin packs clean without reading a character
of them), plus a non-vacuity control that re-runs each list against the two
sentences that pack actually retired.

REVERT both when ADR-0112 v2 re-adds flows and actions — same line of the
roadmap as the chips.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ix (objectui#8329)

`Changeset Declaration` was the one red check on this PR. The diff touches
`@object-ui/i18n` (ten locale packs) and `@object-ui/app-shell` (the two
hardcoded defaultValue fallbacks), so both are declared.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 50 chunks) 3472.8 KB 3512.7 KB
Main entry chunk (gzip) 143.9 KB 350 KB
Entry file index-Di84-Ll2.js
Status PASS

The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it.


📦 Bundle Size Report

Package Size Gzipped
app-shell (consoleActionDispatch.js) 0.20KB 0.19KB
app-shell (index.js) 15.67KB 5.75KB
app-shell (runtime-config.js) 20.68KB 7.36KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.06KB 3.86KB
auth (ActiveOrganizationStorage.js) 25.05KB 9.16KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 2.07KB 1.00KB
auth (AuthProvider.js) 40.18KB 10.59KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.15KB 5.39KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.65KB 2.22KB
auth (SocialSignInButtons.js) 9.61KB 3.89KB
auth (UserMenu.js) 3.41KB 1.23KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.21KB 10.80KB
auth (createAuthenticatedFetch.js) 8.46KB 3.43KB
auth (index.js) 3.19KB 1.44KB
auth (invitation-status.js) 1.22KB 0.70KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 5.30KB 1.02KB
auth (useWorkspaceAdminStatus.js) 11.08KB 4.58KB
collaboration (CommentThread.js) 26.08KB 7.56KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.49KB 2.64KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.68KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.05KB 2.52KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 498.55KB 114.03KB
core (index.js) 7.48KB 2.96KB
create-plugin (index.js) 10.12KB 3.28KB
data-objectstack (index.js) 189.15KB 52.56KB
fields (index.js) 243.15KB 61.40KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (builtinAggregateLabels.js) 0.86KB 0.49KB
i18n (currency.js) 1.22KB 0.64KB
i18n (fallbackInterpolation.js) 6.25KB 2.77KB
i18n (i18n.js) 6.57KB 2.76KB
i18n (index.js) 3.65KB 1.47KB
i18n (pickLocalized.js) 7.62KB 3.26KB
i18n (provider.js) 26.89KB 9.04KB
i18n (useDisplayLocale.js) 2.85KB 1.45KB
i18n (useObjectLabel.js) 34.34KB 9.17KB
i18n (useSafeTranslation.js) 5.60KB 2.33KB
layout (index.js) 38.84KB 10.94KB
mobile (MobileProvider.js) 0.92KB 0.49KB
mobile (ResponsiveContainer.js) 0.94KB 0.38KB
mobile (breakpoints.js) 1.51KB 0.70KB
mobile (createOfflineDataSource.js) 5.61KB 1.75KB
mobile (index.js) 1.99KB 0.87KB
mobile (offlineQueue.js) 3.91KB 1.35KB
mobile (pwa.js) 0.97KB 0.49KB
mobile (serviceWorker.js) 1.48KB 0.62KB
mobile (serviceWorkerSource.js) 3.41KB 1.48KB
mobile (useBreakpoint.js) 1.54KB 0.65KB
mobile (useGesture.js) 6.96KB 1.98KB
mobile (useOfflineSync.js) 1.99KB 0.72KB
mobile (usePullToRefresh.js) 2.53KB 0.85KB
mobile (useResponsive.js) 0.72KB 0.42KB
mobile (useSpecGesture.js) 4.39KB 1.66KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 11.71KB 4.29KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 6.24KB 2.16KB
permissions (discardProofCache.js) 1.04KB 0.55KB
permissions (evaluator.js) 5.12KB 1.74KB
permissions (index.js) 0.93KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.53KB
permissions (usePermissions.js) 4.83KB 2.27KB
plugin-ai (index.js) 15.16KB 3.68KB
plugin-calendar (index.js) 49.00KB 13.91KB
plugin-charts (index.js) 71.39KB 19.92KB
plugin-chatbot (index.js) 194.52KB 46.34KB
plugin-dashboard (index.js) 131.48KB 34.45KB
plugin-designer (index.js) 213.21KB 43.63KB
plugin-detail (index.js) 248.68KB 63.94KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 131.01KB 32.32KB
plugin-gantt (index.js) 167.16KB 40.99KB
plugin-grid (index.js) 208.58KB 56.63KB
plugin-kanban (index.js) 55.38KB 15.72KB
plugin-list (index.js) 112.74KB 27.70KB
plugin-map (index.js) 20.49KB 6.83KB
plugin-markdown (index.js) 13.88KB 4.80KB
plugin-report (index.js) 43.42KB 11.92KB
plugin-timeline (index.js) 30.10KB 8.74KB
plugin-tree (index.js) 9.33KB 3.25KB
plugin-view (index.js) 84.54KB 20.84KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.90KB 0.85KB
providers (UploadProvider.js) 11.66KB 3.50KB
providers (index.js) 0.45KB 0.23KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 5.62KB 2.34KB
react (LazyPluginLoader.js) 4.47KB 1.63KB
react (SchemaRenderer.js) 81.07KB 26.86KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.63KB 2.18KB
react (schema-input.js) 2.32KB 1.24KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (codegen.js) 6.58KB 2.74KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 5.55KB 2.45KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (parse.js) 20.57KB 5.88KB
sdui-parser (provenance.js) 3.66KB 1.82KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 13.64KB 4.59KB
types (ai.js) 0.20KB 0.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 2.87KB 1.00KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 2.93KB 1.49KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
types (data-display.js) 3.75KB 1.85KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.85KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (expression.js) 0.20KB 0.18KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (http-inflight.js) 8.87KB 3.73KB
types (http-retry.js) 4.32KB 2.02KB
types (icon-key-migration.js) 4.26KB 1.63KB
types (index.js) 4.74KB 2.25KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 4.73KB 2.28KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 0.20KB 0.18KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (select-option.js) 0.20KB 0.19KB
types (spec-report.js) 5.05KB 1.93KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 6.28KB 2.87KB
types (ui-action.js) 8.11KB 3.32KB
types (views.js) 0.20KB 0.18KB
types (widget.js) 0.20KB 0.18KB

Size Limits

  • ✅ Core packages should be < 50KB gzipped
  • ✅ Component packages should be < 100KB gzipped
  • ⚠️ Plugin packages should be < 150KB gzipped

@hotlong
hotlong marked this pull request as ready for review September 7, 2026 23:47
@hotlong
hotlong added this pull request to the merge queue Sep 7, 2026
Merged via the queue into main with commit 6e9a3d4 Sep 8, 2026
34 checks passed
@hotlong
hotlong deleted the fix/ai-build-empty-description-v1-boundary-8329 branch September 8, 2026 00:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

1 participant