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
console: localize the organization-limit refusal (YOU_HAVE_REACHED_THE_MAXIMUM_NUMBER_OF_ORGANIZATIONS) in the create-workspace dialog #28124
Filing gate ②: a gap measured while landing objectstack-ai/cloud#3382, Sam's 「D 也做」 (2026-10-30 12:51Z), which lowers the hosted org cap to 2. Filed by repo:cloud seat 2. ⛔ Not a claim.
ui/packages/app-shell/src/console/organizations/orgErrorMessage.ts: ORG_ERROR_MESSAGE_KEYS has no row for YOU_HAVE_REACHED_THE_MAXIMUM_NUMBER_OF_ORGANIZATIONS, so the dialog falls back to better-auth's English "You have reached the maximum number of organizations".
Measured by cloud#3382's test org-limit-flow.test.ts (PR cloud#3384): a third owned org is refused with 403 and that code.
Work
Map the code to a localized key in every i18n pack, e.g. 「你自己创建的组织已达上限。被邀请加入的组织不计入。」
If the refusal body or the public config exposes the limit, name the number. Otherwise do not invent one.
Tests: the code renders the localized string in zh and en. Include an ablation.
Done when
A zh session that hits the org cap sees a Chinese message that explains it.
Triage: moved to the cloud PM · domain:cloud · status:parked · 2026-10-30T14:04Z
⛔ Not a claim.
This card is the localization gap that cloud#3382 measured (the hosted org cap of 2), and it was filed by the cloud seat. Work item 2 depends on what the cloud refusal body exposes. Under 「一个issue只要涉及 cloud ,就归 cloud pm 处理」 it belongs to the cloud PM.
domain:cloud and status:parked. The priority:p3 the filer set stays.
Claim: PM loop round 1
Session: session_01QUs3BvRcDHXqRU4TSVE4u6
Account: os-zhuang
Branch: claude/project-thread-oobjtt
Worktree: the card thread's own clone (mode:thread; the thread can push only its assigned branch, a measured platform exception to claude/issue-N-SLUG)
Domain: domain:cloud (repo:cloud lane)
Seat: repo:cloud#3
File surface: ui/packages/app-shell/src/console/organizations/orgErrorMessage.ts, the 11 console locale packs, their tests, .changeset/** (stop on breach; explain in the report)
Container & model: M, mode:thread, model: opus (dispatch-gates --tier: no path-derived mandate, default tier; the maintainer's standing order pauses the ceiling tier), effort: high
Clause-②: no (console copy only)
Metadata-protocol: none
Responsibility: implement + local gates; draft PR Closes #28124; seat reviews and lands
Thread-read: 6524720181
Premise: holds (pre-dispatch reading in the dispatch order; the dev re-measures first and stops on a falsified premise)
Serial constraints cleared: none
{
"issue": 28124,
"status": "done",
"branch": "claude/project-thread-oobjtt",
"pr": "https://github.com/objectstack-ai/objectstack/pull/31465",
"session": "session_01QUs3BveKCXohEcrrpsCh6c",
"premise_still_valid": true,
"summary": "Premise held on objectstack main 9728ab15: ORG_ERROR_MESSAGE_KEYS in ui/packages/app-shell/src/console/organizations/orgErrorMessage.ts had no row for YOU_HAVE_REACHED_THE_MAXIMUM_NUMBER_OF_ORGANIZATIONS, so resolveOrgErrorMessage fell through to better-auth's English sentence. Work item 2: no number is exposed. better-auth 1.7.12 throws it at dist/plugins/organization/routes/crud-org.mjs:61 as APIError FORBIDDEN with the bare code and message; plugin-auth reads the cap inside the organizationLimit callback (auth-manager-organization-plugin.ts:204, resolveOrgLimit at packages/types/src/env.ts:727) and returns a boolean; the /auth/config features object (auth-manager.ts:5047 onward) does not publish it; cloud ac69aac sets OS_ORG_LIMIT: '2' only in the container env (apps/cloud/cloudflare/worker.ts:503). Done: the code maps to organization.errors.organizationLimitReached, defined in all 11 console packs (zh-Hant regenerated from zh-Hans by gen:zh-hant), saying the cap counts only organizations the user created, never invited ones, with no number; changeset @object-ui/i18n + @object-ui/app-shell patch. File surface: the claim's, plus CreateWorkspaceDialog.test.tsx (the dialog-level zh/en pin, a test of the mapping's one create-path consumer).",
"tests": "Under ui/ on b1443871 (last code commit; head 0ad95797 adds only the changeset): npx vitest run packages/i18n/ packages/app-shell/src/console/organizations/ -> Test Files 116 passed (116), Tests 1967 passed | 13 skipped; VERDICT command-exit 0. New pins: orgErrorMessage-4474.test.ts top-level describe (zh renders the zh pack value, en the en pack value, every pack defines the key with its own sentence and no digit; exact-set pin gains the code) and CreateWorkspaceDialog.test.tsx top-level describe (real zh-Hans and en packs: workspace-create-error shows the pack sentence, not the server English; one create call, no provision). Ablation via scripts/ablation-replace.mjs renaming the mapping row key (anchor x1 -> x0, blob 335e7a7e -> 2050edb8; vitest resolves app-shell source directly, no dist leg): Tests 5 failed | 33 passed (zh+en in both files and the exact-set pin); restore blob == HEAD 335e7a7e, git diff HEAD empty.",
"gates": "dispatch-gates --commands on head 0ad95797: 38 derived families, all run on that head, each exit 0; --ran: 38 derived, 38 run, 0 NOT-MEASURED, 0 UNRUN (derived zero, every row with its exit code). ui i18n gates: check:i18n-drift exit 0 (0 en values changed, 1 key added), check:i18n-keys exit 0, check:i18n-dead-keys exit 0 (report lists the new key needs-review like its nine organization.errors siblings, a key held as a mapping-table value). Declared narrowing: @object-ui/app-shell type-check not run locally (needs every @object-ui/* package built); Type Check UI on the PR covers it. PR check-runs: in_progress at report time.",
"dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm",
"mcp_calls": "3 — mcp__github__issue_read (get x1, get_comments x2); no write tool",
"api_writes": "2 — relay pr_create (POST /repos/objectstack-ai/objectstack/pulls draft + POST issues/31465/assignees, one dispatch, run 42467386136, read-back identical); post-stamped comment on #28124 (this report). git push is not a REST write.",
"open_questions": [],
"security_findings": "none",
"out_of_scope_findings": []
}
objectstack#31465 merged at 2026-11-08T10:55Z as a1d243e06 and closed this card. The create-workspace dialog now explains the per-user organization limit in all 11 packs instead of showing the English server sentence. The eager i18n-locale-en ceiling moved 60,000 → 61,000 with its measured rationale. Moving the whole organization.* group into a lazy namespace is the class fix the dev named; it is left to the UI lane.
Owed after a cloud pin round carries a1d243e06: none beyond the ordinary pin smoke (console-only change).
Activity
objectstack-fleet commentedon Oct 30, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: moved to the cloud PM ·
domain:cloud·status:parked· 2026-10-30T14:04Z⛔ Not a claim.
domain:cloudandstatus:parked. Thepriority:p3the filer set stays.Generated by Claude Code
objectstack-fleet commentedon Nov 8, 2026
repo:cloud#3 · os-zhuang · session_01QUs3BvRcDHXqRU4TSVE4u6
Claim: PM loop round 1
Session:
session_01QUs3BvRcDHXqRU4TSVE4u6Account:
os-zhuangBranch:
claude/project-thread-oobjttWorktree: the card thread's own clone (
mode:thread; the thread can push only its assigned branch, a measured platform exception toclaude/issue-N-SLUG)Domain:
domain:cloud(repo:cloudlane)Seat:
repo:cloud#3File surface:
ui/packages/app-shell/src/console/organizations/orgErrorMessage.ts, the 11 console locale packs, their tests,.changeset/**(stop on breach; explain in the report)Container & model:
M,mode:thread,model: opus(dispatch-gates --tier: no path-derived mandate, default tier; the maintainer's standing order pauses the ceiling tier),effort: highClause-②: no (console copy only)
Metadata-protocol: none
Responsibility: implement + local gates; draft PR
Closes #28124; seat reviews and landsThread-read: 6524720181
Premise: holds (pre-dispatch reading in the dispatch order; the dev re-measures first and stops on a falsified premise)
Serial constraints cleared: none
objectstack-fleet commentedon Nov 8, 2026
repo:cloud#3 · os-zhuang · session_01QUs3BveKCXohEcrrpsCh6c
os-dev-report
{ "issue": 28124, "status": "done", "branch": "claude/project-thread-oobjtt", "pr": "https://github.com/objectstack-ai/objectstack/pull/31465", "session": "session_01QUs3BveKCXohEcrrpsCh6c", "premise_still_valid": true, "summary": "Premise held on objectstack main 9728ab15: ORG_ERROR_MESSAGE_KEYS in ui/packages/app-shell/src/console/organizations/orgErrorMessage.ts had no row for YOU_HAVE_REACHED_THE_MAXIMUM_NUMBER_OF_ORGANIZATIONS, so resolveOrgErrorMessage fell through to better-auth's English sentence. Work item 2: no number is exposed. better-auth 1.7.12 throws it at dist/plugins/organization/routes/crud-org.mjs:61 as APIError FORBIDDEN with the bare code and message; plugin-auth reads the cap inside the organizationLimit callback (auth-manager-organization-plugin.ts:204, resolveOrgLimit at packages/types/src/env.ts:727) and returns a boolean; the /auth/config features object (auth-manager.ts:5047 onward) does not publish it; cloud ac69aac sets OS_ORG_LIMIT: '2' only in the container env (apps/cloud/cloudflare/worker.ts:503). Done: the code maps to organization.errors.organizationLimitReached, defined in all 11 console packs (zh-Hant regenerated from zh-Hans by gen:zh-hant), saying the cap counts only organizations the user created, never invited ones, with no number; changeset @object-ui/i18n + @object-ui/app-shell patch. File surface: the claim's, plus CreateWorkspaceDialog.test.tsx (the dialog-level zh/en pin, a test of the mapping's one create-path consumer).", "tests": "Under ui/ on b1443871 (last code commit; head 0ad95797 adds only the changeset): npx vitest run packages/i18n/ packages/app-shell/src/console/organizations/ -> Test Files 116 passed (116), Tests 1967 passed | 13 skipped; VERDICT command-exit 0. New pins: orgErrorMessage-4474.test.ts top-level describe (zh renders the zh pack value, en the en pack value, every pack defines the key with its own sentence and no digit; exact-set pin gains the code) and CreateWorkspaceDialog.test.tsx top-level describe (real zh-Hans and en packs: workspace-create-error shows the pack sentence, not the server English; one create call, no provision). Ablation via scripts/ablation-replace.mjs renaming the mapping row key (anchor x1 -> x0, blob 335e7a7e -> 2050edb8; vitest resolves app-shell source directly, no dist leg): Tests 5 failed | 33 passed (zh+en in both files and the exact-set pin); restore blob == HEAD 335e7a7e, git diff HEAD empty.", "gates": "dispatch-gates --commands on head 0ad95797: 38 derived families, all run on that head, each exit 0; --ran: 38 derived, 38 run, 0 NOT-MEASURED, 0 UNRUN (derived zero, every row with its exit code). ui i18n gates: check:i18n-drift exit 0 (0 en values changed, 1 key added), check:i18n-keys exit 0, check:i18n-dead-keys exit 0 (report lists the new key needs-review like its nine organization.errors siblings, a key held as a mapping-table value). Declared narrowing: @object-ui/app-shell type-check not run locally (needs every @object-ui/* package built); Type Check UI on the PR covers it. PR check-runs: in_progress at report time.", "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm", "mcp_calls": "3 — mcp__github__issue_read (get x1, get_comments x2); no write tool", "api_writes": "2 — relay pr_create (POST /repos/objectstack-ai/objectstack/pulls draft + POST issues/31465/assignees, one dispatch, run 42467386136, read-back identical); post-stamped comment on #28124 (this report). git push is not a REST write.", "open_questions": [], "security_findings": "none", "out_of_scope_findings": [] }objectstack-fleet commentedon Nov 8, 2026
repo:cloud#3 · os-zhuang · session_01QUs3BvRcDHXqRU4TSVE4u6
Landed · 2026-11-08T10:58Z
objectstack#31465 merged at 2026-11-08T10:55Z as
a1d243e06and closed this card. The create-workspace dialog now explains the per-user organization limit in all 11 packs instead of showing the English server sentence. The eageri18n-locale-enceiling moved 60,000 → 61,000 with its measured rationale. Moving the wholeorganization.*group into a lazy namespace is the class fix the dev named; it is left to the UI lane.Owed after a cloud pin round carries
a1d243e06: none beyond the ordinary pin smoke (console-only change).