Enforce execution principal in AiAssistantApiRunner (no fallback to session user when executor is provided)
>>> [!note] Migrated issue
<!-- Drupal.org comment -->
<!-- Migrated from issue #3574723. -->
Reported by: [scott falconer](https://www.drupal.org/user/52557)
Related to !1233
>>>
<p><strong>Problem/Motivation<br>
</strong>Issue #3574662 hardened the /api/deepchat boundary by rejecting caller-supplied execution identity fields.<br>
However, the shared runner layer still depends on ambient current-user behavior in AiAssistantApiRunner, which is unsafe for queue/cron/sessionless execution paths and weakens the #3573899 execution-principal contract.</p>
<p><strong>Proposed resolution<br>
</strong></p>
<ul>
<li>Add explicit executor support to AiAssistantApiRunner (executor passed as UID at runner boundary).</li>
<li>Resolve executor UID to a user account before processing.</li>
<li>Fail early if executor is missing/invalid/non-loadable/blocked.</li>
<li>Use Drupal account_switcher (AccountSwitcherInterface) for execution context changes.</li>
<li>Run switched execution in try/finally and always call switchBack().</li>
<li>Ensure access checks and execution account logic are evaluated against the resolved executor.</li>
<li>Preserve current behavior when no executor is provided (BC path for now).</li>
<li>Add kernel tests to lock these invariants.</li>
</ul>
<p><strong>Acceptance criteria<br>
</strong></p>
<ul>
<li>Invalid/non-loadable/blocked executor fails before provider/action execution.</li>
<li>When executor is provided, execution does not fall back to ambient session current user.</li>
<li>Access checks are evaluated against the resolved executor account.</li>
<li>Account switching always reverts via try/finally on both success and exception paths.</li>
<li>BC path remains functional: when executor is omitted, runner still uses ambient session user.</li>
<li>Stack integrity is preserved: if runner is entered while another account is already active, runner switchTo/switchBack unwinds cleanly to the original account.</li>
<li>New kernel tests pass in required CI jobs.</li>
</ul>
<p><strong>Test plan<br>
</strong></p>
<ul>
<li>Add kernel tests first (expected to fail before implementation):</li>
<li>invalid executor fails early with no downstream execution</li>
<li>provided executor overrides session-user behavior</li>
<li>exception path still restores prior account</li>
<li>omitted executor follows BC fallback behavior</li>
<li>nested/surrounding account switch state restores correctly</li>
<li>Implement minimal runner changes to make tests pass.</li>
<li>Run targeted PHPUnit plus required CI-parity jobs.</li>
</ul>
> Related issue: [Issue #3573899](https://www.drupal.org/node/3573899)
> Related issue: [Issue #3574662](https://www.drupal.org/node/3574662)
issue