Skip to content

Console half of ActionSchema.onSuccess navigation (objectstack#9566/#9474): SPA route hop, executeAPI handling, ${result.*} interpolation scope #5221

Description

@os-elon

Filed by the objectstack domain:spec seat (os-elon, session_016D9wdJR14KKCxz1WgdAzcw) — the downstream card pre-registered in objectstack#9566's ACCEPT (comment 5328433458). Duplicate-searched: objectui#5034 is the plugin-form navigateOnSuccess key (different key, different call sites, itself blocked on objectui#4989) — deliberately NOT this card.

Upstream contract (landed)

Blocked-by: objectstack-ai/objectstack#9566 · Blocked-by: objectstack-ai/objectstack#9474both satisfied: the spec half merged 2026-08-18T14:15Z as objectstack PR #9601 (squash 07e630e). The ruled shape (maintainer 「9566 同意」, recorded on objectstack#9566):

  • ActionSchema.onSuccess — closed strict object { navigate: string (route/URL template), openIn: 'self' | 'newTab' }, refine-scoped to action types api | script; materialized .default('self') so parse output always carries the resolved member (the console branch needs no fallback of its own).
  • Interpolation scope for the navigate template: ${param.*} + ${ctx.*} + ${result.*} (NEW — the server response).
  • Defaults split by surface: schema-declared onSuccess'self' (SPA route hop, popup-blocker immune); the shipped handler-return convention { redirectUrl } WITHOUT openIn keeps its 17.0.0 new-tab behavior — no silent flip; a handler may return openIn: 'self' explicitly.
  • ⚠️ Spelling tripwire, pinned both ways in spec: the ruled enum value is 'newTab'; the shipped top-level openIn (type 'url', 17.0.0) spells 'new-tab'. Spec refuses the crossover spelling with an issue.input-keyed error in each direction — don't "harmonize" as a rider here.

Scope (from the pre-registration)

  1. consoleServerAction.ts: SPA-navigation branch honoring schema onSuccess (and a handler-returned openIn: 'self') — route hop via the SPA router, not window.open/window.location.
  2. executeAPI navigation handling for api-type actions.
  3. interpolateTarget (or the console's interpolation impl) gains the result scope member.

Dispatch precondition (for the objectui seat)

objectui's @objectstack/spec pin must cover objectstack 07e630e (PR #9601's squash) — verify ancestor relation via REST compare before dispatch, not local merge-base.

On landing

File/trigger the objectstack follow-up: packages/spec/liveness/action.json's onSuccess.navigate / onSuccess.openIn entries amend plannedlive, citing the console read sites (the amend-on-landing instruction is recorded in objectstack#9566's dev report).

Customer ref: steedos-labs/os-project-titanwind-ehr#1172 (clone-then-jump leaves the user on the old record).

Metadata

Metadata

Assignees

Labels

domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpm:queue

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions