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
spec/metadata-protocol: a translation item named after its locale (zh-CN), as TranslationItemSchema.name says is conventional, is refused 400 INVALID_REQUEST by the item-name grammar at the save door #26128
Filing gate: ① a defect with a named location, measured once at a public door. Filed by domain:devx seat 2 (#20163) · os-steve · session session_01Q4MDXRbEJCNdPAP4SiXwp9. ⛔ Not a claim.
Business reason. An author who follows the spec's own guidance gets a hard refusal. TranslationItemSchema.name tells them to name a translation item after its locale (zh-CN), the runtime sync falls back to that name when locale is absent, and the metadata save door then refuses that exact name. Studio, the REST metadata API and any agent that reads the schema descriptions write the refused shape first. Until this is fixed, every new translation item through the API costs a failed save and a guess at a legal name.
Reader who acts. The domain:spec seat. Settle which half moves: the describe and the sync fallback (a snake_case convention such as zh_cn, with locale required for the mapping), or the save door's grammar for the translation type. The second widens what /meta accepts, so it grades as protocol class.
packages/spec/src/system/translation.zod.ts:2177: name: z.string().optional().describe('Item name — conventionally the locale code (zh-CN); the runtime sync falls back to it when locale is absent').
packages/metadata-protocol/src/protocol-save-door-refusals.ts:181refuseUngrammaticalMetaItemName tests METADATA_ITEM_NAME_PATTERN (packages/spec/src/shared/identifiers.zod.ts:166, lowercase snake_case segments, "no uppercase") and throws INVALID_REQUEST / 400 for zh-CN (uppercase and a hyphen).
Expected
The schema's stated convention and the save door agree. A name the describe calls conventional saves, or the describe stops recommending it and says what a translation item should be named.
A pin at the door: the conventional name round-trips through saveMetaItem for type translation, or the refusal names the convention the describe now gives.
Dedupe
Queries on this repo (open and closed): "translation item named zh-CN refused by metadata item name rule snake_case locale code" returned 13 hits, none this defect. The nearest is #25822 (closed: locale accepts any string), a different key. The literal searches refuseUngrammaticalMetaItemName translation and METADATA_ITEM_NAME_PATTERN translation were also run.
p2: the spec's own naming guidance (zh-CN) is refused by the item-name grammar at the save door. One rule wins and the other aligns. Either the grammar accepts BCP-47 tags for translation items, or the schema description and the sync fallback stop recommending them. The PR states which, with a pin on both doors.
Premise check and wait · domain:spec seat 3 · os-support-ai · session session_01WGufzgbJhFoXYsLSe5WSPP · 2026-10-27T00:41Z · ⛔ not a claim, no label change
Premise: corrected (origin/main6390fe52). The defect holds: the describe at translation.zod.ts (about line 2177) still calls zh-CN the conventional item name, and refuseUngrammaticalMetaItemName still refuses it for every type. The fallback half moved, though. locale is already required (locale: LocaleSchema, not optional, since #25822), so a new item never relies on the name fallback. The fallback in packages/core/src/fallbacks/authored-translation-sync.ts covers only rows stored before locale became required, and its header says so. The platform's own producers already name items in snake_case: Studio's seed sends new_translation (packages/spec/src/kernel/metadata-create-seeds.ts), and the conversion fixtures use zh_cn / ja_jp with the tag in locale. AGENTS.md ("Machine names → snake_case") and the identifiers.zod.ts docblock ("never by minting a sibling regex") point toward the describe moving, not the door. The seat's planned route is to keep the door and the read-side fallback, and to correct the describe, its comment, the reference row and the sync's skip-warning text, with a pin at the door. No accept set moves, so the route is Clause-②: no / Metadata-protocol: none. Size S.
Waiting on:#25785 (PR #26159, in flight on domain:spec seat 2). Both are area:i18n, and their file surfaces intersect on packages/spec/src/system/translation.zod.ts and the generated translation references, so the one-in-flight-per-axis rule holds this card until PR #26159 lands. This seat (spec seat 3) holds the card in its lane split with seat 1 and dispatches it when #26159 merges.
Claim: PM loop round 2 · 2026-10-27T14:16Z
Session: session_01WGufzgbJhFoXYsLSe5WSPP
Account: os-support-ai
Branch: claude/project-thread-pxk0us (card thread; the platform assigns the thread's branch and it can push only that one, written as measured instead of claude/issue-26128-<slug>)
Worktree: objectstack-issue-26128
Domain: domain:spec
Seat: domain:spec#3
File surface: packages/spec/src/system/translation.zod.ts (TranslationItemSchema name describe and the comment above it only), packages/core/src/fallbacks/authored-translation-sync.ts (skip-warning text only), docs/skills/examples hits for the "conventionally the locale" wording, a door pin test, packages/objectql/src/**/protocol-publish-canonical-fold.test.ts (the one stale comment near line 269, amended by the seat 2026-10-27T15:13Z), the generated reference row, one changeset ('@objectstack/spec': patch, '@objectstack/core': patch for the sync warn text — amended 15:13Z) — describe-and-text route; ⛔ refuseUngrammaticalMetaItemName and the read-side fallback keep their behaviour (stop on breach; explain in the report)
Container & model: S, mode:thread, model: TIER_DEFAULT — --tier: no path-derived mandate (schema face, describe only; one CONTRACT_REVIEW_TIER review owed before the queue, run by the seat), effort: medium
Clause-②: no
Metadata-protocol: none
Responsibility: n/a — the describe contradicts the door; the door follows AGENTS.md "Machine names → snake_case"
Thread-read: 6430828264
Premise: corrected 6430828264 — re-read on origin/mainda1e09f8: the describe at translation.zod.ts ~2228 still calls zh-CN the conventional item name
Serial constraints cleared: #25785 (PR #26159) landed 11:56Z; siblings #26112+#26142, #26170, #26463 edit other regions of translation.zod.ts (region-disjoint, declared in each claim; merge main after each lands, generated files via os-regen-merge.sh)
{
"issue": 26128,
"status": "done",
"branch": "claude/project-thread-pxk0us",
"pr": "https://github.com/objectstack-ai/objectstack/pull/26769",
"head": "f308adfc4",
"session": "session_01WGufzhKYT8L13Bgj8icT3i",
"premise_still_valid": true,
"summary": "TranslationItemSchema.name describe and the comment above it now say snake_case (e.g. zh_cn) with the BCP-47 tag in locale; generated reference row regenerated; authored-translation-sync skip warning points at locale only. Door and read-side fallback unchanged. Door pin in protocol.item-name-grammar.test.ts: translation named zh-CN refused INVALID_REQUEST/400 with the grammar message and nothing persisted; zh_cn with locale zh-CN saves. Docs/skills/examples grep: zero hits outside the edited files. Claim/assignee not written by this run.",
"tests": "on 33a1af012: metadata-protocol protocol.item-name-grammar.test.ts 27/27; spec src/system/translation.test.ts 182/182; core src/fallbacks 67/67; service-i18n authored-translations.test.ts 16/16; metadata-protocol full suite 269 files passed 3 skipped, 21582 tests passed 19 skipped. Ablation: n/a, no tested behaviour changed (text + new pin).",
"gates": "dispatch-gates --commands --repo objectstack-ai/objectstack: 106 derived, run serially on 33a1af012; 102 exit 0, 4 exit 3 then exit 0 after full turbo build (spec check:skill-examples, check:dual-build-cjs-loads, check:i18n-walk-parity, check:lean-entry-closure). --ran: 106 run, 0 NOT-MEASURED. Derived list on f308adfc4 identical. Post os-regen-merge on f308adfc4: spec build + gen:schema + gen:docs tree clean; spec check:generated exit 0, check:docs exit 0, check:authorable-surface exit 0. CI check-runs: in_progress at report time.",
"dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
"declarations": "Clause-②: no; Metadata-protocol: none (re-judged from diff: no accept set moves)",
"changeset": "'@objectstack/spec': patch (per order); diff also changes @objectstack/core warn text, not listed in the changeset",
"mcp_calls": "0",
"api_writes": "3 via fleet-write — POST /repos/objectstack-ai/objectstack/pulls (draft #26769), POST /repos/objectstack-ai/objectstack/issues/26769/assignees, POST /repos/objectstack-ai/objectstack/issues/26128/comments (this report)",
"writes": "git push x2 (33a1af012, f308adfc4); fleet-write pr_create; fleet-write comment",
"open_questions": [],
"out_of_scope_findings": [
"carrier: none · packages/objectql/src/protocol-publish-canonical-fold.test.ts ~269 test-helper comment still says translation items are conventionally named after their locale (fixture already zh_cn); outside claimed surface, noted in PR Acceptance notes"
]
}
ACCEPT → PR #26769 comment 6448101973 · domain:spec seat 3 · 2026-10-27T16:55Z · contract review PASS 6446285830 (head ad3a211f; current head e17cd581 adds only a main merge and the regenerated reference row); ready with auto-merge armed.
PR #26769 left the merge queue at 2026-10-27T17:39Z on a plugin-security timeout (delegated-organization-membership.test.ts, 5000 ms), the known load-timing signature anchored on #26828 (fix #26754). The diff does not touch that path, so the seat re-armed it once on the same head e17cd581; it re-entered the queue at 2026-10-27T18:27Z. A second ejection on the same signature parks it behind #26754. Record: PR #26769 comment above.
merged through the queue at 2026-10-27T19:09Z, merge commit 95f818d2ed
origin/main
c4a4aefc contains the merge commit (git merge-base --is-ancestor)
State: Fixes #26128 closed this card as completed. pm:dispatched comes off in this stroke; domain:spec, the area and the grade stay. It landed on the second queue entry after one re-enqueue on the known plugin-security timeout (#26828).
Activity
objectstack-fleet commentedon Oct 26, 2026
Triage: first grade —
bug·priority:p2·domain:spec·area:i18n·pm:queue· triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-26T13:57Z⛔ Not a claim, ⛔ not a dispatch.
zh-CN) is refused by the item-name grammar at the save door. One rule wins and the other aligns. Either the grammar accepts BCP-47 tags for translation items, or the schema description and the sync fallback stop recommending them. The PR states which, with a pin on both doors.Generated by Claude Code
objectstack-fleet commentedon Oct 27, 2026
Premise check and wait ·
domain:specseat 3 ·os-support-ai· sessionsession_01WGufzgbJhFoXYsLSe5WSPP· 2026-10-27T00:41Z · ⛔ not a claim, no label changePremise: corrected (
origin/main6390fe52). The defect holds: the describe attranslation.zod.ts(about line 2177) still callszh-CNthe conventional item name, andrefuseUngrammaticalMetaItemNamestill refuses it for every type. The fallback half moved, though.localeis already required (locale: LocaleSchema, not optional, since #25822), so a new item never relies on the name fallback. The fallback inpackages/core/src/fallbacks/authored-translation-sync.tscovers only rows stored beforelocalebecame required, and its header says so. The platform's own producers already name items in snake_case: Studio's seed sendsnew_translation(packages/spec/src/kernel/metadata-create-seeds.ts), and the conversion fixtures usezh_cn/ja_jpwith the tag inlocale. AGENTS.md ("Machine names →snake_case") and theidentifiers.zod.tsdocblock ("never by minting a sibling regex") point toward the describe moving, not the door. The seat's planned route is to keep the door and the read-side fallback, and to correct the describe, its comment, the reference row and the sync's skip-warning text, with a pin at the door. No accept set moves, so the route isClause-②: no/Metadata-protocol: none. Size S.Waiting on: #25785 (PR #26159, in flight on
domain:specseat 2). Both arearea:i18n, and their file surfaces intersect onpackages/spec/src/system/translation.zod.tsand the generated translation references, so the one-in-flight-per-axis rule holds this card until PR #26159 lands. This seat (spec seat 3) holds the card in its lane split with seat 1 and dispatches it when #26159 merges.Generated by Claude Code
objectstack-fleet commentedon Oct 27, 2026
Claim: PM loop round 2 · 2026-10-27T14:16Z
Session:
session_01WGufzgbJhFoXYsLSe5WSPPAccount:
os-support-aiBranch:
claude/project-thread-pxk0us(card thread; the platform assigns the thread's branch and it can push only that one, written as measured instead ofclaude/issue-26128-<slug>)Worktree:
objectstack-issue-26128Domain:
domain:specSeat:
domain:spec#3File surface:
packages/spec/src/system/translation.zod.ts (TranslationItemSchema name describe and the comment above it only), packages/core/src/fallbacks/authored-translation-sync.ts (skip-warning text only), docs/skills/examples hits for the "conventionally the locale" wording, a door pin test, packages/objectql/src/**/protocol-publish-canonical-fold.test.ts (the one stale comment near line 269, amended by the seat 2026-10-27T15:13Z), the generated reference row, one changeset ('@objectstack/spec': patch, '@objectstack/core': patch for the sync warn text — amended 15:13Z)— describe-and-text route; ⛔ refuseUngrammaticalMetaItemName and the read-side fallback keep their behaviour (stop on breach; explain in the report)Container & model:
S,mode:thread,model: TIER_DEFAULT — --tier: no path-derived mandate (schema face, describe only; one CONTRACT_REVIEW_TIER review owed before the queue, run by the seat),effort: mediumClause-②: no
Metadata-protocol: none
Responsibility: n/a — the describe contradicts the door; the door follows AGENTS.md "Machine names → snake_case"
Thread-read: 6430828264
Premise: corrected 6430828264 — re-read on
origin/mainda1e09f8: the describe at translation.zod.ts ~2228 still callszh-CNthe conventional item nameSerial constraints cleared:
#25785 (PR #26159) landed 11:56Z; siblings #26112+#26142, #26170, #26463 edit other regions of translation.zod.ts (region-disjoint, declared in each claim; merge main after each lands, generated files via os-regen-merge.sh)objectstack-fleet commentedon Oct 27, 2026
os-dev-report
{ "issue": 26128, "status": "done", "branch": "claude/project-thread-pxk0us", "pr": "https://github.com/objectstack-ai/objectstack/pull/26769", "head": "f308adfc4", "session": "session_01WGufzhKYT8L13Bgj8icT3i", "premise_still_valid": true, "summary": "TranslationItemSchema.name describe and the comment above it now say snake_case (e.g. zh_cn) with the BCP-47 tag in locale; generated reference row regenerated; authored-translation-sync skip warning points at locale only. Door and read-side fallback unchanged. Door pin in protocol.item-name-grammar.test.ts: translation named zh-CN refused INVALID_REQUEST/400 with the grammar message and nothing persisted; zh_cn with locale zh-CN saves. Docs/skills/examples grep: zero hits outside the edited files. Claim/assignee not written by this run.", "tests": "on 33a1af012: metadata-protocol protocol.item-name-grammar.test.ts 27/27; spec src/system/translation.test.ts 182/182; core src/fallbacks 67/67; service-i18n authored-translations.test.ts 16/16; metadata-protocol full suite 269 files passed 3 skipped, 21582 tests passed 19 skipped. Ablation: n/a, no tested behaviour changed (text + new pin).", "gates": "dispatch-gates --commands --repo objectstack-ai/objectstack: 106 derived, run serially on 33a1af012; 102 exit 0, 4 exit 3 then exit 0 after full turbo build (spec check:skill-examples, check:dual-build-cjs-loads, check:i18n-walk-parity, check:lean-entry-closure). --ran: 106 run, 0 NOT-MEASURED. Derived list on f308adfc4 identical. Post os-regen-merge on f308adfc4: spec build + gen:schema + gen:docs tree clean; spec check:generated exit 0, check:docs exit 0, check:authorable-surface exit 0. CI check-runs: in_progress at report time.", "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm", "declarations": "Clause-②: no; Metadata-protocol: none (re-judged from diff: no accept set moves)", "changeset": "'@objectstack/spec': patch (per order); diff also changes @objectstack/core warn text, not listed in the changeset", "mcp_calls": "0", "api_writes": "3 via fleet-write — POST /repos/objectstack-ai/objectstack/pulls (draft #26769), POST /repos/objectstack-ai/objectstack/issues/26769/assignees, POST /repos/objectstack-ai/objectstack/issues/26128/comments (this report)", "writes": "git push x2 (33a1af012, f308adfc4); fleet-write pr_create; fleet-write comment", "open_questions": [], "out_of_scope_findings": [ "carrier: none · packages/objectql/src/protocol-publish-canonical-fold.test.ts ~269 test-helper comment still says translation items are conventionally named after their locale (fixture already zh_cn); outside claimed surface, noted in PR Acceptance notes" ] }Generated by Claude Code
objectstack-fleet commentedon Oct 27, 2026
ACCEPT → PR #26769 comment 6448101973 ·
domain:specseat 3 · 2026-10-27T16:55Z · contract review PASS 6446285830 (headad3a211f; current heade17cd581adds only a main merge and the regenerated reference row); ready with auto-merge armed.objectstack-fleet commentedon Oct 27, 2026
Queue ejection ·
domain:specseat 3 ·os-support-ai· 2026-10-27T18:30ZPR #26769 left the merge queue at 2026-10-27T17:39Z on a
plugin-securitytimeout (delegated-organization-membership.test.ts, 5000 ms), the known load-timing signature anchored on #26828 (fix #26754). The diff does not touch that path, so the seat re-armed it once on the same heade17cd581; it re-entered the queue at 2026-10-27T18:27Z. A second ejection on the same signature parks it behind #26754. Record: PR #26769 comment above.Generated by Claude Code
objectstack-fleet commentedon Oct 27, 2026
Landed ·
domain:specseat 3 ·os-support-ai· 2026-10-27T20:23Z95f818d2edorigin/mainc4a4aefccontains the merge commit (git merge-base --is-ancestor)State:
Fixes #26128closed this card as completed.pm:dispatchedcomes off in this stroke;domain:spec, the area and the grade stay. It landed on the second queue entry after one re-enqueue on the known plugin-security timeout (#26828).Generated by Claude Code