Skip to content

Commit 506fb6d

Browse files
docs(skills): objectstack-i18n names the action-entry keys os validate judges (#21656)
Fixes #21583 Clause-②: no Tier H (`skills/**`): left as a draft; lands only by the maintainer's hand or an authorized APPROVED review, then the owning seat lands it. Not readied, no auto-merge armed. ## What changed One file, `skills/objectstack-i18n/SKILL.md`, three places, mirroring `content/docs/protocol/kernel/i18n-standard.mdx` :1039–:1058 (the sentence at :1039 and the table rows at :1053, :1055–:1058). No second vocabulary: keys and conditions are spelled the way the page and the lint spell them; the skill names shapes and outcomes, never the gate's internals. ### 1. The `_actions.{action_name}` row of the bundle-shape table (was :164) Before: | `_actions.{action_name}` | `label`, `description`, `confirmText`, `successMessage`, `params.{param_name}`, `resultDialog` | After: | `_actions.{action_name}` | `label`, `description`, `confirmText`, `successMessage`, `params.{param_name}` (and `.options.{value}` beneath it — an option's stored `value` in that param's inline `options`), `outcomeMessages.{outcome}` (an outcome the action's own `outcomeMessages` declares), `resultDialog.title` / `.description` / `.acknowledge` (only under an action that declares a `resultDialog`), `resultDialog.fields.{path}` (the literal `path` of a field in `resultDialog.fields[]`, dots included — `client.secret` is one key); the same keys hold under `globalActions.{action_name}` | Reference rows: :1055 (param options), :1056 (`outcomeMessages`), :1057 (`resultDialog.fields.{path}`), :1058 (dialog leaves), :1039 (a `{action}.` row holds at both action addresses). ### 2. The `globalActions` line (was :170) Before: `globalActions` (object-less actions) After: `globalActions` (actions with no `objectName` — a key naming a bound action is an **error** whose message names the `objects.{owner}._actions.{action_name}` key to write instead) Reference row: :1053. ### 3. The `translation-target-unknown` paragraph (was :198–:203) Before, after the enumeration sentence: that do. A bundle keyed to something since renamed still parses — the label just renders silently in its source locale while every neighbouring one resolves. After: that do. Three more shapes under an action entry are the error: an outcome the action does not declare in `outcomeMessages`; a `resultDialog.fields` path it does not declare; and `resultDialog` `title` / `description` / `acknowledge` under an action that declares no `resultDialog` — a bundle translates a dialog the action declares and cannot add one. A param's inline option keys share the option warning with a field's `options`; a param that references a `field` and declares no inline `options` is not judged. A bundle keyed to something since renamed still parses — the label just renders silently in its source locale while every neighbouring one resolves. Reference: rows :1055–:1058 and the paragraph under the table (the error, and the option warning as the deliberate exception). ### Gate-side reading (read only, not changed) `packages/lint/src/validate-translation-references.ts` judges every rule the page states: `checkActionEntry` is called from both the `_actions` loop and the `globalActions` loop; `checkActionParamOptionKeys` is the warning rule and returns without judging a field-backed param that declares no inline `options`; `checkActionOutcomeMessages`, `checkActionResultDialogLeaves` (which returns when the action declares a `resultDialog`) and `checkActionResultDialogFields` are the error rule; a `globalActions` key naming a bound action is an orphan whose hint reads "Move these keys under `objects.{owner}._actions.{action}`". Page and gate agree, so the page was not touched. Placeholder spelling: the skill's own `{action_name}` / `{param_name}` are kept in the table (the row already used them); `{value}`, `{outcome}`, `{path}` and `{owner}` are the page's. ## Readings - `skills/objectstack-i18n/SKILL.md`: 496 → 503 lines (net +7, budget at most +8). - All `skills/**/SKILL.md` together: 4397 → 4404 lines (base `origin/main` 759dbe9). - Token ratchet (`node scripts/check-skills-token-ratchet.mjs`): 4752 → 5032 tokens against the unchanged ceiling 6338 (headroom 1586 → 1306). ## Verification (tree at afecd20) Derived with `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` (24 commands, the same 24 the dispatch named) and reconciled with `--ran`. Every exit code was captured before any pipe, from a redirected log. - Direct node gates, each exit 0: `check-ci-filter-parity`; `check-closing-keyword-parity` and its `--self-test` (40 assertions); `check-comment-mask-corpus` (8122 files, 0 disagree); `check-doc-route-spelling --advisory` ("population clean") and its `--self-test`; `check-skills-token-ratchet` ("54 authored bundle file(s) within their ceilings") and its `--self-test` (65 cases). - `pnpm check:*`, each exit 0: `agent-test-spelling` (0 violations), `corpus-claim-drift` (251 files, 53 under skills), `cross-package-test-inputs`, `doc-authoring` ("53 published skill files clean — no internal issue-id references"), `driver-memory-census`, `gitlink-declared`, `nul-bytes` ("10027 text file(s) … no raw ASCII control bytes"), `pm-governed-merges`, `refd-timer-probe`, `role-word`, `skill-compatibility` ("10 SKILL.md file(s) reconciled"), `skill-frame-sync`, `skill-identifier-liveness` ("Leg 1: 457 citation(s) over 53 published file(s) … Leg 2: 8 registered exhaustive section(s), 0 ledgered gap(s)"), `watch-hint-literal`. - `pnpm --filter @objectstack/spec run check:skill-docs` exit 0 ("Skill docs in sync"); `check:skill-refs` exit 0 ("9 generated files in sync with packages/spec") — the second added because a SKILL.md body edit names it in AGENTS.md. Both read SKILL.md frontmatter and `packages/spec/src` through tsx, so no build was needed for them. - `pnpm --filter @objectstack/lint run check:doc-formula-expressions` exit 0 ("22 record-scoped formula example(s) across 460 files / 1381 TS blocks judged clean"), after `turbo run build --filter=@objectstack/lint` under `scripts/pm/os-verify-lock.sh` (4 tasks, all cache hits; no tracked file changed by the build). - Not measured locally, declared to CI: the whole-tree families, the type-check lanes and the Test Core shards — the diff touches no TypeScript and no package. Byte hygiene: no raw control bytes in the file, no tracker-shaped ids, no new code fence, no model identifier. ## 维护者速读(草稿) **改了什么。** 只改 `skills/objectstack-i18n/SKILL.md` 一个文件、三处:bundle 形状表的 `_actions.{action_name}` 行补齐 `os validate` 实际判定的动作子键(参数选项、`outcomeMessages`、`resultDialog` 的三个文案叶子与 `resultDialog.fields.{path}`),并注明同样的键在 `globalActions` 下同样成立;`globalActions` 一句写明:键名指向已绑定对象的动作是错误,错误消息会指出应改写到 `objects.{owner}._actions.{action_name}`;`translation-target-unknown` 段落列出三种新的错误形状,并说明参数选项键与字段选项键共用同一条警告。措辞与 `i18n-standard.mdx` :1039–:1058 一致,不另造词汇,不复述门禁内部实现。 **为什么改。** 这是您在会话中点名、但当时没有建卡的技能文档修改。技能是 AI 作者写翻译包时读的文本;原文落后于门禁,作者无从得知 `outcomeMessages`、`resultDialog.fields` 可译,也不会被告知在没有对话框的动作下写对话框文案、或把已绑定对象的动作写到 `globalActions` 下会被 `os validate` 以错误拒绝。参考页已经写对,技能只是对齐。 **风险与代价(含回滚)。** 纯技能文本,不发布任何 npm 包,无 changeset(打 `skip-changeset`)。净增 7 行(预算不超过 8),token 棘轮 4752 → 5032 / 6338,上限未动。派生出的 24 项门禁本地全绿,另加 `check:skill-refs` 也绿。回滚即 revert 这一个提交。 **席位意见。** (留空,席位定稿) **你要做的。** 这是 Tier H(`skills/**`):请审阅后给出 APPROVED 评审;之后由席位落地。PR 保持 draft,未开 auto-merge。 ## Acceptance notes - The `translation-target-unknown` paragraph now carries the conditions once and the table row names the keys; the page says "takes the field's list when the dialog renders" as the reason a field-backed param is not judged — the skill states the consequence only, to stay inside the line budget. - `references/_index.md` is generator-owned and unchanged: the body edit touches no frontmatter, which is all `gen:skill-refs` reads from this file. - `content/docs/**` is the source copied from, not an edit target; nothing else in the tree was touched. --- _Generated by [Claude Code](https://claude.ai/code/session_01CB6W87z22K2yjUCDyVrJRk)_ Co-authored-by: objectstack-fleet[bot] <objectstack-fleet[bot]@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com>
1 parent fea6706 commit 506fb6d

1 file changed

Lines changed: 14 additions & 7 deletions

File tree

‎skills/objectstack-i18n/SKILL.md‎

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -161,16 +161,17 @@ All translatable content for a single object is aggregated under
161161
| `label` / `pluralLabel` / `description` | Object-level text (every key optional) |
162162
| `fields.{field_name}` | `label`, `help`, `placeholder`, `options` (option value → label) per field |
163163
| `_views.{view_name}` | `label`, `description`, `emptyState.title` / `emptyState.message`, `bulkActions.{def_name}` (`label`, `confirmText`, `confirmLabel`, `params`) |
164-
| `_actions.{action_name}` | `label`, `description`, `confirmText`, `successMessage`, `params.{param_name}`, `resultDialog` |
164+
| `_actions.{action_name}` | `label`, `description`, `confirmText`, `successMessage`, `params.{param_name}` (and `.options.{value}` beneath it — an option's stored `value` in that param's inline `options`), `outcomeMessages.{outcome}` (an outcome the action's own `outcomeMessages` declares), `resultDialog.title` / `.description` / `.acknowledge` (only under an action that declares a `resultDialog`), `resultDialog.fields.{path}` (the literal `path` of a field in `resultDialog.fields[]`, dots included — `client.secret` is one key); the same keys hold under `globalActions.{action_name}` |
165165
| `_sections.{section_name}` | Form section `label`, `description` |
166166
| `_tabs.{tab_name}` | Filter-preset tab `label` (`ViewTabSchema.name`) |
167167
| `_validations.{rule_name}` | `message` only — the sentence a rejected write returns (replaces the retired `validationMessages`) |
168168

169169
Top-level groups alongside `objects`: `apps` (label, description, navigation),
170-
`messages`, `globalActions` (object-less actions), `dashboards`, `datasets`, `pages`,
171-
`flows`, `metadataForms`, `settingsCommon`. `settings` is **platform-only** — it is
172-
keyed by a settings manifest's namespace and only the platform declares one, so an
173-
app bundle carrying it is refused by name.
170+
`messages`, `globalActions` (actions with no `objectName` — a key naming a bound action is
171+
an **error** whose message names the `objects.{owner}._actions.{action_name}` key to write
172+
instead), `dashboards`, `datasets`, `pages`, `flows`, `metadataForms`, `settingsCommon`.
173+
`settings` is **platform-only** — it is keyed by a settings manifest's namespace and only
174+
the platform declares one, so an app bundle carrying it is refused by name.
174175

175176
For the exact Zod shape (and any field that may have been added since), read
176177
`node_modules/@objectstack/spec/src/system/translation.zod.ts` —
@@ -199,8 +200,14 @@ parse, ship, and resolve to nothing.
199200
is an **error** and fails the run; `translation-option-key-unknown` is a warning.
200201
A key naming an object, field, view, tab, action, param, section, validation rule, app,
201202
nav item, dashboard, widget or flow screen that does not exist is listed alongside the names
202-
that do. A bundle keyed to something since renamed still parses — the label just renders
203-
silently in its source locale while every neighbouring one resolves.
203+
that do. Three more shapes under an action entry are the error: an outcome the action does
204+
not declare in `outcomeMessages`; a `resultDialog.fields` path it does not declare; and
205+
`resultDialog` `title` / `description` / `acknowledge` under an action that declares no
206+
`resultDialog` — a bundle translates a dialog the action declares and cannot add one. A
207+
param's inline option keys share the option warning with a field's `options`; a param that
208+
references a `field` and declares no inline `options` is not judged. A bundle keyed to
209+
something since renamed still parses — the label just renders silently in its source locale
210+
while every neighbouring one resolves.
204211

205212
---
206213

0 commit comments

Comments
 (0)