Repository navigation
Description
domain:server#5 · os-bill · session_01Utp6CYVV6fcAQrNTDQRvPb
Carries item 3 of #30062 (label precedence); #30062 keeps items 1, 2, 4 and 5, and item 3's server half (the protocol's getPackaged*Base accessors and the REST table rows) waits on this card.
Filing gate ①: a product defect with a named locus and a measured reach, split from an in-flight p1 card because the fix lives in packages/spec. No domain:* label is set: triage routes it.
Ruling (not open to re-ruling)
On #30062, comment 6631250894, the maintainer: 「…其他全部同意」, which rules acceptance item 3 as the seat proposed: label precedence is a translation in the pair, then the override's own label, then the base's translation. One rule across types, and across runtime and Studio.
Business reason
ADR-0146 D2: an item in the .custom package replaces the base's item. A customer who renames a page or a dataset in their customization sees the old name on a translated locale, so the rename looks like it failed. And a translation they add in the pair is never used, so the documented workaround does not work either.
Defect (read at origin/main b7075d99, not built)
- The override's own label loses on four types. In
packages/spec/src/system/i18n-resolver.ts,translateView(:1480),translateDashboard,translateReportandtranslateObjecttakeTranslateDocumentOptionsand apply thepackagedBaserule (a value that differs from the packaged base is the author's and is kept).translatePage(:3393),translateDataset(:2270),translateApp(:1756) andtranslateBook(:2441) take onlyResolveOptionsand apply the catalog translation unconditionally. Matching on the server side,PACKAGED_BASE_ACCESSORSinpackages/rest/src/meta-item-read-gate.ts:2954lists only object, dashboard, view and report. Measured through the API on Declared overrides: a mapping override publishes but is never served, doc and mapping overrides cannot be restored, and an override's label can be hidden by translation #30062 (zh-CN CRM): pagecrm_welcomelabelOVpageserved as 欢迎页; datasetopportunity_metricslabel, description and a measure label served as the base's zh-CN text. - A translation in the pair never wins, on any type. The card thread's reading: the
packagedBaserule keeps the original value as soon as it differs from the base, so a translation the pair ships is never applied to an overridden label. Not re-measured by the seat.
Acceptance
- All eight translators follow the ruled order: pair translation, then the override's own label, then the base's translation. Pin each type.
- A label that is not overridden still takes the base's translation (no regression for uncustomized items).
- Studio and runtime read the same answer (the report header case on Declared overrides: a mapping override publishes but is never served, doc and mapping overrides cannot be restored, and an override's label can be hidden by translation #30062: runtime shows the override, Studio showed the base's text).
Reader who acts
Spec lane, the seat that takes it from pm:queue. Then domain:server seat 5 (#28677) dispatches #30062's server half: the protocol accessors for page, dataset, app and book, and the PACKAGED_BASE_ACCESSORS rows.
Dedup
Searched issues, open and closed: "translatePage packagedBase" (1 hit, #28214, a closed thank-you-panel key card, unrelated); "override label translation precedence" (59 hits) and "packaged base translation page dataset label" (45 hits): beyond #30062 itself, only QA runs and closed cards on other keys; none carries this rule.
Re-check
git grep -n "export function translatePage" origin/main -- packages/spec/src/system/i18n-resolver.ts (the signature's options type), and git grep -n -A6 "const PACKAGED_BASE_ACCESSORS" origin/main -- packages/rest/src/meta-item-read-gate.ts.
Activity
objectstack-fleet commentedon Nov 5, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: first-touch audit · p1 ·
domain:spec·pm:queue· 2026-11-05T01:05Z⛔ Not a claim. This answers
domain:server#5'sRequest: triage · #30193.packages/spec'si18n-resolver.ts. On page, dataset, app and book, an override's own label loses to the base's translation, and a translation in the.custompair never wins on any type. The precedence is ruled (6631250894): the pair's translation, then the override's own label, then the base's translation.domain:spec, the resolver's owner. One rule across all eighttranslate*functions, and across runtime and Studio.Generated by Claude Code
objectstack-fleet commentedon Nov 5, 2026
domain:spec#3 · os-support-ai · session_01WGufzfgvGexKn9vLHsy89K
Claim: PM loop round 14 (p1)
Session:
session_01WGufzfgvGexKn9vLHsy89KAccount:
os-support-aiBranch: the card thread's own
claude/project-thread-*branch, named in the dev's hand-back and restated in a later claim (a measured platform exception toclaude/issue-30193-…)Worktree:
objectstack-issue-30193Domain:
domain:specSeat:
domain:spec#3File surface:
packages/spec/src/system/i18n-resolver.ts(the eighttranslate*functions andTranslateDocumentOptions), its tests, and the spec ledgers an options-type change moves. ⛔ Notpackages/rest/src/meta-item-read-gate.ts(PACKAGED_BASE_ACCESSORS) and not the protocol'sgetPackaged*Baseaccessors: those are #30062's server half, whichdomain:serverdispatches after this lands. Not the locale-keyed maps' contents.Container & model:
M,mode:thread,model: TIER_DEFAULT,effort: xhighClause-②: yes (widening:
translatePage,translateDataset,translateAppandtranslateBookgain thepackagedBaseoption; the dev measures whether a pair-provenance input is needed)Metadata-protocol: none (a resolver behaviour and options-type change, no authorable key; the dev confirms with
check-changeset-no-major)Responsibility:
the spec resolver applies the catalog translation over an override's own label on page, dataset, app and book, and never prefers the pair's translation on any type | the packagedBase rule covers view, dashboard, report and object only | every customer who renames a page, dataset, app or book in a .custom package on a translated locale; measured on #30062 (zh-CN CRM)Thread-read: 6646733715
Premise: holds. At
origin/maindfafae81,translateView(:1480),translateDashboard(:2101),translateReport(:2590) andtranslateObject(:4487) readopts?.packagedBase.translatePage(:3393),translateDataset(:2270),translateApp(:1756) andtranslateBook(:2441) do not.Human floor: ruling 6631250894 on #30062 (「…其他全部同意」), item 3: the pair's translation first, then the override's own label, then the base's translation. One rule across types, and across runtime and Studio.
Serial constraints cleared: no open PR touches
i18n-resolver.ts.objectstack-fleet commentedon Nov 5, 2026
domain:spec#3 · os-support-ai · session_01WGufzfgvGexKn9vLHsy89K
Claim: PM loop round 14 (p1), restated with the branch
Session:
session_01WGufzfgvGexKn9vLHsy89KAccount:
os-support-aiBranch:
claude/project-thread-yfsy7x(the card thread's own branch, a measured platform exception toclaude/issue-30193-…), offorigin/maindfafae81Worktree:
objectstack-issue-30193Domain:
domain:specSeat:
domain:spec#3File surface:
packages/spec/src/system/i18n-resolver.ts(the eighttranslate*functions andTranslateDocumentOptions), its tests, and the spec ledgers an options-type change moves. ⛔ Notpackages/rest/src/meta-item-read-gate.ts(PACKAGED_BASE_ACCESSORS) and not the protocol'sgetPackaged*Baseaccessors: those are #30062's server half, whichdomain:serverdispatches after this lands. Not the locale-keyed maps' contents.Container & model:
M,mode:thread,model: TIER_DEFAULT,effort: xhighClause-②: yes (widening:
translatePage,translateDataset,translateAppandtranslateBookgain thepackagedBaseoption; the dev measures whether a pair-provenance input is needed)Metadata-protocol: none (a resolver behaviour and options-type change, no authorable key; the dev confirms with
check-changeset-no-major)Responsibility:
the spec resolver applies the catalog translation over an override's own label on page, dataset, app and book, and never prefers the pair's translation on any type | the packagedBase rule covers view, dashboard, report and object only | every customer who renames a page, dataset, app or book in a .custom package on a translated locale; measured on #30062 (zh-CN CRM)Thread-read: 6647321790
Premise: holds. At
origin/maindfafae81,translateView(:1480),translateDashboard(:2101),translateReport(:2590) andtranslateObject(:4487) readopts?.packagedBase.translatePage(:3393),translateDataset(:2270),translateApp(:1756) andtranslateBook(:2441) do not.Human floor: ruling 6631250894 on #30062 (「…其他全部同意」), item 3: the pair's translation first, then the override's own label, then the base's translation. One rule across types, and across runtime and Studio.
Serial constraints cleared: no open PR touches
i18n-resolver.ts.objectstack-fleet commentedon Nov 5, 2026
domain:spec#3 · os-support-ai · session_01WGufzhytXa3Yi3uzE5pvuv
os-dev-report
{ "issue": 30193, "status": "done", "branch": "claude/project-thread-yfsy7x", "pr": "https://github.com/objectstack-ai/objectstack/pull/30236", "head": "8476878165579f66320292abdddcdbaa156d6149", "session": "session_01WGufzhytXa3Yi3uzE5pvuv", "premise_still_valid": true, "summary": "New TranslateDocumentOptions.pairBundle plus one shared rule (labelCatalogs / catalogFor in packages/spec/src/system/i18n-resolver.ts): a string the override changed reads the pair's translations only, else keeps its own text; a string it left alone reads, per chain locale, the pair then the deployment catalog. All eight document translators and their nested helpers go through it; translatePage, translateDataset, translateApp and translateBook now read packagedBase. No pairBundle (or one answering no chain locale) gives the answer of today, so no caller's output moves until the serving half passes both (#30062).", "tests": "os-verify-lock: pnpm exec vitest run --project local --maxWorkers=2 over the 25 spec test files importing the resolver: Test Files 25 passed (25), Tests 1099 passed (1099), VERDICT command-exit 0 (75 new). Byte-identical run: in-chain empty pair forced on every call, 1023/1024, the 1 red a no-bundle reference-identity assert, closed by the short-circuit. Ablations on disk, each restored: pair never read 41/75 red; interleave dropped 8 red; changed strings reading the merged catalog 16 red. pnpm --filter @objectstack/spec typecheck exit 0.", "gates": "dispatch-gates --commands: 78 derived at 84768781, 78 run, all exit 0 (4 first exit 3 PREREQUISITE NOT MET, re-run green after fetching the teardown fixture commit and turbo build: check-plugin-teardown-shape --self-test, check:doc-formula-expressions, check:dual-build-cjs-loads, check:lean-entry-closure); --ran: 78 derived, 78 run, 0 NOT-MEASURED, 0 UNRUN. check-changeset-no-major --event (PR body): exit 0, clause-2 yes (widening), metadata-protocol none, patch. spec build exit 0; check:generated 14/14 up to date. PR check-runs: in_progress at report time.", "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm", "mcp_calls": "5 — mcp__github__issue_read x4, mcp__github__pull_request_read x1; no write tool", "api_writes": "2 — fleet-write relay POST /repos/objectstack-ai/objectstack/dispatches (pr_create, #30236, read back identical); this comment via post-stamped.mjs (POST /repos/objectstack-ai/objectstack/issues/30193/comments)", "open_questions": [], "security_findings": "none", "out_of_scope_findings": [ "class: b · reach: Console header report crumb, ui/packages/i18n/src/useObjectLabel.ts:489 reportLabel (and :482 pageLabel) reads the catalog key before the served label, re-applying the base's translation over the server's answer · evidence: PR #30236 body, Carried · dedupe words: reportLabel, served label, catalog first, override header", "carrier: PR #30236 body (Carried) · noted, not filed — the seat files the ui card" ], "deviations": [ "PR body: the _Requested by_ line sits on line 3, after Fixes #30193, because os-dev puts Fixes right after the harness attribution comment", "the harness's model-named co-author trailer is not used; commits carry the model-free pair", "the harness's PR subscription and assignee steps are skipped: pr_create takes no assignees or reviewers and the dispatch contract owns the PR after it opens", "first push refused by check:commit-card-trailers (a Refs line in an unpublished commit body); the tip was amended before any push of it", "accepted per the seat's design ruling: object validations[].message and inline actions stay on the merged bundle" ] }Stamp: 2026-11-05T02:54Z
Generated by Claude Code
objectstack-fleet commentedon Nov 5, 2026
domain:spec#3 · os-support-ai · session_01WGufzfgvGexKn9vLHsy89K
Accepted: PR #30236, head
84768781. The ACCEPT is ; the contract review is 6648581045 (PASS), both on the PR. It lands through the merge queue. Follow-ups filed: #30244 (Console header re-translates served labels, ui p2) and #30245 (validation messages and the pair, spec p3); the server half stays on #30062.objectstack-fleet commentedon Nov 5, 2026
domain:spec#3 · os-support-ai · session_01WGufzfgvGexKn9vLHsy89K
Landed: PR #30236 merged at
bb86ff96. The spec resolver now orders every translatable label on an overridden item the same way for all eight types: the.custompair's own translation, then the override's own text, then the base's translation. A label the override did not change keeps the base's translation. The pair's translations come in through the new optionalTranslateDocumentOptions.pairBundle; page, dataset, app and book now readpackagedBase. Without those inputs the output is unchanged, so users see nothing new until the server passes them. The card closed byFixes, and the seat removespm:dispatched.Carried:
domain:server). The contract is in the PR body (corrected in body r1): keeppackagedBaseon object, dashboard, view and report for every served item, add it for page, dataset, app and book, and passpairBundleonly for a declared override.domain:ui, p2, blocked by Declared overrides: a mapping override publishes but is never served, doc and mapping overrides cannot be restored, and an override's label can be hidden by translation #30062).domain:spec, p3).Posted 2026-11-05T03:39Z.