Skip to content

docs(skills): objectstack-i18n names the action-entry keys os validate judges - #21656

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-21583-i18n-skill-action-entry-keys
Oct 4, 2026
Merged

os-zhuang merged 1 commit into
mainfrom
claude/issue-21583-i18n-skill-action-entry-keys

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

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

…e judges

The `_actions.{action_name}` row lists param options, `outcomeMessages`,
the `resultDialog` leaves and `resultDialog.fields.{path}`, and says the
same keys hold under `globalActions`; the `globalActions` line says a key
naming a bound action is an error whose message names the
`objects.{owner}._actions.{action_name}` key; the
`translation-target-unknown` paragraph names the three action-entry error
shapes and the shared option warning. Mirrors
content/docs/protocol/kernel/i18n-standard.mdx; no second vocabulary.

Claude-Session: https://claude.ai/code/session_01CB6W87z22K2yjUCDyVrJRk
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added size/s documentation Improvements or additions to documentation labels Oct 4, 2026
@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Oct 4, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: afecd20b13a2b2967eb609444eb8313621d5603e
Local-runs: none

Read-only shape: the diff against the merge base 759dbe9, card #21583 with every comment, and this head's check-runs; nothing built or run locally. Reviewed by the dispatch seat in seat (served tier equals the constant's value, read from get_session). Review face: skills/**, governed rule text (Tier H). Readings taken at 2026-10-04T01:16Z.

① Derived judgments

  • Accept set: unchanged. Prose in one published skill file (skills/objectstack-i18n/SKILL.md +14/−7); no schema, export, lint rule, error code or runtime behaviour moves. Clause-②: no holds; the text narrows what an author is told is keyable or refused, never widens.
  • The three ruled places, each read against content/docs/protocol/kernel/i18n-standard.mdx :1039–1058 (the reference page triage ruled to mirror) by this seat: the _actions.{action_name} row now names params.{param_name}.options.{value} (an inline option's stored value), outcomeMessages.{outcome}, resultDialog.title / .description / .acknowledge only under an action that declares a resultDialog, and resultDialog.fields.{path} (the literal path, dots included), and says the same keys hold under globalActions.{action_name}; the globalActions line says a key naming a bound action is an error whose message names the objects.{owner}._actions.{action_name} key; the translation-target-unknown paragraph names the three action-entry error shapes and the shared option warning, with the field-backed param (no inline options) not judged. Every sentence matches a row of that table; no second vocabulary; the gate's internals are not restated.
  • The dev read the gate source (packages/lint/src/validate-translation-references.ts, checkActionEntry from both loops) and found page and gate agree; the page was not touched, as instructed.

② Semver level

  • No released package publishes from this diff; no changeset owed; skip-changeset is the correct declaration. No ADR-0087 disposition applies.

③ Boundary flags

  • Dev flags: open_questions empty; one noted-not-filed Acceptance note (the reason clause for the field-backed param, left out for the budget) — agreed, not a card.
  • Ratchet, read off the head blob by this seat against the base: 496 → 503 lines (+7, budget ≤ +8); 4752 → 5032 tokens (ceiling 6338); catalog SKILL.md sum 4397 → 4404. No ceiling moved.
  • Deviation read: the dev's first pr_create was refused by the fleet write-pace budget (exit 10) and sent once more after the window reopened on the same route — a pacing wait, not a route change; recorded, no action.
  • Check-runs on this head at this write: Governed Surface Queue Guard success, TypeScript Type Check lanes mostly complete; Lint & Repo Gates, Type Check · workspace, Test Core 1/6 and 2/6 in progress — the enqueue gate reads them at landing, not this record.

Implemented-by: claude/issue-21583-i18n-skill-action-entry-keys
Reviewed-by: session_01CB6W87z22K2yjUCDyVrJRk

VERDICT: PASS

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

维护者速读(终稿)— PR #21656(#21583)· skills seat 1 · 2026-10-04T01:32Z

改了什么: 发布的 objectstack-i18n 技能里三处与 os validate 实际判定脱节的句子。① bundle 形状表的 _actions.{action_name} 行补齐 action 条目下可翻译的键:参数的内联选项值(params.{param_name}.options.{value},错键是 warning)、outcomeMessages.{outcome}、resultDialog 的 title / description / acknowledge(只在 action 声明了 resultDialog 时合法)、resultDialog.fields.{path}(字面 path,含点),并说明同样的键在 globalActions.{action_name} 下同判;② globalActions 那句写明:键名指向绑定对象的 action 是 error,报错会点名该写的 objects.{owner}._actions.{action_name};③ translation-target-unknown 段补上三种 error 情形与共用的选项 warning。净 +7 行(预算 ≤ +8),token 4752 → 5032(上限 6338 未动)。

为什么改: 这是你本人在 spec 席对话里点名要立卡修的那处(卡正文引原话)。技能是 AI 写翻译包的直接依据;旧文本既不告诉作者 outcomeMessages 与 resultDialog.fields 的文案可以翻译,也不告诉它在无对话框的 action 下写对话框文案会被 os validate 以 error 拒绝。参考页 i18n-standard.mdx 早已写全,本 PR 只是把技能对齐到参考页,不另造词汇。

风险与代价(含回滚): 纯技能文本,不碰 packages/**,无 changeset(skip-changeset);dev 逐条核过 packages/lint/src/validate-translation-references.ts 与参考页一致,未动参考页。席内契约复核 PASS(5975318963),CI 全绿。回滚 = revert 单个 commit afecd20。

席位意见: 建议批准。三处措辞逐句对照参考页 :1039–1058 的表核过,无第二套词汇,也没有复述门禁内部;一处可选的理由句(字段引用型参数为何不判)为守预算未写,记在 Acceptance notes。

你要做的(一个动作): 在 PR #21656 上给一次 APPROVED review;批准后由席位清标、ready、挂 auto-merge 入队。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/s skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

2 participants