実行セマンティクス、制約、セキュリティ

最終更新: 2026年7月21日

Scriptランタイムでどのように動作するか(順序、トランザクション、エラー、ロック)、保存時にどのような静的制約を受けるか、そして セキュリティモデルを整理します。文法は Statement カタログ値式、実践的な組み合わせは クックブック を参照してください。

実行順序とモード

  • statements上から下へ順次実行されます。Return に到達すると、その時点で終了します。
  • Sync はリクエストを処理する経路で、Async はバックグラウンドで実行されます。 実行場所の区別にすぎず、結果はどちらであっても Return の値です(呼び出しのレスポンス形式は Script 概要のリクエストとレスポンス実行モード を参照)。
  • 能力(capability)からモードへ: statement ツリーに ExternalIoHttp 外部呼び出し)、MediaIngestMedia ファイルのインジェスト。fields.file{ source, encoding }。url・base64 共通)、LongRunning(大量の Loop など)のいずれか一つでもあれば、executionModeAsync 強制になります。この三つは別個の能力であり、下記の 静的制約 でカウント対象が分かれます。

実行セマンティクス

Guard(事前条件)

専用の guard 文はありません。Ifthen:[Return] で表現します。条件に違反した場合は結果を返し、以降の statement は実行しません(guard のない Script も当然可能です)。

{ "type": "If", "condition": { "<": [ "{ /wallet/fields/balance/en-US }", "{ /payload/fields/cost }" ] },
  "then": [ { "type": "Return", "value": { "ok": false, "reason": "insufficient credit" }, "statusCode": 402 } ] }

トランザクションなしと best-effort 補償

Scriptトランザクションではありません。 失敗した場合、エンジンはそれまでに行った操作の補償(compensation)を試み、エラーの原因を返しますが、次の制限があります(設計上許容しています)。

  • 削除の取り消しは新しい sys.id を作るため、これを指していた参照が壊れます(生成のロールバックは容易で、更新には before-image が必要です)。
  • 外部効果Http)は不可逆です(すでに送信された呼び出しと課金は取り消せません)。
  • プロセスがクラッシュした場合、未補償の状態(orphan)が残ることがあります。

真の原子性が必要な場合は、ユーザーが Script で直接補償するか、取り消せない操作(外部呼び出しなど)を最後に配置します。「連鎖はできるがロールバックはできず、しかも安全に見える」順序が最も危険です。

楽観的ロック

update/patch の競合ResourceUpdateResourcePatchversion で絞ります。version(値式、Int)を渡すと、対象の現在の sys.version一致する場合のみ更新し、不一致の場合は バージョン競合エラーで abort されます(Try/catch で局所的に処理できます)。省略すると検査なしの last-write-wins になります。通常は ResourceReadResourcePageRead で先に読み込み、その sys.version を渡します(クックブックの楽観的ロック CAS を参照)。

origin 基準の書き込み

書き込みは常に origin(draft)に反映され、delivery(CDA/ACDA)への公開は publish で制御します(ResourceCreate/ResourceUpdate/ResourcePatchpublish、または ResourcePublish/ResourceUnpublish)。

何が失敗か

  • 本当の失敗は statement のランタイムエラーです。Http の最終 status が 400 以上(4xx·5xx。ignoreStatusCode: true なら失敗ではない)かタイムアウト、応答本文が 10MiB を超える、リソース操作の失敗(対象なし、バージョン競合、未対応の演算など)。このような失敗は エンジンが abort して補償し、Try/catch/finally で局所的に処理できます。
  • Return はエラーではなく正常な早期終了です。catch の対象ではありません(ユーザーによる throw の概念はありません)。
  • catch の中では /error{ message, statement } を参照します。

サーバー側集計なし

count、sum、group-by 専用のサーバー操作はありません。ResourcePageRead の巡回と SetVar/JsonLogic で計算するため、fetch サイズと maxIterations に縛られます(数百万件の集計には不向きです)。

待機と遅延なし

Script には Delay 文はありません。Script はリクエスト経路(Sync)またはバックグラウンド(Async)で 一度実行されて終わりであり、外部 job が終わるまで内部で待機したりポーリングしたりしません(Async の結果は別です。呼び出し元が 202 で受け取った requestId でポーリングして Return の値を取得します)。

静的制約(保存時の検証)

以下は Script保存(作成/更新)する時点で検査されます。違反すると保存が拒否されます(ランタイムではなく作成時の失敗です)。

制約デフォルト値
外部 I/O があれば executionModeAsync該当なし
Loopbody 内で Http 外部呼び出しと Media ファイルのインジェストを 禁止該当なし
定義ごとの Http 外部呼び出しの最大数3(maxExternalIo
定義ごとの SetVar の最大数(ネスト含む)5(maxSetVar
定義ごとの 全 statement の最大数(ネスト含む)15(maxStatements
Http.retry の上限2(maxHttpRetry

上限はサーバー設定(weegloo.core.script.*)で調整できます(上記はデフォルト値です)。

Media ファイルのインジェストは MediaIngest 能力であり、Http 外部呼び出し(ExternalIo)とは異なり、maxExternalIo(3)の上限には含まれません。 ただし Async 強制と Loop body 禁止は Http と同じく適用されます。

時間予算(ランタイム)

モードデフォルト予算
Sync10秒(syncTimeoutMs
Async60秒(asyncTimeoutMs

プランごとの個数上限

ScriptBillable リソースであり、Organization ごとの個数がプランごとに制限されます。

PlanScript の個数
Free3
Basic10
Pro50
Enterprise無制限

上限に達すると新しい Script の作成が拒否されます(他の Billable リソースと同じ経路です)。

セキュリティモデル

secret ヘッダー

Http.headerssecret:true の項目は CMA(管理者)専用であり、エンドユーザー(ServiceUser)には公開されず、送信の直前にのみ復号されます。LLM API キーのような秘密をここに置きます(App Bundle にパッキングされる際も secret 値はマスキングされ、元の space の外には出ません)。

実行アイデンティティと認可

  • 実行アイデンティティ: 実行中のすべてのリソース操作は、/execute を呼び出したユーザーのアイデンティティで実行されます。作成または更新されるリソースの createdBy/updatedBy は呼び出し元となり、createdBy: ":self" スコープも呼び出し元を基準に解決されます。
  • 認可の境界は二つであり、ランタイムでは statement ごとにリソース権限を再検査しません。
    1. 作成時(保存): Script を保存する際に、作成者がそれらの statement が使う リソースとアクションの権限を実際に持っているかを検査します。一つでも欠けていれば保存が拒否されます(WGL403015)。つまり、権限のない操作を含む Script はそもそも保存されません。
    2. 呼び出し時(/execute: 呼び出し元の Script Execute 権限のみを検査します。権限がなければ 403 です。通過すると、statement ごとのリソース権限はランタイムで再確認せずに実行します。プログラミングにおける関数の実行権限と同じ方式です。関数を実行する権限さえあれば、その中の個々の操作の権限は再び問われません。
  • 所有権スコープ: where フィルターの createdBy: ":self" は「現在の呼び出し元が作成したものだけ」を意味します(例: 自分のウォレットのみ照会)。
  • 委任された権限(作成時の注意): 上記の二つの境界を合わせると、Script の実行は 作成者の権限を委任されて行われるのと同じです。呼び出し元は Execute 一つだけあればよく、Script 内の statement は作成者が保存時に認可された範囲でそのまま実行されます。したがって、呼び出し元が自分自身ではできないリソース操作も Script を通じて起こりえます。作成者に付与された権限がそのまま その Script の影響範囲となるため、Script に含める動作は慎重に決めます。

要約チェックリスト

保存前に次を確認します。

  • 外部呼び出し(Http)または Media ファイルのインジェストがあれば、executionMode"Async" です。
  • Loop body の中に外部呼び出しを入れていません。
  • 外部呼び出しは 3 個以下、SetVar は 5 個以下、全 statement は 15 個以下です。
  • secret 値は Http.headerssecret:true でのみ入れています。
  • 取り消せない操作(外部呼び出し)はできるだけ後ろに置いています。
  • update/patch の競合が心配なら ResourceUpdateResourcePatchversion を使います。
  • 結果を返すには Return.value を明示しています。