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 both confirmText 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.)

File Line Action
examples/app-showcase/src/ui/views/project.view.ts 50 set_labels
examples/app-showcase/src/ui/views/project.view.ts 72 assign_team
examples/app-showcase/src/ui/views/project.view.ts 89 reassign_account
examples/app-showcase/src/ui/views/project.view.ts 105 reschedule
packages/platform-objects/src/identity/sys-account.object.ts 84 unlink_account
packages/platform-objects/src/identity/sys-oauth-application.object.ts 69 disable_oauth_application
packages/platform-objects/src/identity/sys-oauth-application.object.ts 89 enable_oauth_application
packages/platform-objects/src/identity/sys-oauth-application.object.ts 141 rotate_client_secret
packages/platform-objects/src/identity/sys-oauth-application.object.ts 166 delete_oauth_application
packages/platform-objects/src/identity/sys-organization.object.ts 151 change_slug
packages/platform-objects/src/identity/sys-sso-provider.object.ts 198 delete_sso_provider
packages/platform-objects/src/identity/sys-team-member.object.ts 70 remove_team_member
packages/platform-objects/src/identity/sys-two-factor.object.ts 93 disable_two_factor
packages/platform-objects/src/identity/sys-two-factor.object.ts 109 regenerate_backup_codes
packages/platform-objects/src/identity/sys-user.object.ts 99 ban_user
packages/platform-objects/src/identity/sys-user.object.ts 364 delete_my_account
packages/platform-objects/src/identity/sys-user.object.ts 403 disable_two_factor
packages/platform-objects/src/identity/sys-user.object.ts 420 generate_backup_codes
packages/plugins/plugin-approvals/src/sys-approval-request.object.ts 291 approval_reject
packages/plugins/plugin-approvals/src/sys-approval-request.object.ts 387 approval_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 params always 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

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions