Skip to content

refactor(agents): agent, session and port calls route by their workspace owner - #27283

Merged
OrcaWin merged 1 commit into
mainfrom
OrcaWin/d4-g1-terminals-b
Oct 10, 2026
Merged

OrcaWin merged 1 commit into
mainfrom
OrcaWin/d4-g1-terminals-b

Conversation

@OrcaWin

@OrcaWin OrcaWin commented Oct 10, 2026 •

Copy link
Copy Markdown
Collaborator
Files Added Deleted Net
Test 8 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​29 $\color{#cf222e}{\Huge{\mathbf{−}}}$​77 $\color{#cf222e}{\Huge{\mathbf{−}}}$​48
Prod 14 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​65 $\color{#cf222e}{\Huge{\mathbf{−}}}$​115 $\color{#cf222e}{\Huge{\mathbf{−}}}$​50

ELI5

Agent notes, background agent launches, reopening saved chats and the tab strip's shell menu used to make up a fake copy of the user's settings, with the workspace's owner swapped in as the "Active Server". They then read the target server back out of that copy. Now they ask the workspace for its owner directly. Two places that still fell back to the Active Server now go only by the terminal's own id. One more fix: the ports list now refreshes this computer's ports when a local dev server starts, even if a server is set as the default host.

Builds on #27279 and #27275 (both merged).

What Changed

  • Before (user) / after (user):
    • Agent notes, background launches, saved-chat reveal and activation, and the tab strip's Windows shell options already went to the workspace's owner. They still do; only how they get there changed.
    • Before, the automation observer and the Codex account lane used the Active Server for an old terminal id that names no server. Now that id gets no server. The Codex lane reads "remote, unattributed".
    • Before, when a server was the default host, a local dev server printing its URL did not trigger a rescan of this computer's ports, so new local ports showed up only on the next 30-second poll. Now they show up right away.
  • Mechanism:
    • Call sites that did getActiveRuntimeTarget(getSettingsForWorktreeRuntimeOwner(state, id)) or getActiveRuntimeTarget({ activeRuntimeEnvironmentId: ownerId }) now call runtimeTargetForOwnerEnvironment(getRuntimeEnvironmentIdForWorktree(state, id)). The result is the same, but nothing is shaped like settings any more.
    • automation-session-observer uses getRemoteRuntimePtyOwner, which comes from refactor(terminals): terminal input and inspection route by the PTY's owner #27279. codex-pane-selection-lane uses the id's own owner segment.
    • WorkspacePortScanner no longer reads the Active Server. The single-host view key is the only scan target, which is what the old code amounted to. Local advertised-URL events always refresh { kind: 'local' }.
    • ActiveTerminalNoteTargetState drops its unused settings field.
    • Ratchets: owner-routing 204 → 191, focus-read 1423 → 1396.

Why

Making a settings object only to read one field back out is the pattern the owner-routing ratchet exists to catch. Passing the owner's id straight through keeps the result the same and removes the place where the Active Server could slip back in.

For ports, we considered keeping the "only when focus is local" gate. We rejected it because the event always describes this computer's processes, so tying it to the default host was a bug.

Linked Issue

None. This is part of the host-ownership routing stack (D4 G1).

Visual Proof

N/A. There is no UI change. The only visible effect is that local ports appear sooner when a server is the default host.

Testing

  • I manually tested these changes locally

  • Automated tests added/updated, or explained why not below

  • WorkspacePortScanner.test.tsx: "rescans this computer on a local URL change while a server is the default host". It fails on the parent branch, because the event listener was never installed. The test that asserted a focus change cancels a poll was removed, because focus no longer drives the scanner.

  • codex-pane-selection-lane.test.ts: an ownerless remote pane is never given the focused server.

  • structured-agent-session-tab-activation, activate-ai-vault-structured-session-reveal and launch-worktree-background-terminals tests now stub the owner lookup instead of getActiveRuntimeTarget.

  • Ran: pnpm tc:web, focused pnpm test (lib, hooks, tab-bar, ports, terminal-pane), oxlint, oxfmt, pnpm run check:code-quality:changed, and pnpm check:owner-routing-ratchet.

Review

Agent skill upstream boundary

  • Not applicable, or this change copies or mechanically translates no upstream skill-installer source, tests, fixtures, registry entries, path tables, comments, or documentation.

Notes

No wire change. Folder workspaces resolve through getRuntimeEnvironmentIdForWorktree, as before. SSH workspaces stay on this app's transport.

Checklist

  • This PR is small and focused
  • I explained what changed and why (ELI5, the user-facing before/after, the mechanism, and why over the alternatives)
  • Before/after screenshots or videos attached for UI changes, or N/A with reason
  • Self-reviewed for correctness, security, and performance
  • Cross-platform, SSH/remote, and path/shortcut impact considered (or N/A)
  • pnpm lint, pnpm typecheck, pnpm test, and pnpm build pass (or CI will cover; local preferred)

@coderabbitai

coderabbitai Bot commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 473f27e0-6092-4674-8803-6c60ce56f867



📥 Commits

Reviewing files that changed from the base of the PR and between f0b859d and 58e754b.




📒 Files selected for processing (5)
  • config/focus-setting-read-baseline.txt
  • config/owner-routing-baseline.txt
  • tests/e2e/__mocks__/native-chat-ssh-delivery.ts
  • tests/e2e/native-chat-ssh-delivery.unit.test.ts
  • tests/e2e/remote-agent-completion-authority.unit.test.ts



💤 Files with no reviewable changes (2)
  • config/owner-routing-baseline.txt
  • tests/e2e/remote-agent-completion-authority.unit.test.ts



🚧 Files skipped from review as they are similar to previous changes (1)
  • config/focus-setting-read-baseline.txt



Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 0 remain after this review.





📝 Walkthrough
📝 Walkthrough
📝 Walkthrough

Walkthrough

The change removes runtime settings from native-chat, terminal, paste, inspection, and stream APIs. Runtime operations now resolve remote ownership from PTY identities, while worktree operations use owner environment IDs. Native-chat and terminal callers, mocks, and tests use the updated signatures. Workspace port scanning refreshes the local target for advertised-URL changes. Two routing baselines are updated.





Priority: ➖ Normal

Merge Risk: 🔵 Low · up to 58e75

Input for an ownerless remote terminal may be misrouted or falsely reported as delivered; resolve this bounded routing risk before relying on the new behavior.

Pre-merge checks | Passed 4 | Failed 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 38.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 75 functions across 52 files. (1 skipped:… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Title check Passed The title is concise and clearly identifies the main change: routing agent, session, and port operations by workspace owner.
Description check Passed The description is complete and focused. It explains the user-visible changes, mechanism, rationale, testing, visual proof, compatibility notes, and checklist status. It also identifies the related ho…

Full details: Docstring Coverage

Explanation

Docstring coverage is 38.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 75 functions across 52 files. (1 skipped: 1 unsupported.)


  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR









  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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 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


ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 4b8fa85d-db37-4cda-8a65-3ace60b4df31
📥 Commits

Reviewing files that changed from the base of the PR and between 5c7c493 and f0b859d.

📒 Files selected for processing (113)
  • config/focus-setting-read-baseline.txt
  • config/owner-routing-baseline.txt
  • config/scripts/check-owner-routing-ratchet.mjs
  • config/scripts/check-owner-routing-ratchet.test.mjs
  • src/renderer/src/components/native-chat/NativeChatComposer.paste-remount.test.tsx
  • src/renderer/src/components/native-chat/NativeChatComposer.test.tsx
  • src/renderer/src/components/native-chat/NativeChatComposer.tsx
  • src/renderer/src/components/native-chat/NativeChatResolvedView.prompt-card-composer.test.tsx
  • src/renderer/src/components/native-chat/NativeChatResolvedView.tsx
  • src/renderer/src/components/native-chat/claude-model-switch-confirmation.test.ts
  • src/renderer/src/components/native-chat/claude-model-switch-confirmation.ts
  • src/renderer/src/components/native-chat/native-chat-composer-prompt-recall.test.tsx
  • src/renderer/src/components/native-chat/native-chat-composer-target.ts
  • src/renderer/src/components/native-chat/native-chat-input-clear.ts
  • src/renderer/src/components/native-chat/native-chat-observed-send.test.ts
  • src/renderer/src/components/native-chat/native-chat-observed-send.ts
  • src/renderer/src/components/native-chat/native-chat-queue-send-confirm.test.tsx
  • src/renderer/src/components/native-chat/native-chat-runtime-image-send.ts
  • src/renderer/src/components/native-chat/native-chat-runtime-send-launch-draft.test.ts
  • src/renderer/src/components/native-chat/native-chat-runtime-send.test.ts
  • src/renderer/src/components/native-chat/native-chat-runtime-send.ts
  • src/renderer/src/components/native-chat/native-chat-structured-send-composition-clear.test.tsx
  • src/renderer/src/components/native-chat/use-native-chat-composer-attachments.test.tsx
  • src/renderer/src/components/native-chat/use-native-chat-composer-interrupt.ts
  • src/renderer/src/components/native-chat/use-native-chat-interactive-send.test.tsx
  • src/renderer/src/components/native-chat/use-native-chat-interactive-send.ts
  • src/renderer/src/components/native-chat/use-native-chat-picker-command-dispatch.test.tsx
  • src/renderer/src/components/native-chat/use-native-chat-picker-command-dispatch.ts
  • src/renderer/src/components/native-chat/use-native-chat-pty-composer-send.test.tsx
  • src/renderer/src/components/native-chat/use-native-chat-pty-composer-send.ts
  • src/renderer/src/components/native-chat/use-native-chat-session-option-command.test.tsx
  • src/renderer/src/components/native-chat/use-native-chat-session-option-command.ts
  • src/renderer/src/components/ports/WorkspacePortScanner.test.tsx
  • src/renderer/src/components/ports/WorkspacePortScanner.tsx
  • src/renderer/src/components/tab-bar/TabBar.os-file-drop.test.tsx
  • src/renderer/src/components/tab-bar/TabBar.worktree-write-gate.test.tsx
  • src/renderer/src/components/tab-bar/TabBar.worktree-write-gate.windows.test.tsx
  • src/renderer/src/components/tab-bar/use-tab-bar-runtime-model-worktree-write-probe.ts
  • src/renderer/src/components/tab-bar/use-tab-bar-runtime-model.ts
  • src/renderer/src/components/terminal-pane/agent-completion-coordinator-attention-dispatch.test.ts
  • src/renderer/src/components/terminal-pane/agent-completion-coordinator-completion-replay-guard.test.ts
  • src/renderer/src/components/terminal-pane/agent-completion-coordinator-dispose-leak.test.ts
  • src/renderer/src/components/terminal-pane/agent-completion-coordinator-hook-done-quiet-window.test.ts
  • src/renderer/src/components/terminal-pane/agent-completion-coordinator-hook-title-precedence.test.ts
  • src/renderer/src/components/terminal-pane/agent-completion-coordinator-monitoring-turn-end.test.ts
  • src/renderer/src/components/terminal-pane/agent-completion-coordinator-pending-title-inspection.test.ts
  • src/renderer/src/components/terminal-pane/agent-completion-coordinator-process-cadence.test.ts
  • src/renderer/src/components/terminal-pane/agent-completion-coordinator-process-exit-turn-boundary.test.ts
  • src/renderer/src/components/terminal-pane/agent-completion-coordinator-queued-inspection-disposal.test.ts
  • src/renderer/src/components/terminal-pane/agent-completion-coordinator-stamped-turn-boundary.test.ts
  • src/renderer/src/components/terminal-pane/agent-completion-coordinator-stamped-turn-replay.test.ts
  • src/renderer/src/components/terminal-pane/agent-completion-coordinator-types.ts
  • src/renderer/src/components/terminal-pane/agent-completion-no-evidence-cadence.test.ts
  • src/renderer/src/components/terminal-pane/agent-completion-process-monitor.ts
  • src/renderer/src/components/terminal-pane/agent-completion-stale-evidence-backoff.test.ts
  • src/renderer/src/components/terminal-pane/agent-completion-steady-state-opt-in.test.ts
  • src/renderer/src/components/terminal-pane/pane-foreground-process-exit-retire.test.ts
  • src/renderer/src/components/terminal-pane/pending-pane-close-confirmation.test.ts
  • src/renderer/src/components/terminal-pane/pty-connection/pane-agent-identity.ts
  • src/renderer/src/components/terminal-pane/pty-connection/pane-serializer-settle.ts
  • src/renderer/src/components/terminal-pane/pty-connection/terminal-keydown-fit.ts
  • src/renderer/src/components/terminal-pane/terminal-paste-operation-order.test.ts
  • src/renderer/src/components/terminal-pane/use-terminal-pane-close-actions.ts
  • src/renderer/src/components/terminal/pty-running-work-probe-child-evidence.test.ts
  • src/renderer/src/components/terminal/pty-running-work-probe.ts
  • src/renderer/src/components/terminal/running-terminal-close-guard.test.ts
  • src/renderer/src/components/terminal/running-terminal-close-guard.ts
  • src/renderer/src/components/terminal/window-close-running-work.test.ts
  • src/renderer/src/components/terminal/window-close-running-work.ts
  • src/renderer/src/hooks/agent-hook-completion-notifications.ts
  • src/renderer/src/lib/activate-ai-vault-structured-session-reveal.test.ts
  • src/renderer/src/lib/activate-ai-vault-structured-session.ts
  • src/renderer/src/lib/active-agent-note-send.ts
  • src/renderer/src/lib/active-agent-note-target.ts
  • src/renderer/src/lib/active-agent-terminal-send-readiness.ts
  • src/renderer/src/lib/agent-draft-paste-content.ts
  • src/renderer/src/lib/agent-draft-readiness.test.ts
  • src/renderer/src/lib/agent-draft-readiness.ts
  • src/renderer/src/lib/agent-followup-delivery.test.ts
  • src/renderer/src/lib/agent-followup-delivery.ts
  • src/renderer/src/lib/agent-paste-draft-readiness-budget.test.ts
  • src/renderer/src/lib/agent-paste-draft-submit-retry.test.ts
  • src/renderer/src/lib/agent-paste-draft.test.ts
  • src/renderer/src/lib/agent-paste-draft.ts
  • src/renderer/src/lib/agent-ready-wait.ts
  • src/renderer/src/lib/automation-session-observer.ts
  • src/renderer/src/lib/codex-pane-selection-lane.test.ts
  • src/renderer/src/lib/codex-pane-selection-lane.ts
  • src/renderer/src/lib/codex-session-restart-shell-flap.test.ts
  • src/renderer/src/lib/codex-session-restart.test.ts
  • src/renderer/src/lib/codex-session-restart.ts
  • src/renderer/src/lib/default-creation-host.test.ts
  • src/renderer/src/lib/default-creation-host.ts
  • src/renderer/src/lib/launch-agent-background-session.ts
  • src/renderer/src/lib/launch-agent-new-tab-host-route-readiness.test.ts
  • src/renderer/src/lib/launch-worktree-background-terminals.test.ts
  • src/renderer/src/lib/launch-worktree-background-terminals.ts
  • src/renderer/src/lib/new-workspace.test.ts
  • src/renderer/src/lib/new-workspace.ts
  • src/renderer/src/lib/resolve-owner.test.ts
  • src/renderer/src/lib/resolve-owner.ts
  • src/renderer/src/lib/startup-draft-input-kind.test.ts
  • src/renderer/src/lib/structured-agent-session-tab-activation.test.ts
  • src/renderer/src/lib/structured-agent-session-tab-activation.ts
  • src/renderer/src/runtime/runtime-client-target.test.ts
  • src/renderer/src/runtime/runtime-client-target.ts
  • src/renderer/src/runtime/runtime-terminal-inspection.test.ts
  • src/renderer/src/runtime/runtime-terminal-inspection.ts
  • src/renderer/src/runtime/runtime-terminal-stream.test.ts
  • src/renderer/src/runtime/runtime-terminal-stream.ts
  • src/renderer/src/runtime/runtime-terminal-verified-input.test.ts
  • src/renderer/src/runtime/runtime-terminal-verified-input.ts
  • src/renderer/src/runtime/web-session-tabs-agent-completion-notifications.test.ts
💤 Files with no reviewable changes (33)
  • src/renderer/src/hooks/agent-hook-completion-notifications.ts
  • src/renderer/src/components/native-chat/native-chat-structured-send-composition-clear.test.tsx
  • src/renderer/src/components/native-chat/native-chat-queue-send-confirm.test.tsx
  • src/renderer/src/runtime/web-session-tabs-agent-completion-notifications.test.ts
  • src/renderer/src/components/terminal-pane/pty-connection/terminal-keydown-fit.ts
  • src/renderer/src/components/tab-bar/TabBar.os-file-drop.test.tsx
  • src/renderer/src/components/tab-bar/TabBar.worktree-write-gate.windows.test.tsx
  • src/renderer/src/components/native-chat/native-chat-composer-target.ts
  • src/renderer/src/components/tab-bar/use-tab-bar-runtime-model-worktree-write-probe.ts
  • src/renderer/src/components/native-chat/native-chat-composer-prompt-recall.test.tsx
  • src/renderer/src/components/native-chat/claude-model-switch-confirmation.test.ts
  • src/renderer/src/components/terminal-pane/agent-completion-coordinator-process-exit-turn-boundary.test.ts
  • src/renderer/src/components/terminal-pane/agent-completion-no-evidence-cadence.test.ts
  • src/renderer/src/components/native-chat/NativeChatComposer.paste-remount.test.tsx
  • src/renderer/src/components/terminal-pane/pane-foreground-process-exit-retire.test.ts
  • src/renderer/src/components/tab-bar/TabBar.worktree-write-gate.test.tsx
  • src/renderer/src/components/terminal-pane/agent-completion-coordinator-monitoring-turn-end.test.ts
  • src/renderer/src/lib/startup-draft-input-kind.test.ts
  • src/renderer/src/components/terminal-pane/agent-completion-coordinator-dispose-leak.test.ts
  • src/renderer/src/components/terminal-pane/terminal-paste-operation-order.test.ts
  • src/renderer/src/components/terminal-pane/agent-completion-coordinator-queued-inspection-disposal.test.ts
  • src/renderer/src/components/terminal-pane/agent-completion-stale-evidence-backoff.test.ts
  • src/renderer/src/components/terminal-pane/agent-completion-coordinator-completion-replay-guard.test.ts
  • src/renderer/src/components/terminal-pane/agent-completion-coordinator-stamped-turn-replay.test.ts
  • src/renderer/src/components/terminal-pane/agent-completion-coordinator-process-cadence.test.ts
  • src/renderer/src/components/terminal-pane/agent-completion-coordinator-attention-dispatch.test.ts
  • src/renderer/src/components/terminal-pane/agent-completion-coordinator-types.ts
  • src/renderer/src/components/terminal-pane/agent-completion-coordinator-hook-title-precedence.test.ts
  • src/renderer/src/components/terminal-pane/agent-completion-coordinator-hook-done-quiet-window.test.ts
  • src/renderer/src/lib/new-workspace.test.ts
  • src/renderer/src/components/terminal-pane/agent-completion-coordinator-stamped-turn-boundary.test.ts
  • src/renderer/src/components/terminal-pane/agent-completion-coordinator-pending-title-inspection.test.ts
  • config/owner-routing-baseline.txt

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 0 remain after this review.

Comment on lines +73 to +75
const owner = getRemoteRuntimePtyOwner(ptyId)
const remote = isRemoteInspectionPtyId(ptyId)
if (target.kind !== 'environment' || !terminal) {
if (!owner) {

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🔎 Supported by static analysis

🏁 Script executed:

sed -n '65,105p' src/renderer/src/runtime/runtime-terminal-inspection.ts
sed -n '145,195p' src/renderer/src/runtime/runtime-terminal-inspection.ts
sed -n '15,90p' src/renderer/src/runtime/runtime-terminal-verified-input.ts
sed -n '25,70p' src/renderer/src/runtime/runtime-terminal-stream.ts

Repository: stablyai/orca

Length of output: 6829


🏁 Script executed:

set -o pipefail
printf '%s\n' '--- parser, predicates, owner helper ---'
rg -n -F --glob '*.ts' --glob '*.tsx' -- 'parseRemoteRuntimePtyId' src/ || test "$?" -eq 1
rg -n -F --glob '*.ts' --glob '*.tsx' -- 'isRemoteInspectionPtyId' src/ || test "$?" -eq 1
rg -n -F --glob '*.ts' --glob '*.tsx' -- 'getRemoteRuntimePtyOwner' src/ || test "$?" -eq 1

printf '%s\n' '--- PTY IPC symbols and receivers ---'
rg -n -F --glob '*.ts' --glob '*.tsx' -- 'inspectProcess' src/ | head -120
rg -n -F --glob '*.ts' --glob '*.tsx' -- 'writeAccepted' src/ | head -120
rg -n -F --glob '*.ts' --glob '*.tsx' -- 'pty.write' src/ | head -120

printf '%s\n' '--- remote ID generation and ownerless fixtures ---'
rg -n -F --glob '*.ts' --glob '*.tsx' -- 'remote:' src/ | head -160
rg -n -i -F --glob '*.ts' --glob '*.tsx' -- 'ownerless' src/ | head -160
rg -n -F --glob '*.ts' --glob '*.tsx' -- 'remote<' src/ | head -80

printf '%s\n' '--- likely parser/helper files ---'
find src -type f \( -name '*.ts' -o -name '*.tsx' \) | grep -E 'runtime|pty|terminal|ipc|preload' | head -160

Repository: stablyai/orca

Length of output: 41638


🏁 Script executed:

set -o pipefail
rg -n -F --glob '*.ts' --glob '*.tsx' -- 'parseRemoteRuntimePtyId' src/ || test "$?" -eq 1
rg -n -F --glob '*.ts' --glob '*.tsx' -- 'isRemoteInspectionPtyId' src/ || test "$?" -eq 1
rg -n -F --glob '*.ts' --glob '*.tsx' -- 'getRemoteRuntimePtyOwner' src/ || test "$?" -eq 1
rg -n -F --glob '*.ts' --glob '*.tsx' -- 'inspectProcess' src/ | head -120
rg -n -F --glob '*.ts' --glob '*.tsx' -- 'writeAccepted' src/ | head -120
rg -n -F --glob '*.ts' --glob '*.tsx' -- 'pty.write' src/ | head -120
rg -n -i -F --glob '*.ts' --glob '*.tsx' -- 'ownerless' src/ | head -160
rg -n -F --glob '*.ts' --glob '*.tsx' -- 'remote:' src/ | head -160

Repository: stablyai/orca

Length of output: 41994


🏁 Script executed:

set -o pipefail
printf '%s\n' '--- remote ID contract ---'
nl -ba src/shared/remote-runtime-pty-id.ts | sed -n '1,80p'
printf '%s\n' '--- inspection predicate and wrappers ---'
nl -ba src/renderer/src/runtime/runtime-terminal-inspection.ts | sed -n '1,115p'
nl -ba src/renderer/src/runtime/runtime-terminal-inspection.ts | sed -n '155,205p'
nl -ba src/renderer/src/runtime/runtime-terminal-verified-input.ts | sed -n '1,90p'
printf '%s\n' '--- provider routing ---'
nl -ba src/main/ipc/pty/provider/registry.ts | sed -n '85,140p'
printf '%s\n' '--- PTY write/inspection IPC bindings ---'
rg -n -F --glob '*.ts' -- 'pty:write' src/main src/preload | head -80 || test \"$?\" -eq 1
rg -n -F --glob '*.ts' -- 'writeAccepted' src/main src/preload | head -100 || test \"$?\" -eq 1
rg -n -F --glob '*.ts' -- 'registerPtyIpc' src/main | head -40 || test \"$?\" -eq 1
nl -ba src/main/ipc/pty/ipc/inspect.ts | sed -n '150,230p'
printf '%s\n' '--- ownerless tests ---'
nl -ba src/renderer/src/runtime/runtime-terminal-stream.test.ts | sed -n '1,55p'
nl -ba src/renderer/src/runtime/runtime-terminal-verified-input.test.ts | sed -n '90,130p'
nl -ba src/main/ipc/pty/provider/registry-host-routing.test.ts | sed -n '1,90p'

Repository: stablyai/orca

Length of output: 32791


🏁 Script executed:

set -o pipefail
nl -ba src/main/ipc/pty/ipc/write.ts | sed -n '1,90p'
nl -ba src/main/ipc/pty/ipc/write-input.ts | sed -n '1,95p'
nl -ba src/main/ipc/pty/register-handlers.ts | sed -n '115,155p'

Repository: stablyai/orca

Length of output: 9861


🏁 Script executed:

set -o pipefail
nl -ba src/main/ipc/pty/ipc/write-input.ts | sed -n '88,190p'
nl -ba src/renderer/src/runtime/runtime-terminal-inspection.ts | sed -n '115,175p'

Repository: stablyai/orca

Length of output: 7017


Reject ownerless remote: IDs before local and deferred input paths.

remote:<handle> is a valid ownerless remote ID. isRemoteInspectionPtyId does not recognize it because it requires an environment ID. Use isRemoteRuntimePtyId for this guard.

The local receiver cannot route this ID to a provider, but sendRuntimePtyInput can return true before its helper runs, and verified input can convert a local refusal into a successful fire-and-forget fallback.

🐛 Suggested fix
  const owner = getRemoteRuntimePtyOwner(ptyId)
  const remote = isRemoteInspectionPtyId(ptyId)
+ if (isRemoteRuntimePtyId(ptyId) && !owner) {
+   return clientOnlyUnverifiableInspection('terminal_gone')
+ }
  if (!owner) {

Guard the exported ordinary-input function before deferred size measurement:

 ): boolean {
+ if (isRemoteRuntimePtyId(ptyId) && !getRemoteRuntimePtyOwner(ptyId)) {
+   return false
+ }
  const tooLarge = isRuntimePtyInputTooLarge(data)

Apply the same prefix-based guard after the size check in sendRuntimePtyInputVerified:

  const owner = getRemoteRuntimePtyOwner(ptyId)
+ if (isRemoteRuntimePtyId(ptyId) && !owner) {
+   return false
+ }
  if (!owner) {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const owner = getRemoteRuntimePtyOwner(ptyId)
const remote = isRemoteInspectionPtyId(ptyId)
if (target.kind !== 'environment' || !terminal) {
if (!owner) {
const owner = getRemoteRuntimePtyOwner(ptyId)
const remote = isRemoteInspectionPtyId(ptyId)
if (isRemoteRuntimePtyId(ptyId) && !owner) {
return clientOnlyUnverifiableInspection('terminal_gone')
}
if (!owner) {

@OrcaWin
OrcaWin force-pushed the OrcaWin/d4-g1-terminals-b branch 2 times, most recently from e2d4eb9 to 58e754b Compare October 10, 2026 18:05
…ace owner

Agent note sends, background agent and terminal launches, structured chat
reveal and activation, and the tab strip's Windows shell probe take their
transport from the workspace owner's environment instead of building
owner-shaped settings for getActiveRuntimeTarget. The automation observer and
the Codex selection lane read the owner from the PTY id alone, so an
ownerless remote id is never assigned the focused server. Local
advertised-URL events always rescan this computer, even when a server is
the default host.
@OrcaWin
OrcaWin force-pushed the OrcaWin/d4-g1-terminals-b branch from 58e754b to a39b0c0 Compare October 10, 2026 18:45
@OrcaWin
OrcaWin merged commit 572f178 into main Oct 10, 2026
29 checks passed
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.

1 participant