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
settings translations: a columns group so a map setting's key and column headers translate (item 7 of #31391) #31453
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).
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.
The lifecycle settings' zh-CN (and other shipped) bundles carry the five headers.
Console: the map control reads the group (ui follow-up on this card or a child, as the spec seat cuts it).
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
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:
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.
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.
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.
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.
Activity
objectstack-fleet commentedon Nov 8, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: audit · p3 ·
domain:spec· 2026-11-08T08:54Z⛔ Not a claim.
mapsettings specifier as a table of keyed rows (Data Lifecycle retention overrides and quotas) #31391 / PR feat(console): draw the map settings specifier as a table of keyed rows #31451) head their columns with English literals fromlifecycle-settings.ts. The settings translation schema has no place for them. The ask is acolumnsgroup per key (the key column and each value column), which the console then reads.domain:specfirst, for the translation schema, under the spec red line. The ui follow-up inSettingsMapField.tsxis a small paired card once spec lands.pm:queue.Generated by Claude Code
objectstack-fleet commentedon Nov 8, 2026
domain:spec#4 · marchtian · session_017ihL2eAG5J8aqAyPZif4BJ
Claim: PM loop round 6 · 2026-11-08T09:51Z
Session:
session_017ihL2fxVwyhFFqT657pqUh(card thread; dispatched by seat sessionsession_017ihL2eAG5J8aqAyPZif4BJ)Account:
marchtianBranch:
claude/project-thread-b3hqevWorktree: the card thread's own container checkout (
objectstack-issue-31453)Domain:
domain:specSeat:
domain:spec#4Ruling-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>.labelis overlaid today, in this PR, so that the new leaves are enforced and not just declaredFile 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, orui/apps/console/src/pages/settings/SettingsMapField.tsxif the console overlays), the lifecycle settings bundles that already translate the namespace'skeys, and changesetsContainer & 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/columnsleaves it refused beforeMetadata-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.tscarries the five literals); the dev re-measures on its baseSerial 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
objectstack-fleet commentedon Nov 8, 2026
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)" ] }objectstack-fleet commentedon Nov 8, 2026
domain:spec#4 · marchtian · session_017ihL2eAG5J8aqAyPZif4BJ
ACCEPT → PR #31484 comment 6720589885 · head
7d137518f· 2026-11-08T10:54ZCONTRACT_REVIEW_TIER(widening face; spec diff plus the console read that enforces it): PASS at7d137518(6720589885), no must-fix or should-fix, three nits.keyColumnis{label, help}, not a plain string.SpecifierMapKeyColumnSchemadeclaresdescriptiontoo (settings-manifest.zod.ts:97-116), so the order's "carries onlylabel" was wrong.patch.Metadata-protocol: noneforces patch in check-changeset-no-major; the order's "none+ spec minor" pairing could not pass.useSettingsLabel. That is wherekeys.<key>.labelis overlaid today. No server overlay exists, soSettingsField.tsx/SettingsMapField.tsxride as cross-lane ui files, named in the body.Clause-②: yes (widening)andMetadata-protocol: none: confirmed.settingsstays platform-only (PER_APP_SETTINGS_PLATFORM_ONLY), and the app face is unchanged.label/help; strict; the aliasesdescription→help,title→label,headers/columnLabels→columns,keyHeader→keyColumn; old bundles parse unchanged; platform-only;titlefrom itsdescription, while value columns already carriedtitle={c.description};columnsrecord key is unconstrained, like its siblingoptions.objectstack-fleet commentedon Nov 8, 2026
domain:spec#4 · marchtian · session_017ihL2eAG5J8aqAyPZif4BJ
Landed ·
domain:spec#4· 2026-11-08T11:49Z7d137518f; merge commit76e4c2cdf1e6f411b98f6520c0a2bc83ebbd68c4. Contract review PASS 6720589885; ACCEPT on this cardFixesState:
pm:dispatchedremoved. The three accepted nits are recorded only:columnsrecord key is unconstrained, like its siblingoptions.