Repository navigation
fix(spec): serve a field's translated help on its authored inlineHelpText - #29217
Conversation
…Text The i18n extractor scaffolds objects.O.fields.F.help from help ?? inlineHelpText ?? description and the console draws inlineHelpText || description, but translateObject served the entry on description only, so a field authoring inlineHelpText kept showing its source text in every locale. The entry is now served on the authored, non-empty inlineHelpText too, under the same per-slot packaged-base divergence rule (ADR-0029 D9.2a); description keeps today's behaviour. Claude-Session: https://claude.ai/code/session_01ADHkmStM2XRLNZKJCmbBaA Co-authored-by: Claude <noreply@anthropic.com>
…elpText Claude-Session: https://claude.ai/code/session_01ADHkmStM2XRLNZKJCmbBaA Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift CheckThis PR changes 1 package(s): 6 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
⛔ 3 release-owned page(s) also name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 168 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin def6773c5068eb0ac7d85759353e630efb76b4d8 && git checkout def6773c5068eb0ac7d85759353e630efb76b4d8
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 14208f2c504ff6f1529be8a28323a91df53d0562 e1451dc02f544a7024084fc622ac218a6ba8407a && git checkout -B drift-repro 14208f2c504ff6f1529be8a28323a91df53d0562 && git merge --no-ff e1451dc02f544a7024084fc622ac218a6ba8407a
node scripts/docs-audit/affected-docs.mjs --json 14208f2c504ff6f1529be8a28323a91df53d0562
|
|
domain:spec#1 · os-steve · session_01ADHkmPi25XXKx92Xmg4viS Head-sha: 维护者速读
席位意见:可落地,等契约复审。 席位核对 — ACCEPT ·
|
|
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U Contract-review-claim: Taken on the lane's Generated by Claude Code |
|
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U Contract reviewServed-tier: Inputs read: card #29153 body and all three comments (triage, claim 6572667349, os-dev-report 6573912237); PR #29217 body, file list (3 files), the net diff against Check-runs on the head: 55 success, 13 skipped (opt-in and filter-gated jobs), 0 failure, 1 pending — a second ① Derived judgments
② Semver level
③ Boundary flags
④ Design judgment
Holds:
Findings:
Implemented-by: VERDICT: PASS Generated by Claude Code |
|
domain:spec#1 · os-steve · session_01ADHkmPi25XXKx92Xmg4viS Contract-review-claim: session_01ADHkmPi25XXKx92Xmg4viS · head e1451dc · 2026-11-02T10:45Z Triage ruling 6575141496 returned contract review to the lane, so the spec seat reviews this head itself at |
|
domain:spec#1 · os-steve · session_01ADHkmPi25XXKx92Xmg4viS Contract reviewServed-tier: ① Derived judgmentsRead off the net diff at the head, each named right or wrong against the cited code:
② Semver level
③ Boundary flagsThe dev's os-dev-report on card #29153 (comment 6573912237):
④ Design judgment
Attempts to break it, each read in the live tree at the head:
Findings:
Implemented-by: VERDICT: PASS |
Requested by Steve · project thread
Fixes #29153
Clause-②: no
Metadata-protocol: none
维护者速读
description,还写到字段自己填写的inlineHelpText上。inlineHelpText,以前译文只写在description,所以填了inlineHelpText的字段在任何语言下都显示英文原文(如 showcase 的「线索评分」)。inlineHelpText的字段不变,租户改过的文本照旧保留。回滚即还原本 PR。packages/spec/src/system/i18n-resolver.ts的translateField帮助分支,再看同文件translateObject文档块,最后看新测试块。pnpm --filter @objectstack/spec exec vitest run src/system/i18n-resolver.test.ts,预期全部通过,含lead_score在 zh-CN 下的inlineHelpText为「由评分规则计算,不可手动编辑。」。What changes
translateObject(packages/spec/src/system/i18n-resolver.ts) serves the bundle'sobjects.OBJECT.fields.FIELD.helpentry on the field's owninlineHelpTextwhen the field authors a non-empty one, as well as ondescription(unchanged). The new slot follows the same per-slot packaged-base divergence rule (valueOverridesPackagedBase, ADR-0029 D9.2a) that already guardsdescription; no second comparison was added. The docblock that said help was "not served oninlineHelpTexteither, which the extractor never reads" is corrected: the extractor has readinlineHelpTextsince #25683.No new key, no second fold, and nothing is ever served on
help.ui/packages/fieldsandpackages/cliare untouched.The matrix (one derivation, three places)
helpfrominlineHelpText || description)inlineHelpTextonlyinlineHelpTextinlineHelpText+descriptioninlineHelpTextinlineHelpText+descriptioninlineHelpTextinlineHelpText+descriptioninlineHelpTextdescriptiononlydescriptiondescription(noinlineHelpTextkey added)descriptioninlineHelpText: ''+description??chain stops at''andpushOptionalscaffolds no seed for it (see Acceptance notes)description; the emptyinlineHelpTextstays emptydescriptionhelphelphelpFieldSchemarefuseshelp(unrecognized_keys, "Did you meanhelp→inlineHelpText?"), so no stored field carries itForced test edits
i18n-resolver.test.ts, describe "a field's translated help is served ondescription": thephonefixture's bundle entries now carry what the extractor actually writes for a field authoringinlineHelpText(itsinlineHelpTexttext, not itsdescription), and the test that pinned "inlineHelpTextis untouched" now pins the translation on both slots. Two sibling assertions onphone.descriptionfollow the new fixture string.Tests
New describe block "a field's translated help reaches the slot the console draws first": the showcase
lead_scorecase (zh-CN serves 由评分规则计算,不可手动编辑。 oninlineHelpText, parses with no unrecognized key), CONTROL for the source locale, CONTROL for a locale with nohelpentry, never another field's entry, noinlineHelpTextgained by a field without one, the empty-string case, divergence kept in every locale throughtranslateMetadataDocument, an extension field counting as diverged, no packaged base, and no input mutation.Readings (head e1451dc, tree objectstack-ai/objectstack)
@objectstack/spectest: Test Files 790 passed (790), Tests 23377 passed, 1 todo. typecheck exit 0.@objectstack/specbuild +check:generated: "All 14 generated artifacts are up to date". No regenerated file changed.@objectstack/restfull suite, Test Files 367 passed (367), Tests 6963 passed, 332 skipped.@objectstack/metadata-protocolfull suite, Test Files 298 passed, 4 skipped.@objectstack/cliunittest/i18n-extract-inline-help-text.test.ts6/6.@objectstack/objectqlsrc/engine-formula-option-label.test.ts7/7.ui/packages/fields/src/__tests__/fieldHelpText-12213.test.tsx5/5 (run fromui/).node scripts/ablation-replace.mjsreplaced thenext.inlineHelpText = translatedHelp;line (anchor 1 → 0, blob 0241a7c5ab2e → 5fc0e733d89c);i18n-resolver.test.tswent red, 3 failed / 377 passed (thephoneboth-slots test, thelead_scoretest, the no-packaged-base test). Restored: blob == HEAD,git diff HEADempty.Acceptance notes
inlineHelpTextand a differentdescription, the entry is the translation ofinlineHelpText(the extractor's source), anddescriptionis also served that text. That was already the served behaviour before this PR; the seat's ruling keeps it ("keeps servingdescriptionas today"). It is recorded in the report's open questions.help ?? inlineHelpText ?? descriptionstops at an authoredinlineHelpText: '', soos i18n extractscaffolds nohelpentry for such a field, while the console (||) draws itsdescription. That half ispackages/cli, outside this card's file surface; it is reported to the seat as a finding, not fixed here. The resolver side of that row is pinned (an entry, when one exists, lands ondescriptionand the emptyinlineHelpTextstays empty).Verification
Derived gate list (
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack) run locally at the final head; per-command exits are in the os-dev-report on the card. Repo-wide scans (pnpm lint, the fullcheck:*farm) are CI's.Human Minimum
packages/specholds no runtime logic. (The resolver is existing spec-owned translation code; no new runtime surface.)pnpm lintis CI's run.main, one pull request.packages/spectouched: its generated artifacts are regenerated and committed (none were stale).content/docs/references/,packages/*/CHANGELOG.mdorcontent/docs/releases/.🤖 Generated with Claude Code
https://claude.ai/code/session_01ADHkmStM2XRLNZKJCmbBaA
Generated by Claude Code