docs(i18n): the translations guide lists the bulkActions and datasets groups (#15435) - #15772
Conversation
…ons guide The "What you can translate" table is this page's inventory of the bundle surface, and it omitted two groups that shipped live in 17.3.0 (#14253): `objects.<name>._views.<view>.bulkActions.<def>.*` and `datasets.<name>.*`. The word `dataset` did not occur on the page at all. Both are declared in `packages/spec/src/system/translation.zod.ts`, read by `translateView` (via `translateBulkActionDefs` against `config.bulkActionDefs`) and by `translateDataset`, and emitted by `os i18n extract` — so an author scanning the inventory concluded two live surfaces were not translatable. Adds one bulk-action row, two dataset rows, and the short callout the `datasets` group needs (the page introduced no dataset concept anywhere). Also names `dataset` in the resolved-metadata-types sentence, which listed six of the seven entries in `METADATA_DOCUMENT_TRANSLATORS` — the same omission, one paragraph down from the table. The `_validations` row is untouched; it landed with #14402. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk
|
ACCEPT — PR #15772 (head Docs-only, as ruled: three table rows ( Measured by this seat: branch blob greps
Flip + arm when both required jobs report success on Generated by Claude Code |
|
Flipped ready + auto-merge enabled (07:32Z, Generated by Claude Code |
Fixes #15435
content/docs/ui/translations.mdxcarries the page's inventory of the bundle surface,the "What you can translate" table. It omitted two groups that shipped live in 17.3.0
(#14253) — and the word
datasetdid not occur on the page at all, so thedatasetsgroup had no concept to hang a row on.
The key shapes, read from the schema on this branch's base
Both groups are declared in
packages/spec/src/system/translation.zod.ts::206—objects.OBJECT._views.VIEW.bulkActions.DEF.*:281—bulkActions: z.record(z.string(), strictObject({— declaringlabel,confirmText,confirmLabel, andparams(:327), whose members declarelabel/help/placeholder:734-:737— thedatasetsconvention, verbatim:datasets.NAME.label,datasets.NAME.description,datasets.NAME.dimensions.DIM.label,datasets.NAME.measures.MEASURE.label:770—datasets: z.record(z.string(), strictObject({Every key written is one a reader actually reads
Not declared-only — each is quoted at its reading site in
packages/spec/src/system/i18n-resolver.ts:bulkActions.DEF.label/.confirmText/.confirmLabel:750function translateBulkActionDefs, called fromtranslateViewat:852againstconfig.bulkActionDefsbulkActions.DEF.params.PARAM.label/.help/.placeholderdef.params[]datasets.NAME.label/.description:1282translateDatasetvialookupDatasetAttrdatasets.NAME.dimensions.DIM.label/.measures.MEASURE.label:1231translateDatasetMembersvialookupDatasetMemberLabelparamswas checked specifically, because a declared-but-unread sub-key would have had tobe left out or marked declared-only. It is read: the param branch of
translateBulkActionDefsresolveslabel,helpandplaceholderper param name andoverlays them. Nothing in either group is declared-only.
os i18n extractproduces exactly these keys —packages/cli/src/utils/i18n-extract.ts:332pushBulkActionDefsand:1293walkDatasets, both listed in that file's own keyinventory at
:37-:40and:58-:60. Neither group is behind the liveness gate thatholds
flowsback (:68,authorWarnedTranslationGroups), soos lintcoverage reportsboth.
Liveness:
packages/spec/liveness/translation.json:57recordsdatasetsas"status": "live","verifiedAt": "2026-09-02", and the file header records it as"seeded LIVE and DRILLED by #14253 with its reader (
translateDataset) in the samechange".
bulkActionshas no ledger row of its own by design — it sits underobjects,below the boundary that header states ("every group is a
z.recordkeyed by target names— the drill sees each record's VALUE shape one level; the deeper per-key conventions … are
governed by the resolvers cited per row, not by ledger rows"), so its liveness evidence is
the resolver and extractor quoted above.
What changed on the page
Three table rows, in the existing row style and placed beside the surfaces they belong to
(bulk actions after the view row; datasets after the dashboard-widget row, mirroring how
dashboardsalready takes two rows — one for label/description, one for its members):objects.NAME._views.VIEW.bulkActions.DEF.label/.confirmText/.confirmLabel/.params.PARAM.label/.help/.placeholderdatasets.NAME.label/descriptiondatasets.NAME.dimensions.DIM.label/datasets.NAME.measures.MEASURE.labelThe def key is spelled
DEFrather thanNAME, becauseNAMEis already the objectin that same path;
DEFis also how the extractor's own inventory spells it. The rowcarries one trailing clause naming the
help/helpTextdivergence, in the style theflowsrow already uses for its trailing note — a bulk param declareshelp, an actionparam declares
helpText, and the schema calls that out as a known divergence at:276.One
Callout type="info"fordatasets, since the page introduced no dataset conceptanywhere: why the group is top-level rather than nested under
dashboards(one definitionthat N widgets across M dashboards bind to by reference), and that
labelis the only copybelow the dataset —
descriptionbelongs to the dataset itself, which is why writing oneon a dimension or measure is rejected.
One line beyond the two rows, called out for review
The paragraph directly under the table read "The metadata types resolved per request are
object, view, action, app, dashboard, and page" — six of the seven entries in
METADATA_DOCUMENT_TRANSLATORS(i18n-resolver.ts:929-:939), which has carrieddataset: translateDataset(:938) since 17.3.0;TRANSLATABLE_METADATA_TYPESis derivedfrom that table at
:946. This is the same omission as the table's, one paragraph down, andadding a dataset row while the next sentence excludes dataset from the resolved types would
have shipped a self-contradicting page. Added the one word. Flagging it because it is the
only edit outside the table and the callout.
⛔ The
_validationsrow is untouched — confirmed present on this branch's base attranslations.mdx:72before any edit, and it stays exactly as #14402 landed it.#14402 is not addressed here.No file underpackages/orcontent/docs/releases/is touched.Verification
Grep controls on the page, base → HEAD:
ef60224fcgrep -c 'bulkActions' content/docs/ui/translations.mdxgrep -c -i 'dataset' content/docs/ui/translations.mdxgrep -c 'bulkActions' packages/spec/src/system/translation.zod.tsgrep -c -i 'dataset' packages/spec/src/system/translation.zod.tsBoth zeros were real absences, not a broken pattern — the same pattern fires on the schema file.
Gate family derived, not recalled:
node scripts/pm/dispatch-gates.mjs --changed --commands --repo objectstack-ai/objectstack→ exit 0, 38 commands, derived at commit
4405a8b4dagainst merge baseef60224fc.All 38 run; exit codes captured before any pipe (
cmd > log 2>&1; EXIT=$?).37 of the 38 measured green; the one remaining is the NOT MEASURED entry below, which is not a red. Includes
check:doc-authoring,check:doc-frontmatter,check:docs-section-name,check:docs-single-h1,check:doc-anchors,check:docs-redirects,check:docs-audit-scope,check:docs-transcript-drift,check:section-landing-index,check:doc-route-spelling,check:nul-bytes,and the
@objectstack/lint/@objectstack/specdoc families.Four gates hit a build prerequisite on first run and were re-run after building through the
shared verify lock (
OS_VERIFY_LOCK_SLOT=issue-15435, two locked runs, verdicts verbatim:VERDICT command-exit 0 · held the lock 172s (2m52s) · waited 0sandVERDICT command-exit 0 · held the lock 384s (6m24s) · waited 120s (2m00s)):check:docs-transcript-drift(neededpackages/lint/dist, as predicted), and the@objectstack/lint/@objectstack/specfamilies needing@objectstack/formula,@objectstack/specand@objectstack/client-reactbuilt. All four green on re-run —check:skill-exampleslast, at✅ 257 prose examples type-check across 3 surface(s).⊘ NOT MEASURED, by name:
pnpm --filter @objectstack/spec run check:docs— exit 1,PREREQUISITE NOT MET:"packages/spec/json-schema is missing … it is a gitignored build artifact". Not run
because regenerating it would rewrite a tracked baseline inside a docs-only PR. Nothing
was measured; this is not a finding. CI builds and runs it.
as the derivation printed them:
check-cross-package-test-inputs.mjs --union-into "$RUNNER_TEMP/…",check-shard-attestation.mjs --shard ${{ matrix.shard }}, andcheck-test-completeness.mjs "$RUNNER_TEMP/test-core.log".Governed-surface predicate, re-run on the final file list:
node scripts/pm/check-governed-merges.mjs --test content/docs/ui/translations.mdx→ exit 0,"✅ NOT governed — ordinary queue landing applies to a PR with exactly this file list."
Control-character self-scan beyond the gate:
grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]' content/docs/ui/translations.mdx→ exit 1, clean.Changeset: none,
skip-changesetapplied.content/sits at the repo root and matches noglob in
pnpm-workspace.yaml, and the root package isprivate: true— so this diffpublishes nothing from any released package, which is exactly what AGENTS.md reserves the
label for.
🤖 Generated with Claude Code
https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk
Generated by Claude Code