The script declaration, and the grant that says what tenant data it may touch.

Scripts and grants

A script is a JavaScript module the platform runs at a defined moment. The kind says when: a guard before a transition, an action from a button or do run, a compute for a computed field, or a process in the background. The declaration names that kind and the source. What the module may call, and the name it exports, is the scripting runtime.

app billing "Billing" {}

script score compute js """
export function compute(ctx) {
  return ctx.record.total;
}
"""

script reconcile action using db read, write js """
export function runAction(ctx) {
  return db.transaction(() => {
    db.from("Note").insert({ invoice: ctx.record_id, body: "Reconciled" });
    return { effects: [{ kind: "refresh" }] };
  });
}
"""

entity Invoice {
  total: number

  workflow {
    initial Open
    states Open, Closed
    terminal Closed

    close: Open -> Closed {
      do run script reconcile
    }
  }
}

score has no using clause. It sees the record it was given and has no db. That is the usual shape of a guard or a compute that only looks at its own record.

reconcile says using db read, write. read lets the body query tenant data. write lets it insert, update, and delete. fsm lets it fire a transition. The words are on Scripts. A body that calls db with no grant is effect/script-grant-missing.

The source above is inline, js """…""". The same declaration can name a file beside the app, from "scripts/reconcile.js". yokec check reads that file next to the source.

A component is the other kind. Its grant is using sdk, and a page mounts it with use. That declaration is in Components. An spa page carries the same grant; see Single-page app pages.