Skip to content

spec: guard the confirmText + params PAIR at authoring time, once the 20 shipped sites have migrated to action.description #7428

Description

@os-zhuang

Follow-up split out of #7367 item 5, filed with the census measured rather than folded into that PR. Filed unassigned.

Blocked-by:#7278
Blocked-by:#7309

The structural fix

An action that declares bothconfirmText and a non-empty params shows the user two sequential dialogs for one decision — the confirm, then the param prompt. That is the defect class #7278 and #7309 are migrating away from, and the maintainer's 2026-08-10 ruling on #7278 gives the correct shape: carry the confirm question in description (now authorable, #7367) so one decision is one dialog.

Migrating the sites fixes today's instances. It does not stop the next one being written. The structural version is an authoring-time guard on the PAIR — the thing that would have prevented all 20 rather than repairing them — which is why #7367's item 5 raised it. This card carries it.

Why it is NOT in #7367, and why it is blocked rather than ready

Censused across the repo on origin/main @ 18ff1dab1: 20 shipped sites declare confirmText beside a non-empty params. (#7309 counts 16 in platform-objects; the four examples/app-showcase actions below are additional, and plugin-approvals contributes the two from #7278.)

FileLineAction
examples/app-showcase/src/ui/views/project.view.ts50set_labels
examples/app-showcase/src/ui/views/project.view.ts72assign_team
examples/app-showcase/src/ui/views/project.view.ts89reassign_account
examples/app-showcase/src/ui/views/project.view.ts105reschedule
packages/platform-objects/src/identity/sys-account.object.ts84unlink_account
packages/platform-objects/src/identity/sys-oauth-application.object.ts69disable_oauth_application
packages/platform-objects/src/identity/sys-oauth-application.object.ts89enable_oauth_application
packages/platform-objects/src/identity/sys-oauth-application.object.ts141rotate_client_secret
packages/platform-objects/src/identity/sys-oauth-application.object.ts166delete_oauth_application
packages/platform-objects/src/identity/sys-organization.object.ts151change_slug
packages/platform-objects/src/identity/sys-sso-provider.object.ts198delete_sso_provider
packages/platform-objects/src/identity/sys-team-member.object.ts70remove_team_member
packages/platform-objects/src/identity/sys-two-factor.object.ts93disable_two_factor
packages/platform-objects/src/identity/sys-two-factor.object.ts109regenerate_backup_codes
packages/platform-objects/src/identity/sys-user.object.ts99ban_user
packages/platform-objects/src/identity/sys-user.object.ts364delete_my_account
packages/platform-objects/src/identity/sys-user.object.ts403disable_two_factor
packages/platform-objects/src/identity/sys-user.object.ts420generate_backup_codes
packages/plugins/plugin-approvals/src/sys-approval-request.object.ts291approval_reject
packages/plugins/plugin-approvals/src/sys-approval-request.object.ts387approval_recall

Consequences, which is the whole reason this is a separate card:

So the guard is correct and its timing is not. It becomes shippable — refuse or warn — once #7278 and #7309 have migrated their sites and the census reaches zero. Standalone rather than a sub-issue because it merely depends on those cards; the fix does not fall inside either one's completion scope.

Design questions left open for whoever picks this up

Not decided here — they shape the authoring contract and deserve their own read:

  1. Severity. Refuse (a .refine on ActionSchema) vs a lint rule. A refusal is contract-first and declared = enforced; a lint rule is recoverable for third-party metadata already in the wild. The census reaching zero in-repo says nothing about third-party stacks.
  2. Scope of the predicate. Is confirmText + non-empty paramsalways wrong, or is there a legitimate shape — e.g. a destructive action whose params are all optional? Worth measuring against the migrated sites before encoding, rather than presuming.
  3. Whether the guard should also require description when params is present, or only forbid the pair. The ruling's "one condition, one wording" argues the former; that is a strictly bigger authoring demand and should be measured.

Verification note for the eventual fix

The census above was produced by a brace-balanced scan for confirmText inside an object literal carrying a non-empty params: array, excluding node_modules, dist and test files. Re-run it as the acceptance check: the guard is ready to ship when it returns 0.

Refs: #7367 (the description key this depends on), #7278 (ruling + the two approvals actions), #7309 (the platform-objects census), objectui#3126 (renderer-side precedent).


Generated by Claude Code

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions