Skip to content

onSuccess is authorable as of @objectstack/spec 17.1.0 and honoured by ActionRunner, but all four declared action surfaces drop it one hop before the runner #5493

Description

@os-support-ai

Filed unassigned by the dev seat implementing the @objectstack/spec 17.1.0 pin bump (#5328, branch claude/issue-5328-spec-pin-17-1-0). Not claiming — this is the wiring half, which the pin-bump card explicitly does not take as a rider.

What was measured

@objectstack/spec@17.1.0 declares onSuccess on the ActionSchema contract. It is entirely new in this release:

reading 17.0.0 17.1.0
occurrences of onSuccess in dist/**/*.d.ts 0 53

objectui's runtime has honoured the key for some time — packages/core/src/actions/ActionRunner.ts:

323:  onSuccess?: ActionDef | ActionDef[];
1196:    // Execute onSuccess/onFailure callbacks
1197:    if (result.success && action.onSuccess) {
1198:      const callbacks = Array.isArray(action.onSuccess) ? action.onSuccess : [action.onSuccess];

So both halves of check:action-forward-parity's owed-set now hold — authorable on the contract AND read off the forwarded def at execute time — and the gate fails on the pin bump, naming four surfaces:

  • action:buttonpackages/components/src/renderers/action/action-button.tsx
  • action:iconpackages/components/src/renderers/action/action-icon.tsx
  • action:grouppackages/components/src/renderers/action/action-group.tsx
  • action:menupackages/components/src/renderers/action/action-menu.tsx

element:button (the inline contract) does not fail: onSuccess is not on spec's InlineActionSchema pick list, so it is not owed there.

Counter-probe that this is the bump and not a pre-existing red: check:action-forward-parity exits 0 on origin/main (2524e7450) with the 17.0.0 lockfile, and 1 on the same tree with only pnpm-lock.yaml moved to 17.1.0.

Why it matters

This is the "shipped green while silently dropped" class the gate was built for, in its most reachable form: as of the bump an author can write onSuccess in metadata, the publish/save gate accepts it because the spec declares it, and ActionRunner is ready to execute the chained actions — but on all four declared surfaces the key never reaches the runner. The action succeeds and the declared follow-up silently does not run.

Scope

Add onSuccess to the forwarded literal in the four renderers, following the established house pattern in those files (an explicit whitelist key with a comment stating why it is forwarded, e.g. bodyShape / resultDialog), and delete the four KNOWN_GAPS entries added alongside the pin bump — the gate ratchets, so a stale entry fails once the key is forwarded.

Recorded meanwhile as KNOWN_GAPS in scripts/check-action-forward-parity.mjs ("really dropped, filed, not fixed here"), referencing this card.

Refs: #5328 (the pin bump that made it owed) · #4202 (the sibling objectName / onClick gaps in the same ledger) · objectstack#6837 / #6938 (the motivating class).

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpm:blocked

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions