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 }}
Repository navigation
A language picked on the sign-in page is dropped when someone else last used that browser, and the sign-in list differs from the signed-in one #30338
Filing gate: ③ the maintainer's direct order, verbatim: 「你发现的问题都立卡,安全问题总专用的安全密卡通道,需要进一步分析的进一步测试,还是没有把握的用决策卡。」 (2026-11-05). Found in a real-user browser walkthrough of Setup on main04f36b63f8, with a test app and a local test deployment.
Business reason. A shared computer on a shop floor or front desk is the normal case for a repair company. An employee who picks their language on the sign-in page and then lands in another language loses trust in the setting.
Reader. The UI lane dev, in ui/packages/app-shell/src/hooks/useUserLocale.ts (useLanguageResetOnOwnerChange) and ui/apps/console/src/loadLocales.ts.
Duplicates. Searched login language lost after sign in (20 hits) and locale switcher sign-in choice (8 hits). They are QA run anchors and #27521, closed, a list of suggestions; none has this subject.
Measured
Each started from the sign-in page, choosing a language in the menu at the bottom left:
Case
Choice
After sign-in
Same person who last used the browser
Français
Stays French
Clean browser, nobody signed in before
Français
Stays French
A different person last used the browser
Français
Back to 中文, and the choice is removed from storage
Clean browser
Deutsch
German, while /api/v1/i18n/locales for that user lists en, zh-CN, ja-JP, es-ES, fr-FR and vi-VN only
sys_user.locale stays empty in these cases, so a choice made at sign-in does not follow the person to another device.
Signed out, the menu shows the 10 built-in packs, because the console requests no list then (loadLocales.ts). Signed in, it follows the deployment's list. Vietnamese, which this deployment offers, cannot be picked at sign-in. Deutsch can, though the deployment does not list it.
I did not open the signed-in menu while in German to see what it shows as selected.
Expected
A language picked on the sign-in page by the person who then signs in is kept, and saved as their own preference if they have none.
Note for the dev: the purge on a change of person comes from objectui#10193, ruling B, which stops one person's language reaching the next. That rule stands. It covers what the previous person left, and a choice made after they signed out is not that. If those two cannot be told apart without a new stored marker, report it instead of guessing. Whether the signed-out list should match the deployment's is limited by the rule that signed-out readers make no request (objectui#12034), so leave that list alone unless the fix needs it, and say what you did.
Claim: PM loop round 2 · 2026-11-05T08:15Z
Session: session_01Utp6CZGT41gdDg2656as2b (card thread, os-dev); dispatched by seat session session_01Utp6CbPN5UYMnBaNJPJWfG
Account: os-bill
Branch: claude/project-thread-6njg67 (platform-assigned to the card thread; it can push only this branch)
Worktree: objectstack-issue-30338
Domain: domain:ui
Seat: domain:ui#3
File surface: ui/packages/app-shell/src/hooks/useUserLocale.ts, ui/apps/console/src/loadLocales.ts only if the fix needs it, the sign-in language menu's host if needed, their tests, one root .changeset/ file; ⛔ ui/apps/console/src/pages/auth/** (#30157), packages/** (stop on breach; explain in the report)
Container & model: M, mode:thread, model: default tier (opus) — dispatch-gates --tier at fdad1786: no path-derived mandate, effort: high
Clause-②: no — client-side locale persistence order
Metadata-protocol: none
Responsibility: useLanguageResetOnOwnerChange in useUserLocale.ts purges a choice made after the previous person signed out | objectui#10193 ruling B covers only what the previous person left | everyone on a shared browser
Thread-read: 6652095543
Premise: holds
Serial constraints cleared: ui/apps/console/src/pages/auth/** is held by #30157 (domain:ui#4), kept out. main red at claim (#30367), not this card's.
{
"issue": 30338,
"status": "done",
"branch": "claude/project-thread-6njg67",
"pr": "https://github.com/objectstack-ai/objectstack/pull/30397",
"session": "session_01Utp6CZGT41gdDg2656as2b",
"premise_still_valid": false,
"summary": "Premise falsified: useLanguageResetOnOwnerChange is mounted only in AppContent (/apps/:appName/*), not on the sign-in page. The drop happens in the sign-in page-load: SessionUserScope.adopt(B) sweeps objectui-locale with the previous owner's state, then LoginPage leaves by window.location.assign, so the next page-load boots in the browser language. Per the seat's ruling D, PR #30397 ships the keep half only: useLanguageSelection remembers a signed-out pick for the page-load (memory, no new key) and a module-level subscribeSessionOwnerChange listener writes it back into objectui-locale after the sweep; objectui#10193 ruling B is unchanged (pinned). The save-as-own-preference half needs the knowledge to cross the post-login navigation; the seat routes it to its own card (await the existing sys_user save before LoginPage navigates), blocked by #30157. The sign-in list is left alone: matching the deployment needs a signed-out request (objectui#12034), and #30001's PLATFORM_LOCALES is the platform table (no vi), phase 4 of #29428.",
"tests": "New userLocaleSignInPick-30338.test.tsx (5 cases). Merged head 1ec0fe4c: vitest run of the three locale hook files plus packages/app-shell/src/layout/ (LocaleSwitcher, the importer): Test Files 143 passed (143), Tests 926 passed (926), VERDICT command-exit 0. Ablation (useUserLocale.ts set to origin/main, restored from HEAD, hash equal, git diff HEAD empty): 3 failed | 2 passed (5), VERDICT command-exit 1; the 2 green are the ruling-B control and the signed-in-switch guard. turbo type-check --filter=@object-ui/app-shell: 68/68 successful, VERDICT command-exit 0 (includes tsconfig.test.json). Live local boot (showcase + console vite, Playwright zh-CN, two users): row 3 before zh-CN with slot removed, after fr with slot fr and fr after reload; rows 1, 2, 4 unchanged; control (different person, no pick) swept before and after; sys_user.locale empty in all rows.",
"gates": "On 1ec0fe4c: dispatch-gates --commands --repo objectstack-ai/objectstack derived 35; all 35 exit 0, codes captured before any pipe (check-sdui-manifest and its self-test among them). dispatch-gates --ran: 35 derived, 35 run, 0 NOT-MEASURED. CI families: in_progress at report time; main red on check:liveness (#30367, PR #30368) is not this PR's.",
"line_budget": "3 files, +344 / -5 vs merge base (useUserLocale.ts, one new test file, one changeset); human-merge threshold 3000: under.",
"files_changed": [
"ui/packages/app-shell/src/hooks/useUserLocale.ts",
"ui/packages/app-shell/src/hooks/__tests__/userLocaleSignInPick-30338.test.tsx",
".changeset/30338-keep-sign-in-language-pick.md"
],
"deviations": [
"PR body says Refs #30338 (item: keep the sign-in choice), not Fixes, by the seat's ruling D: the save half stays open.",
"The harness's assignee and review-request step was skipped, per the order's Writes line; the PR carries no assignee.",
"The test run included the whole packages/app-shell/src/layout/ directory (143 files) to cover the LocaleSwitcher importer, wider than the order's changed-tests-plus-importers rule.",
"A first gate run on the pre-merge head was stopped after 16 commands (all exit 0) and the full list re-run on the merged head 1ec0fe4c."
],
"dogfood_battery": "n/a — no ! in the PR title and Clause-② no without a (narrowing) arm",
"mcp_calls": "5 — mcp__github__issue_read only (get 30338, get_comments 30338 twice, get 30001, get 30367); no write tool",
"api_writes": "2 — relay pr_create (POST pulls, #30397, read-back identical 10800 bytes) and this os-dev-report comment via post-stamped; git push is not counted",
"open_questions": [],
"security_findings": "none",
"out_of_scope_findings": []
}
Release: 2026-11-05T10:18Z — PR #30397 landed (merge commit 6fa842af1, merged 2026-11-05T10:15Z; seat ACCEPT 6654999895 on head 43bcd1f2), Refs #30338, so this card stays open.
Landed (the kept half): a language picked on the sign-in page now survives the sweep that follows a sign-in by someone other than the browser's last user (same page-load, no new storage key; objectui#10193 unchanged).
Claim: PM loop round 2 · 2026-11-05T16:33Z · the register-page remainder
Session: session_01L6bhgWn6zhNa4LL7VB1rtL
Account: os-sales (the seat's linked user as GET /user answers it; the card's assignee)
Branch: the card thread's designated claude/project-thread-* branch, named in a claim amendment once the thread reports it
Worktree: objectstack-issue-30338
Domain: domain:ui
Seat: domain:ui#1
File surface: ui/apps/console/src/pages/auth/RegisterPage.tsx and ui/packages/app-shell/src/console/auth/RegisterPage.tsx (their register-then-signed-in exits), their tests, the write census ui/packages/plugin-form/src/affordanceGrantMap-12082.test.tsx if a new adapter write call site appears, one root .changeset/ file. Reads saveSignInLanguagePick / hasSignInLanguagePick (@object-ui/app-shell, PR #30539) as they stand; ui/packages/app-shell/src/hooks/useUserLocale.ts only if the dev measures that it must change. ⛔ LoginPage.tsx (landed by PR #30539), ⛔ packages/**, ⛔ the signed-out language list in loadLocales.ts (the card says to leave it alone; objectui#12034). Stop on breach and explain in the report.
Container & model: M, mode:thread, model: default (opus) (dispatch-gates --tier over the two paths: no path-derived mandate; floor sonnet · default opus · ceiling fable), effort: high
Clause-②: no (console and app-shell page internals; no export is added). An export, if one is needed, comes by amendment.
Metadata-protocol: none
Responsibility: a language picked on the register page is not saved as the person's own when registering signs them in | PR #30539 saves the sign-in page's pick (LoginPage) and stops there; PR #30397 kept the pick only through the owner-change sweep | everyone who registers, including an invitation join (PR #30556)
Thread-read: 6655482512
Premise: holds on origin/main27b0bc79: neither RegisterPage calls saveSignInLanguagePick. The console page leaves by window.location.assign at five sites (L206, L218, L233, L236, L241); the app-shell page leaves at L132 (window.location.assign) and by navigate('/') at L271. The remainder is recorded in the domain:ui#4 ACCEPT 6661578471 on PR #30539 ("RegisterPage.tsx 同形").
Ruling carried: seat ruling D on this card (domain:ui#3, route B on #30399): ⛔ no new storage marker; the save is awaited before each full navigation, never fire-and-forget. A pick followed by a reload of the page, or an identity-provider round trip, stays dropped under that ruling, as PR #30397 stated.
Serial constraints cleared: PR #30539 (#30399) merged 2026-11-05T16:15:41Z and PR #30556 (#30125 item 2) merged 2026-11-05T16:30:28Z. The file lists of all 39 open PRs, read at claim time: none touches either RegisterPage, useUserLocale.ts or affordanceGrantMap-12082.test.tsx.
席位核对 · Amendment · 2026-11-05T16:36Z · claim 6663446873 branch named
Branch: claude/project-thread-b4xtgz (the card thread of this project, based on main27b0bc79, which carries PR #30556; a thread can push only its designated branch).
{
"issue": 30338,
"status": "done",
"branch": "claude/project-thread-b4xtgz",
"pr": "https://github.com/objectstack-ai/objectstack/pull/30597",
"session": "session_01L6bhgUaeNktxjHB4qxqPKg",
"premise_still_valid": true,
"summary": "Both register pages now save a language picked while signed out as the new person's own (saveSignInLanguagePick from app-shell, as PR #30539 landed it) and await it before leaving after a sign-up that signs the person in. Console RegisterPage: a step 0 at the top of the post-signup effect, the same shape as LoginPage's, so all six exits wait: OAuth hand-off, mobile hand-off, invitation join root entry, no organization, several organizations, final redirect. DefaultRegisterPage: a render-time hold while the save runs covers the invitation join's root assign, the signed-in Navigate to the root and the form onSuccess navigate, which now leaves the move to the signed-in branch when a pick is held or its save has started. No pick: no request, no wait. A failed save does not hold the sign-up. Ruling D kept: no new storage marker, nothing fire-and-forget; reload or identity-provider round trip still drops the pick, stated in the PR and changeset.",
"tests": "New console registerLanguagePick-30338.test.tsx (19 cases) and app-shell registerLanguagePick-30338.test.tsx (6 cases), each case reached by a sign-up on the form, invitation join included. vitest over every console and app-shell auth page test, the sign-in pick hook file and the write census on e15bb2eb: Test Files 47 passed (47), Tests 404 passed (404), exit 0. Ablations through ablation-replace, each restored blob == HEAD: A1 drop console step-0 return 8 failed of 19, exit 1; A1b delete console save-in-flight guard 4 failed of 19 (both invitation cases red), exit 1; A2 app-shell hold forced false 2 failed of 6, exit 1. app-shell type-check exit 0; console tsc --noEmit (6144 heap) exit 0; eslint 0 errors, 2 warnings both present on main. Live (showcase fresh, console vite, zh-CN invitation sign-up with Francais picked in the register footer): before sys_user.locale empty, after fr with GET then PATCH sys_user before the next page-load; control with no pick sent no PATCH and locale stayed empty.",
"gates": "On e15bb2eb: dispatch-gates --commands --repo objectstack-ai/objectstack derived 35; all 35 exit 0, codes captured before any pipe. dispatch-gates --ran: 35 derived, 35 run, 0 NOT-MEASURED. CI: running at report time.",
"line_budget": "5 files, +614 / -5 vs merge base 27b0bc79 (two RegisterPage files, two new test files, one changeset); human-merge threshold 3000: under.",
"files_changed": [
"ui/apps/console/src/pages/auth/RegisterPage.tsx",
"ui/apps/console/src/pages/auth/__tests__/registerLanguagePick-30338.test.tsx",
"ui/packages/app-shell/src/console/auth/RegisterPage.tsx",
"ui/packages/app-shell/src/console/auth/__tests__/registerLanguagePick-30338.test.tsx",
".changeset/30338-save-register-language-pick.md"
],
"deviations": [
"The console step 0 also holds the OAuth hand-off (followOauthAuthorize), a sixth exit the order did not list; it sits where LoginPage puts it, above every exit.",
"No write census entry: the pages add no adapter write call site (saveSignInLanguagePick is not a census write helper, and its own update is already registered); the census test ran green unchanged.",
"The branch carries a WIP commit 3c2beb39 under the fix commit e15bb2eb, pushed before the long build; no force push was used to remove it.",
"The harness's assignee and review-request step was skipped, per the order: the PR carries no assignee and no reviewer."
],
"dogfood_battery": "n/a — no ! in the PR title and Clause-② no without a (narrowing) arm",
"mcp_calls": "0",
"api_writes": "2 — relay pr_create (POST pulls, #30597, read-back identical 9079 bytes) and this os-dev-report comment via post-stamped; git push is not counted",
"open_questions": [],
"security_findings": "none",
"out_of_scope_findings": [
"With no pick and several organizations, the post-signup step navigates to the root before the organization list answers and then to the picker (the same double navigation PR #30539 noted on the sign-in page). Not filed: observed in a jsdom harness only."
]
}
:153 (DefaultRegisterPage saves it and holds its exits until the save settles)
State: the card closed on the merge (Fixes); pm:dispatched removed in the same stroke. As ruled (seat ruling D), a pick followed by a reload of the register page or an identity provider's redirect is still not saved.
Activity
objectstack-fleet commentedon Nov 5, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: first-touch audit · p2 ·
domain:ui·pm:queue· 2026-11-05T07:13Z⛔ Not a claim.
loadLocales.ts,useUserLocale.ts). p2. The list should read spec(system): export the platform locale table PLATFORM_LOCALES and its read aliases (phase 1 of #29428) #30001's table.Generated by Claude Code
objectstack-fleet commentedon Nov 5, 2026
domain:ui#3 · os-bill · session_01Utp6CbPN5UYMnBaNJPJWfG
Claim: PM loop round 2 · 2026-11-05T08:15Z
Session:
session_01Utp6CZGT41gdDg2656as2b(card thread, os-dev); dispatched by seat sessionsession_01Utp6CbPN5UYMnBaNJPJWfGAccount:
os-billBranch:
claude/project-thread-6njg67(platform-assigned to the card thread; it can push only this branch)Worktree:
objectstack-issue-30338Domain:
domain:uiSeat:
domain:ui#3File surface:
ui/packages/app-shell/src/hooks/useUserLocale.ts,ui/apps/console/src/loadLocales.tsonly if the fix needs it, the sign-in language menu's host if needed, their tests, one root.changeset/file; ⛔ui/apps/console/src/pages/auth/**(#30157),packages/**(stop on breach; explain in the report)Container & model:
M,mode:thread,model: default tier (opus) — dispatch-gates --tier at fdad1786: no path-derived mandate,effort: highClause-②: no — client-side locale persistence order
Metadata-protocol: none
Responsibility:
useLanguageResetOnOwnerChangeinuseUserLocale.tspurges a choice made after the previous person signed out | objectui#10193 ruling B covers only what the previous person left | everyone on a shared browserThread-read: 6652095543
Premise: holds
Serial constraints cleared:
ui/apps/console/src/pages/auth/**is held by #30157 (domain:ui#4), kept out. main red at claim (#30367), not this card's.objectstack-fleet commentedon Nov 5, 2026
domain:ui#3 · os-bill · session_01Utp6CbPN5UYMnBaNJPJWfG
os-dev-report
{ "issue": 30338, "status": "done", "branch": "claude/project-thread-6njg67", "pr": "https://github.com/objectstack-ai/objectstack/pull/30397", "session": "session_01Utp6CZGT41gdDg2656as2b", "premise_still_valid": false, "summary": "Premise falsified: useLanguageResetOnOwnerChange is mounted only in AppContent (/apps/:appName/*), not on the sign-in page. The drop happens in the sign-in page-load: SessionUserScope.adopt(B) sweeps objectui-locale with the previous owner's state, then LoginPage leaves by window.location.assign, so the next page-load boots in the browser language. Per the seat's ruling D, PR #30397 ships the keep half only: useLanguageSelection remembers a signed-out pick for the page-load (memory, no new key) and a module-level subscribeSessionOwnerChange listener writes it back into objectui-locale after the sweep; objectui#10193 ruling B is unchanged (pinned). The save-as-own-preference half needs the knowledge to cross the post-login navigation; the seat routes it to its own card (await the existing sys_user save before LoginPage navigates), blocked by #30157. The sign-in list is left alone: matching the deployment needs a signed-out request (objectui#12034), and #30001's PLATFORM_LOCALES is the platform table (no vi), phase 4 of #29428.", "tests": "New userLocaleSignInPick-30338.test.tsx (5 cases). Merged head 1ec0fe4c: vitest run of the three locale hook files plus packages/app-shell/src/layout/ (LocaleSwitcher, the importer): Test Files 143 passed (143), Tests 926 passed (926), VERDICT command-exit 0. Ablation (useUserLocale.ts set to origin/main, restored from HEAD, hash equal, git diff HEAD empty): 3 failed | 2 passed (5), VERDICT command-exit 1; the 2 green are the ruling-B control and the signed-in-switch guard. turbo type-check --filter=@object-ui/app-shell: 68/68 successful, VERDICT command-exit 0 (includes tsconfig.test.json). Live local boot (showcase + console vite, Playwright zh-CN, two users): row 3 before zh-CN with slot removed, after fr with slot fr and fr after reload; rows 1, 2, 4 unchanged; control (different person, no pick) swept before and after; sys_user.locale empty in all rows.", "gates": "On 1ec0fe4c: dispatch-gates --commands --repo objectstack-ai/objectstack derived 35; all 35 exit 0, codes captured before any pipe (check-sdui-manifest and its self-test among them). dispatch-gates --ran: 35 derived, 35 run, 0 NOT-MEASURED. CI families: in_progress at report time; main red on check:liveness (#30367, PR #30368) is not this PR's.", "line_budget": "3 files, +344 / -5 vs merge base (useUserLocale.ts, one new test file, one changeset); human-merge threshold 3000: under.", "files_changed": [ "ui/packages/app-shell/src/hooks/useUserLocale.ts", "ui/packages/app-shell/src/hooks/__tests__/userLocaleSignInPick-30338.test.tsx", ".changeset/30338-keep-sign-in-language-pick.md" ], "deviations": [ "PR body says Refs #30338 (item: keep the sign-in choice), not Fixes, by the seat's ruling D: the save half stays open.", "The harness's assignee and review-request step was skipped, per the order's Writes line; the PR carries no assignee.", "The test run included the whole packages/app-shell/src/layout/ directory (143 files) to cover the LocaleSwitcher importer, wider than the order's changed-tests-plus-importers rule.", "A first gate run on the pre-merge head was stopped after 16 commands (all exit 0) and the full list re-run on the merged head 1ec0fe4c." ], "dogfood_battery": "n/a — no ! in the PR title and Clause-② no without a (narrowing) arm", "mcp_calls": "5 — mcp__github__issue_read only (get 30338, get_comments 30338 twice, get 30001, get 30367); no write tool", "api_writes": "2 — relay pr_create (POST pulls, #30397, read-back identical 10800 bytes) and this os-dev-report comment via post-stamped; git push is not counted", "open_questions": [], "security_findings": "none", "out_of_scope_findings": [] }Report taken 2026-11-05T09:34Z.
Generated by Claude Code
objectstack-fleet commentedon Nov 5, 2026
domain:ui#3 · os-bill · session_01Utp6CbPN5UYMnBaNJPJWfG
Release: 2026-11-05T10:18Z — PR #30397 landed (merge commit
6fa842af1, merged 2026-11-05T10:15Z; seat ACCEPT 6654999895 on head43bcd1f2),Refs #30338, so this card stays open.Resume-from: none
Back to
pm:queue. Triage may close this card in favour of #30399 if it prefers one card for the remainder.objectstack-fleet commentedon Nov 5, 2026
domain:ui#1 · os-sales · session_01L6bhgWn6zhNa4LL7VB1rtL
Claim: PM loop round 2 · 2026-11-05T16:33Z · the register-page remainder
Session:
session_01L6bhgWn6zhNa4LL7VB1rtLAccount:
os-sales(the seat's linked user asGET /useranswers it; the card's assignee)Branch: the card thread's designated
claude/project-thread-*branch, named in a claim amendment once the thread reports itWorktree:
objectstack-issue-30338Domain:
domain:uiSeat:
domain:ui#1File surface:
ui/apps/console/src/pages/auth/RegisterPage.tsxandui/packages/app-shell/src/console/auth/RegisterPage.tsx(their register-then-signed-in exits), their tests, the write censusui/packages/plugin-form/src/affordanceGrantMap-12082.test.tsxif a new adapter write call site appears, one root.changeset/file. ReadssaveSignInLanguagePick/hasSignInLanguagePick(@object-ui/app-shell, PR #30539) as they stand;ui/packages/app-shell/src/hooks/useUserLocale.tsonly if the dev measures that it must change. ⛔LoginPage.tsx(landed by PR #30539), ⛔packages/**, ⛔ the signed-out language list inloadLocales.ts(the card says to leave it alone; objectui#12034). Stop on breach and explain in the report.Container & model:
M,mode:thread,model: default (opus)(dispatch-gates --tierover the two paths: no path-derived mandate; floor sonnet · default opus · ceiling fable),effort: highClause-②: no (console and app-shell page internals; no export is added). An export, if one is needed, comes by amendment.
Metadata-protocol: none
Responsibility: a language picked on the register page is not saved as the person's own when registering signs them in | PR #30539 saves the sign-in page's pick (LoginPage) and stops there; PR #30397 kept the pick only through the owner-change sweep | everyone who registers, including an invitation join (PR #30556)
Thread-read: 6655482512
Premise: holds on
origin/main27b0bc79: neither RegisterPage callssaveSignInLanguagePick. The console page leaves bywindow.location.assignat five sites (L206, L218, L233, L236, L241); the app-shell page leaves at L132 (window.location.assign) and bynavigate('/')at L271. The remainder is recorded in thedomain:ui#4ACCEPT 6661578471 on PR #30539 ("RegisterPage.tsx同形").Ruling carried: seat ruling D on this card (
domain:ui#3, route B on #30399): ⛔ no new storage marker; the save is awaited before each full navigation, never fire-and-forget. A pick followed by a reload of the page, or an identity-provider round trip, stays dropped under that ruling, as PR #30397 stated.Serial constraints cleared: PR #30539 (#30399) merged 2026-11-05T16:15:41Z and PR #30556 (#30125 item 2) merged 2026-11-05T16:30:28Z. The file lists of all 39 open PRs, read at claim time: none touches either RegisterPage,
useUserLocale.tsoraffordanceGrantMap-12082.test.tsx.objectstack-fleet commentedon Nov 5, 2026
domain:ui#1 · os-sales · session_01L6bhgWn6zhNa4LL7VB1rtL
席位核对 · Amendment · 2026-11-05T16:36Z · claim 6663446873 branch named
Branch:
claude/project-thread-b4xtgz(the card thread of this project, based onmain27b0bc79, which carries PR #30556; a thread can push only its designated branch).Everything else in claim 6663446873 stands.
objectstack-fleet commentedon Nov 5, 2026
domain:ui#1 · os-sales · session_01L6bhgWn6zhNa4LL7VB1rtL
os-dev-report
{ "issue": 30338, "status": "done", "branch": "claude/project-thread-b4xtgz", "pr": "https://github.com/objectstack-ai/objectstack/pull/30597", "session": "session_01L6bhgUaeNktxjHB4qxqPKg", "premise_still_valid": true, "summary": "Both register pages now save a language picked while signed out as the new person's own (saveSignInLanguagePick from app-shell, as PR #30539 landed it) and await it before leaving after a sign-up that signs the person in. Console RegisterPage: a step 0 at the top of the post-signup effect, the same shape as LoginPage's, so all six exits wait: OAuth hand-off, mobile hand-off, invitation join root entry, no organization, several organizations, final redirect. DefaultRegisterPage: a render-time hold while the save runs covers the invitation join's root assign, the signed-in Navigate to the root and the form onSuccess navigate, which now leaves the move to the signed-in branch when a pick is held or its save has started. No pick: no request, no wait. A failed save does not hold the sign-up. Ruling D kept: no new storage marker, nothing fire-and-forget; reload or identity-provider round trip still drops the pick, stated in the PR and changeset.", "tests": "New console registerLanguagePick-30338.test.tsx (19 cases) and app-shell registerLanguagePick-30338.test.tsx (6 cases), each case reached by a sign-up on the form, invitation join included. vitest over every console and app-shell auth page test, the sign-in pick hook file and the write census on e15bb2eb: Test Files 47 passed (47), Tests 404 passed (404), exit 0. Ablations through ablation-replace, each restored blob == HEAD: A1 drop console step-0 return 8 failed of 19, exit 1; A1b delete console save-in-flight guard 4 failed of 19 (both invitation cases red), exit 1; A2 app-shell hold forced false 2 failed of 6, exit 1. app-shell type-check exit 0; console tsc --noEmit (6144 heap) exit 0; eslint 0 errors, 2 warnings both present on main. Live (showcase fresh, console vite, zh-CN invitation sign-up with Francais picked in the register footer): before sys_user.locale empty, after fr with GET then PATCH sys_user before the next page-load; control with no pick sent no PATCH and locale stayed empty.", "gates": "On e15bb2eb: dispatch-gates --commands --repo objectstack-ai/objectstack derived 35; all 35 exit 0, codes captured before any pipe. dispatch-gates --ran: 35 derived, 35 run, 0 NOT-MEASURED. CI: running at report time.", "line_budget": "5 files, +614 / -5 vs merge base 27b0bc79 (two RegisterPage files, two new test files, one changeset); human-merge threshold 3000: under.", "files_changed": [ "ui/apps/console/src/pages/auth/RegisterPage.tsx", "ui/apps/console/src/pages/auth/__tests__/registerLanguagePick-30338.test.tsx", "ui/packages/app-shell/src/console/auth/RegisterPage.tsx", "ui/packages/app-shell/src/console/auth/__tests__/registerLanguagePick-30338.test.tsx", ".changeset/30338-save-register-language-pick.md" ], "deviations": [ "The console step 0 also holds the OAuth hand-off (followOauthAuthorize), a sixth exit the order did not list; it sits where LoginPage puts it, above every exit.", "No write census entry: the pages add no adapter write call site (saveSignInLanguagePick is not a census write helper, and its own update is already registered); the census test ran green unchanged.", "The branch carries a WIP commit 3c2beb39 under the fix commit e15bb2eb, pushed before the long build; no force push was used to remove it.", "The harness's assignee and review-request step was skipped, per the order: the PR carries no assignee and no reviewer." ], "dogfood_battery": "n/a — no ! in the PR title and Clause-② no without a (narrowing) arm", "mcp_calls": "0", "api_writes": "2 — relay pr_create (POST pulls, #30597, read-back identical 9079 bytes) and this os-dev-report comment via post-stamped; git push is not counted", "open_questions": [], "security_findings": "none", "out_of_scope_findings": [ "With no pick and several organizations, the post-signup step navigates to the root before the organization list answers and then to the picker (the same double navigation PR #30539 noted on the sign-in page). Not filed: observed in a jsdom harness only." ] }Report taken 2026-11-05T17:15Z.
objectstack-fleet commentedon Nov 5, 2026
domain:ui#1 · os-sales · session_01L6bhgWn6zhNa4LL7VB1rtL
ACCEPT → PR #30597 comment 6664669650 · head
e15bb2eb· 2026-11-05T17:29Z —pr_ready+automerge_enablerelayed; the card closes on the merge (Fixes).objectstack-fleet commentedon Nov 5, 2026
domain:ui#1 · os-sales · session_01L6bhgWn6zhNa4LL7VB1rtL
Landed 2026-11-05T17:44Z: PR #30597 merged as
4831d5006d(seat ACCEPT 6664669650 on heade15bb2eb), 2026-11-05T17:44:33Z on the PR.git grep -n "saveSignInLanguagePick(" origin/main -- ui/apps/console/src/pages/auth/RegisterPage.tsx:214(step 0 of the post-signup effect saves the pick before any exit)git grep -n "saveSignInLanguagePick(" origin/main -- ui/packages/app-shell/src/console/auth/RegisterPage.tsx:153(DefaultRegisterPagesaves it and holds its exits until the save settles)State: the card closed on the merge (
Fixes);pm:dispatchedremoved in the same stroke. As ruled (seat ruling D), a pick followed by a reload of the register page or an identity provider's redirect is still not saved.