Repository navigation
fix(spec/system): read the script-subtag Chinese spellings (zh-Hant-TW, zh-Hans-CN, …) as platform locale read aliases - #30681
Conversation
…m locale aliases PLATFORM_LOCALE_READ_ALIASES gains one row per regional Chinese alias for its script-subtag spelling: zh-Hans-CN and zh-Hans-SG read as zh-Hans; zh-Hant-TW, zh-Hant-HK and zh-Hant-MO read as zh-Hant. The list stays closed: enumerated rows only, no pattern and no region fallback. So resolveLocaleAmong's table step reaches a registered zh-Hant for a zh-Hant-TW reader over a two-script bundle in either registration order, where the first registered zh-* key used to answer. Pins: platform-locales.test.ts (each row, case-folded; the closed-list case keeps pt-PT, de-AT, en-GB, es-419, fr-CA, it and he and gains two unlisted script-subtag codes), i18n-resolver.test.ts (both orders) and core's shared case list in fallbacks.test.ts (both resolvers, both orders, and the in-memory service). Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L6bhgVugtCCwBs98FeR27P
…he script-subtag aliases Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L6bhgVugtCCwBs98FeR27P
Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L6bhgVugtCCwBs98FeR27P
📓 Docs Drift CheckThis PR changes 1 package(s): 1 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
What this run could not see
Coarse fallback — 170 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin b6d0d67a5780cdbc784f4737b3a8edc67f6af9fc && git checkout b6d0d67a5780cdbc784f4737b3a8edc67f6af9fc
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin a2437b560bd8872feece6ec8b57c6fdf21cff1f4 d8713f3f32b323798a6416046bf4704ed6a9d82b && git checkout -B drift-repro a2437b560bd8872feece6ec8b57c6fdf21cff1f4 && git merge --no-ff d8713f3f32b323798a6416046bf4704ed6a9d82b
node scripts/docs-audit/affected-docs.mjs --json a2437b560bd8872feece6ec8b57c6fdf21cff1f4
|
…s, and the ladder paragraph names the table step The Read aliases section of content/docs/protocol/kernel/i18n-standard.mdx lists the five script-subtag rows (zh-Hans-CN and zh-Hans-SG read as zh-Hans; zh-Hant-TW, zh-Hant-HK and zh-Hant-MO as zh-Hant), and says a script-subtag spelling without a row (zh-Hant-US) still answers undefined: the list is closed and read row by row. The ladder paragraph said the ladder alone cannot tell the two Chinese scripts apart and answers zh / zh-CN by key order. That has been false since resolveLocaleAmong gained its table-language step. It now names the five steps, says which requests the table step answers in any key order, and which still fall to base language and the first registered variant: a code the table does not name, and a request whose table language has no key. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L6bhgVugtCCwBs98FeR27P
|
domain:spec#2 · os-sales · session_01L6bhgVugtCCwBs98FeR27P Contract reviewServed-tier: Written 2026-11-05T22:28Z. Inputs: card #30618 body and all four comments (6666534830, 6669501005, 6670989840, 6671045459), PR #30681 body and file list, the net diff Gate verdicts on this head (check-run conclusions, as they stood): success 22, among them Check Changeset, PR-body guards, Governed Surface Queue Guard, Spec property liveness, Lint · ESLint, Lint · docs & code guards, Lint · CI/release/engine gates, Lint · PM dispatch-gates, Lint · repo & tooling gates, Type Check · source gates, Type Check · debt ledger, Check PR Size, Flag docs affected, Dogfood Regression Gate, Plan Test Core shards, Build UI Deps. Skipped 9 (opt-in and path-filtered). Still pending: Test Core 1/8-8/8. Never concluded on this head: Build Core, Test UI 1/16-16/16, Build & E2E UI, Live E2E UI, Type Check UI, Type Check · workspace, Type Check · consumer gates were cancelled at 22:24Z by the superseding push, and the two ① Derived judgments
② Semver level
③ Boundary flags
④ Design judgment
Must-fix: none. Should-fix:
Implemented-by: VERDICT: PASS Generated by Claude Code |
…ag keys (#30618) A bundle key or offered code spelled zh-Hant-TW / zh-Hans-CN is mapped through the table too, so it counts as its script: zh-TW and zh-Hant over [en, zh-CN, zh-Hant-TW] reach zh-Hant-TW, zh-CN over [en, zh-Hant, zh-Hans-CN] reaches zh-Hans-CN, and zh-Hant-TW over [en, zh, zh-Hant-HK] reaches zh-Hant-HK, in both registration orders. With one script registered (zh-Hant-TW over [en, zh-CN]) the related language still answers. Pinned in core's shared case list and in spec's table-step cases; the changeset says the key side goes through the table. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L6bhgVugtCCwBs98FeR27P
|
domain:spec#2 · os-sales · session_01L6bhgVugtCCwBs98FeR27P Contract reviewServed-tier: Delta re-review, written 2026-11-05T23:20Z. Inputs: card #30618 (body, comments 6666534830, 6669501005, 6670989840, 6671045459 and the patch-round report 6672039879), the PR's r2 body and file list, the delta Carried from the record on Gate verdicts on this head (check-run conclusions as they stood): success 57 — Test Core 1/8-8/8 and its aggregate, Test UI 1/16-16/16 and its aggregate, TypeScript Type Check, Type Check · source gates / workspace / consumer gates / debt ledger / UI, Build Core, Build & E2E UI, Live E2E UI, Build Docs, every Lint row, Check Changeset, PR-body guards, Governed Surface Queue Guard, Spec property liveness, Check Documentation Links, Flag docs affected, Check PR Size, Dogfood Regression Gate. Skipped 10 (opt-in and path-filtered). Still pending: a second ① Derived judgments
② Semver levelUnchanged from the first record: ③ Boundary flags
④ Design judgment
Must-fix: none. Should-fix: none. Implemented-by: VERDICT: PASS Generated by Claude Code |
|
domain:spec#2 · os-sales · session_01L6bhgVugtCCwBs98FeR27P 维护者速读
席位核对ACCEPT · head
Generated by Claude Code |
Requested by Sales · project thread
domain:spec#2 · os-sales · session_01L6bhgVugtCCwBs98FeR27P
Fixes #30618
Clause-②: yes (widening)
Metadata-protocol: semantic
Skills-docs: none —
skills/**carries no script-subtag or read-alias claim, measured atd8713f3f:git grep -i -E 'zh-Han[st]-[A-Za-z0-9]+' -- skills/0 hits,git grep -E 'PLATFORM_LOCALE_READ_ALIASES|platformLocaleTagOf|read alias|zh-Hant' -- skills/0 hits. The one docs page that states the read aliases,content/docs/protocol/kernel/i18n-standard.mdx(its "Read aliases" section), is fixed in this PR.维护者速读
zh-Hans-CN、zh-Hans-SG读作zh-Hans,zh-Hant-TW、zh-Hant-HK、zh-Hant-MO读作zh-Hant。解析阶梯的“同表语言”一步对已注册的 key 也查这张表,所以拼成zh-Hant-TW/zh-Hans-CN的包 key 或可选代码,按它写明的文字归入繁体或简体。别名表仍是逐行列举的封闭清单,不按模式推断,也不按区域回退。文档页i18n-standard.mdx的 Read aliases 一节同步改正。zh-Hant-TW)。原来这五个代码不在表里,同时有简体包和繁体包时,繁体读者拿到的是先注册的那个 zh-* 包;主干上 service-storage 的对象翻译包(zh-CN排在zh-Hant前)就是这样把繁体读者答成简体。pt-PT、en-GB、zh-Hant-US)照旧。Setup「默认语言」对这五个代码改用表里的名称(繁體中文 / 简体中文),已存的繁体值改显示在繁體中文选项上;可接受的取值不变。回滚即还原本 PR。packages/spec/src/system/platform-locales.ts的五行别名及其注释;packages/core/src/fallbacks/fallbacks.test.ts的共享用例表(两个解析器、两种注册顺序,含 key 侧用例);packages/spec/src/system/platform-locales.test.ts的封闭清单用例;content/docs/protocol/kernel/i18n-standard.mdx的 Read aliases 一节。pnpm --filter @objectstack/spec exec vitest run src/system/platform-locales.test.ts src/system/i18n-resolver.test.ts,预期 2 个文件、576 例全绿。What changes
PLATFORM_LOCALE_READ_ALIASES(packages/spec/src/system/platform-locales.ts) gains five rows, one for the script-subtag spelling of each regional Chinese alias.platformLocaleTagOf, FROM → TO:zh-Hans-CNundefinedzh-Hanszh-Hans-SGundefinedzh-Hanszh-Hant-TWundefinedzh-Hantzh-Hant-HKundefinedzh-Hantzh-Hant-MOundefinedzh-HantCase is folded as for every row (
ZH-HANT-twreads aszh-Hant).PlatformLocaleReadAliasgains the five literal keys. The list stays closed: enumerated rows only, no pattern, no region fallback.zh-Hant-US,zh-Hans-US,pt-PT,de-AT,en-GB,es-419,fr-CA,itandhestill answerundefined.What the ladder answers for a script-subtag request (
resolveLocaleAmong, soresolveBundleLocaleand core'sresolveLocale/resolveOfferedLocale), FROM → TO, measured by the ablation below:en, zh-CN, zh-Hanten, zh-Hant, zh-CNen, zh, zh-Hantzh-Hant-TW,zh-Hant-HK,zh-Hant-MOzh-CN→zh-Hantzh-Hant(unchanged)zh→zh-Hantzh-Hans-CN,zh-Hans-SGzh-CN(unchanged)zh-Hant→zh-CNzh(unchanged)The key side. The table step maps each registered key through the table too (
i18n-resolver.tsL573, unchanged), so a bundle key or offered code spelledzh-Hant-TW/zh-Hans-CNnow counts as the script it names for every request the table reads as that script. FROM measured onmaina2437b56(whosei18n-resolver.tsandplatform-locales.tsare unchanged since the merge base47c457b2), TO at this head;resolveLocaleAmong,resolveBundleLocaleand core'sresolveLocalegive the same answer in every row:main)zh-TWen, zh-CN, zh-Hant-TWzh-CNzh-Hant-TWzh-TWen, zh-Hant-TW, zh-CNzh-Hant-TWzh-Hant-TW(unchanged)zh-Hanten, zh-CN, zh-Hant-TWzh-CNzh-Hant-TWzh-Hanten, zh-Hant-TW, zh-CNzh-Hant-TWzh-Hant-TW(unchanged)zh-CNen, zh-Hant, zh-Hans-CNzh-Hantzh-Hans-CNzh-CNen, zh-Hans-CN, zh-Hantzh-Hans-CNzh-Hans-CN(unchanged)zh-Hant-TWen, zh, zh-Hant-HKzhzh-Hant-HKzh-Hant-TWen, zh-Hant-HK, zhzhzh-Hant-HKzh-Hant-TWen, zh-CN(one script registered)zh-CNzh-CN(unchanged)No request that matched before stops matching. With no key of the requested script, a script-subtag request still reaches the other script's key, as before (last row).
Docblocks in
platform-locales.ts: the read-alias block no longer says "zh-Hans-CNis not listed"; it says the five rows exist, that the list is closed, and that a script-subtag spelling without a row (zh-Hant-US) answers nothing because rows are read one by one, never as a pattern. TheplatformLocaleTagOfparagraph nameszh-Hans-CN/zh-Hant-TWbesidezh-CN/zh-TW.Docs page
content/docs/protocol/kernel/i18n-standard.mdx, the "Read aliases" section only (L166-207 at this head; nothing outside it moves):undefined" stays and is true again: the section now says the list is closed and read row by row, never as a pattern, sozh-Hant-USanswersundefinedtoo.zh/zh-CNby key order (false since PR fix(spec,core): resolve locales through the platform table's read aliases, so a zh-TW / zh-HK reader gets zh-Hant #30601 added the table step) is rewritten against the code. It names the ladder's one function (resolveLocaleAmong, whichresolveBundleLocaleand core'sresolveLocalerun) and its five steps, says the table step takes the key spelled as the table tag or else the first key the table maps to it, and says a two-script bundle answerszh,zh-CN,zh-Hans-CNSimplified andzh-TW,zh-Hant-TWTraditional in any registration order.zh-Hant-USoveren, zh-CN, zh-Hantgetszh-CN, andzh-Hantwhen that key is registered first) and a request whose table language has no key (zh-TWoveren, zh-CNgetszh-CN).Pins (no new file; each extends the existing harness):
packages/spec/src/system/platform-locales.test.ts: the five rows in the alias table (toEqualover the whole map, now fifteen), a typed index onzh-Hant-TW, a case-folded spelling of each row (ZH-HANS-cn,zh-hans-sg,ZH-HANT-tw,zh-hant-hk,Zh-Hant-Mo). The closed-list case dropszh-Hans-CNandzh-Hant-TW, keepspt-PT,de-AT,en-GB,es-419,fr-CA,it,he, and addszh-Hant-USandzh-Hans-US: a script-subtag code without a row still answersundefined.packages/spec/src/system/i18n-resolver.test.ts: the two-registration-order loop (Simplified first/Traditional first) gainszh-Hant-TW,zh-Hant-HK,zh-Hant-MO,ZH-HANT-tw→zh-Hantandzh-Hans-CN,zh-Hans-SG,zh-hans-cn→zh-CN. The "runs before the base-language step" case gains{ zh, zh-Hant }forzh-Hant-TW→zh-Hantandzh-Hans-CN→zh, andzh-Hant-TWoveren, zh, zh-Hant-HK→zh-Hant-HKin both orders. A new case, "reads a key spelled with a script subtag as the script it names, in either registration order", pins the key-side rows above and the one-script control.packages/core/src/fallbacks/fallbacks.test.ts: PR fix(spec,core): resolve locales through the platform table's read aliases, so a zh-TW / zh-HK reader gets zh-Hant #30601's shared case list (run on bothresolveLocaleandresolveBundleLocale) gains twelve request-side rows (each of the five codes in both registration orders,ZH-HANT-tw, andzh-Hant-TWoveren, zh, zh-Hant) and the nine key-side rows of the table above (four requests in both registration orders, plus the one-script control). A new case drives the in-memory i18n service in both load orders forzh-Hant-TW,zh-Hant-HK,zh-Hans-CN.Changeset
.changeset/30618-script-subtag-read-aliases.md:@objectstack/specminor. It states the rows, the request-side and key-side moves (each moved key-side row with its before), the Setup effect, and what stays.@objectstack/coreis not moved (its diff is a test file, outside itsfiles[]).Verification
Head
d8713f3f32b323798a6416046bf4704ed6a9d82b. Against the last fully built heade731b654it adds two commits:6a1d4627(the docs section) andd8713f3f(the key-side pins and the changeset sentence). That delta is four files: the changeset, the docs page and two test files.platform-locales.ts(blobbaefd871) andplatform-locales.test.ts(blob410cf43e) are byte-identical toe731b654, so every non-test source file the branch touches is unchanged since then. Againstmainthe branch is six files, +149 / −29 (merge base47c457b2). No full build this round: spec was rebuilt by the ablation, then the dependency closures of@objectstack/coreand of@objectstack/lint/@objectstack/formulawere built (all exit 0).@objectstack/spec817 files / 25799 tests + 1 todo (platform-locales.test.ts+i18n-resolver.test.ts: 2 / 576);@objectstack/core136 / 3130 (fallbacks.test.ts151). Carried frome731b654, code files byte-identical:@objectstack/service-settings69 / 1178,@objectstack/service-storage73 / 1353.check:test-typecheckundertsconfig.test.json.--no-inline-configonplatform-locales.ts,platform-locales.test.ts,i18n-resolver.test.tsandfallbacks.test.ts: exit 0.dispatch-gates --commandsatd8713f3f: 102 derived (79 ate731b654; the 23 added came with the docs page, and6a1d4627already derived these 102). 99 exit 0 on the first run. Three first answeredPREREQUISITE NOT MET(exit 3):check:skill-examplesandcheck:lean-entry-closurewere re-run after building the client SDK and objectql closures, exit 0;check:dual-build-cjs-loadsneeds every package built, so its reading is carried frome731b654(exit 0), code files byte-identical.--ranwith the codes measured here: 102 derived, 101 run, 1 NOT-MEASURED (check:dual-build-cjs-loads), 0 UNRUN; with the carried reading: 102 derived, 102 run, 0 NOT-MEASURED, 0 UNRUN.d8713f3fwarnedSTALE TREE(at least 7 commits behindorigin/main, and 8 files the derivation reads changed); after a fetch,origin/mainbadf24dfis 12 commits ahead. Re-derived fromorigin/mainbadf24dfwith this branch merged in (a scratch merge in a separate worktree, clean, never committed): the same 102 commands.pnpm --filter @objectstack/spec check:generated: exit 0, all 14 artifacts up to date.check:dev-prereqs(local-only family; it needs every package built): carried frome731b654(exit 0), code files byte-identical. At this head it answers exit 1, naming the unbuiltdist/folders; its--self-test, which is derived, is exit 0 here.Derived gates at
d8713f3f(102, each exit code captured before any pipe)node scripts/check-adr-0087-registration.mjs --base origin/mainnode scripts/check-adr-0087-registration.mjs --self-testnode scripts/check-adr-links.mjsnode scripts/check-adr-links.mjs --self-testnode scripts/check-changeset-no-major.mjs --base origin/mainnode scripts/check-closing-keyword-parity.mjsnode scripts/check-closing-keyword-parity.mjs --self-testnode scripts/check-comment-mask-adoption.mjsnode scripts/check-comment-mask-adoption.mjs --self-testnode scripts/check-comment-mask-corpus.mjsnode scripts/check-dev-prereqs.mjs --self-testnode scripts/check-doc-route-spelling.mjs --advisorynode scripts/check-doc-route-spelling.mjs --self-testnode scripts/check-docs-section-name.mjsnode scripts/check-docs-section-name.mjs --self-testnode scripts/check-dts-emitted.mjs --self-testnode scripts/check-empty-changeset.mjs --base origin/mainnode scripts/check-empty-changeset.mjs --self-testnode scripts/check-issue-citations.mjsnode scripts/check-plugin-teardown-shape.mjsnode scripts/check-plugin-teardown-shape.mjs --self-testnode scripts/check-section-landing-index.mjsnode scripts/check-section-landing-index.mjs --self-testnode scripts/ci/assert-turbo-remote-cache.mjs --self-testnode scripts/ci/plan-test-core-shards.mjs --self-testnode scripts/ci/prune-turbo-cache.mjs --self-testnode scripts/docs-audit/check-affected-docs.mjsnode scripts/docs-audit/check-drift-comment.mjsnode scripts/pm/release-rehearsal-clone.mjs --self-testnode scripts/release-pending-publish.mjs --self-testpnpm --filter @objectstack/lint run check:doc-formula-expressionspnpm --filter @objectstack/lint run check:doc-security-posturepnpm --filter @objectstack/spec run check:api-surfacepnpm --filter @objectstack/spec run check:authorable-surfacepnpm --filter @objectstack/spec run check:browser-reachable-entriespnpm --filter @objectstack/spec run check:docspnpm --filter @objectstack/spec run check:dual-source-exportspnpm --filter @objectstack/spec run check:duration-unit-keyspnpm --filter @objectstack/spec run check:empty-statepnpm --filter @objectstack/spec run check:entry-nameabilitypnpm --filter @objectstack/spec run check:export-originspnpm --filter @objectstack/spec run check:exported-anypnpm --filter @objectstack/spec run check:livenesspnpm --filter @objectstack/spec run check:llms-txtpnpm --filter @objectstack/spec run check:skill-examplespnpm --filter @objectstack/spec run check:skill-refspnpm --filter @objectstack/spec run check:strictness-ledgerpnpm --filter @objectstack/spec run check:variant-docspnpm --filter @objectstack/spec run check:yaml-examplespnpm check:changeset-gate-self-testspnpm check:ci-filter-paritypnpm check:closed-ceremony-textpnpm check:corpus-claim-driftpnpm check:cross-package-test-inputspnpm check:dispatcher-error-vocabularypnpm check:doc-anchorspnpm check:doc-authoringpnpm check:doc-frontmatterpnpm check:docs-audit-scopepnpm check:docs-redirectspnpm check:docs-single-h1pnpm check:docs-spec-enumerationspnpm check:docs-transcript-driftpnpm check:driver-memory-censuspnpm check:dts-closurepnpm check:dual-build-cjs-loadspnpm check:engine-double-contractpnpm check:gitlink-declaredpnpm check:issue-citationspnpm check:kernel-hook-pairspnpm check:keyed-text-boundspnpm check:lean-entry-closurepnpm check:logger-receiver-detachpnpm check:merge-driverpnpm check:nul-bytespnpm check:objectql-double-limitpnpm check:org-identifierpnpm check:page-declaration-shapepnpm check:platform-object-tenancy-censuspnpm check:pm-prior-rulingspnpm check:published-filespnpm check:published-readme-linkspnpm check:query-options-erasurepnpm check:react-page-adapter-contractpnpm check:refd-timer-probepnpm check:registry-log-declaredpnpm check:rest-log-spy-declaredpnpm check:role-wordpnpm check:skill-identifier-livenesspnpm check:slot-lookuppnpm check:sourcemap-no-sources-contentpnpm check:spec-docblock-symbol-anchorspnpm check:spec-parsed-aliaspnpm check:system-context-censuspnpm check:test-source-aliaspnpm check:tier-file-adoptionpnpm check:type-check-coveragepnpm check:type-check-debtpnpm check:undeclared-dep-importspnpm check:vendor-version-stampspnpm check:watch-hint-literalpnpm check:where-matcherAblation: drop the five rows (run at
d8713f3f)scripts/ablation-replace.mjs --deleteon the five rows and their comment: anchor 1 → 0, blobbaefd871→be1e0adf; on disk the rows count 0. Spec rebuilt (VERDICT command-exit 0);ablation-dist-preflight --absentfor"zh-Hant-TW": "zh-Hant"and"zh-Hans-CN": "zh-Hans": exit 0 for both.platform-locales.test.ts+i18n-resolver.test.ts: 21 failed / 555 passed (576). Red: the five rows, their five case-folded spellings, the whole-map and typed-key cases, the two-order loop entries (zh-Hant-TW/zh-Hant-HK/zh-Hant-MO/ZH-HANT-twunder "Simplified first",zh-Hans-CN/zh-Hans-SG/zh-hans-cnunder "Traditional first"), the{ zh, zh-Hant }case, and the new key-side case (first failing assertion:zh-TWoveren, zh-CN, zh-Hant-TWreceivedzh-CN). The twozh-Hant-HKassertions added to the{ zh, zh-Hant }case come after an assertion that is already red there, so vitest stops before them; core's list below fails those rows one by one.fallbacks.test.ts: 26 failed / 125 passed (151). Red: on each ofresolveLocaleandresolveBundleLocale, the seven request-side rows (each code in the order where the other script is registered first,ZH-HANT-tw, andzh-Hant-TWoveren, zh, zh-Hant) and five key-side rows (zh-TWandzh-Hantoveren, zh-CN, zh-Hant-TW,zh-CNoveren, zh-Hant, zh-Hans-CN,zh-Hant-TWoveren, zh, zh-Hant-HKin both orders); plus the in-memory service case in both load orders. Green, as the FROM column says: the key-side rows in the order where the script-subtag key is registered first, and the one-script control.resolveLocaleAmongandresolveBundleLocale(source) and core'sresolveLocale(core source over spec's builtdist/) answers exactly the FROM column on the mutated tree, and exactly the TO column after the restore.git checkout HEAD -- packages/spec/src/system/platform-locales.ts; blob after restorebaefd8712cec92d2a22aac2a8f3fd909a62635a5equals the HEAD blob,git diff HEADempty,git status --porcelainempty. Rebuilt (exit 0); both markers present (preflight exit 0); spec 576 passed, core 151 passed.dist/on disk, service-settings and service-storage failed to resolve workspace package entries (@objectstack/metadata-core) in both legs alike, a setup failure and not a reading. Their reading is carried from the round-one ablation ateadbe6e8(sameplatform-locales.tsblobbaefd871): service-settings 1178 and service-storage 1353 green with and without the rows, so no consumer test pins these answers.Consumer probe (each direct caller, 14 codes, with and without the rows; carried from
e731b654, code files byte-identical)platformLocaleTagOf: the five codes andZH-HANT-twmoveundefined→ table tag;zh-TW,zh-CN,zh-Hant,zh-Hansunchanged;zh-Hant-US,zh-Hans-US,pt-PT,fr-CAstayundefined.localeSelfName: the five codes move from the runtime display name to the table label (see Acceptance notes); the other nine unchanged.admitsidentical for all 14 codes; options move only where a stored or offered code is one of the five.notOfferedCopy: unchanged for all 14.storageTestCopyLocaleOf: unchanged for all 14.Acceptance notes
content/docs/protocol/kernel/i18n-standard.mdx(platform locale table: script-subtag codes (zh-Hant-TW, zh-Hans-CN, zh-Hant-HK) are not read aliases, so a two-script bundle answers them with the first registered zh-* key #30618 comment 6671045459), and commit6a1d4627edits that section only: the five rows, the closed-list sentence made true, and the ladder paragraphs rewritten against the code (see What changes). So theSkills-docs:line isnone, and the follow-up the earlier body owed is closed.e731b654) asked that the key-side move be pinned and stated. Commitd8713f3fpins it in core's shared list and in spec's table-step cases, both registration orders, with the one-script control, and adds the changeset sentence. FROM was measured onmainfirst; it agrees with the review's three rows (zh-TWoveren, zh-CN, zh-Hant-TW:zh-CN→zh-Hant-TW;zh-Hant-TWoveren, zh, zh-Hant-HK:zh→zh-Hant-HK; controlzh-Hant-TWoveren, zh-CN:zh-CN, unchanged).zh-Hant-US,zh-Hans-US) has no row, so it keeps the old path: over service-storage's shipped bundle it reacheszh-CN, the firstzh-*key, for either script. That is the decision of record on this card (enumerated rows only).platformLocaleTagOf/PLATFORM_LOCALE_READ_ALIASES(git grep, three non-test call sites; the map itself is read only insideplatform-locales.ts):packages/spec/src/system/i18n-resolver.tsL569/L573 (resolveLocaleAmongtable step): moves, as the tables above, on the request side (L569) and on the key side (L573).packages/services/service-settings/src/localization-locale-options.tsL67 (localeSelfName): moves. The five codes are named from the table (zh-Hant-TW中文(繁體,台灣) → 繁體中文,zh-Hant-HK中文(繁體字,中國香港特別行政區) → 繁體中文,zh-Hans-CN中文(简体,中国) → 简体中文, likewisezh-Hans-SG,zh-Hant-MO). ThroughresolveOfferedLocale, a storedzh-Hant-TWover offereden, zh-CN, zh-Hantused to take the place of the 简体中文 option (zh-Hant-TW=简体中文) and now sits on 繁體中文 (zh-CN=简体中文,zh-Hant-TW=繁體中文); a storedzh-Hans-CNoveren, zh-Hant, zh-CNmoved the same way. The accepted set (admits) is unchanged for all 14 probed codes in 4 scenarios, andnotOfferedCopyis unchanged.packages/services/service-storage/src/storage-test-copy.tsL152 (storageTestCopyLocaleOf): does not move. Its subtag truncation already reached the same tag (zh-Hant-TW→zh-Hant), for all 14 probed codes.mainmerge: service-storage's object translations (zh-CNregistered beforezh-Hant, from i18n(service-storage): ship the file and upload-session objects in all eleven platform languages #30649) now serve azh-Hant-TW/zh-Hant-HK/zh-Hant-MOreader thezh-Hantobjects; the row-less controlzh-Hant-USstill reacheszh-CN.Clause-②: yes (widening): the published map andPlatformLocaleReadAliasgain five keys, nothing removed or narrowed (check:api-surfacegreen: the snapshot records names and kinds); the key-side move is a widening too.Metadata-protocol: semantic: no key or value is added to what an author writes, but a bundle key or translation item an author keyszh-Hant(orzh-CN/zh-Hans) now serveszh-Hant-*(orzh-Hans-*) readers it did not serve over a two-script bundle, and a key an author spellszh-Hant-TWis now read aszh-Hant. Levelminoron@objectstack/spec, the one package the diff moves.dist/half, and is not a reading reported here. Its mutation landed, but the spec build in the mutated leg never got the shared lock (VERDICT queue-timeout (exit 99)), sodist/still carried the rows. Every later leg aborts unless the build verdict iscommand-exit 0and the dist preflight passes; both held in this round's run.resolveLocaleAmong's step 3 (i18n-resolver.ts) and core'sresolveLocale/resolveOfferedLocaledocblocks givezh-TW/zh-HKexamples, not an exhaustive list. The unreleased.changeset/30001-platform-locale-table.mdsays the map is "typed on its ten literal keys", which is true of that change; this changeset states the five added.skip-changesetdoes not apply (the diff publishes@objectstack/spec).Generated by Claude Code
🤖 Generated with Claude Code
https://claude.ai/code/session_01L6bhgVugtCCwBs98FeR27P