Rules: change sessions (NEWSESSION, APPLY)
Change session rules (NEWSESSION, NESTEDSESSION, APPLY)
-
Before introducing
NEWSESSION, the assistant MUST decide which session behavior is required. None of the choices below applies during anAPPLYtransaction — inside a global event handler or an applied action — where no session is created at all: the inner action is deferred and runs in the current session, inside the same transaction. The assistant MUST NOT expect an independent commit there.- isolated independent unit ->
NEWSESSION - isolated unit that must also see selected local properties
from the upper session ->
NEWSESSION NESTED (...) - isolated unit that must see all local properties
from the upper session ->
NEWSESSION NESTED LOCAL - child dialog or editor that must work with unsaved upper-session
objects and return its changes to that upper session
->
NESTEDSESSION
- isolated independent unit ->
-
For actions added to forms, there are two main patterns:
- readonly form pattern: the form is effectively browse-only, so actions added to it SHOULD run in a new session by default
- editable form pattern:
the form has editable properties, so any action added to it
that uses
NEWSESSIONMUST either:APPLY;IF canceled() THEN RETURN;beforeNEWSESSION, or be fully independent from unsaved changes in that form
-
Plain
NEWSESSIONis the default for isolated work that must not accidentally apply the caller's pending form changes.Typical patterns in the source:
- readonly list forms with
PROPERTIES(...) NEWSESSION NEW, EDIT, DELETE - status transitions or dependent document creation
after a preceding
APPLY - external or integration actions that isolate HTTP calls and persist their own results
- small immediate UI updates with
NEWSESSION { APPLY { ... } }
- readonly list forms with
-
If inner logic depends on upper-session local state such as selections, marks, or import buffers, the assistant MUST carry that state explicitly through
NESTED (...)orNESTED LOCALon the operator, or declare the property itselfDATA LOCAL NESTED, which carries it over without being listed on the operator. Neither route works underNEWSQL: on a connection of its own it migrates nothing, so the assistant MUST NOT combineNEWSQLwith a dependency on upper-session local state. -
A successful
APPLYclears the session, and with it everyLOCALproperty in it by default: after such anAPPLYreturns, a plainLOCALis empty again. AnAPPLYthat fails or is cancelled leaves the session as it was, locals included — which is why the assistant MUST NOT read aLOCALafterAPPLYto tell success from failure;canceled()is what tells them apart. Inside a nested session there is no clearing at all: the changes are copied to the parent session and the nested one is left standing, locals and all.Outside a nested session, a
LOCALvalue survives a SUCCESSFULAPPLYwhen EITHER:- the
LOCALis declared asNESTEDat declaration time (LOCAL NESTED name = Type ();orname = DATA LOCAL NESTED Type (...);), OR - the
APPLYexplicitly preserves it viaAPPLY NESTED (name1, ..., nameN)orAPPLY NESTED LOCALfor all locals.
The assistant MUST NOT rely on a plain
LOCALvalue computed before a SUCCESSFULAPPLYto still be readable after it. Two cases keep it: a nested session, which clears nothing at all, and an apply that failed or was cancelled, which leaves the session as it was. If a staged value must outliveAPPLY— for example, an import buffer read during post-apply follow-up — the assistant MUST either declare it withNESTED, or list it inAPPLY NESTED (...)(or useAPPLY NESTED LOCAL) at the call site. - the
-
When using
NEWSESSION NESTED (...)orNEWSESSION NESTED LOCAL, the assistant SHOULD preserve the same nested local properties onAPPLYif the result must be copied back to the upper session, for example withAPPLY NESTED (...)orAPPLY NESTED LOCAL. -
The assistant MUST NOT replace
NESTEDSESSIONwith plainNEWSESSIONfor child forms or dialogs attached to a parent object that may still be unsaved in the current form session. -
Before opening a fresh
NEWSESSIONfrom an action started on an edit form, the assistant SHOULD decide whether current form changes must be saved first.The common pattern is:
APPLY;IF canceled() THEN RETURN;NEWSESSION { ... }This pattern is used before status changes, document generation, and other isolated follow-up actions.
-
After
APPLY, the assistant MUST checkcanceled()only when later logic depends on whether the save succeeded — to early-return, skip a follow-up side effect, or roll back staged work.APPLYin an interactive context shows the constraint message to the user on its own. The assistant MUST NOT addIF canceled() THEN MESSAGE applyMessage()afterAPPLYin interactive actions solely to report the failure — it duplicates the message the platform already shows. Explicit surfacing viaapplyMessage()orthrowException(applyMessage())is required only for non-interactive callers (API endpoints, background integrations) where no dialog is shown.If
APPLYfails because of a constraint, the changes remain unsaved in the current session, and any followingAPPLYin the same session will also fail until the offending data is fixed or the changes are discarded (for example withCANCEL). -
The assistant SHOULD keep
NEWSESSIONblocks small and purpose-specific: isolate one unit of work, apply it if needed, and exit.The assistant MUST NOT introduce
NEWSESSIONmerely to hide session-visibility bugs. If upper-session changes must remain visible, nested session semantics are required. -
The body of
APPLYmay run more than once. The apply transaction MAY be retried automatically after an update conflict, a deadlock or a timeout — whether it is depends on the failure and on the attempt limit — and the applied action and the synchronous global handlers are inside what a retry repeats.So they MUST be safe to repeat. An irreversible external side effect — sending mail, calling an HTTP API, printing, writing a file — MUST NOT be done there: it belongs after the apply has succeeded, where
canceled()says whether it did.