Skip to content

feat(spec)!: a single-word language name (Chinese, English, Japanese) is refused as a locale - #26770

Merged
objectstack-fleet[bot] merged 6 commits into
mainfrom
claude/project-thread-zxzeeg
Oct 27, 2026
Merged

objectstack-fleet[bot] merged 6 commits into
mainfrom
claude/project-thread-zxzeeg

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Yibo Wang · project thread
Fixes #26463

Clause-②: no (narrowing)
Metadata-protocol: narrowed
Skills-docs: none — content/docs/ui/translations.mdx and content/docs/protocol/kernel/i18n-standard.mdx already say a language name is refused (this diff makes that sentence true), and skills/objectstack-i18n/SKILL.md already teaches tag-shaped codes only (en, en-US, zh-CN, pt-BR); nothing taught there changes

维护者速读

  • 改了什么:locale 的主语言子标签从 2–8 个字母收紧为 2–3 个字母,Chinese、English、Japanese 这类单词语言名现在被拒;spec、sys_user.locale 列规则、通知读侧三处同一字符串同步改。
  • 为什么改:作者写 locale: 'Chinese' 能保存成功,但没有会话会请求这个 locale,译文永远不显示;拒收文案和 spec: a translation item accepts any locale string ("not a locale!!" saves 200, valid) — LocaleSchema is a bare z.string() #25822 的 changeset 早已承诺「语言名会被拒」。
  • 风险与回滚:已存为 Chinese 之类的翻译行或用户 locale,解析时会被拒(存量行照常加载并由 os migrate meta --stored 列为 TODO);回滚即还原这三处正则。
  • 先看:packages/spec/src/system/translation.zod.ts(正则与拒收文案)、packages/platform-objects/src/identity/sys-user.object.ts(列规则)、packages/services/service-messaging/src/recipient-locale.ts(读侧副本与 null 说明)。
  • 两分钟验证:pnpm --filter @objectstack/spec exec vitest run src/system/translation.test.ts,预期 Chinese/English/Japanese 三行拒收、en/zh-CN/zh-Hans-CN/es-419 通过。
  • 需要你做的:无,席位落地。

What changes

LOCALE_TAG_SHAPE accepted a 2–8 letter language subtag, so any single English word of that length passed as a locale, though LOCALE_TAG_REFUSAL and the #25822 changeset both say a language name is refused. The primary subtag is now 2–3 letters, the ISO 639 codes every tag in use starts with: BCP-47 reserves 4 letters and registers no 5–8 letter language. Hyphen subtags, zh-Hans-CN, es-419, yue-HK and case folding are unchanged.

The one shape lives in three places, and all three move in the same commit, still byte-identical:

Copy Role Edit
packages/spec/src/system/translation.zod.ts LOCALE_TAG_SHAPE LocaleSchema: translation item locale, bundle keys, i18n.* locales, seed locale pattern; docblock and refusal text re-read so each sentence is true (the refusal now names Chinese and says write the tag, not the name)
packages/platform-objects/src/identity/sys-user.object.ts SYS_USER_LOCALE_TAG_PATTERN the locale_bcp47_shape rule on sys_user.locale pattern and docblock
packages/services/service-messaging/src/recipient-locale.ts LOCALE_TAG_SHAPE read side for a recipient's notification locale pattern; docblock: null is now shape-refused on both sides, NOTHING_LITERALS stays as the read side's own floor

Also: the 18.x D3 entry translation-locale-non-tag-refused described the replacement as "a 2-8 letter language subtag"; this diff made that false, so it now reads 2-3 (one word). Its conversion already judges with LocaleSchema, so a stored item under Chinese is now listed as a TODO with no further change.

ADR-0087 disposition: not-required (already-registered translation-locale-non-tag-refused) in the changeset. The D3 entry already prescribes rewriting a language name by hand; this diff narrows the same shape.

Copies of the pattern deliberately not moved

  • packages/plugins/plugin-hono-server/src/current-user-endpoints-localization.test.ts:69: a fixture rule. Its own docblock says what is under test is that the endpoint evaluates whatever rule the registry declares, and none of its 13 cases depends on a 4–8 letter subtag (all 13 pass unchanged). Outside the claim's file surface.
  • ui/packages/i18n/src/provider.tsx:224: the no-Intl fallback of isWellFormedLanguageTag. The main branch is Intl.getCanonicalLocales, which accepts Chinese; narrowing only the fallback would make the two branches disagree. It reads a UI language preference, not stored metadata.
  • ui/packages/app-shell/src/views/metadata-admin/previews/doc-draft.ts:28: add-locale input hygiene for a doc's translations map, which the spec keys by any string. A different contract, outside the claim's file surface.

Tests

  • packages/spec/src/system/translation.test.ts: refusal rows Chinese, English, Japanese, chinese-CN, null (each an invalid_format issue whose message names the shape and the release); controls en, zh-CN, zh-Hans-CN, es-419, yue-HK, zh-cn accepted; the card's reproduction at the item door (locale: 'Chinese' refused at locale only) and a Chinese bundle key refused.
  • packages/plugins/plugin-auth/src/sys-user-locale-write-contract.test.ts: the shape-not-membership pin is rewritten. Japanese is now refused by the column (VALIDATION_FAILED), and a well-formed tag nothing ships (tlh-QQ) is still accepted, which keeps the pin about shape, not membership.
  • packages/services/service-messaging/src/recipient-locale-shape-parity.test.ts: source equality unchanged; behavioural rows gain Chinese, Japanese, null; the null case now pins that both sides refuse it by shape and the read side refuses it anyway.

Acceptance notes

Verification

All readings on head 84506a0c (this branch merged with main 5cc31c78) unless noted.

Tests and typecheck
  • Before the merge, on ee3058c2: pnpm --filter @objectstack/spec test 731 files, 21928 passed, 1 todo; @objectstack/service-messaging test 61 files, 732 passed; @objectstack/plugin-auth test 198 files, 3780 passed, 10 skipped; @objectstack/platform-objects test 96 files, 1361 passed; plugin-hono-server src/current-user-endpoints-localization.test.ts 13 passed.
  • typecheck exit 0 for spec, platform-objects, service-messaging and plugin-auth (plugin-auth after a full build; its examples leg needs its own dist).
  • After the merge, on 84506a0c: src/system/translation.test.ts 189 passed; platform-objects 96 files, 1361 passed; recipient-locale-shape-parity.test.ts 19 passed; sys-user-locale-write-contract.test.ts 24 passed.
  • pnpm build: 116 of 116 tasks; pnpm --filter @objectstack/spec check:generated: all 14 generated artifacts up to date (no regeneration commit needed).
Ablation (one-time, not kept)

node scripts/ablation-replace.mjs put the spec pattern back to the 2–8 letter subtag (anchor hit 1 to 0, blob fa4a2333 to 1108375e) and ran src/system/translation.test.ts: 6 failed, 183 passed. The red rows are Chinese, English, Japanese, chinese-CN, null and the door test that carries the card's reproduction. Restored: blob equals HEAD (fa4a2333) and git diff HEAD is empty. The test imports src, so no build leg applies.

Derived gates

node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 87 families on 84506a0c. Each was run and recorded as CMD :: exit N: all 87 exit 0. --ran reconciliation: 87 derived, 87 run, 0 NOT-MEASURED, 0 UNRUN. check-adr-0087-registration --base origin/main: one declared-breaking changeset, disposition not-required (already-registered).

Dogfood battery

pnpm --filter @objectstack/dogfood test under the verify lock, after a full build. On 84506a0c: VERDICT command-exit 0, 302 files passed and 3 skipped (305), 2505 tests passed and 20 skipped (2525). Also on the pre-merge head 32f73697: the same counts.

main gained six more commits after the merge (none touch the eight files here); CI judges the merge ref.


Generated by Claude Code

The locale shape's 2–8 letter language subtag admitted any single word
(Chinese, English, Japanese), though the refusal text says a language
name is refused. The subtag is now 2–3 letters in LocaleSchema,
SYS_USER_LOCALE_TAG_PATTERN and service-messaging's read-side copy.

Claude-Session: https://claude.ai/code/session_01WGufziYkxRFm6oPR7CmuDg
Co-authored-by: Claude <noreply@anthropic.com>
…eady-registered)

Claude-Session: https://claude.ai/code/session_01WGufziYkxRFm6oPR7CmuDg
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

3 anchor(s) derived from 3 changed package(s); no hand-written page names any of them, so this run has nothing to list — not a clean bill of health. This check sees only pages that NAME a derived anchor: one that documents this change in prose, or enumerates it in an authoring dialect, names none and stays invisible to it on every run.

What this run could not see

Coarse fallback — 148 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json 83c4bd29f7ee653f10f4b83f61e36a1aeb8292d9 → packageMentionDocs.

Which tree this was computed on

This run read content/docs from 2e345bb42ce6902a7343d86363f582abe9c24d99 — the merge of head 25fe0e3fc0f28f718149dcdf8b372a2c9d1a91cb into base 83c4bd29f7ee653f10f4b83f61e36a1aeb8292d9, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 2e345bb42ce6902a7343d86363f582abe9c24d99 && git checkout 2e345bb42ce6902a7343d86363f582abe9c24d99
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 83c4bd29f7ee653f10f4b83f61e36a1aeb8292d9 25fe0e3fc0f28f718149dcdf8b372a2c9d1a91cb && git checkout -B drift-repro 83c4bd29f7ee653f10f4b83f61e36a1aeb8292d9 && git merge --no-ff 25fe0e3fc0f28f718149dcdf8b372a2c9d1a91cb

node scripts/docs-audit/affected-docs.mjs --json 83c4bd29f7ee653f10f4b83f61e36a1aeb8292d9

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 84506a0c0ad07c60295dcde5e63d63ae10c54910
Local-runs: none
Scope: packages/spec/src/system/translation.zod.ts, packages/spec/src/migrations/entries/semantic/18.translation-locale-non-tag-refused.ts, packages/spec/src/system/translation.test.ts, packages/platform-objects/src/identity/sys-user.object.ts, packages/services/service-messaging/src/recipient-locale.ts, packages/services/service-messaging/src/recipient-locale-shape-parity.test.ts, packages/plugins/plugin-auth/src/sys-user-locale-write-contract.test.ts, .changeset/26463-locale-language-name.md + packages/plugins/plugin-hono-server/src/current-user-endpoints-localization.test.ts, ui/packages/i18n/src/provider.tsx, ui/packages/app-shell/src/views/metadata-admin/previews/doc-draft.ts, packages/spec/src/system/doc.zod.ts, packages/objectql/src/validation/rule-validator.ts, scripts/check-adr-0087-registration.mjs, content/docs/ui/translations.mdx, content/docs/protocol/kernel/i18n-standard.mdx, skills/objectstack-i18n/SKILL.md

Inputs read: card #26463 body and all four comments (triage 6434121727, premise 6434443639, claim 6442902707, os-dev-report 6445697484); PR #26770 body, file list (8 paths, +97/-49), its one comment (docs-drift 6445696117; no review comments, no reviews), the net diff against main at the head; the head tree fetched into a ref of my own and read with git show / git grep; the check-runs on the head, read at 2026-10-27T15:14Z and again at 15:22Z (the reading at post time is in ③).

① Derived judgments

Shape. The one change is the primary-subtag width, {2,8} to {2,3}; every other part of the grammar ((?:-[A-Za-z0-9]{1,8})*, both anchors, no flags) is byte-unchanged. The claim that "BCP-47 reserves 4 letters and registers no 5–8 letter language" is accurate (RFC 5646 §2.2.1), so the new shape admits every registered tag and refuses only words. Census of the head tree, non-test code, quoted values on locale / defaultLocale / fallbackLocale / supportedLocales lines across examples/**, packages/**, ui/**, skills/**: en, zh-CN, en-US, ja-JP, es-ES, zh, de-DE, pt-br, fr-FR, de-CH, de, and default (the last only as ui/packages/plugin-calendar prop defaults handed to Intl, never to LocaleSchema). Bundle filenames: en, zh-CN, ja-JP, es-ES. UI builtInLocales: en zh ja ko de fr es pt ru ar. No 4–8 letter primary subtag anywhere a shipped value lives; the test-file sweep finds only the plugin-auth pin itself, the new spec rows, and i18n-label-resolver.test.ts keys (toString, valueOf) that never reach LocaleSchema. Read against the regex: zh-Hans-CN, es-419, en-US pass (pinned at translation.test.ts:50, plugin-auth :127–132, parity :59); the 3-letter class (yue-HK pinned in all three files; fil, haw, art-lojban by the same clause) passes; an extension form (en-US-u-ca-gregory) passes since each subtag is 1–8 alphanumerics; a bare private-use x-… failed the old shape too (one letter) and none is in use. Chinese, English, Japanese, chinese-CN, null are refused with invalid_format and a message naming the shape and the release (translation.test.ts:58–71); Chinese is refused at the item door at path locale only and as a bundle key (:80–82, :91). The refusal text (translation.zod.ts:37–42) now says 2–3, names Chinese and says "write the tag, not the name" — each sentence is true of the code under it; it carries no tracker number.

Byte-identity. On the head, git grep for the shape finds exactly three {2,3} copies — translation.zod.ts:35, sys-user.object.ts:39, recipient-locale.ts:115 — and all three read ^[A-Za-z]{2,3}(?:-[A-Za-z0-9]{1,8})*$. The parity test's source-equality half (LOCALE_TAG_SHAPE.source against the string, flags '', parity :48–56) is unchanged and still the assertion that cannot miss a divergence. Left behind, and exactly the three the dev named: plugin-hono-server current-user-endpoints-localization.test.ts:69 (a fixture row), ui/packages/i18n/src/provider.tsx:224 (the no-Intl fallback), ui/.../previews/doc-draft.ts:28 (add-locale hygiene). Judged each in ③. Two other {2,3} regexes on the head (packages/cli/src/utils/collect-docs.ts:118, ui/.../machineLocaleCensus-9909.test.ts:199) are different grammars for different jobs, not copies.

The two contrary pins. The seat's reading of the 2026-09-03 ruling holds: the ruling's quoted clause is "a malformed value is refused loudly by the column's BCP-47 shape check … and never dead-letters a notification", a shape check with no subtag length fixed; the quotation stays verbatim in the plugin-auth header (:4–11) and in the parity header (:7–14). The rewritten plugin-auth pin (:205–217) refuses Japanese with VALIDATION_FAILED AND accepts tlh-QQ, so it still guards "shape, not membership" and the ruling's second clause (an unknown tag falls to the ladder's floor rather than dead-lettering); its comment explains the width honestly. The rewritten parity pin (:72–84) inverts null on both sides and keeps normalizeRecipientLocale('null') undefined; NOTHING_LITERALS stays (recipient-locale.ts:122) and the docblock (:99–109) now says truthfully that it no longer changes an answer and is kept as the read side's own floor against a future widening. Both pins still guard what the ruling protects.

ADR-0087. The disposition not-required (already-registered translation-locale-non-tag-refused) is the honest one: the entry exists at the merge base and at the head, the gate's rule for that category is exactly those two facts (check-adr-0087-registration.mjs:143–146, 5166–5190), and CI ran it with --base inside Check Changeset (pr-automation.yml:1017–1018), success at 15:12:36Z. Editing the registered D3 entry is legitimate here: it is the same major (18), the same retirement family and the same prescription (rewrite a language name by hand); the edit changes one number in replacement so the sentence matches the shape it describes, which is a correction, not the reversal Prime Directive 13 reserves for a new ADR; D4 projections are generated at publish, so no committed artifact goes stale (the dev's check:generated all-current reading is consistent with that); check-closed-ceremony-text.mjs pins a different entry only. Coverage: the entry's surface names translation items, bundle keys, the i18n configuration, seed datasets and the seed loader — the metadata surfaces — and its conversion lists a stored Chinese translation row as a TODO through LocaleSchema. It does NOT name sys_user.locale, and it cannot: a user row is data, not sys_metadata, so os migrate meta --stored never sees it and ADR-0087 has no reach there by construction. What covers a stored sys_user.locale = 'Japanese' row is the code, read: the delivery side normalizes it to undefined and falls to the deployment default (recipient-locale.ts:130–135, 148–163), the current-user endpoint falls to the next rung (hono test :232–240 pins the class), checkFormat skips an update that omits the field (rule-validator.ts:4606), and a re-send of the value is refused loudly. The ruling's two properties hold for stored rows with no migration entry owed. The changeset's prose on this point is judged in ③.

Declarations. Clause-②: no (narrowing) and Metadata-protocol: narrowed appear line-initial in both the PR body and the changeset body. no (narrowing) is the legal spelling for a published accept set that shrinks ((narrowing) is BREAKING; no (widening) is the malformed pair), identical to the shipped precedent .changeset/25822-locale-tag-shape.md (read at 27f38ada^). Skills-docs: none is verified: content/docs/ui/translations.mdx:22–24 and content/docs/protocol/kernel/i18n-standard.mdx:244–246 already say a language name is refused at parse (this diff makes that true), skills/objectstack-i18n/SKILL.md names only tag-shaped codes (zh-CN ×19, en ×17, ja-JP, pt-BR, en-US, es-ES, zh), and no page under content/**, skills/**, .claude/skills/** or docs/** states the old 2–8 width.

② Semver level

minor on @objectstack/spec, @objectstack/platform-objects, @objectstack/service-messaging, with the BREAKING banner, a FROM → TO fix and the ADR-0087 marker. Agreed. The kind is narrowed, and the rule is that a kind takes at least minor on every package the diff moves: spec's LocaleSchema accept set shrinks; platform-objects' exported SYS_USER_LOCALE_TAG_PATTERN value and the locale_bcp47_shape rule tighten; service-messaging's exported LOCALE_TAG_SHAPE value tightens. No major (the repo ships none), and Check Changeset is green. Metadata-protocol: narrowed is the right kind for a value newly refused; Clause-②: no (narrowing) keeps the BREAKING banner on a non-widening change.

③ Boundary flags

  • Dev deviation: Clause-② corrected from the dispatch's yes (narrowing) to no (narrowing). Answered: correct. The seat rule and the shipped 25822 precedent both spell a narrowing of a published accept set as no (narrowing); the claim 6442902707 records the correction.
  • Dev deviation: main gained six commits after the pre-PR merge and the head was not re-merged. Answered: verified — git log 5cc31c78..origin/main -- (the eight files) is empty, 5cc31c78 is in the head's ancestry, and the PR's checks run on the merge ref (6f381985, named by the docs-drift comment); the queue rebuilds again. Acceptable.
  • Dev deviation: test comments cite #26463 at the seat's request. Answered: the no-tracker-number rule binds AGENTS.md, skill prose and runtime strings; test comments already cite #25822 on the adjacent rows, and LOCALE_TAG_REFUSAL carries no number. Acceptable.
  • Dev flag: hono-server fixture not moved (current-user-endpoints-localization.test.ts:69). Reason holds in behaviour: the test's own docblock says what is under test is that the endpoint evaluates whatever rule the registry hands it, and every stored value it iterates (Chinese (Simplified), undefined, zh_CN!, 42) fails both widths, so none of the 13 cases turns on {2,8}. It was outside the claim's file surface, so leaving it was the right act under "stop on breach". One sentence in that fixture's docblock (:59–60, "The column's own rule, as the registry hands it to the endpoint — the validations[] entry sys-user.object.ts declares") is now stale: the fixture carries a string the column no longer declares. Non-blocking; a note for the plugin-hono-server lane to import SYS_USER_LOCALE_TAG_PATTERN or restate the fixture as a stand-in.
  • Dev flag: ui/packages/i18n/src/provider.tsx:224 not moved. Reason holds: the main branch is Intl.getCanonicalLocales, whose grammar admits a 5–8 letter language subtag, so narrowing only the fallback would make the two branches disagree on the same input; it reads a UI language preference, not stored metadata, and a word finds no pack. Outside this contract. Noted, not filed, as the dev recorded.
  • Dev flag: doc-draft.ts:28 not moved. Reason holds: the doc's translations map is z.record(z.string(), …) (doc.zod.ts:136–138), a different contract keyed by any string. Outside this contract. The same silent-key class remains in that add-locale box for the ui lane; noted, not filed.
  • Reviewer flag: the changeset's Fix bullet. "os migrate meta --stored lists a stored row as a TODO (D3 entry translation-locale-non-tag-refused) and you rewrite it by hand" is true of a stored translation row and not of a stored sys_user.locale row, which that command never reads (see ①, ADR-0087). The D3 id in the same sentence scopes it for a careful reader, and the stored-row behaviour for a user is the ruling's own (floor, loud refusal on re-send, no dead-letter), so no contract is violated and no entry is owed. Non-blocking: the owning seat should tighten "a stored row" to "a stored translation row" before this text ships as CHANGELOG.md, or carry the precision into the release notes. Likewise Metadata-protocol: narrowed (… and a user's locale column) over-includes a data-validation rule under the metadata-protocol kind; the kind is unchanged by it.
  • Reviewer flag: the spec shape is now narrower than the BCP-47 grammar. By decision and said in the docblock (translation.zod.ts:27–32): the grammar's 5–8 letter language subtags have no registered member, so the spec trades an unregistered syntactic class for the refusal its own text promised. Consistent with Prime Directive 12 (reject at the producer, no consumer fallback) and with the entry's "syntax check only" sentence.
  • Gates. Read at 15:14Z and 15:22Z: Lint & Repo Gates success, Governed Surface Queue Guard success, Build & E2E UI success, Check Changeset success (carries check-adr-0087-registration --base), Lint UI skipped (paths filter), every Lint · and Type Check · source gates / debt ledger lane success, Test Core (8/8) success. Still in_progress at the second read: Build Core, Test Core (1–7/8), Type Check UI, Type Check · workspace, Type Check · consumer gates. Third read at 15:26Z, the one this record is posted on: Build Core success, TypeScript Type Check success, every Type Check · lane success, Test Core (8/8) success; still in_progress: Test Core (1/8) through (7/8) and Type Check UI; nothing red or cancelled. An in_progress gate is an honest reading, not a pass: this verdict is on the contract; landing still waits for every required check green, as Prime Directive 14 requires of the owning seat.

Implemented-by: claude/project-thread-zxzeeg
Reviewed-by: session_01WGufzgbJhFoXYsLSe5WSPP

VERDICT: PASS

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

维护者速读 (席位终稿)

  • 改了什么:locale 的主语言子标签从 2–8 个字母收紧到 2–3 个字母,Chinese、English、Japanese 这类语言名现在会被拒。spec、sys_user.locale 的列规则和通知读侧三处用的是同一个正则字符串,这次一起改。
  • 为什么改:作者写 locale: 'Chinese' 能保存成功,但没有会话会请求这个 locale,译文永远不会显示。拒收文案和 spec: a translation item accepts any locale string ("not a locale!!" saves 200, valid) — LocaleSchema is a bare z.string() #25822 的 changeset 早就承诺过「语言名会被拒」。
  • 风险与回滚:已存为语言名的翻译条目会由 os migrate meta --stored 列为待办,需要手改成标签。已存为语言名的用户 locale 照常加载,通知按部署默认语言发送,再次保存会被拒,直到改成标签为止。回滚 = revert 本 PR。
  • 先看:packages/spec/src/system/translation.zod.ts(正则与拒收文案)、packages/platform-objects/src/identity/sys-user.object.ts(列规则)、packages/services/service-messaging/src/recipient-locale.ts(读侧副本)。
  • 两分钟验证:pnpm --filter @objectstack/spec exec vitest run src/system/translation.test.ts,预期 Chinese / English / Japanese 被拒,en / zh-CN / zh-Hans-CN / es-419 通过。
  • 需要你做的:无,席位落地。

席位意见:接受。契约复核 PASS(6446067343)。有两个旧测试按旧的 2–8 写法断言了相反结论,席位依据 2026-09-03 维护者裁决裁定它们随本卡一起改:裁决要求的是形状检查,没有规定长度。

席位核对 · ACCEPT · domain:spec seat 3 · os-support-ai · session session_01WGufzgbJhFoXYsLSe5WSPP · 2026-10-27T16:57Z

Head: 25fe0e3fc0f28f718149dcdf8b372a2c9d1a91cb · card #26463 · claim 6442902707

  1. 形态: a draft PR to main with Fixes #26463 as its only closing keyword. 8 paths, +97 / −49. check-governed-merges --pr 26770: NOT governed, 146 lines ≤ 3000, so the ordinary queue landing applies. The file list is inside the claim surface: the three byte-identical copies of the shape, the two re-ruled pins, the spec refusal rows, the D3 migration entry and the changeset.
  2. 前提实测: the premise holds on 43731031. The review's census found no shipped locale with a 4–8 letter primary subtag, and zh-Hans-CN, es-419 and yue-HK pass (record ①1). The claim ruled on the two contrary pins: plugin-auth's Japanese-accepted pin and service-messaging's null-shape-legal pin. The review judged both rewritten pins honest. The plugin-auth pin still proves shape-not-membership by accepting tlh-QQ, and NOTHING_LITERALS stays as the read-side floor.
  3. 门禁 check-runs (on this head): 46 runs, 38 success, 8 skipped, none red or pending. The contract-tier review is PASS on 84506a0c (record 6446067343, narrowing face). After it, the head moved by two commits that change only .changeset/26463-locale-language-name.md (2528b68) and one merge of origin/main (25fe0e3f, after sibling PR feat(spec): a joined report's block headings and a master-detail field's inline grid heading are translatable #26757 landed; no regeneration was needed and check:generated is up to date). The dogfood battery ran full on this head and gave VERDICT 0, 304 files / 2516 tests.
  4. 接受的偏差: (a) Clause-②: no (narrowing), the seat rule for narrowing a published accept set, corrected from the dispatch order's yes in the claim. (b) Release text, changed after the review (a release-text-only change: the seat confirms it here instead of a second review). The changeset Fix bullet before: "so os migrate meta --stored lists a stored row as a TODO (D3 entry translation-locale-non-tag-refused) and you rewrite it by hand." After: "so os migrate meta --stored lists a stored translation row as a TODO (D3 entry translation-locale-non-tag-refused) and you rewrite it by hand. A user whose stored locale is already a name such as Japanese keeps loading: their notifications fall to the deployment default, and saving that value again is refused until it is replaced with a tag." The Metadata-protocol parenthetical before ended "…seed datasets and a user's locale column"; after, it ends "…the i18n configuration and seed datasets". The user column is data validation, not metadata protocol. Both changes make the text true per review ③5. (c) ADR-0087: not-required (already-registered translation-locale-non-tag-refused), with the D3 entry's subtag length corrected. The review judged that a same-major correction, and Check Changeset ran the gate green.
  5. 范围外去向: three copies of the pattern were left unmoved, each for a reason the review accepted: the hono-server fixture, the provider's Intl fallback and the doc-draft add-locale box. The hono fixture's docblock (around :59–60, "the column's own rule") is now stale. It is a test fixture with no published surface, so it is noted for the plugin-hono-server lane and not filed. Skills-docs: none is true, because the docs already say a language name is refused and the skill teaches tag-shaped codes only.
  6. 落地条款: the prose faces were checked sentence by sentence against the diff: the changeset's BREAKING Before / Now / Fix, as quoted in 4(b), and the refusal text, which now names Chinese and says to write the tag. Ready and auto-merge go through the relay in this act, and the seat follows the PR to MERGED.

Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation protocol:system size/m tests tooling

Projects

None yet

2 participants