Skip to content

docs(skills): teach an action param's widget key in the action dialog - #30684

Merged
os-zhuang merged 1 commit into
mainfrom
claude/project-thread-6x86qk
Nov 6, 2026
Merged

os-zhuang merged 1 commit into
mainfrom
claude/project-thread-6x86qk

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Elon · project thread

domain:skills#1 · os-elon-musk · session_016WV4cyNZ7aKsfF5vTBgKKn

Fixes #30549

Clause-②: no
Metadata-protocol: none

维护者速读

  • 改了什么: 两个技能文件教动作参数的 widget:objectui 协议规则的内联参数清单加上 widget(写注册过的字段控件名,如 text 参数写 'permission-ref' 就是权限集选择器;未注册的名字退回 type 控件,批量对话框不读它,服务端仍按 type 校验);objectstack-ui 动作规则说清字段型参数只在沿用或重述字段 type 时继承字段的 widget,改了 type 要自己写 widget。
  • 为什么改: PR feat(ui): an action param's widget draws the named widget, so the action dialog can pick a permission set (#30260) #30543 落地后控制台已读这个键,但技能没教,作者和 AI 仍写自由文本参数;原句还暗示字段型参数总会继承字段控件,与代码不符。
  • 风险与回滚: 只改文档,无 schema、键或行为变化;token 预算靠同文件删重复句付清,不抬上限。回滚即撤销本 PR。
  • 先看: ① skills/objectui/rules/protocol.md 的 Inline params 条;② skills/objectstack-ui/rules/actions.md 的 Action Parameter Patterns 段;③ 两文件中被删的重复句(付账用)。
  • 两分钟验证: node scripts/check-skills-token-ratchet.mjs,预期 actions.md 2259/2259、protocol.md 4352/4368,整体通过。
  • 需要你做的: 审阅并批准(skills/** 为 Tier H,需人工合并)。

What changes

  • skills/objectui/rules/protocol.md, "Inline params": the widget-config list gains widget. It names a registered field widget that draws the param instead of its type widget ('permission-ref' on a text param is the permission-set picker); an unregistered name keeps the type widget; the selection bar's bulk dialog ignores it; the server validates by type.
  • skills/objectstack-ui/rules/actions.md, "Action Parameter Patterns": the field's widget is inherited only while the param keeps or restates the field's type; a param that overrides type names its own widget.
  • One root changeset, '@objectstack/skills': patch.

Every taught fact is read off origin/main (b77c160a), not the card's prose:

  • ui/packages/fields/src/resolveActionParams.ts inheritedWidget: the param's own widget wins; with no type the field's widget is inherited; with a type, only when resolveParamWidgetType(param.type) === resolveParamWidgetType(field.type). Inline and unresolved branches copy param.widget.
  • ui/packages/app-shell/src/utils/paramToField.ts authoredWidgetKey: a name resolveFormWidgetType resolves (not the text fallback) replaces the type widget key; otherwise the type widget stays.
  • packages/spec/liveness/action.json params.widget: live; the dispatcher still validates the submitted value by type; not read by plugin-grid bulkParamToField.
  • permission-ref is a registered widget (ui/packages/fields/src/FieldEditWidget.tsx, ui/packages/components/src/renderers/form/form.tsx).

Token ratchet: paid by same-file deletion, no ceiling raise

file before (bytes / tokens) after (bytes / tokens) ceiling
skills/objectstack-ui/rules/actions.md 9024 / 2256 9033 / 2259 2259
skills/objectui/rules/protocol.md 17456 / 4364 17408 / 4352 4368

Lines: actions.md 179 → 180, protocol.md 377 → 377 (whole-file wc -l). No SKILL.md changes, so the package's SKILL.md sum is unchanged.

Deleted restatements (each already said elsewhere in the same file):

  • protocol.md: "resolve the value in the host … or carry it on a text node's content" under Fields That are NOT Evaluated (the Bindable Text Keys rule says it, and now carries the SchemaRenderer wording); "There is no way to opt a type in from metadata …" (the closed-list sentence above it says it); "the third row works today, but its channel is an open contract question" (the Keys Live on the Node rule says it, and the sentence already points there).
  • actions.md: "so a body that must scope by org reads it from ctx explicitly" (the preceding sentence says how to read the org); the skipped while newTabUrl is set comment (the prose says newTabUrl skips the round-trip); static template; in a comment (the heading line says static target).

Why

After PR #30543 the action dialog draws a param's widget, but neither skill named the key, and the actions rule promised that every field-backed param inherits the field widget. Authors kept writing free-text params where a picker exists.

Acceptance notes

  • The bulk dialog's limit is stated as a limit, not taught as supported (card "Not in scope").
  • The field-backed bullet in protocol.md still lists what is inherited without widget; the inheritance rule is taught once, in actions.md, to stay inside the ceiling.

Verification

All local readings are on head f49a7c33 (the only commit), base b77c160a.

Gates: 44 derived families + pnpm lint

node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 44 families from the diff; each ran with its exit code captured before any pipe, then --ran reconciled: ✓ dispatch-gates --ran: 44 derived famil(ies) accounted for — 43 run, 1 NOT-MEASURED (1 DERIVED from a recorded exit 3).

  • 43 families: exit 0, including check-skills-token-ratchet.mjs (and --self-test), pnpm --dir ui exec vitest run scripts/, check:skill-examples, check:doc-formula-expressions, check:doc-authoring, check:skill-identifier-liveness, check:nul-bytes, check-empty-changeset, check-changeset-no-major, check-adr-0087-registration.
  • NOT MEASURED: pnpm check:dual-build-cjs-loads, reason: exit 3, PREREQUISITE NOT MET (needs a whole-tree build; only the @objectstack/client-react..., @objectstack/formula, @objectstack/lint... closures were built). CI runs it.
  • pnpm lint: exit 0.
  • check-commit-card-trailers.mjs --range origin/main..HEAD: pass.

Generated by Claude Code

The objectui protocol rule lists `widget` among an inline param's widget
config: a registered field widget draws the param instead of its `type`
widget, an unregistered name keeps the `type` widget, the bulk dialog does
not read it, and the server validates by `type`. The objectstack-ui actions
rule says a field-backed param inherits the field's `widget` only while it
keeps or restates the field's `type`.

Paid inside both files' token ceilings by deleting restatements.

Co-authored-by: Claude <[email protected]>
Claude-Session: https://claude.ai/code/session_016WV4cyNZ7aKsfF5vTBgKKn
@github-actions github-actions Bot added size/s documentation Improvements or additions to documentation tooling Fix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface labels Nov 5, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:skills#1 · os-elon-musk · session_016WV4d1mkgEris4MHHLjtnk

Contract-review-claim: session_016WV4d1mkgEris4MHHLjtnk · head f49a7c3 · 2026-11-05T22:26Z

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:skills#1 · os-elon-musk · session_016WV4d1mkgEris4MHHLjtnk

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: f49a7c3310d2ed52455622b367105b1dad8f7625
Local-runs: none
Scope: skills/objectui/rules/protocol.md, skills/objectstack-ui/rules/actions.md (hits) + cited (read at origin/main, merge-base b77c160a) ui/packages/fields/src/resolveActionParams.ts, ui/packages/app-shell/src/utils/paramToField.ts, packages/spec/src/ui/action.zod.ts, packages/spec/liveness/action.json, packages/runtime/src/action-execution.ts, ui/packages/plugin-grid/src/components/bulkParamToField.ts, ui/packages/plugin-grid/src/components/BulkActionDialog.tsx, ui/packages/fields/src/index.tsx, ui/packages/fields/src/FieldEditWidget.tsx, ui/packages/components/src/renderers/form/form.tsx, scripts/check-skills-token-ratchet.mjs, skills/objectstack-data/references/data-hooks.md, skills/objectui/evals/protocol.json, .changeset/30549-skills-action-param-widget.md

① Derived judgments

  • Diff = 3 files (changeset, actions.md +6/−5, protocol.md +10/−10). No packages/spec/src/**, no ui/**. Published accept set unchanged; the only face is governed rule text.
  • widget draws the named registered field widget instead of the type widget; unregistered keeps the type widget: true, paramToField.ts:42-47 (authoredWidgetKey) and :119; spec describe agrees, action.zod.ts:261-266.
  • 'permission-ref' on a text param is the permission-set picker: registered at FieldEditWidget.tsx:192, form.tsx:745; mirrors action.zod.ts:264.
  • The server validates by type: action-execution.ts:3095-3096,3192 (validateActionParams / valueSchemaFor); liveness note action.json params.widget.note agrees.
  • The selection bar's bulk dialog ignores widget, taught as a limit: BulkActionDialog.tsx:792-795 mounts by field.type from bulkParamToField.ts:132; getLazyFieldWidget takes only the type (index.tsx:4991-4992). The card's "Not in scope" is honoured.
  • Field-backed inheritance (actions.md:173-176): the field's widget is inherited only while the param keeps or restates the field's type: true, resolveActionParams.ts:604-613 (inheritedWidget), wired at :894.
  • Liveness: packages/spec/liveness/action.json props.params.children.widget is live (verified 2026-11-05) with the same evidence.
  • Token payment, each deletion checked for another home: the Fields-NOT-Evaluated host/content sentence lives at head protocol.md:95-97 (cross-referenced at :32); "no way to opt a type in from metadata" at :68-70; the properties channel "open contract question" at :156-158 and :247-248 (eval protocol.json:25 keeps its source); the actions.md org-scope consequence is implied by the adjacent "Bodies execute trusted (ctx.api/ctx.engine bypass RLS/FLS)" (:114-118) and taught in objectstack-data/references/data-hooks.md:612-622; the two // comments are restated in the heading :123 and prose :147. No rule dropped.
  • Ratchet re-measured: actions.md 2256 → 2259 (ceiling 2259, check-skills-token-ratchet.mjs:835); protocol.md 4364 → 4352 (ceiling 4368, :1048). No ceiling raise.

② Semver level

'@objectstack/skills': patch with Clause-②: no / Metadata-protocol: none; not skip-changeset. Docs-only skill text ⇒ patch, matching the PR body.

③ Boundary flags

  • PR author objectstack-fleet[bot]. Fixes #30549 present; Clause-②: no and Metadata-protocol: none re-derived correct; no Skills-docs: line owed.
  • Deviation "default model; the seat's at-tier review before ACCEPT": this record is that review.
  • Deviation "no evals edited": neither skill's evals pin the inline-params widget list; nothing owed.
  • open_questions: none. The field-backed bullet in protocol.md:311-313 omits widget from its inherited list; inheritance is taught once in actions.md. An omission, not a false promise; no card.
  • File surface respected.
  • Head check-runs at 2026-11-05T22:29Z: 0 red, 24 still in progress. All-green is the landing-time check.

④ Design judgment

  • skills/objectui/rules/protocol.md: the new widget sentence sits in the Inline params bullet where the card points and names the registered/unregistered split, the dialog-only scope and validation by type; each clause matches paramToField.ts and the liveness note. Holds.
  • skills/objectstack-ui/rules/actions.md: the parenthetical corrects the old over-promise with the exact condition inheritedWidget implements. Holds at 2259/2259.
  • must-fix: none. should-fix: none required. Optional at a later ceiling raise: restore one explicit clause that a trusted body scopes by org itself (actions.md:117-118).

Implemented-by: claude/project-thread-6x86qk
Reviewed-by: session_016WV4d1mkgEris4MHHLjtnk

VERDICT: PASS

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:skills#1 · os-elon-musk · session_016WV4d1mkgEris4MHHLjtnk

维护者速读

  • 改了什么:两个技能文件教动作参数的 widget:objectui 协议规则的内联参数清单加上 widget(写注册过的字段控件名,如 text 参数写 'permission-ref' 就是权限集选择器;未注册的名字退回 type 控件;批量对话框不读它;服务端仍按 type 校验);objectstack-ui 动作规则说清字段型参数只在沿用或重述字段 type 时继承字段的 widget。
  • 为什么改:PR feat(ui): an action param's widget draws the named widget, so the action dialog can pick a permission set (#30260) #30543 落地后控制台已读这个键,但技能没教,作者和 AI 仍写自由文本参数;原句还暗示字段型参数总会继承字段控件,与代码不符。
  • 风险与回滚:只改技能文档,无 schema、键或行为变化;token 靠同文件删重复句付清,不抬上限。回滚即 revert 本 PR。
  • 先看:skills/objectui/rules/protocol.md 的 Inline params 条;skills/objectstack-ui/rules/actions.md 的 Action Parameter Patterns 段。
  • 两分钟验证:node scripts/check-skills-token-ratchet.mjs,actions.md 2259/2259、protocol.md 4352/4368。
  • 需要你做的:批准并合并(skills/** 为 Tier H)。契约复核 PASS 评论 6671247716,Head-sha f49a7c3310d2ed52455622b367105b1dad8f7625。
  • 席位意见:可合。

席位核对 — ACCEPT · head f49a7c3

@objectstack-fleet objectstack-fleet Bot added the pm:awaiting-merge PR only: landing waits on the maintainer's own review and merge (SKILL.md 复核 ②); never on an issue label Nov 5, 2026
@os-zhuang
os-zhuang marked this pull request as ready for review November 6, 2026 00:57
@os-zhuang
os-zhuang added this pull request to the merge queue Nov 6, 2026
Merged via the queue into main with commit a4c3246 Nov 6, 2026
62 checks passed
@os-zhuang
os-zhuang deleted the claude/project-thread-6x86qk branch November 6, 2026 01:19
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 pm:awaiting-merge PR only: landing waits on the maintainer's own review and merge (SKILL.md 复核 ②); never on an issue size/s tooling Fix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

skills: teach an action param's widget (objectui protocol inline params; objectstack-ui actions field-backed inheritance) once #30260 lands

2 participants