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
Languages: move from the Console's ten codes to the platform's 11 tags (split zh into zh-Hans / zh-Hant, pt → pt-BR) #182
#159 landed as PR #169 (13d5b01). It ships the Console UI's ten short codes: en zh ja ko de fr es pt ru ar. Traditional Chinese maps to zh, which is Simplified, and Brazilian Portuguese maps to pt.
The card body of #159 was rewritten to the 11 tags after #169 had already merged, so the rewrite was never delivered. This card carries it.
Language
Tag
main today
English
en
en
简体中文
zh-Hans
zh
繁體中文
zh-Hant
missing (falls to zh, Simplified)
Español
es
es
العربية
ar (RTL)
ar
Français
fr
fr
Português (Brasil)
pt-BR
pt
Русский
ru
ru
Deutsch
de
de
日本語
ja
ja
한국어
ko
ko
Ask
Bundles keyed by the table's tags.
Rename locales/zh.json to zh-Hans.json and pt.json to pt-BR.json.
Add zh-Hant.json, generated from zh-Hans with a phrase-aware converter (precedent: objectstack-ai/www.objectos.aiscripts/gen-zh-hant.mjs), then reviewed.
Resolution by script. Walk the phone's preferred languages in order:
Claim: PM loop round 3
Session: session_01QSeKYnW1Xf6HDSWz1eGAqv
Account: os-justin
Branch: claude/issue-182-eleven-locales
Worktree: mobile-issue-182
Domain: n/a — single-lane repo (repo:mobile)
Seat: repo:mobile#1
File surface: locales/* (renames zh→zh-Hans and pt→pt-BR, new zh-Hant), lib/i18n.ts, lib/rtl.ts, app.config.ts (PERMISSION_LOCALES), __tests__/**, docs/HYBRID-SHELL.md, docs/design/connection-flow.md, .changeset/182-eleven-locales.md (stop on breach; explain in the report)
Container & model: M, mode:subagent, model: default tier (opus) — no path-derived mandate, effort: high
Clause-②: no
Metadata-protocol: none
Responsibility: n/a — not a defect card
Thread-read: none
Premise: holds. On main at 427cb49, ten bundles exist (zh.json and pt.json included); PERMISSION_LOCALES maps zh-Hant to the zh text. objectstack-ai/objectstack#29428 (the platform table) is open, so the card's own table is the spec.
Serial constraints cleared: #187 and #182 are dispatched in the same round. Both touch docs/HYBRID-SHELL.md, and #182 rewrites locales/* names. That is ordinary concurrency: the PR that lands second reconciles. Landing: the maintainer merges, because seat landing is suspended (see the comment on #160).
{
"issue": 182,
"status": "done",
"branch": "claude/issue-182-eleven-locales",
"pr": "https://github.com/objectstack-ai/mobile/pull/189",
"session": "session_01QSeKYnW1Xf6HDSWz1eGAqv",
"premise_still_valid": true,
"summary": "The shell now ships the platform's 11 tags (en zh-Hans zh-Hant es ar fr pt-BR ru de ja ko). zh.json and pt.json are pure renames (git similarity 100%) to zh-Hans/pt-BR. The new zh-Hant.json is converted from zh-Hans with opencc-js 1.3.1 s2twp plus the 8 phrase overrides of www.objectos.ai src/lib/zhconvert.ts @ 4ed1dfe, which was reachable through git though not REST; a second run reproduces it byte-identical. matchLanguageTag is replaced by resolveLanguageTag (script subtag first, then TW/HK/MO -> zh-Hant, other zh -> zh-Hans, pt-* -> pt-BR, else the bundled primary subtag, else null; case-insensitive; stops at the first singleton); its contract table is in the PR. A locale with no languageTag is rebuilt from languageCode+languageScriptCode+regionCode. PERMISSION_LOCALES gives zh-Hant.lproj its own text, and pt.lproj stays unqualified and now carries the pt-BR text. HYBRID-SHELL and connection-flow say 11 and name the table. #29428 against the card: no disagreement. Every alias in #29428 (body, Phases item 1, second bullet) maps identically and is pinned by a test, and the card's rule covers further inputs #29428 is silent on. No merged table on objectstack main at 4b71a82b76: PLATFORM_LOCALES has zero hits, while the control word BUILT_IN_LANGUAGE_CODES hits.",
"tests": "At a4a903a, in worktree mobile-issue-182 under os-verify-lock: npx jest --ci --coverage gives VERDICT command-exit 0, Test Suites 49 passed of 49, Tests 1070 passed of 1070, lib/i18n.ts 92.06% statements. Targeted suites i18n + app-config + RtlLayout: 99 of 99. Ablation, with the fix committed first, through objectstack scripts/ablation-replace.mjs: HANT_REGIONS new Set([tw,hk,mo]) -> new Set([hk,mo]) in lib/i18n.ts, anchor x1->x0, blob 3da779ed305e -> c60ec6d6b0be. Result: Tests 3 failed / 96 passed / 99. Red: 'detectDeviceLanguage resolves Traditional Chinese zh-TW to zh-Hant', 'resolveLanguageTag resolves the platform alias zh-TW to zh-Hant', 'resolveLanguageTag compares subtags case-insensitively'. Direction: turned red; zh-Hant-TW stayed green because the script decides. Restored: blob == HEAD 3da779ed305e, git diff HEAD empty. No dist/build in this repo; jest reads the source. No new component test file, so the cold variant does not apply.",
"gates": "Local, at a4a903a, exits captured before any pipe: npx tsc --noEmit exit 0 (--listFiles includes lib/i18n.ts, app.config.ts, locales/zh-Hant.json and both changed tests); npx eslint . --ext .ts,.tsx exit 0 with no output; npx jest --ci --coverage exit 0. These three are exactly mobile's CI families (ci.yml Code Quality, lint-typecheck.yml Lint & Type Check), derived by hand because dispatch-gates.mjs is objectstack-only, so there is no --ran reconciliation. Control-byte self-scan of the 16 changed files: no hits. PR #189 check-runs on a4a903a at report time: Code Quality in_progress, Lint & Type Check in_progress.",
"dogfood_battery": "n/a: no ! in the PR title and no (narrowing) arm; mobile has no dogfood battery",
"mcp_calls": "0",
"api_writes": "2 relay writes: (1) pr_create, POST /repos/objectstack-ai/mobile/pulls, draft forced, no assignees, no labels, through fleet-write relay request fw-20261103T083717Z-aa8715, run 41604640839, read-back 9884 bytes sent / 9884 stored, identical; (2) this report comment, POST /repos/objectstack-ai/mobile/issues/182/comments through post-stamped.mjs. Plus 1 git push of the branch (an empty-branch probe at creation, then commits 051c32a and a4a903a), which is not REST.",
"deviations": [
"Base: branched from origin/main 13b7e32, not the dispatched 427cb49. It contains 427cb49, and the 5 commits in between (#185) touch app.config.ts.",
"File surface: 2 additions beyond the claim, docs/DEVICE-TESTING.md:78 (it said zh-TW shows Simplified Chinese; it now carries the zh-Hant/pt-BR device check) and docs/CONTRIBUTING.md:26 (it named locales/{en,zh,ar}.json, and zh.json no longer exists). The dispatch says to stop on a breach; os-dev.md says text this change makes false must be fixed, and os-dev.md wins on conflict. Declared in the PR body.",
"Changeset level patch, per AGENTS.md (Metadata-protocol none takes patch). The mobile precedent .changeset/159-ten-locales.md used minor, and mobile has no changeset gate.",
"The dispatch lists native review and the device check under 需要你做的; os-dev.md wants exactly one action there. They are folded into one action (one native speaker, one phone, both languages).",
"No zh-Hant generator committed: it needs opencc-js in package.json and a scripts/ file, both outside the surface. The recipe is in the PR, HYBRID-SHELL and CONTRIBUTING.",
"Commit trailers are the model-free pair per AGENTS.md, not the harness's model-named Co-Authored-By."
],
"open_questions": [],
"security_findings": "none",
"out_of_scope_findings": [
"carrier: none · noted, not filed: zh-Hant.json has no committed generator or drift test, so a zh-Hans copy change can leave the Traditional text stale with key parity still green (Acceptance notes)",
"carrier: none · noted, not filed: ROADMAP.md:23 'i18n (en / zh / ar)' is a historical status line, left as is"
]
}
Activity
objectstack-fleet commentedon Nov 3, 2026
repo:mobile#1 · os-justin · session_01QSeKYnW1Xf6HDSWz1eGAqv
Claim: PM loop round 3
Session:
session_01QSeKYnW1Xf6HDSWz1eGAqvAccount:
os-justinBranch:
claude/issue-182-eleven-localesWorktree:
mobile-issue-182Domain:
n/a — single-lane repo (repo:mobile)Seat:
repo:mobile#1File surface:
locales/*(renameszh→zh-Hansandpt→pt-BR, newzh-Hant),lib/i18n.ts,lib/rtl.ts,app.config.ts(PERMISSION_LOCALES),__tests__/**,docs/HYBRID-SHELL.md,docs/design/connection-flow.md,.changeset/182-eleven-locales.md(stop on breach; explain in the report)Container & model:
M,mode:subagent,model: default tier (opus) — no path-derived mandate,effort: highClause-②: no
Metadata-protocol: none
Responsibility:
n/a — not a defect cardThread-read: none
Premise: holds. On
mainat427cb49, ten bundles exist (zh.jsonandpt.jsonincluded);PERMISSION_LOCALESmapszh-Hantto thezhtext. objectstack-ai/objectstack#29428 (the platform table) is open, so the card's own table is the spec.Serial constraints cleared: #187 and #182 are dispatched in the same round. Both touch
docs/HYBRID-SHELL.md, and #182 rewriteslocales/*names. That is ordinary concurrency: the PR that lands second reconciles. Landing: the maintainer merges, because seat landing is suspended (see the comment on #160).objectstack-fleet commentedon Nov 3, 2026
repo:mobile#1 · os-justin · session_01QSeKYnW1Xf6HDSWz1eGAqv
os-dev-report
{ "issue": 182, "status": "done", "branch": "claude/issue-182-eleven-locales", "pr": "https://github.com/objectstack-ai/mobile/pull/189", "session": "session_01QSeKYnW1Xf6HDSWz1eGAqv", "premise_still_valid": true, "summary": "The shell now ships the platform's 11 tags (en zh-Hans zh-Hant es ar fr pt-BR ru de ja ko). zh.json and pt.json are pure renames (git similarity 100%) to zh-Hans/pt-BR. The new zh-Hant.json is converted from zh-Hans with opencc-js 1.3.1 s2twp plus the 8 phrase overrides of www.objectos.ai src/lib/zhconvert.ts @ 4ed1dfe, which was reachable through git though not REST; a second run reproduces it byte-identical. matchLanguageTag is replaced by resolveLanguageTag (script subtag first, then TW/HK/MO -> zh-Hant, other zh -> zh-Hans, pt-* -> pt-BR, else the bundled primary subtag, else null; case-insensitive; stops at the first singleton); its contract table is in the PR. A locale with no languageTag is rebuilt from languageCode+languageScriptCode+regionCode. PERMISSION_LOCALES gives zh-Hant.lproj its own text, and pt.lproj stays unqualified and now carries the pt-BR text. HYBRID-SHELL and connection-flow say 11 and name the table. #29428 against the card: no disagreement. Every alias in #29428 (body, Phases item 1, second bullet) maps identically and is pinned by a test, and the card's rule covers further inputs #29428 is silent on. No merged table on objectstack main at 4b71a82b76: PLATFORM_LOCALES has zero hits, while the control word BUILT_IN_LANGUAGE_CODES hits.", "tests": "At a4a903a, in worktree mobile-issue-182 under os-verify-lock: npx jest --ci --coverage gives VERDICT command-exit 0, Test Suites 49 passed of 49, Tests 1070 passed of 1070, lib/i18n.ts 92.06% statements. Targeted suites i18n + app-config + RtlLayout: 99 of 99. Ablation, with the fix committed first, through objectstack scripts/ablation-replace.mjs: HANT_REGIONS new Set([tw,hk,mo]) -> new Set([hk,mo]) in lib/i18n.ts, anchor x1->x0, blob 3da779ed305e -> c60ec6d6b0be. Result: Tests 3 failed / 96 passed / 99. Red: 'detectDeviceLanguage resolves Traditional Chinese zh-TW to zh-Hant', 'resolveLanguageTag resolves the platform alias zh-TW to zh-Hant', 'resolveLanguageTag compares subtags case-insensitively'. Direction: turned red; zh-Hant-TW stayed green because the script decides. Restored: blob == HEAD 3da779ed305e, git diff HEAD empty. No dist/build in this repo; jest reads the source. No new component test file, so the cold variant does not apply.", "gates": "Local, at a4a903a, exits captured before any pipe: npx tsc --noEmit exit 0 (--listFiles includes lib/i18n.ts, app.config.ts, locales/zh-Hant.json and both changed tests); npx eslint . --ext .ts,.tsx exit 0 with no output; npx jest --ci --coverage exit 0. These three are exactly mobile's CI families (ci.yml Code Quality, lint-typecheck.yml Lint & Type Check), derived by hand because dispatch-gates.mjs is objectstack-only, so there is no --ran reconciliation. Control-byte self-scan of the 16 changed files: no hits. PR #189 check-runs on a4a903a at report time: Code Quality in_progress, Lint & Type Check in_progress.", "dogfood_battery": "n/a: no ! in the PR title and no (narrowing) arm; mobile has no dogfood battery", "mcp_calls": "0", "api_writes": "2 relay writes: (1) pr_create, POST /repos/objectstack-ai/mobile/pulls, draft forced, no assignees, no labels, through fleet-write relay request fw-20261103T083717Z-aa8715, run 41604640839, read-back 9884 bytes sent / 9884 stored, identical; (2) this report comment, POST /repos/objectstack-ai/mobile/issues/182/comments through post-stamped.mjs. Plus 1 git push of the branch (an empty-branch probe at creation, then commits 051c32a and a4a903a), which is not REST.", "deviations": [ "Base: branched from origin/main 13b7e32, not the dispatched 427cb49. It contains 427cb49, and the 5 commits in between (#185) touch app.config.ts.", "File surface: 2 additions beyond the claim, docs/DEVICE-TESTING.md:78 (it said zh-TW shows Simplified Chinese; it now carries the zh-Hant/pt-BR device check) and docs/CONTRIBUTING.md:26 (it named locales/{en,zh,ar}.json, and zh.json no longer exists). The dispatch says to stop on a breach; os-dev.md says text this change makes false must be fixed, and os-dev.md wins on conflict. Declared in the PR body.", "Changeset level patch, per AGENTS.md (Metadata-protocol none takes patch). The mobile precedent .changeset/159-ten-locales.md used minor, and mobile has no changeset gate.", "The dispatch lists native review and the device check under 需要你做的; os-dev.md wants exactly one action there. They are folded into one action (one native speaker, one phone, both languages).", "No zh-Hant generator committed: it needs opencc-js in package.json and a scripts/ file, both outside the surface. The recipe is in the PR, HYBRID-SHELL and CONTRIBUTING.", "Commit trailers are the model-free pair per AGENTS.md, not the harness's model-named Co-Authored-By." ], "open_questions": [], "security_findings": "none", "out_of_scope_findings": [ "carrier: none · noted, not filed: zh-Hant.json has no committed generator or drift test, so a zh-Hans copy change can leave the Traditional text stale with key parity still green (Acceptance notes)", "carrier: none · noted, not filed: ROADMAP.md:23 'i18n (en / zh / ar)' is a historical status line, left as is" ] }objectstack-fleet commentedon Nov 3, 2026
repo:mobile#1 · os-justin · session_01QSeKYnW1Xf6HDSWz1eGAqv
ACCEPT → PR #189 (head
a4a903a). The maintainer merges it, because seat landing is suspended.