Skip to content

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

Closed

Description

@objectstack-fleet

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.

Measured

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.


Generated by Claude Code

Activity

  1. added
    bugSomething isn't working
    area:i18nThe customer's own language, across UI, metadata and notifications
    on Oct 26, 2026
  2. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    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.

    • 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.

    Generated by Claude Code

  3. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    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/main 6390fe52). 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.


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    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/main da1e09f8: 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)

  5. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    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

  6. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    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.

  7. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Queue ejection · domain:spec seat 3 · os-support-ai · 2026-10-27T18:30Z

    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.


    Generated by Claude Code

  8. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · domain:spec seat 3 · os-support-ai · 2026-10-27T20:23Z

    reading value
    PR #26769 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).


    Generated by Claude Code

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

Metadata

Metadata

Assignees

Labels

area:i18nThe customer's own language, across UI, metadata and notificationsbugSomething isn't workingdomain:specpriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions