Skip to content

fix(cli): send the caller handle from dispatch-show - #15965

Closed
Tauri-EPO wants to merge 2 commits into
stablyai:mainfrom
Tauri-EPO:Tauri-EPO/step-de4fe6
Closed

Tauri-EPO wants to merge 2 commits into
stablyai:mainfrom
Tauri-EPO:Tauri-EPO/step-de4fe6

Conversation

@Tauri-EPO

@Tauri-EPO Tauri-EPO commented Aug 22, 2026 •

Copy link
Copy Markdown
Contributor

ELI5

dispatch-show never tells the runtime who is asking. That means any future rule of the form "you may only inspect dispatches belonging to your own Run" cannot work when the command is run from the CLI, however carefully the runtime enforces it. This sends the caller's identity along — and sends nothing when there is no identity to send, so no command that works today starts failing.

What Changed

orca orchestration dispatch-show now resolves a caller handle on every read and passes it as callerTerminalHandle, following the pattern taskCreate / taskList / taskUpdate already use and resolveRunScope already consumes.

Resolution is best-effort, via a new resolveOptionalCallerTerminalHandle in src/cli/handlers/orchestration/terminal-identity.ts:

  1. explicit --from
  2. a live-validated ORCA_TERMINAL_HANDLE
  3. a pane remint from ORCA_PANE_KEY
  4. undefined

Any failure at any step yields undefined rather than an error. callerTerminalHandle was added to DispatchShowParams (src/main/runtime/rpc/methods/orchestration/schemas.ts) so zod does not strip it; the handler still ignores it, so authorization behaviour is unchanged.

--preamble keeps main's strict resolution byte-for-byte and produces identical preamble text.

Why

On main, src/cli/handlers/orchestration/dispatch-handlers.ts:

const from = showPreamble
  ? await resolveCoordinatorTerminalHandle(flags, cwd, client)
  : undefined
await client.call('orchestration.dispatchShow', { task, preamble: showPreamble, from, devMode })

from is resolved only for --preamble, and only so the previewed preamble text embeds a realistic coordinator handle. callerTerminalHandle is never sent at all. #14898 reports that dispatchShow resolves another Run's context without a Run check; a fix for that needs to know who is calling, and today the runtime cannot know because the CLI does not say.

Why best-effort, and why that matters. An earlier revision of this change made the resolution mandatory. A review caught that as a regression with no benefit: the handler ignores the field at this step, so requiring it could only break callers — a headless invocation, or one with no active terminal — for nothing. --from is a mechanical escape that requires knowing the handle and does not remove the problem.

Why there is no focus-based fallback. An "active terminal" fallback selected by focus can, on a remote or multi-window host, pick a terminal belonging to someone else. Sending a wrong identity is worse than sending none. The test suite arms the focus selector to reject in beforeEach, so any future code path that reaches for it fails the suite rather than silently working.

Linked Issue

Fixes #15952

Unblocks #14898, which is the enforcement half and is not attempted here.

Visual Proof

N/A — CLI plumbing with no user-visible output change. --preamble output is byte-identical to main.

Testing

Rebase onto upstream/main (2026-09-07, head 9d29e6878e), after #16904 moved the RPC methods into src/main/runtime/rpc/methods/orchestration/* and split the CLI handlers. Run on Windows 11, Node 24.19.0, pnpm 12:

pnpm tc:node                                        exit 0
pnpm tc:cli                                         exit 0
check:code-quality:changed (base upstream/main)     0 findings across 7 changed files, all three scans
vitest src/main/runtime/rpc/methods/orchestration   75 files, 694/694 passed
vitest (6 files touched by this PR)                 105/105 passed
vitest (7 further dispatchShow call sites)          135/135 passed

The full src/cli run has 13 pre-existing failures on this machine (executable-path resolution in orchestration-mutation-recovery, orchestration-gate-cli, orchestration-timeout-cli, orchestration-worker-cli, runtime/client-recovery). The identical 13 fail on a clean upstream/main checkout at 9d29e6878e with the same command, so they are environmental and not caused by this diff.

Original implementation pass, before the rebase: pnpm typecheck, pnpm build (including build:native) and oxlint all exit 0; new suite 9/9; nine orchestration suites 148/148.

New coverage for the four cases an earlier review named as missing: a caller with no resolvable identity, SSH/remote pane remint plus remote-pane-gone, the focus selector never being called (armed to reject, so any use fails the suite), and a folder workspace.

  • I manually tested these changes locally
  • Automated tests added/updated

Platforms: Windows 11. The remote and folder-workspace tests exercise the resolver contracts rather than a live relay or a real folder workspace — stated plainly because a reviewer should not read them as end-to-end. The rebase pass above is automated gates only; no live CLI session was re-run against it.

AI Disclosure

Written with Claude Opus 5 at high effort under my direction and reviewed by an independent Codex (gpt-5.6-sol) pass, which raised the mandatory-resolution regression as a P1 and confirmed it closed on a second verification pass. The rebase onto upstream/main was likewise done with Claude Opus 5.

Review

Cross-platform: no path handling.
SSH / remote: the pane-remint step is the remote-aware branch; failures there are absorbed, and the focus fallback that could select a foreign terminal was deliberately excluded.
Wire compatibility: a new optional param on an existing RPC call, ignored by the handler — safe in both directions today. Making it required later would break an old CLI against a new runtime with no fallback, so the enforcement step needs a capability or a fallback decided first, per docs/reference/remote-wire-compatibility.md.
Agent compatibility: unaffected.
Performance: at most one extra handle validation per dispatch-show.
UI: none.
Security: sends an identity the runtime already receives from sibling commands; it grants nothing, since the handler ignores it.

Notes

Rebase notes, for reviewers comparing against the pre-#16904 version of this branch:

  • The schema field moved with its file: DispatchShowParams is now in src/main/runtime/rpc/methods/orchestration/schemas.ts, not the old monolithic orchestration.ts.
  • isLiveTerminalHandle on main now probes terminal.resolveIdentity before falling back to terminal.show, so the new suite's mocks assert terminal.resolveIdentity.
  • The dispatch-show preamble test this branch used to delete from orchestration.test.ts had moved to orchestration-caller-identity-cli.test.ts; it is deleted there instead, since orchestration-dispatch-show-caller.test.ts covers the same scenario plus the new field.
  • orchestration-module-boundaries.test.ts now clears ORCA_TERMINAL_HANDLE / ORCA_PANE_KEY in its beforeEach. Without that, its boundary assertion depended on whether the suite happened to run inside a live Orca pane.

Known prerequisites for the enforcement step, recorded so they are not rediscovered (all re-verified against 9d29e6878e):

  • requireWorkerDoneSettlement calls dispatchShow with only { task } from the worker CLI and would break if the handle became required.
  • dispatchShow is absent from COORDINATOR_PREFLIGHT_METHODS / CURRENT_AUTHORITY_PREFLIGHT_METHODS and from currentCallerHandle in src/main/runtime/rpc/orchestration-legacy-compatibility.ts, so the handle would not be recognised on the legacy-compatibility path.

Agent skill upstream boundary

  • Not applicable.

Checklist

  • This PR is small and focused
  • I explained what changed and why (including ELI5)
  • N/A with reason for visual proof
  • Self-reviewed for correctness, security, and performance
  • Cross-platform, SSH/remote, and path/shortcut impact considered
  • pnpm lint, pnpm typecheck and pnpm build pass locally

Author

  • X / Twitter: @EnricoPin

@coderabbitai

coderabbitai Bot commented Aug 22, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Team

Run ID: 3b205efb-8a4c-444f-98f1-cf479aed88b2

📥 Commits

Reviewing files that changed from the base of the PR and between ab691f1 and 3fe0df6.

📒 Files selected for processing (4)
  • src/cli/handlers/orchestration-dispatch-show-caller.test.ts
  • src/cli/handlers/orchestration/dispatch-handlers.ts
  • src/cli/handlers/orchestration/terminal-identity.ts
  • src/main/runtime/rpc/methods/orchestration/runs/tasks-dispatch.test.ts
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/cli/handlers/orchestration/terminal-identity.ts
  • src/cli/handlers/orchestration/dispatch-handlers.ts
  • src/main/runtime/rpc/methods/orchestration/runs/tasks-dispatch.test.ts
  • src/cli/handlers/orchestration-dispatch-show-caller.test.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 8 remain after this review.


📝 Walkthrough

Walkthrough

The orchestration dispatch-show handler now resolves the caller terminal handle independently from --from and includes it in the RPC payload. Resolution checks live environment state, pane reminting, and explicit input as a final fallback. The RPC schema accepts the new field. Tests cover stale handles, resolution failures, folder workspaces, preamble previews, distinct coordinator and caller handles, and environment isolation.

Merge Risk: 🔵 Low · up to 3fe0d

Dispatch-show now sends optional caller identity metadata while retaining existing authorization behavior. A test-coverage gap remains around verifying that the metadata reaches the runtime handler, but no concrete runtime regression is established.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR sends callerTerminalHandle and keeps resolution best-effort, but the implementation resolves ORCA_TERMINAL_HANDLE and pane identity before using --from. Linked issue #15952 requires explicit --… Change resolveOptionalCallerTerminalHandle so explicit --from is checked first, followed by live ORCA_TERMINAL_HANDLE validation, pane reminting, and omission when unresolved. Update tests and the PR description to match the implemented ord…
Docstring Coverage ⚠️ Warning Docstring coverage is 28.57% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 7 functions across 10 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the primary change: sending the caller handle from dispatch-show.
Description check ✅ Passed The description includes the required sections, explains the change and rationale, links issue #15952, documents testing, provides the required N/A visual proof, and completes the checklist.
Out of Scope Changes check ✅ Passed The changes are limited to dispatch-show caller identity propagation, RPC schema support, related tests, and test-environment isolation. These changes support the linked issue and no unrelated scope i…
Full details: Linked Issues check

Explanation

The PR sends callerTerminalHandle and keeps resolution best-effort, but the implementation resolves ORCA_TERMINAL_HANDLE and pane identity before using --from. Linked issue #15952 requires explicit --from to be the first resolution step.

Resolution

Change resolveOptionalCallerTerminalHandle so explicit --from is checked first, followed by live ORCA_TERMINAL_HANDLE validation, pane reminting, and omission when unresolved. Update tests and the PR description to match the implemented order.

  • Fix all pre-merge checks with AI

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai

coderabbitai Bot commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@greptile-apps

greptile-apps Bot commented Aug 29, 2026

Copy link
Copy Markdown

Greptile Summary

The PR adds best-effort caller identity forwarding to orchestration dispatch-show without changing current authorization behavior.

  • Resolves identity from explicit --from, a validated environment handle, or pane reminting.
  • Adds the optional caller handle to the RPC schema and request.
  • Covers live, absent, stale, remote, explicit, folder-workspace, and preamble cases.

Confidence Score: 5/5

The PR appears safe to merge with no actionable current failures identified.

The optional identity is forwarded without becoming required, unknown RPC fields remain wire-compatible, and the runtime continues to return the same dispatch-show result because it does not yet consume the new field.

Important Files Changed

Filename Overview
src/cli/handlers/orchestration/dispatch-handlers.ts Forwards a best-effort caller handle while retaining strict coordinator resolution for preamble previews.
src/cli/handlers/orchestration/terminal-identity.ts Adds optional identity resolution that avoids focus-based attribution and preserves existing headless-read behavior.
src/main/runtime/rpc/methods/orchestration.ts Extends the dispatch-show parameter schema so the optional caller identity survives request parsing.
src/cli/handlers/orchestration-dispatch-show-caller.test.ts Exercises identity forwarding, fallback suppression, stale pane reminting, and preamble compatibility.

Reviews (1): Last reviewed commit: "fix(cli): send the caller handle from di..." | Re-trigger Greptile

@Tauri-EPO
Tauri-EPO force-pushed the Tauri-EPO/step-de4fe6 branch from 3e8021e to ab691f1 Compare September 7, 2026 11:55
@coderabbitai

coderabbitai Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@Tauri-EPO

Copy link
Copy Markdown
Contributor Author

Rebased onto upstream/main at 9d29e6878e, after #16904 restructured orchestration. New head: ab691f161d92494ab4d33d2509180cb6719208ff. GitHub reports the PR as mergeable again.

Two conflicts, both from the file moves:

  • DispatchShowParams no longer lives in the monolithic src/main/runtime/rpc/methods/orchestration.ts; the callerTerminalHandle field moved to src/main/runtime/rpc/methods/orchestration/schemas.ts.
  • The dispatch-show preamble test this branch removed from src/cli/handlers/orchestration.test.ts had moved to src/cli/handlers/orchestration-caller-identity-cli.test.ts, so it is removed there instead. src/cli/handlers/orchestration-dispatch-show-caller.test.ts covers the same scenario plus the new field.

Two follow-ups the rebase surfaced:

  • isLiveTerminalHandle now probes terminal.resolveIdentity before falling back to terminal.show, so the new suite's mocks were updated to match.
  • orchestration-module-boundaries.test.ts now clears ORCA_TERMINAL_HANDLE / ORCA_PANE_KEY in its beforeEach. Its non-preamble assertion previously depended on the ambient environment, which is only invisible because CI has no pane env set.

Verified on Windows 11 / Node 24.19.0 / pnpm 12:

pnpm tc:node                                        exit 0
pnpm tc:cli                                         exit 0
check:code-quality:changed (base upstream/main)     0 findings across 7 changed files, all three scans
vitest src/main/runtime/rpc/methods/orchestration   75 files, 694/694 passed
vitest (6 files touched by this PR)                 105/105 passed
vitest (7 further dispatchShow call sites)          135/135 passed

The full src/cli run has 13 failures on this machine, in orchestration-mutation-recovery, orchestration-gate-cli, orchestration-timeout-cli, orchestration-worker-cli and runtime/client-recovery. The same 13 fail on a clean checkout of 9d29e6878e with the same command, so they are local environment, not this diff.

No live CLI session was re-run against the rebased branch; the checks above are automated gates only.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/main/runtime/rpc/methods/orchestration/runs/tasks-dispatch.test.ts (1)

558-563: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Make this RPC test assert callerTerminalHandle at the method boundary.

rpc-test-harness.ts parses requests with DispatchShowParams, while the handler ignores this field. Since z.object strips undeclared fields, removing callerTerminalHandle from DispatchShowParams would not change the current dispatch.task_id assertion. Add a boundary spy or parsed-request assertion.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Team

Run ID: 0f1239d8-b327-4546-a7d5-3452ba8edcda

📥 Commits

Reviewing files that changed from the base of the PR and between 8cd0abf and ab691f1.

📒 Files selected for processing (7)
  • src/cli/handlers/orchestration-caller-identity-cli.test.ts
  • src/cli/handlers/orchestration-dispatch-show-caller.test.ts
  • src/cli/handlers/orchestration-module-boundaries.test.ts
  • src/cli/handlers/orchestration/dispatch-handlers.ts
  • src/cli/handlers/orchestration/terminal-identity.ts
  • src/main/runtime/rpc/methods/orchestration/runs/tasks-dispatch.test.ts
  • src/main/runtime/rpc/methods/orchestration/schemas.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/cli/handlers/orchestration/dispatch-handlers.ts
  • src/cli/handlers/orchestration/terminal-identity.ts
  • src/cli/handlers/orchestration-dispatch-show-caller.test.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 4 remain after this review.

Comment thread src/cli/handlers/orchestration-caller-identity-cli.test.ts
--from names the terminal to speak as, not the process speaking. Coalescing
the two meant a preamble read reported the coordinator as its own caller, and
when --from was absent the coordinator's focus-based fallback could name a pane
the caller does not own.

Resolve the caller from its own ambient identity (env handle, then pane remint)
and fall back to --from only for a shell that carries no pane identity, so the
Run scoping in stablyai#14898 keys on the real caller.
@Tauri-EPO Tauri-EPO closed this Sep 7, 2026
@Tauri-EPO

Copy link
Copy Markdown
Contributor Author

Closing. This PR only sends the caller's handle on dispatch-show; nothing on main consumes it for that method (src/main/runtime/rpc/methods/orchestration/runs/dispatch-methods.ts reads params.from for the preamble only), so on its own it changes nothing a user can observe. The enforcement it was meant to enable is #14900, which is the right place for the CLI half to land alongside the runtime rule. #14898 stays open as the underlying report.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Other]: dispatch-show reaches the runtime with no caller identity, so Run-scoped enforcement cannot attach

1 participant