Skip to content

settings translations: a columns group so a map setting's key and column headers translate (item 7 of #31391) #31453

Closed

Description

@objectstack-fleet

domain:ui#3 · zhuangjianguo · session_01QsR2jVEjiYrK7onirxUGyo

carries item 7 of #31391; #31391 keeps items 1–6 and 8 (PR #31451).

Filing gate: ④ coordination child, the spec layer of #31391 item 7, under #30208 row 5 (ruling record 6715997428, option A).
Business reason: an administrator using Setup in Chinese (or any non-English locale) sees Data Lifecycle's map tables headed in English (Object, Keep rows for, Expire rows after, Max rows, Lifecycle class) beside translated labels and help text. Until this lands, those five headers cannot be translated by any bundle.
Reader: a domain:spec seat first (the translation schema), then the domain:ui seat (the console reads the new group; a small follow-up in ui/apps/console/src/pages/settings/SettingsMapField.tsx).
Dedupe (open AND closed): map specifier columns translation, keyColumn label translation → #31391 and #30208 only; none is this group.
reach: Setup → Data Lifecycle in any non-English locale, once PR #31451 draws the map tables (the headers render keyColumn.label / columns[].label as served).

维护者速读

数据生命周期的三张 map 表(保留期覆盖、行数配额、按类默认配额)表头是英文字面量,现在没有地方可以翻译。要在设置的翻译结构里给每个键加一个 columns 分组(键列 + 各值列的标签),控制台再读它。存储与保存门不变。

Readings (origin/main 216b18a6c)

Expected

  1. Spec: the settings keys.<key> translation entry gains an optional columns group (the key column's label and each value column's label, by column name), with the strictness the sibling groups use.
  2. The lifecycle settings' zh-CN (and other shipped) bundles carry the five headers.
  3. Console: the map control reads the group (ui follow-up on this card or a child, as the spec seat cuts it).

Refs #31391, #30208

Activity

  1. objectstack-fleet commented on Nov 8, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: audit · p3 · domain:spec · 2026-11-08T08:54Z

    ⛔ Not a claim.


    Generated by Claude Code

  2. objectstack-fleet commented on Nov 8, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:spec#4 · marchtian · session_017ihL2eAG5J8aqAyPZif4BJ

    Claim: PM loop round 6 · 2026-11-08T09:51Z
    Session: session_017ihL2fxVwyhFFqT657pqUh (card thread; dispatched by seat session session_017ihL2eAG5J8aqAyPZif4BJ)
    Account: marchtian
    Branch: claude/project-thread-b3hqev
    Worktree: the card thread's own container checkout (objectstack-issue-31453)
    Domain: domain:spec
    Seat: domain:spec#4
    Ruling-ref: triage 6719503629 (spec translation schema first; the console read is a paired ui follow-up once spec lands). Seat: the overlay goes wherever keys.<key>.label is overlaid today, in this PR, so that the new leaves are enforced and not just declared
    File surface: packages/spec/src/system/translation.zod.ts (+ test, regenerated references), the settings-translation overlay site (measured by the dev: @objectstack/service-settings / packages/objectql, or ui/apps/console/src/pages/settings/SettingsMapField.tsx if the console overlays), the lifecycle settings bundles that already translate the namespace's keys, and changesets
    Container & model: M, mode:thread, model: default tier, effort: default; independent Fable review of the spec diff before ACCEPT (the maintainer's standing spec rule)
    Clause-②: yes — the bundle schema accepts the new keyColumn / columns leaves it refused before
    Metadata-protocol: none
    Responsibility: n/a — the five map-table headers cannot be translated by any bundle today
    Thread-read: 6719503629
    Premise: holds (settings.<ns>.keys.<key> declares label/help/placeholder/options/confirmOffText and no column leaf; lifecycle-settings.ts carries the five literals); the dev re-measures on its base
    Serial constraints cleared: none (disjoint from #31380 / PR #31456); PR #31451 (domain:ui) draws these tables, and the dev states whether this branch is serial behind it

  3. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Nov 8, 2026
  4. objectstack-fleet commented on Nov 8, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:spec#4 · marchtian · session_017ihL2fxVwyhFFqT657pqUh

    os-dev-report

    {
     "card": 31453,
     "status": "pr_open",
     "pr": {
      "number": 31484,
      "head_sha": "7d137518f17b648f28560b3f2d859c964cf2d176",
      "draft": true,
      "branch": "claude/project-thread-b3hqev"
     },
     "premise_still_valid": true,
     "premise_reading": "origin/main 3c380253: settings.NAMESPACE.keys.KEY declared label/help/placeholder/options/confirmOffText and no column leaf; lifecycle-settings.ts carries the five header literals; PR 31451 (SettingsMapField) merged as f88ca70e.",
     "files_changed": [
      ".changeset/31453-settings-map-column-translations.md",
      "docs/audits/2026-07-unknown-key-strictness-ledger.counts/system.md",
      "packages/services/service-settings/src/translations/ar.ts",
      "packages/services/service-settings/src/translations/de.ts",
      "packages/services/service-settings/src/translations/es-ES.ts",
      "packages/services/service-settings/src/translations/fr.ts",
      "packages/services/service-settings/src/translations/ja-JP.ts",
      "packages/services/service-settings/src/translations/ko.ts",
      "packages/services/service-settings/src/translations/pt-BR.ts",
      "packages/services/service-settings/src/translations/ru.ts",
      "packages/services/service-settings/src/translations/settings-translation-coverage.test.ts",
      "packages/services/service-settings/src/translations/zh-CN.ts",
      "packages/services/service-settings/src/translations/zh-Hant.ts",
      "packages/spec/src/system/settings-manifest.zod.ts",
      "packages/spec/src/system/translation.test.ts",
      "packages/spec/src/system/translation.zod.ts",
      "ui/apps/console/src/pages/settings/SettingsField.tsx",
      "ui/apps/console/src/pages/settings/SettingsMapField.tsx",
      "ui/apps/console/src/pages/settings/__tests__/SettingsView.mapRows-31391.test.tsx",
      "ui/apps/console/src/pages/settings/useSettingsLabel.ts"
     ],
     "line_budget": {
      "insertions": 350,
      "deletions": 11,
      "files": 20,
      "over_3000": false
     },
     "gates": {
      "dispatch_gates": "97 derived, 97 run, 0 NOT-MEASURED, 0 UNRUN (dispatch-gates --ran exit 0)",
      "first_pass_exit_3": [
       "check-plugin-teardown-shape --self-test (fixture commit absent from shallow clone)",
       "spec check:api-surface, check:browser-reachable-entries, check:dual-source-exports, check:entry-nameability, check:exported-any, check:generated (stale dist)",
       "check:dual-build-cjs-loads, check:i18n-walk-parity (unbuilt packages)"
      ],
      "after_build_and_fetch": "all 9 exit 0",
      "extra": [
       "spec check:generated :: exit 0",
       "check:doc-authoring :: exit 0",
       "eslint on touched packages files :: exit 0",
       "eslint on touched console files :: exit 0 (2 pre-existing warnings)",
       "turbo type-check @object-ui/console :: exit 0",
       "spec translation.test.ts + src/shared :: 1224 pass",
       "service-settings src/translations :: 135 pass",
       "console SettingsView.mapRows-31391 + useSettingsLabel suites :: 22 pass",
       "check:test-typecheck :: exit 0 with NODE_OPTIONS heap 12288 (local OOM only; debt not regenerated)"
      ]
     },
     "proof": {
      "spec": "leaves parse on platform face, platform bundle and served document; entry aliases name targets; undeclared column leaf refused at its path; bare string refused as invalid_type at its path; pasted specifier column gets the columns.NAME prescription, no name rename",
      "coverage_mutation": "renaming zh-CN expireAfter to expireAt reds both missing (columns.expireAfter) and undeclared (columns.expireAt)",
      "overlay_reverse": "with headerText unwired in SettingsField, both new console cases red (headers stay Object / Keep rows for / ...)",
      "zh_cn_before_after": "retention_overrides headers: before Object | Keep rows for | Expire rows after; after 对象 | 行保留时长 | 行过期时长"
     },
     "deviations": [
      "Shape: keyColumn is an object {label, help}, not the plain string the order proposed. Measured: SpecifierMapKeyColumnSchema declares label AND description; SpecifierMapColumnSchema declares label, description, kind, name. description is user-visible (value column headers render it as title), so both groups are {label, help}; the key column now also shows its declared description as hover text so the help leaf is read.",
      "Changeset level: @objectstack/spec patch, not minor. Metadata-protocol none grades every entry patch (check-changeset-no-major.mjs); none holds because settings is platform-only (both application doors refuse it) and authorable-surface does not move.",
      "Overlay location: keys.KEY.label is overlaid in the console (useSettingsLabel), not server-side; the new read rides this PR as cross-lane ui files (useSettingsLabel.ts, SettingsField.tsx, SettingsMapField.tsx, map rows test).",
      "Aliases: key_column dropped after review (distance fallback already answers keyColumn); column-level name alias replaced by a prescription."
     ],
     "ui_exhaustive_copies": "not moved: nested leaf, SpecTranslationData forwards settings opaquely; only useSettingsLabel enumerates settings-key leaves and it is extended here",
     "serial": "PR 31451 merged; no open PR on these files found",
     "open_questions": [],
     "out_of_scope_findings": [],
     "fable_review": {
      "comment": 6720495586,
      "round1": "PASS with should-fix (3 should-fix, 3 nits), all fixed",
      "round2": "PASS on delta 7d137518"
     },
     "mcp_calls": {
      "reads": [
       "issue_read x3 (31453 get/comments x2)",
       "pull_request_read get_files 30489 (precedent)"
      ],
      "writes": 0
     },
     "api_writes": [
      "relay pr_create 31484 (run 42472548071, read-back identical)",
      "post-stamped comment 6720495586 on PR 31484",
      "post-stamped os-dev-report on 31453 (this comment)"
     ]
    }
  5. objectstack-fleet commented on Nov 8, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:spec#4 · marchtian · session_017ihL2eAG5J8aqAyPZif4BJ

    ACCEPT → PR #31484 comment 6720589885 · head 7d137518f · 2026-11-08T10:54Z

    • Contract review at CONTRACT_REVIEW_TIER (widening face; spec diff plus the console read that enforces it): PASS at 7d137518 (6720589885), no must-fix or should-fix, three nits.
    • Three deviations from the seat order, each measured correct and accepted:
      1. keyColumn is {label, help}, not a plain string. SpecifierMapKeyColumnSchema declares description too (settings-manifest.zod.ts:97-116), so the order's "carries only label" was wrong.
      2. All three packages ship as patch. Metadata-protocol: none forces patch in check-changeset-no-major; the order's "none + spec minor" pairing could not pass.
      3. The overlay lives in the console's useSettingsLabel. That is where keys.<key>.label is overlaid today. No server overlay exists, so SettingsField.tsx / SettingsMapField.tsx ride as cross-lane ui files, named in the body.
    • Declared Clause-②: yes (widening) and Metadata-protocol: none: confirmed. settings stays platform-only (PER_APP_SETTINGS_PLATFORM_ONLY), and the app face is unchanged.
    • Changeset prose checked sentence by sentence against the diff; all hold:
      • the spec bullet: two optional groups keyed as the specifier spells them; label / help; strict; the aliases description→help, title→label, headers/columnLabels→columns, keyHeader→keyColumn; old bundles parse unchanged; platform-only;
      • the service-settings bullet: the ten named locales are exactly the ten files changed, plus the coverage test's two refusals;
      • the console bullet: a miss keeps the literal; the key column gains title from its description, while value columns already carried title={c.description};
      • "stored values, save door, manifest shape do not change".
    • Accepted nits:
      • the body says "against the shipped zh-CN strings", but the console test uses an inline copy (the coverage test ties the shipped bundle);
      • "no authorable surface moves" is a property of the shard (top-level keys only), not proof;
      • the columns record key is unconstrained, like its sibling options.
    • Lands on green CI through the merge queue after the governed / expected-skips checks.
  6. objectstack-fleet commented on Nov 8, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:spec#4 · marchtian · session_017ihL2eAG5J8aqAyPZif4BJ

    Landed · domain:spec#4 · 2026-11-08T11:49Z

    reading value
    PR #31484 merged 2026-11-08T11:49:19Z through the queue at head 7d137518f; merge commit 76e4c2cdf1e6f411b98f6520c0a2bc83ebbd68c4. Contract review PASS 6720589885; ACCEPT on this card
    queue first queue build was green, with no requeue
    card closed completed by Fixes

    State: pm:dispatched removed. The three accepted nits are recorded only:

    • the PR body's "shipped zh-CN strings" wording;
    • the authorable-surface shard reads only top-level keys;
    • the columns record key is unconstrained, like its sibling options.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

domain:specDomain lane — seat card indexed by label:pm:seatenhancementNew feature or requestpriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions