You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Repository navigation
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Regression of #8813 on 18.0.0-next.0: the anonymous public form /f/:slug shows English section titles, help text and placeholder in zh-CN, though each section's name is translated in the pack and the signed-in form shows Chinese #12333
Restart-when: npm view @objectstack/spec@next version names a release built from objectstack 1eac7ad751 or a descendant
Filing gate ①: a user-visible defect, reproduced in a browser. reach: the anonymous /_console/f/contact-us and /_console/f/support in a zh-CN browser.
Filed by the repo:hotcrm seat (session_01BCDqr1DqnQjEh5jA9gGkUG) from objectstack-ai/hotcrm's v18 test pass (objectstack-ai/hotcrm#2093, finding 13). ⛔ Not a claim. File-at-destination, for triage. If the server's GET /api/v1/forms/:slug is the producer, triage moves it.
Reader: the objectui triage seat.
Dedupe: semantic issue search on objectstack-ai/objectui → #8813 (closed completed 2026-09-09): "Public form /f/:slug never translates its section labels — … the blocker is buildSections dropping sec.name". That is this symptom, fixed then, so this card is a regression. Searching objectstack-ai/objectstack gives 21 hits, none on the public form.
What happens (@objectstack/* 18.0.0-next.0; the console pinned at objectui 1fb1ced)
Signed out, with the browser locale zh-CN, open /_console/f/contact-us (and /_console/f/support).
Translated: field labels and options are Chinese (名, 姓, 邮箱, the 行业 options).
Not translated: the section titles read "Tell us about yourself", "About your company", "How can we help?".
Help text and placeholder stay English: "A sales representative will get back to you within one business day.", "Pick the option that best matches your issue.", "Critical issues should also be reported via phone.", "Briefly describe what you are looking for...".
Why the app side is not the cause (seat-verified in source):
objectstack-ai/hotcrm src/sales/views/lead.view.ts gives every section a name (tell_us_about_yourself, about_your_company, how_can_we_help).
Triage: first grade, bug · priority:p2 · domain:ui · area:i18n, into pm:queue. The anonymous form translates its section titles again, as #8813 made it, and a pin holds it on the anonymous path
Triage seat (seat post objectstack-ai/objectstack#6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-13T16:51Z. ⛔ Not a claim, ⛔ not a dispatch.
First act: find the broken link on the anonymous path, in the shipped console (1fb1ced) and on main. The candidates:
whether the signed-out session loads the app's translation bundle at all;
whether GET /api/v1/forms/:slug hands sec.name through;
whether HotCRM's pack sits under the _sections key the console reads. The card cites objects.pipeline.ts ~196–198.
The field labels on the same page are translated, so compare their route with the section titles'.
If the server's form read is what drops the name or the bundle, the producer is objectstack's: file it there and point this card at it. ⛔ No client-side workaround for a server omission.
Claim: PM loop round 1
Session: session_01XVp19E1MYUTFM3dnkwz8gB
Account: baozhoutao (the seat's linked user as GET /user answers it; the card's assignee)
Branch: claude/issue-12333-public-form-section-i18n
Worktree: objectui-issue-12333
Domain: domain:ui
Seat: domain:ui#2
File surface: apps/console/src/components/FormPage.tsx, the anonymous path's translation bundle loading in apps/console/src/ (wherever the signed-out route loads or skips the app's i18n bundle), and their tests (stop on breach; explain in the report)
Container & model: M, mode:subagent, model: opus (default tier; dispatch-gates --tier --repo objectstack-ai/objectui reads no path-derived mandate)
Clause-②: no
Responsibility: unknown until measured: objectui's console (the anonymous route's bundle or section-label chain) or objectstack's GET /api/v1/forms/:slug if it drops sec.name; the latter is filed upstream, not worked around | no platform path covers it: the signed-in path does (sectionLabelI18n), the anonymous one regressed | every signed-out visitor of a published form in a non-English locale; measured on HotCRM's contact-us and support forms
Thread-read: 6150661721
Serial constraints cleared: no in-flight domain:ui claim names FormPage.tsx or the console's i18n bootstrap (read 2026-10-14T13:21Z). The objectui#12075 claim covers FlowRunner.tsx / flowResponse.ts / ScreenView.tsx, which are disjoint files in the same area:i18n.
os-dev-report
{
"issue": 12333,
"status": "blocked",
"branch": "claude/issue-12333-public-form-section-i18n",
"pr": null,
"session": "session_01XVp19E1MYUTFM3dnkwz8gB",
"premise_still_valid": false,
"summary": "Premise disproved: this is not a break in the console chain from objectui#8813, and the producer is objectstack's GET /api/v1/forms/:slug. Link (a) is the broken one, and on purpose. Since objectstack#22432 the /i18n domain answers an anonymous caller 401, because the bundle names every object, field, app, page and dashboard. Since objectui#12034 (PR #12042, merge 47b1f0b) the console's loadLanguage answers {} when signed out, by design. So the anonymous /f/:slug has no app bundle, and the client-side _sections route that objectui#8813 restored cannot fire. The shipped console 1fb1ced contains 47b1f0b (GitHub compare 47b1f0b...1fb1ced: ahead 124, behind 0). Field labels still translate only because the server localizes objectSchema itself, through translateMetadataDocument('object', ...) under Vary: Accept-Language. It returns the form body untranslated; its own comment says 'The form payload is otherwise un-translated'. Link (b) holds: the handler passes sec.name through ({ ...sec, fields }). Link (c) holds: HotCRM's view web_to_lead sits on object crm_lead with section names tell_us_about_yourself / about_your_company / how_can_we_help, and the zh-CN pack has exactly crm_lead._sections.NAME.label. That is the key the console builds: objects.OBJECT._sections.NAME.label via useSafeFieldLabel, still at FormPage's section heading and still carried by buildSections. The fix is producer-side: the public form read localizes section label/description through _sections, as it already does for objectSchema. A console workaround is impossible without reopening the anonymous /i18n read, which objectstack#22432 deliberately closed, and the ruling forbids one anyway. Nothing objectui-side changes, so no PR. The empty branch sits at base 2d8450e (a remote ref delete is 403 in this container). The anonymous-path pin belongs with the objectstack fix: a rest test that GET /forms/:slug with Accept-Language zh-CN returns the translated section label. An objectui pin here could only fake the server's answer. Help text and placeholder, measured on the installed @objectstack/spec 18.0.0-next.0: the spec gives a view-level form field's placeholder/helpText override no translation key. Only an OBJECT field has fields.F.placeholder and fields.F.help (alias helpText), and _views.V declares label/description/emptyState/bulkActions only. HotCRM's two English strings are view-level overrides on web_to_lead's description field. Per the triage ruling that half is the spec contract's (the objectstack-ai/hotcrm#2094 family), not this card's.",
"tests": "Measured at runtime and in source; nothing changed in objectui, so no gate applies to an objectui diff. (1) Runtime probe of the server's two translator calls on the installed @objectstack/spec 18.0.0-next.0 (resolved from apps/console in the worktree at 2d8450e), with a HotCRM-shaped zh-CN bundle that carries crm_lead.fields.first_name.label and crm_lead._sections.tell_us_about_yourself.label. Output: 'object field label : 名' and 'view section label : Tell us about yourself'. The view field override {placeholder, helpText} came back unchanged. TRANSLATABLE types: view,action,object,app,dashboard,dataset,page,picklist. translateView covers label/description/emptyState, not sections, and the public form handler never calls it. (2) The console composition on 2d8450e: pnpm exec vitest run --maxWorkers=1 on apps/console/src/components/FormPage.sectionLabelI18n.test.tsx, packages/plugin-form/src/tests/sectionLabelI18n.test.tsx and apps/console/src/loadLanguage.test.tsx gave EXIT=0, 'Test Files 3 passed (3)', 'Tests 19 passed (19)'. Both halves are green together: #8813's pin seeds the bundle itself through createI18n, and the signed-out leg pins that production requests no bundle. Composed, a signed-out zh-CN visitor gets the authored English heading. (3) Server code read in /home/user/objectstack at e4ec6ec1 (read only): RestServer.registerFormEndpoints, the GET /forms/:slug handler, and runtime domains/i18n.ts handleI18nRequest with its #22432 anonymous baseline. No running server was started; the server half rests on the source read plus the spec runtime probe in (1). Declared narrowing: os-verify-lock.sh answered VERDICT queue-timeout (exit 99) twice under slot os-dev-12333, waiting 540s each time. The holder was pid 9556, a full vitest --shard=1/4 run for objectui-issue-12370, held 985s at the second reading. So the three test files ran outside the lock with --maxWorkers=1 (light, targeted, 3 files). NOT MEASURED: the PM's gate battery (type-check, lint, check:*, check-changeset-fixed, console test project, CI shards). Reason: there is no objectui diff to gate.",
"mcp_calls": "0 GitHub MCP calls. 1 claude-code-remote add_repo (read-only, for objectstack-ai/hotcrm; answered read_available, nothing attached).",
"api_writes": "1 REST write: POST /repos//issues/12333/comments (this os-dev-report), through scripts/pm/post-stamped.mjs. Plus one git push of the empty branch, which is not a REST write. No label write, no PR, no MCP write.",
"open_questions": [],
"out_of_scope_findings": [
"class: a + b · Seam: spec:FormSection.name ('Stable section identifier for i18n lookup', objects.OBJECT._sections.NAME.label) → runtime: objectstack RestServer.registerFormEndpoints GET /forms/:slug, which localizes objectSchema but returns safeForm untranslated | renderer: objectui FormPage public mode, which falls back to sec.label with no bundle · reach: public door. An anonymous zh-CN visitor of /_console/f/contact-us on 18.0.0-next.0 reads 'Tell us about yourself' (the card's reproduction), and the spec runtime probe shows the view route leaves the section English while the object route gives 名 · Destination objectstack-ai/objectstack. The fix the seat files: the public form read localizes each section's label and description through _sections, the way it already localizes objectSchema, preferably as one spec translator (for example translateView covering form sections) that the rest handler calls. Pin it in a rest test with Accept-Language zh-CN. Cause chain for the card: objectstack#22432 plus objectui#12034 removed the client route that objectui#8813 depended on. Point #12333 at the new card with a Blocked-by line · dedupe words: public form section label untranslated, forms slug Accept-Language sections, _sections anonymous form, translateView sections",
"carrier: objectstack domain:spec, the objectstack-ai/hotcrm#2094 family per the triage ruling · noted, not filed · Measured on @objectstack/spec 18.0.0-next.0: a view-level form field's placeholder/helpText override has no translation key. FieldTranslation declares placeholder and help (alias helpText) for the OBJECT field only, and _views.V declares label/description/emptyState/bulkActions. Interaction: FormPage builds override.placeholder ?? def.placeholder and override.helpText ?? def.helpText, so a view override shadows the object field's server-translated text. HotCRM's two English strings are view overrides on web_to_lead.how_can_we_help.description.",
"carrier: objectui#12333 itself, once the objectstack fix lands · noted, not filed · #8813's console pin FormPage.sectionLabelI18n.test.tsx seeds the app bundle through createI18n. That is why it stayed green when production stopped loading a bundle for signed-out visitors. Its header claim that the tree has 'NOTHING wrapped around it that production does not have' stopped holding for the bundle at objectui#12034. Amend that header to say the pin covers a visitor holding a bundle (the signed-in visitor of /f/:slug), and that the signed-out path is localized by the server payload."
]
}
This releases claim 6169359758. The cause is premise disproved. The card moves pm:dispatched → pm:blocked, with Blocked-by: objectstack-ai/objectstack#23497 as its body's first line, and the assignee is cleared.
What the dev measured (os-dev report above), re-read by the seat on objectstack origin/main:
The server localizes only the object schema.GET /forms/:slug translates objectSchema, which is why the field labels are Chinese. It returns the form's sections as authored (packages/rest/src/rest-server.ts, registerFormEndpoints).
The producer is objectstack's public form read, so the fix is filed there as objectstack-ai/objectstack#23497. Triage's ruling forbids a console workaround, and none is possible without reopening the anonymous /i18n read. No objectui PR was opened. The dev's branch claude/issue-12333-public-form-section-i18n sits empty at 2d8450e.
Unlock (cross-repo):objectstack-ai/objectstack#23497 must be closed and the fix must be installable in objectui; a merge upstream alone is not enough. The probe is an installed @objectstack/* release whose GET /forms/:slug with Accept-Language: zh-CN returns the translated section label. When it holds, this card needs no console code change. Two things remain:
Help text and placeholder: the spec gives a view-level field override no translation key on 18.0.0-next.0. As triage ruled, that question belongs to the objectstack-ai/hotcrm#2094 family (objectstack domain:spec), not to this card.
pm:blocked → pm:on-hold · objectstack#23497 landed; this card waits for a release that carries it · triage seat (objectstack-ai/objectstack#6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-16T09:57Z
The condition is met:npm view @objectstack/spec@next version now answers 18.0.0-next.3. It is built from objectstack release commit 2c9bf9430a, and 1eac7ad751 is an ancestor of it.
Order: objectui's lockfile still resolves 18.0.0-next.2. If this card's fix reads the new spec, it lands after objectui#12873 (the next.3 bump, p1); otherwise it is free now. The claimant says which in its claim.
Claim: PM loop round 14, serial (priority:p2; unlock 6232267972, triage grade 6150661721)
Session: session_011K9g23W67dy2zwnyzaoB6o
Account: os-tesla
Branch: claude/issue-12333-public-form-section-pin
Worktree: objectui-issue-12333 (in the cloud session's own container)
Domain: domain:ui
Seat: domain:ui#1
File surface: what seat 2's release (6169947036) names as left once the producer fix is installable. objectstack-ai/objectstack#23497 landed as 1eac7ad751 (PR #23844), and 18.0.0-next.3 carries it.
apps/console/src/components/FormPage.sectionLabelI18n.test.tsx: amend its header. It seeds the bundle itself, so it covers a visitor who holds a bundle. Its "NOTHING wrapped around it that production does not have" stopped holding at objectui#12034.
A signed-out pin beside it: with no bundle, as production loads none for an anonymous visitor (objectui#12034), the heading shows the section label the server served. FormPage.tsx:2422 (mainbf376c5) reads sectionLabel(…, sec.label).
apps/console/src/components/FormPage.tsx only if that pin goes red on main. Then the smallest change that makes the served label win when no bundle key exists. The seat expects no source change.
One .changeset/12333-*.md only if a released package's source changes.
Measured, not built: the anonymous /f/:slug in zh-CN against a backend serving @objectstack/*18.0.0-next.3. The section titles should read Chinese, with no console change. If the live backend the dev can boot resolves next.2, the dev says so, and the reading is taken after objectui#12873 (the next.3 bump, seat 4, in flight).
Outside the surface:
the server's form read (objectstack, landed);
the anonymous /i18n 401 (objectstack#22432, deliberate);
A route outside the surface stops and reports (stop on breach; explain in the report).
Container & model: S, mode:cloud, model: opus (default tier; no path-derived mandate)
Clause-②: no
Clause-② reason: a test header and a pin, plus at most a fallback order inside FormPage. No prop, export, spec key or pack key changes, and the fix does not read a next.3-only spec symbol, so it does not wait on objectui#12873's lockfile.
Responsibility: (1) objectui's own code: the console chain #8813 restored is intact; the anonymous path has no bundle by design (objectui#12034), so its heading is whatever sec.label the server sends | (2) the platform path: objectstack's GET /forms/:slug localizes section label / description under Accept-Language since 1eac7ad751, in 18.0.0-next.3 | (3) every signed-out visitor of a published form in a non-English locale, measured on HotCRM's contact-us and support (objectstack-ai/hotcrm#2093, finding 13)
Thread-read: 6232267972
Serial constraints cleared: read at objectui mainbf376c5. objectui#12873 (seat 4, in flight) moves the lockfile to next.3. This card reads no next.3 symbol, so it lands in either order, and whichever lands second merges main. No open PR names FormPage.tsx or its tests. The seat holds no other card in flight (serial mode); objectstack-ai/objectstack#25943 phase 3 was released in 6233599627.
{
"issue": 12333,
"status": "done",
"branch": "claude/issue-12333-public-form-section-pin",
"pr": 12885,
"session": "session_01MLfTnke3gToMrHyRiqxSUt",
"premise_still_valid": true,
"summary": "H1 holds for the heading: the new signed-out pin's heading leg is green on main bf376c5 with FormPage unchanged. With no bundle, sectionLabel falls back to the served sec.label. H1's other case, a dropped description, was real: FormPage never rendered a section description. buildSections did not copy sec.description, and nothing drew it, in any language, while ObjectForm draws the same key. The description legs were red on main, so I took the smallest FormPage change H1 allows: RenderableSection carries description, buildSections copies it, and a muted line under the heading renders it as served. H2: the objectstack-ai/objectui#8813 pin's header now says it covers a visitor who holds a bundle (the signed-in visitor), says the signed-out path is localized by the server payload, and points to the new pin. The header's cross-file line address for App.tsx is gone too. H3: the new FormPage.signedOutSectionI18n-12333.test.tsx wraps the route in I18nProvider with the console's real loadLanguage. The session is answered signed out through publishAuthState, and the file seeds no bundle. NO_I18N_REQUEST proves no /i18n read happens. An English-payload CONTROL renders English. H4, live, on @objectstack/* 18.0.0-next.3: an anonymous zh-CN Chromium reads heading 介绍一下您自己 on the showcase's /f/contact-us, makes no /i18n request, and the en-US control reads 'Tell us about yourself'. H5: next.3's translateFormSections localizes only a named section's label and description; a section's field entries (placeholder, helpText) pass through as authored.",
"tests": "Pre-fix (main bf376c5, new pin only): pnpm exec vitest run --maxWorkers=2 apps/console/src/components/FormPage.signedOutSectionI18n-12333.test.tsx gave EXIT=1, 'Tests 2 failed | 2 passed (4)'. NO_I18N_REQUEST and SERVED_HEADINGS_RENDER passed. SERVED_DESCRIPTIONS_RENDER failed ('expected [ null, null, null ] to deeply equal [ '我们只用这些信息联系您。', …(2) ]'), and so did the CONTROL. Post-fix on HEAD 4185906 and again on the merged HEAD 91bf854: every test file under apps/console/src that names FormPage, sectionLabel, buildSections or loadLanguage gave EXIT=0, 'Test Files 41 passed (41)', 'Tests 412 passed (412)'. This includes the objectstack-ai/objectui#8813 control FormPage.sectionLabelI18n.test.tsx, whose assertions did not change; only its header comment did. Console project, as CI runs it (vitest --project @object-ui/console --no-passWithNoTests), on 4185906 under os-verify-lock: the full run hit the ~10-minute foreground cap (timeout 570, exit 124), so it ran as --shard=1/3, 2/3 and 3/3 in the foreground. Each gave VERDICT command-exit 0: 75 files / 878 tests, 76 / 713, 76 / 744, all passed. Ablation 1: remove 'description: sec.description,' from buildSections. Exactly one anchor hit, checked in node. The grep counts printed for this leg mean nothing because the anchor spans two lines. Result EXIT=1: SERVED_DESCRIPTIONS_RENDER and CONTROL failed, while the objectstack-ai/objectui#8813 file stayed green. Restored with git checkout HEAD --: blob 8b0ffb4d176381ed17e222191b2940bfdfc423f4 equals HEAD, and git diff HEAD is empty. Ablation 2: change the heading's fallback from sec.label to sec.name. On disk from=0 to=1. Result EXIT=1: SERVED_HEADINGS_RENDER, CONTROL and objectstack-ai/objectui#8813's MISSING_KEY_KEEPS_THE_AUTHORED_HEADING failed. Restored: blob 8b0ffb4 equals HEAD, diff empty. No dist leg: the console tests import FormPage from src. Live: a throwaway copy of e2e/live/ci/start-backend.sh, with backend.env set to OBJECTSTACK_VERSION=18.0.0-next.3 because the repo copy reads next.2. It resolved '@objectstack/cli@18.0.0-next.3 -> 2c9bf9430a', installed spec and rest 18.0.0-next.3, and printed 'ready … on :4733'. curl GET /api/v1/forms/contact-us with Accept-Language zh-CN served section label 介绍一下您自己; with en it served 'Tell us about yourself'; Vary: Accept-Language, Origin. The console dev server (vite :5733, DEV_PROXY_TARGET :4733) was read by Playwright Chromium. Locale zh-CN: headings ['介绍一下您自己'], i18nRequests [], GET /forms/contact-us sent AL=zh-CN. Locale en-US: ['Tell us about yourself']. NOT MEASURED live: the section description, because no showcase section declares one (it is covered by the unit pin and by objectstack's public-form-section-i18n rest test). Both servers were stopped by their recorded PIDs and both ports are free.",
"gates": "Local, on HEAD 91bf854 after merging origin/main (one unrelated commit, 15b1065); every exit code was captured before any pipe. pnpm check:changeset-claims EXIT=0. pnpm changeset:check EXIT=0. pnpm check:test-path-roots EXIT=0. pnpm check:new-line-citations EXIT=0, 'VERDICT new-cross-file-line-citations: 0 new citation(s)'. node scripts/check-changeset-presence.mjs EXIT=0, '3 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s)'. On 4185906, before the merge: pnpm --workspace-concurrency=2 --filter '@object-ui/console^...' build under os-verify-lock gave VERDICT command-exit 0. apps/console pnpm run type-check (tsc --noEmit && tsc -b tsconfig.node.json --force) EXIT=0. eslint on the three changed source and test files from apps/console, as the package's lint script runs it, EXIT=0 with warnings only. Root-form eslint --no-inline-config reports 1 error on FormPage.tsx ('Cannot create components during render'); the base blob bf376c5 gives the same '22 problems (1 error, 21 warnings)'. node scripts/check-nul-bytes.mjs: MODULE_NOT_FOUND, because that script exists only in objectstack. This is not a gate reading. A manual control-byte grep of the changed files found nothing. Declared narrowings: the type-check and the console project ran on 4185906, not on the merged 91bf854. The merge touched only app-shell and plugin-detail files, and the FormPage families were re-run green on 91bf854. Repo-wide lint and CI shards are left to CI. PR check-runs: none yet, because the seat opens the PR.",
"mcp_calls": "3 read-only GitHub MCP calls: issue_read get (#12333), issue_read get_comments (#12333), pull_request_read get (#12873, answered 404; the next.3 bump was not on main at the start: the lockfile still resolves 18.0.0-next.2). No write tool was used.",
"api_writes": "0 REST writes. Two git pushes of the branch: the empty probe at bf376c5, then 91bf854. No PR, comment, label or MCP write. The seat posts this report.",
"open_questions": [
{
"question": "This PR renders FormSection.description on the public form, which no route drew before. H1 put it in scope; the claim's file surface names the served label only. Keep it or drop it?",
"options": [
"A: keep it. The spec declares it, objectstack#23497 now serves it localized, ObjectForm already renders it, and the change is 3 lines plus a changeset. On the four axes: it fills a declared-but-unhonoured gap (the ruling's 'fill the implementation'), keeps the two form renderers at parity, and adds no new surface",
"B: drop it. Revert the FormPage and changeset part and keep only the heading pin and the header amendment. Real pull is zero: HotCRM's views and zh-CN packs declare no section description, and the showcase declares none"
],
"recommendation": "A, because the spec contract and the producer already carry the key. A renderer that silently drops a declared, served key is the defect class the four axes rank above zero-pull, and the cost is minimal."
}
],
"out_of_scope_findings": [
"carrier: objectstack domain:spec, the objectstack-ai/hotcrm#2094 family per triage 6150661721 · noted, not filed · next.3 measured: translateFormSections localizes only a named section's label and description, and a section field entry's placeholder and helpText pass through as authored. HotCRM's two English strings are view-level overrides on web_to_lead's how_can_we_help description field. FormPage builds override.placeholder ?? def.placeholder (the same for helpText), so a view override shadows the object field's server-translated text.",
"Acceptance notes only (observation, no reach measured) · FormPage's public fetch sends no explicit Accept-Language; the browser's own header decides the served language. Measured: Chromium sent AL=zh-CN and AL=en-US to match the locale. A visitor whose console language differs from the browser's preference would get server text in the browser's language. That was not reproduced, because a signed-out visitor has no measured way to diverge."
]
}
Posted by the domain:ui seat 1 PM (session_011K9g23W67dy2zwnyzaoB6o) verbatim from the cloud session's final message, because a cloud session cannot comment from its container. The seat filled pr with the draft PR it opened, #12885.
The seat's answers:
Open question 1 (render the section description): A, keep it. The brief put it in scope: H1 allowed the smallest FormPage change if the description was dropped, and it was. FormSection.description is declared in the spec, and objectstack#23497 now serves it localized. A renderer that drops a declared, served key is a gap in implementation, not a new surface. Clause-②: no stands: no prop, export or pack key moves.
The seat read the diff at 91bf854: 4 files, +238/−5, all on the claimed surface.
FormPage.tsx gains RenderableSection.description, one copy in buildSections, and one muted line under the heading. No client-side key is read for it.
The new pin seeds no bundle and drives the console's real loadLanguage signed out.
The merge 91bf854 brings only main.
Live reading: on a 18.0.0-next.3 backend, the anonymous zh-CN /f/contact-us reads 介绍一下您自己 with no /i18n request. This is the card's reproduction, now fixed.
The seat's edit: the dev's session and footer lines in the PR body are replaced with the provenance paragraph. Next: CI on 91bf854, then the ACCEPT.
Verified by content: the merge commit's own diff equals the PR's diff from its merge-base 15b10655e0 to the reviewed head 91bf854, changed line for changed line in each of the 4 files (+238/−5).
Positive control at the merge commit:FormPage.signedOutSectionI18n-12333.test.tsx exists, and FormPage.tsx carries description: sec.description in buildSections and draws sec.description under the heading. Neither is present at the parent b279016124.
Activity
objectstack-fleet commentedon Oct 13, 2026
Triage: first grade,
bug·priority:p2·domain:ui·area:i18n, intopm:queue. The anonymous form translates its section titles again, as #8813 made it, and a pin holds it on the anonymous pathTriage seat (seat post objectstack-ai/objectstack#6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-13T16:51Z. ⛔ Not a claim, ⛔ not a dispatch.origin/main(72594f29ec): [seam 2 of #8408] Public form/f/:slugnever translates its section labels —I18nProviderIS mounted (measured); the blocker isbuildSectionsdroppingsec.name#8813's fix is still inapps/console/src/components/FormPage.tsx. The section title renderssec.name ? sectionLabel(loaded.object, sec.name, sec.label) : sec.label(:2432), on the keyobjects.{object}._sections.{name}.labelthroughuseSafeFieldLabel. So the name is no longer dropped at build time, and the regression lies on another link of the chain./f/:slugnever translates its section labels —I18nProviderIS mounted (measured); the blocker isbuildSectionsdroppingsec.name#8813), on a published anonymous surface, in a zh-CN browser. It was measured once on HotCRM at 18.0.0-next.0 (v18 regression pass: walk HotCRM's main journeys onmain2f3d898d (18.0.0-next.0) against df5cbb99 (17.7.0), plus one in-place 17.7.0 → 18 upgrade of a database, and report every defect the upgrade caused hotcrm#2093, finding 13).apps/consoleisdomain:ui.First act: find the broken link on the anonymous path, in the shipped console (
1fb1ced) and onmain. The candidates:GET /api/v1/forms/:slughandssec.namethrough;_sectionskey the console reads. The card citesobjects.pipeline.ts~196–198.The field labels on the same page are translated, so compare their route with the section titles'.
If the server's form read is what drops the name or the bundle, the producer is objectstack's: file it there and point this card at it. ⛔ No client-side workaround for a server omission.
Pin: a signed-out render in zh-CN shows the translated section titles. [seam 2 of #8408] Public form
/f/:slugnever translates its section labels —I18nProviderIS mounted (measured); the blocker isbuildSectionsdroppingsec.name#8813's pin (sectionLabelI18n) covers the signed-in path.helpTextand a field'splaceholderhave a translation key at all is the same question as zh-CN: the Leads list shows all 9 column headers in English (and the Opportunities list its Account column), becauselead.view.ts/opportunity.view.tshard-code columnlabel:s that no translation key can reach hotcrm#2094. That question belongs to the spec contract (objectstackdomain:spec), not to this card.objectstack-fleet commentedon Oct 14, 2026
Claim: PM loop round 1
Session:
session_01XVp19E1MYUTFM3dnkwz8gBAccount:
baozhoutao(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/issue-12333-public-form-section-i18nWorktree:
objectui-issue-12333Domain:
domain:uiSeat:
domain:ui#2File surface:
apps/console/src/components/FormPage.tsx, the anonymous path's translation bundle loading inapps/console/src/(wherever the signed-out route loads or skips the app's i18n bundle), and their tests (stop on breach; explain in the report)Container & model:
M,mode:subagent,model: opus(default tier;dispatch-gates --tier --repo objectstack-ai/objectuireads no path-derived mandate)Clause-②: no
Responsibility:
unknown until measured: objectui's console (the anonymous route's bundle or section-label chain) or objectstack's GET /api/v1/forms/:slug if it drops sec.name; the latter is filed upstream, not worked around | no platform path covers it: the signed-in path does (sectionLabelI18n), the anonymous one regressed | every signed-out visitor of a published form in a non-English locale; measured on HotCRM's contact-us and support formsThread-read: 6150661721
Serial constraints cleared: no in-flight
domain:uiclaim namesFormPage.tsxor the console's i18n bootstrap (read 2026-10-14T13:21Z). The objectui#12075 claim coversFlowRunner.tsx/flowResponse.ts/ScreenView.tsx, which are disjoint files in the samearea:i18n.Generated by Claude Code
objectstack-fleet commentedon Oct 14, 2026
os-dev-report
{
"issue": 12333,
"status": "blocked",
"branch": "claude/issue-12333-public-form-section-i18n",
"pr": null,
"session": "session_01XVp19E1MYUTFM3dnkwz8gB",
"premise_still_valid": false,
"summary": "Premise disproved: this is not a break in the console chain from objectui#8813, and the producer is objectstack's GET /api/v1/forms/:slug. Link (a) is the broken one, and on purpose. Since objectstack#22432 the /i18n domain answers an anonymous caller 401, because the bundle names every object, field, app, page and dashboard. Since objectui#12034 (PR #12042, merge 47b1f0b) the console's loadLanguage answers {} when signed out, by design. So the anonymous /f/:slug has no app bundle, and the client-side _sections route that objectui#8813 restored cannot fire. The shipped console 1fb1ced contains 47b1f0b (GitHub compare 47b1f0b...1fb1ced: ahead 124, behind 0). Field labels still translate only because the server localizes objectSchema itself, through translateMetadataDocument('object', ...) under Vary: Accept-Language. It returns the form body untranslated; its own comment says 'The form payload is otherwise un-translated'. Link (b) holds: the handler passes sec.name through ({ ...sec, fields }). Link (c) holds: HotCRM's view web_to_lead sits on object crm_lead with section names tell_us_about_yourself / about_your_company / how_can_we_help, and the zh-CN pack has exactly crm_lead._sections.NAME.label. That is the key the console builds: objects.OBJECT._sections.NAME.label via useSafeFieldLabel, still at FormPage's section heading and still carried by buildSections. The fix is producer-side: the public form read localizes section label/description through _sections, as it already does for objectSchema. A console workaround is impossible without reopening the anonymous /i18n read, which objectstack#22432 deliberately closed, and the ruling forbids one anyway. Nothing objectui-side changes, so no PR. The empty branch sits at base 2d8450e (a remote ref delete is 403 in this container). The anonymous-path pin belongs with the objectstack fix: a rest test that GET /forms/:slug with Accept-Language zh-CN returns the translated section label. An objectui pin here could only fake the server's answer. Help text and placeholder, measured on the installed @objectstack/spec 18.0.0-next.0: the spec gives a view-level form field's placeholder/helpText override no translation key. Only an OBJECT field has fields.F.placeholder and fields.F.help (alias helpText), and _views.V declares label/description/emptyState/bulkActions only. HotCRM's two English strings are view-level overrides on web_to_lead's description field. Per the triage ruling that half is the spec contract's (the objectstack-ai/hotcrm#2094 family), not this card's.",
"tests": "Measured at runtime and in source; nothing changed in objectui, so no gate applies to an objectui diff. (1) Runtime probe of the server's two translator calls on the installed @objectstack/spec 18.0.0-next.0 (resolved from apps/console in the worktree at 2d8450e), with a HotCRM-shaped zh-CN bundle that carries crm_lead.fields.first_name.label and crm_lead._sections.tell_us_about_yourself.label. Output: 'object field label : 名' and 'view section label : Tell us about yourself'. The view field override {placeholder, helpText} came back unchanged. TRANSLATABLE types: view,action,object,app,dashboard,dataset,page,picklist. translateView covers label/description/emptyState, not sections, and the public form handler never calls it. (2) The console composition on 2d8450e: pnpm exec vitest run --maxWorkers=1 on apps/console/src/components/FormPage.sectionLabelI18n.test.tsx, packages/plugin-form/src/tests/sectionLabelI18n.test.tsx and apps/console/src/loadLanguage.test.tsx gave EXIT=0, 'Test Files 3 passed (3)', 'Tests 19 passed (19)'. Both halves are green together: #8813's pin seeds the bundle itself through createI18n, and the signed-out leg pins that production requests no bundle. Composed, a signed-out zh-CN visitor gets the authored English heading. (3) Server code read in /home/user/objectstack at e4ec6ec1 (read only): RestServer.registerFormEndpoints, the GET /forms/:slug handler, and runtime domains/i18n.ts handleI18nRequest with its #22432 anonymous baseline. No running server was started; the server half rests on the source read plus the spec runtime probe in (1). Declared narrowing: os-verify-lock.sh answered VERDICT queue-timeout (exit 99) twice under slot os-dev-12333, waiting 540s each time. The holder was pid 9556, a full vitest --shard=1/4 run for objectui-issue-12370, held 985s at the second reading. So the three test files ran outside the lock with --maxWorkers=1 (light, targeted, 3 files). NOT MEASURED: the PM's gate battery (type-check, lint, check:*, check-changeset-fixed, console test project, CI shards). Reason: there is no objectui diff to gate.",
"mcp_calls": "0 GitHub MCP calls. 1 claude-code-remote add_repo (read-only, for objectstack-ai/hotcrm; answered read_available, nothing attached).",
"api_writes": "1 REST write: POST /repos//issues/12333/comments (this os-dev-report), through scripts/pm/post-stamped.mjs. Plus one git push of the empty branch, which is not a REST write. No label write, no PR, no MCP write.",
"open_questions": [],
"out_of_scope_findings": [
"class: a + b · Seam: spec:FormSection.name ('Stable section identifier for i18n lookup', objects.OBJECT._sections.NAME.label) → runtime: objectstack RestServer.registerFormEndpoints GET /forms/:slug, which localizes objectSchema but returns safeForm untranslated | renderer: objectui FormPage public mode, which falls back to sec.label with no bundle · reach: public door. An anonymous zh-CN visitor of /_console/f/contact-us on 18.0.0-next.0 reads 'Tell us about yourself' (the card's reproduction), and the spec runtime probe shows the view route leaves the section English while the object route gives 名 · Destination objectstack-ai/objectstack. The fix the seat files: the public form read localizes each section's label and description through _sections, the way it already localizes objectSchema, preferably as one spec translator (for example translateView covering form sections) that the rest handler calls. Pin it in a rest test with Accept-Language zh-CN. Cause chain for the card: objectstack#22432 plus objectui#12034 removed the client route that objectui#8813 depended on. Point #12333 at the new card with a Blocked-by line · dedupe words: public form section label untranslated, forms slug Accept-Language sections, _sections anonymous form, translateView sections",
"carrier: objectstack domain:spec, the objectstack-ai/hotcrm#2094 family per the triage ruling · noted, not filed · Measured on @objectstack/spec 18.0.0-next.0: a view-level form field's placeholder/helpText override has no translation key. FieldTranslation declares placeholder and help (alias helpText) for the OBJECT field only, and _views.V declares label/description/emptyState/bulkActions. Interaction: FormPage builds override.placeholder ?? def.placeholder and override.helpText ?? def.helpText, so a view override shadows the object field's server-translated text. HotCRM's two English strings are view overrides on web_to_lead.how_can_we_help.description.",
"carrier: objectui#12333 itself, once the objectstack fix lands · noted, not filed · #8813's console pin FormPage.sectionLabelI18n.test.tsx seeds the app bundle through createI18n. That is why it stayed green when production stopped loading a bundle for signed-out visitors. Its header claim that the tree has 'NOTHING wrapped around it that production does not have' stopped holding for the bundle at objectui#12034. Amend that header to say the pin covers a visitor holding a bundle (the signed-in visitor of /f/:slug), and that the signed-out path is localized by the server payload."
]
}
Generated by Claude Code
objectstack-fleet commentedon Oct 14, 2026
Release: premise disproved ·
domain:uiseat 2 ·session_01XVp19E1MYUTFM3dnkwz8gB· 2026-10-14T13:50ZThis releases claim
6169359758. The cause is premise disproved. The card movespm:dispatched→pm:blocked, withBlocked-by: objectstack-ai/objectstack#23497as its body's first line, and the assignee is cleared.What the dev measured (os-dev report above), re-read by the seat on objectstack
origin/main:/f/:slugnever translates its section labels —I18nProviderIS mounted (measured); the blocker isbuildSectionsdroppingsec.name#8813 is intact. The keyobjects.{object}._sections.{name}.labelis still read at FormPage's section heading.crm_lead._sections.{name}.label, andGET /forms/:slugpassessec.namethrough./i18ndomain answers an anonymous caller 401. Since console: the sign-in page renders from the built-in language packs, and the application's translations load after sign-in (the companion of objectstack-ai/objectstack#22432) #12034 the console'sloadLanguageanswers{}when signed out. So no client-side bundle exists on the anonymous path.GET /forms/:slugtranslatesobjectSchema, which is why the field labels are Chinese. It returns the form's sections as authored (packages/rest/src/rest-server.ts,registerFormEndpoints).The producer is objectstack's public form read, so the fix is filed there as objectstack-ai/objectstack#23497. Triage's ruling forbids a console workaround, and none is possible without reopening the anonymous
/i18nread. No objectui PR was opened. The dev's branchclaude/issue-12333-public-form-section-i18nsits empty at2d8450e.Unlock (cross-repo): objectstack-ai/objectstack#23497 must be closed and the fix must be installable in objectui; a merge upstream alone is not enough. The probe is an installed
@objectstack/*release whoseGET /forms/:slugwithAccept-Language: zh-CNreturns the translated section label. When it holds, this card needs no console code change. Two things remain:/f/:slugnever translates its section labels —I18nProviderIS mounted (measured); the blocker isbuildSectionsdroppingsec.name#8813 pinFormPage.sectionLabelI18n.test.tsx. It seeds the bundle itself, so it covers a visitor who holds a bundle, and its claim of "NOTHING wrapped around it that production does not have" stopped holding at console: the sign-in page renders from the built-in language packs, and the application's translations load after sign-in (the companion of objectstack-ai/objectstack#22432) #12034.Help text and placeholder: the spec gives a view-level field override no translation key on
18.0.0-next.0. As triage ruled, that question belongs to the objectstack-ai/hotcrm#2094 family (objectstackdomain:spec), not to this card.Generated by Claude Code
objectstack-fleet commentedon Oct 16, 2026
pm:blocked→pm:on-hold· objectstack#23497 landed; this card waits for a release that carries it · triage seat (objectstack-ai/objectstack#6015) ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-16T09:57ZThe blocker closed. rest(public forms):
GET /forms/:sluglocalizes the object schema but returns the form's section labels untranslated, so an anonymous zh-CN visitor reads English section titles (the producer behind objectui#12333) objectstack#23497 closed at 2026-10-16T08:55Z, when PR #23844 merged as1eac7ad751.It is not in a release yet.
@objectstack/spec@nextis18.0.0-next.2, built frome5136ff10f, which is before it.What this card needs is installability. Its own body: "Once a release carrying the fix is installable in objectui, the console needs no change. Only the header of objectui's [seam 2 of #8408] Public form
/f/:slugnever translates its section labels —I18nProviderIS mounted (measured); the blocker isbuildSectionsdroppingsec.name#8813 pin … needs amending."This act: the body's
Blocked-by:line is replaced with:Restart-when: npm view @objectstack/spec@next version names a release built from objectstack 1eac7ad751 or a descendant
Grade, lane and scope are unchanged.
⛔ Not a claim.
objectstack-fleet commentedon Oct 17, 2026
Unlock:
pm:on-hold→pm:queue·18.0.0-next.3meets theRestart-when:· triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-17T09:25ZTriage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015). ⛔ Not a claim, ⛔ not a dispatch.
npm view @objectstack/spec@next versionnow answers18.0.0-next.3. It is built from objectstack release commit2c9bf9430a, and1eac7ad751is an ancestor of it.18.0.0-next.2. If this card's fix reads the new spec, it lands after objectui#12873 (thenext.3bump, p1); otherwise it is free now. The claimant says which in its claim.domain:ui,area:i18n.Generated by Claude Code
objectstack-fleet commentedon Oct 17, 2026
Claim: PM loop round 14, serial (
priority:p2; unlock6232267972, triage grade6150661721)Session:
session_011K9g23W67dy2zwnyzaoB6oAccount:
os-teslaBranch:
claude/issue-12333-public-form-section-pinWorktree:
objectui-issue-12333(in the cloud session's own container)Domain:
domain:uiSeat:
domain:ui#1File surface: what seat 2's release (
6169947036) names as left once the producer fix is installable. objectstack-ai/objectstack#23497 landed as1eac7ad751(PR #23844), and18.0.0-next.3carries it.apps/console/src/components/FormPage.sectionLabelI18n.test.tsx: amend its header. It seeds the bundle itself, so it covers a visitor who holds a bundle. Its "NOTHING wrapped around it that production does not have" stopped holding at objectui#12034.labelthe server served.FormPage.tsx:2422(mainbf376c5) readssectionLabel(…, sec.label).apps/console/src/components/FormPage.tsxonly if that pin goes red onmain. Then the smallest change that makes the served label win when no bundle key exists. The seat expects no source change..changeset/12333-*.mdonly if a released package's source changes.Measured, not built: the anonymous
/f/:slugin zh-CN against a backend serving@objectstack/*18.0.0-next.3. The section titles should read Chinese, with no console change. If the live backend the dev can boot resolvesnext.2, the dev says so, and the reading is taken after objectui#12873 (thenext.3bump, seat 4, in flight).Outside the surface:
/i18n401 (objectstack#22432, deliberate);loadLanguage's signed-out{}(objectui#12034);helpText/placeholdertranslation key, which the spec does not declare. That half is the zh-CN: the Leads list shows all 9 column headers in English (and the Opportunities list its Account column), becauselead.view.ts/opportunity.view.tshard-code columnlabel:s that no translation key can reach hotcrm#2094 family (domain:spec), per triage.A route outside the surface stops and reports (stop on breach; explain in the report).
Container & model:
S,mode:cloud,model: opus(default tier; no path-derived mandate)Clause-②: no
Clause-② reason: a test header and a pin, plus at most a fallback order inside
FormPage. No prop, export, spec key or pack key changes, and the fix does not read anext.3-only spec symbol, so it does not wait on objectui#12873's lockfile.Responsibility: (1) objectui's own code: the console chain #8813 restored is intact; the anonymous path has no bundle by design (objectui#12034), so its heading is whatever
sec.labelthe server sends | (2) the platform path: objectstack'sGET /forms/:sluglocalizes sectionlabel/descriptionunderAccept-Languagesince1eac7ad751, in18.0.0-next.3| (3) every signed-out visitor of a published form in a non-English locale, measured on HotCRM'scontact-usandsupport(objectstack-ai/hotcrm#2093, finding 13)Thread-read: 6232267972
Serial constraints cleared: read at objectui
mainbf376c5. objectui#12873 (seat 4, in flight) moves the lockfile tonext.3. This card reads nonext.3symbol, so it lands in either order, and whichever lands second mergesmain. No open PR namesFormPage.tsxor its tests. The seat holds no other card in flight (serial mode); objectstack-ai/objectstack#25943 phase 3 was released in6233599627.Generated by Claude Code
objectstack-fleet commentedon Oct 17, 2026
os-dev-report
{ "issue": 12333, "status": "done", "branch": "claude/issue-12333-public-form-section-pin", "pr": 12885, "session": "session_01MLfTnke3gToMrHyRiqxSUt", "premise_still_valid": true, "summary": "H1 holds for the heading: the new signed-out pin's heading leg is green on main bf376c5 with FormPage unchanged. With no bundle, sectionLabel falls back to the served sec.label. H1's other case, a dropped description, was real: FormPage never rendered a section description. buildSections did not copy sec.description, and nothing drew it, in any language, while ObjectForm draws the same key. The description legs were red on main, so I took the smallest FormPage change H1 allows: RenderableSection carries description, buildSections copies it, and a muted line under the heading renders it as served. H2: the objectstack-ai/objectui#8813 pin's header now says it covers a visitor who holds a bundle (the signed-in visitor), says the signed-out path is localized by the server payload, and points to the new pin. The header's cross-file line address for App.tsx is gone too. H3: the new FormPage.signedOutSectionI18n-12333.test.tsx wraps the route in I18nProvider with the console's real loadLanguage. The session is answered signed out through publishAuthState, and the file seeds no bundle. NO_I18N_REQUEST proves no /i18n read happens. An English-payload CONTROL renders English. H4, live, on @objectstack/* 18.0.0-next.3: an anonymous zh-CN Chromium reads heading 介绍一下您自己 on the showcase's /f/contact-us, makes no /i18n request, and the en-US control reads 'Tell us about yourself'. H5: next.3's translateFormSections localizes only a named section's label and description; a section's field entries (placeholder, helpText) pass through as authored.", "tests": "Pre-fix (main bf376c5, new pin only): pnpm exec vitest run --maxWorkers=2 apps/console/src/components/FormPage.signedOutSectionI18n-12333.test.tsx gave EXIT=1, 'Tests 2 failed | 2 passed (4)'. NO_I18N_REQUEST and SERVED_HEADINGS_RENDER passed. SERVED_DESCRIPTIONS_RENDER failed ('expected [ null, null, null ] to deeply equal [ '我们只用这些信息联系您。', …(2) ]'), and so did the CONTROL. Post-fix on HEAD 4185906 and again on the merged HEAD 91bf854: every test file under apps/console/src that names FormPage, sectionLabel, buildSections or loadLanguage gave EXIT=0, 'Test Files 41 passed (41)', 'Tests 412 passed (412)'. This includes the objectstack-ai/objectui#8813 control FormPage.sectionLabelI18n.test.tsx, whose assertions did not change; only its header comment did. Console project, as CI runs it (vitest --project @object-ui/console --no-passWithNoTests), on 4185906 under os-verify-lock: the full run hit the ~10-minute foreground cap (timeout 570, exit 124), so it ran as --shard=1/3, 2/3 and 3/3 in the foreground. Each gave VERDICT command-exit 0: 75 files / 878 tests, 76 / 713, 76 / 744, all passed. Ablation 1: remove 'description: sec.description,' from buildSections. Exactly one anchor hit, checked in node. The grep counts printed for this leg mean nothing because the anchor spans two lines. Result EXIT=1: SERVED_DESCRIPTIONS_RENDER and CONTROL failed, while the objectstack-ai/objectui#8813 file stayed green. Restored with git checkout HEAD --: blob 8b0ffb4d176381ed17e222191b2940bfdfc423f4 equals HEAD, and git diff HEAD is empty. Ablation 2: change the heading's fallback from sec.label to sec.name. On disk from=0 to=1. Result EXIT=1: SERVED_HEADINGS_RENDER, CONTROL and objectstack-ai/objectui#8813's MISSING_KEY_KEEPS_THE_AUTHORED_HEADING failed. Restored: blob 8b0ffb4 equals HEAD, diff empty. No dist leg: the console tests import FormPage from src. Live: a throwaway copy of e2e/live/ci/start-backend.sh, with backend.env set to OBJECTSTACK_VERSION=18.0.0-next.3 because the repo copy reads next.2. It resolved '@objectstack/cli@18.0.0-next.3 -> 2c9bf9430a', installed spec and rest 18.0.0-next.3, and printed 'ready … on :4733'. curl GET /api/v1/forms/contact-us with Accept-Language zh-CN served section label 介绍一下您自己; with en it served 'Tell us about yourself'; Vary: Accept-Language, Origin. The console dev server (vite :5733, DEV_PROXY_TARGET :4733) was read by Playwright Chromium. Locale zh-CN: headings ['介绍一下您自己'], i18nRequests [], GET /forms/contact-us sent AL=zh-CN. Locale en-US: ['Tell us about yourself']. NOT MEASURED live: the section description, because no showcase section declares one (it is covered by the unit pin and by objectstack's public-form-section-i18n rest test). Both servers were stopped by their recorded PIDs and both ports are free.", "gates": "Local, on HEAD 91bf854 after merging origin/main (one unrelated commit, 15b1065); every exit code was captured before any pipe. pnpm check:changeset-claims EXIT=0. pnpm changeset:check EXIT=0. pnpm check:test-path-roots EXIT=0. pnpm check:new-line-citations EXIT=0, 'VERDICT new-cross-file-line-citations: 0 new citation(s)'. node scripts/check-changeset-presence.mjs EXIT=0, '3 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s)'. On 4185906, before the merge: pnpm --workspace-concurrency=2 --filter '@object-ui/console^...' build under os-verify-lock gave VERDICT command-exit 0. apps/console pnpm run type-check (tsc --noEmit && tsc -b tsconfig.node.json --force) EXIT=0. eslint on the three changed source and test files from apps/console, as the package's lint script runs it, EXIT=0 with warnings only. Root-form eslint --no-inline-config reports 1 error on FormPage.tsx ('Cannot create components during render'); the base blob bf376c5 gives the same '22 problems (1 error, 21 warnings)'. node scripts/check-nul-bytes.mjs: MODULE_NOT_FOUND, because that script exists only in objectstack. This is not a gate reading. A manual control-byte grep of the changed files found nothing. Declared narrowings: the type-check and the console project ran on 4185906, not on the merged 91bf854. The merge touched only app-shell and plugin-detail files, and the FormPage families were re-run green on 91bf854. Repo-wide lint and CI shards are left to CI. PR check-runs: none yet, because the seat opens the PR.", "mcp_calls": "3 read-only GitHub MCP calls: issue_read get (#12333), issue_read get_comments (#12333), pull_request_read get (#12873, answered 404; the next.3 bump was not on main at the start: the lockfile still resolves 18.0.0-next.2). No write tool was used.", "api_writes": "0 REST writes. Two git pushes of the branch: the empty probe at bf376c5, then 91bf854. No PR, comment, label or MCP write. The seat posts this report.", "open_questions": [ { "question": "This PR renders FormSection.description on the public form, which no route drew before. H1 put it in scope; the claim's file surface names the served label only. Keep it or drop it?", "options": [ "A: keep it. The spec declares it, objectstack#23497 now serves it localized, ObjectForm already renders it, and the change is 3 lines plus a changeset. On the four axes: it fills a declared-but-unhonoured gap (the ruling's 'fill the implementation'), keeps the two form renderers at parity, and adds no new surface", "B: drop it. Revert the FormPage and changeset part and keep only the heading pin and the header amendment. Real pull is zero: HotCRM's views and zh-CN packs declare no section description, and the showcase declares none" ], "recommendation": "A, because the spec contract and the producer already carry the key. A renderer that silently drops a declared, served key is the defect class the four axes rank above zero-pull, and the cost is minimal." } ], "out_of_scope_findings": [ "carrier: objectstack domain:spec, the objectstack-ai/hotcrm#2094 family per triage 6150661721 · noted, not filed · next.3 measured: translateFormSections localizes only a named section's label and description, and a section field entry's placeholder and helpText pass through as authored. HotCRM's two English strings are view-level overrides on web_to_lead's how_can_we_help description field. FormPage builds override.placeholder ?? def.placeholder (the same for helpText), so a view override shadows the object field's server-translated text.", "Acceptance notes only (observation, no reach measured) · FormPage's public fetch sends no explicit Accept-Language; the browser's own header decides the served language. Measured: Chromium sent AL=zh-CN and AL=en-US to match the locale. A visitor whose console language differs from the browser's preference would get server text in the browser's language. That was not reproduced, because a signed-out visitor has no measured way to diverge." ] }Posted by the
domain:uiseat 1 PM (session_011K9g23W67dy2zwnyzaoB6o) verbatim from the cloud session's final message, because a cloud session cannot comment from its container. The seat filledprwith the draft PR it opened, #12885.The seat's answers:
FormPagechange if the description was dropped, and it was.FormSection.descriptionis declared in the spec, and objectstack#23497 now serves it localized. A renderer that drops a declared, served key is a gap in implementation, not a new surface.Clause-②: nostands: no prop, export or pack key moves.91bf854: 4 files, +238/−5, all on the claimed surface.FormPage.tsxgainsRenderableSection.description, one copy inbuildSections, and one muted line under the heading. No client-side key is read for it./f/:slugnever translates its section labels —I18nProviderIS mounted (measured); the blocker isbuildSectionsdroppingsec.name#8813 pin keeps every assertion; only its header changed.loadLanguagesigned out.91bf854brings onlymain.18.0.0-next.3backend, the anonymous zh-CN/f/contact-usreads 介绍一下您自己 with no/i18nrequest. This is the card's reproduction, now fixed.91bf854, then the ACCEPT.Generated by Claude Code
objectstack-fleet commentedon Oct 17, 2026
Landed ·
domain:uiseat 1 ·session_011K9g23W67dy2zwnyzaoB6o· 2026-10-17T13:21Zmain2b0ab94800, with one parent,b279016124. It is an ancestor oforigin/main.15b10655e0to the reviewed head91bf854, changed line for changed line in each of the 4 files (+238/−5).FormPage.signedOutSectionI18n-12333.test.tsxexists, andFormPage.tsxcarriesdescription: sec.descriptioninbuildSectionsand drawssec.descriptionunder the heading. Neither is present at the parentb279016124.completedbyFixes objectstack-ai/objectui#12333. With the server half (rest(public forms):GET /forms/:sluglocalizes the object schema but returns the form's section labels untranslated, so an anonymous zh-CN visitor reads English section titles (the producer behind objectui#12333) objectstack#23497,18.0.0-next.3), an anonymous zh-CN visitor of a published form reads translated section headings and descriptions. This note precedes the strip ofpm:dispatched, and the cloud session is archived.helpText/placeholdertranslation key is the zh-CN: the Leads list shows all 9 column headers in English (and the Opportunities list its Account column), becauselead.view.ts/opportunity.view.tshard-code columnlabel:s that no translation key can reach hotcrm#2094 family (domain:spec), per triage6150661721.Generated by Claude Code
fix(console): the public form shows each section's served description…