feat(executor): thread the defining node into ExecRequest (Phase 4b C2)

Carry the resolved script's owner (its defining node) from dispatch into
the executor so `import` resolution can be lexical (§5.5). The executing
app (`app_id`) stays the SDK isolation boundary; `script_owner` is a
separate axis — the lexical origin for imports.

- `ExecRequest.script_owner: Option<ScriptOwner>` (serde default; `None`
  falls back to `App(app_id)` in the engine for old payloads / cluster wire).
- `ScriptOwner` gains `Serialize`/`Deserialize` for the wire.
- The engine computes `default_origin` and hands it to the resolver
  (used fully in C3; the resolve() lookup already uses it).
- Every dispatch site sets it from the resolved `Script.owner()`:
  the 4 dispatcher arms (queue/trigger/http/invoke_async, via a new
  `ResolvedTrigger.script_owner`), the orchestrator id-bypass, and the
  `invoke()` SDK path (new `ResolvedScript.owner`, so a group script
  invoked by an app resolves imports from the group).

Behaviour-preserving: app scripts still resolve `App(app_id)`; group
scripts can't yet carry imports (lifted in C4).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
MechaCat02
2026-06-26 07:17:33 +02:00
parent 7fef098b48
commit 1844bef132
25 changed files with 86 additions and 17 deletions

View File

@@ -23,6 +23,7 @@ fn req(body: serde_json::Value) -> ExecRequest {
rest: String::new(),
sandbox_overrides: ScriptSandbox::default(),
app_id: AppId::new(),
script_owner: None,
principal: None,
trigger_depth: 0,
root_execution_id: execution_id,

View File

@@ -74,6 +74,7 @@ fn req(app_id: AppId) -> ExecRequest {
rest: String::new(),
sandbox_overrides: ScriptSandbox::default(),
app_id,
script_owner: None,
principal: None,
trigger_depth: 0,
root_execution_id: execution_id,

View File

@@ -137,6 +137,7 @@ fn req(app_id: AppId) -> ExecRequest {
rest: String::new(),
sandbox_overrides: ScriptSandbox::default(),
app_id,
script_owner: None,
principal: None,
trigger_depth: 0,
root_execution_id: execution_id,

View File

@@ -51,6 +51,7 @@ fn baseline_request() -> ExecRequest {
rest: String::new(),
sandbox_overrides: ScriptSandbox::default(),
app_id: AppId::new(),
script_owner: None,
principal: None,
trigger_depth: 0,
root_execution_id: execution_id,

View File

@@ -257,6 +257,7 @@ fn baseline_request(app_id: AppId) -> ExecRequest {
rest: String::new(),
sandbox_overrides: ScriptSandbox::default(),
app_id,
script_owner: None,
principal: None,
trigger_depth: 0,
root_execution_id: execution_id,

View File

@@ -66,6 +66,7 @@ fn baseline_request(app_id: AppId) -> ExecRequest {
rest: String::new(),
sandbox_overrides: ScriptSandbox::default(),
app_id,
script_owner: None,
principal: None,
trigger_depth: 0,
root_execution_id: execution_id,

View File

@@ -194,6 +194,7 @@ fn baseline_request(app_id: AppId) -> ExecRequest {
rest: String::new(),
sandbox_overrides: ScriptSandbox::default(),
app_id,
script_owner: None,
principal: None,
trigger_depth: 0,
root_execution_id: execution_id,

View File

@@ -117,6 +117,7 @@ fn baseline_request(app_id: AppId, script_id: ScriptId) -> ExecRequest {
rest: String::new(),
sandbox_overrides: ScriptSandbox::default(),
app_id,
script_owner: None,
principal: None,
trigger_depth: 0,
root_execution_id: execution_id,

View File

@@ -58,6 +58,7 @@ impl InvokeService for FakeInvokeService {
Ok(ResolvedScript {
script_id: id,
app_id: app,
owner: None,
source,
updated_at: Utc::now(),
name,
@@ -114,6 +115,7 @@ fn baseline_request(app_id: AppId) -> ExecRequest {
rest: String::new(),
sandbox_overrides: ScriptSandbox::default(),
app_id,
script_owner: None,
principal: None,
trigger_depth: 0,
root_execution_id: execution_id,

View File

@@ -136,6 +136,7 @@ fn baseline_request(app_id: AppId) -> ExecRequest {
rest: String::new(),
sandbox_overrides: ScriptSandbox::default(),
app_id,
script_owner: None,
principal: None,
trigger_depth: 0,
root_execution_id: execution_id,

View File

@@ -74,6 +74,7 @@ fn baseline_request(app_id: AppId) -> ExecRequest {
rest: String::new(),
sandbox_overrides: ScriptSandbox::default(),
app_id,
script_owner: None,
principal: None,
trigger_depth: 0,
root_execution_id: execution_id,

View File

@@ -88,6 +88,7 @@ fn baseline_request(app_id: AppId) -> ExecRequest {
rest: String::new(),
sandbox_overrides: ScriptSandbox::default(),
app_id,
script_owner: None,
principal: None,
trigger_depth: 0,
root_execution_id: execution_id,

View File

@@ -52,6 +52,7 @@ fn baseline_request(app_id: AppId) -> ExecRequest {
rest: String::new(),
sandbox_overrides: ScriptSandbox::default(),
app_id,
script_owner: None,
principal: None,
trigger_depth: 0,
root_execution_id: execution_id,

View File

@@ -127,6 +127,7 @@ fn baseline_request(app_id: AppId) -> ExecRequest {
rest: String::new(),
sandbox_overrides: ScriptSandbox::default(),
app_id,
script_owner: None,
principal: None,
trigger_depth: 0,
root_execution_id: execution_id,

View File

@@ -121,6 +121,7 @@ fn request(app_id: AppId, with_principal: bool) -> ExecRequest {
rest: String::new(),
sandbox_overrides: ScriptSandbox::default(),
app_id,
script_owner: None,
principal: with_principal.then(|| Principal {
user_id: AdminUserId::new(),
instance_role: InstanceRole::Owner,

View File

@@ -37,6 +37,7 @@ fn baseline_request() -> ExecRequest {
rest: String::new(),
sandbox_overrides: ScriptSandbox::default(),
app_id: AppId::new(),
script_owner: None,
principal: None,
trigger_depth: 0,
root_execution_id: execution_id,