Skip to content

test(native-chat): cover paired runtime launch compatibility - #25072

Merged
brennanb2025 merged 8 commits into
mainfrom
brennanb2025/acp-b1-paired-runtime
Oct 5, 2026
Merged

brennanb2025 merged 8 commits into
mainfrom
brennanb2025/acp-b1-paired-runtime

Conversation

@brennanb2025

@brennanb2025 brennanb2025 commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor
Files Added Deleted Net
Test 4 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​357 $\color{#cf222e}{\Huge{\mathbf{−}}}$​1 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​356
Prod 1 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​6 0 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​6

ELI5

#24205 lets you open Claude or Codex native chat on a workspace that lives on a paired Orca server (another machine running Orca that this desktop is connected to). That only works if the desktop sends every chat action to the server that owns the chat, and asks that server what it supports before using a newer request shape. Before this PR, nothing checked the second half: if a code change made the desktop ask its own machine "does the server support answering questions / stopping before a turn starts / ..." instead of asking the server, every test still passed. With a newer desktop paired to an older server, the desktop would then send requests the older server rejects, and answering a question or pressing Stop would quietly fail.

There is no user-visible change. This PR only adds and tightens tests so those mistakes fail CI.

What Changed

  • New use-structured-agent-session-paired-runtime.test.tsx. It renders the real chat-session hook for a chat on a fake paired server. The fake server advertises today's capability list and this machine advertises none, so asking the wrong machine changes what gets sent. The test checks that:

    • history, live updates, the rail's conversation outline, the hold on the session, sends, and the final release all go to the server;
    • Stop before a turn has started, a repeated Stop, cancelling a pending prompt, and structured question answers all use the server's answer about what it supports;
    • a chat on this machine and a chat on the server that happen to have the same session id each read from and write to their own machine.
      This moves the paired-chat case this PR first added to use-structured-agent-session-transport.test.tsx into the new file. That file is now unchanged from main.
  • cross-version-paired-structured-launch.unit.test.ts (cross-version suite). It reads the capability names that release v1.4.219 really advertises, straight from that release's source. That is the newest release that has structured chat but predates the desktop choosing each launch's mode. The test checks:

    • that the release still uses the exact capability name today's desktop looks for. Renaming that name would follow along silently in tests that use hand-written lists;
    • that, with the list the desktop really sends when it pairs, Claude and Codex keep the terminal on that server and get native chat on a current server. The current-server half is there as a control: it proves the refusal comes from the old server, not from the desktop's own list.
  • agent-launch-routing.test.ts (one line, existing test on main). The "released server keeps the terminal" case gave no client capabilities, so it was refused by the client check instead of the old-server check it describes. It now passes a capable client, so it really tests the old-server check.

  • CI job routing (config/scripts/pr-code-change-scope.mjs). The cross-version CI job runs only when a file it covers changes. It now also runs when the launch route or the client capability list the desktop sends a paired server changes, because the cross-version test runs that code. A new pr-code-change-scope-cross-version-launch-route.test.mjs pins those paths.

Only tests and CI routing change. Production code, the wire format, and mobile are untouched.

Why

The paired-server behavior in #24205 depends on two rules: send each call to the server that owns the session, and ask that same server what it supports. Before this PR, no native-chat test drove these hooks with a chat on a paired server, so neither rule was checked for paired chats. The launch tests also used only hand-written capability lists. I checked each new test by deliberately breaking the production code in a throwaway copy:

  • Every "send this to the local machine instead" break fails the new hook test. That covers hold, release, history, live updates, send, and Stop/answer calls, plus the rail outline read and each of the four capability questions (repeated Stop, Stop before a turn, prompt cancel, question answers).
  • Keying the session reader by session id alone, ignoring which machine, fails the same-id test.
  • Dropping the old-server check now also fails agent-launch-routing.test.ts; before the one-line fix, that file stayed green.
  • Renaming the structured-chat capability fails only the cross-version test.
  • Removing the launch-mode capability from the desktop's pairing list fails the cross-version test.

Coverage I left where it already lives, instead of copying it into the cross-version file:

  • the client-capability check: agent-launch-routing.test.ts;
  • the real route input against a hand-written old server: agent-launch-route-input.test.ts;
  • folder workspaces: agent-launch-routing.test.ts.

The other version mix

An old desktop (v1.4.219) never routes a paired workspace to structured chat: its launch check refuses any host that isn't this machine. A current server with its own chat setting off refusing a client that leaves the launch mode to the server, as a released desktop does, is already covered by cross-version-agent-session-wire.unit.test.ts ("a client that leaves the launch mode to the host").

Differences from the common pattern

  • Intended: the desktop sends directly to the paired server rather than through a separate command broker. That server owns both the session records and the agent processes, so there is one authority over execution; these tests exercise that existing path.
  • Intended: the cross-version test pins v1.4.219 rather than "newest release". The newest release now has client-chosen launch modes, so a rolling baseline would stop testing refusal of older servers. The tag can't change, and the first test asserts the premise, so a wrong pin fails loudly.

Linked Issue

Follow-up to #24205 (maintainer PR; no new issue).

Visual Proof

N/A — tests only; no visual or interaction change.

Testing

  • I manually tested these changes locally
  • Automated tests added/updated, or explained why not below

What I verified:

  • On macOS, each touched file passed when run the way CI runs it (vitest --config config/vitest.config.ts):
    • cross-version test: 3 tests;
    • CI routing tests (pr-code-change-scope*.test.mjs): 70 tests;
    • new paired-chat hook test: 4 tests;
    • agent-launch-routing.test.ts: 17 tests;
    • use-structured-agent-session-transport.test.tsx: 4 tests.
  • The deliberate breaks listed under Why, in a throwaway copy of the tree.
  • A scoped web typecheck. Its only errors were 4 missing-module errors from a stale local dependency install, in files this PR doesn't touch.
  • The end-to-end test typecheck, which CI doesn't enforce, reports no errors in these files.
  • Changed-file formatting and lint pass.

CI on 7f9aa9a53a4 (this branch with current main merged in): repository guards, test vs non-test line count, and the mobile web bundle pass. The static analysis and typecheck job fails before its typecheck step. The failure is the localization coverage audit flagging two strings in src/renderer/src/lib/worktree-creation-hook-preparation.ts ("setup", "vmRecipe"). That file came from main in #25472, whose own check failed the same way, and this PR doesn't touch it. Because that job failed, CI skipped the unit-test and cross-version jobs on this head. On the previous head e89ba285c0f, before the main merge, typecheck, cross-version, and relay passed. Unit-test shards 2–4 passed there; shards 1 and 5 failed only in two locale tests that main has since fixed, and both pass locally after this merge.

What I didn't: no Orca/Electron/daemon launch, real agent run, live paired server, or Linux/Windows run. The release test reads published source and the hook test uses fakes; neither starts an app or an agent.

AI Disclosure

Review

Reviewed against the owning-runtime boundary and per-runtime capability negotiation. Passing tests and failing deliberate breaks show these tests guard those rules; they don't show the whole design is right.

Agent skill upstream boundary

  • Not applicable, or this change follows docs/reference/agent-skill-sharing-upstream-boundary.md and copies or mechanically translates no upstream skill-installer source, tests, fixtures, registry entries, path tables, comments, or documentation.

Notes

No new dependency, persisted field, process, RPC, or UI notice. SSH and WSL refusals stay covered by the existing shared route suite (structured-native-chat-launch-route.test.ts). Noticed while writing the same-id test: unsent messages waiting in this machine's outbox are stored by session id alone, not by machine. Session ids are random, so I didn't change anything here; I'm noting it rather than testing it.

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)

Main made journalItems a required outbox input; mirror production by
passing the read state's items.
- Move the paired-runtime chat test into its own file and render the real
  session hook against a paired server that advertises today's capabilities
  while this machine advertises none, so Stop, prompt cancel, repeated Stop
  and question answers fail if their capability question goes to the wrong
  runtime. Add a local and a paired session sharing one id.
- Cross-version: state that the file pins the capability strings a
  v1.4.219 server really advertises, use the desktop's real handshake list,
  and keep the current server only as the control for the refusal.
- agent-launch-routing: give the released-server case a capable client so
  it is refused by the server gate, not the client one.
…e read

- Start the cross-version job when the launch route or the client list the
  desktop sends a paired host changes, since the paired launch suite runs
  them.
- Check the rail's conversation outline is read from the paired server, and
  narrow the hook test's header to what it covers.
@brennanb2025

Copy link
Copy Markdown
Contributor Author

Review summary (head 7f9aa9a53a4)

The problem. #24205 (merged) lets you open Claude and Codex native chat on a workspace that lives on a paired Orca server. Nothing tested that decision against what a real older server advertises. Nothing tested either that every chat action from the desktop goes to the server that owns the session. An older server can advertise structured chat while still needing its own setting turned on. A check that looked only at general structured support would offer a chat that server refuses.

What changes for users. Nothing visible; this PR only adds tests.

What the tests now prove

  • Against a real older release (v1.4.219): a current desktop refuses structured chat on that server with the existing message and keeps terminal chat, for Claude and Codex in both git and folder workspaces. The test pins the exact capability names that release advertises and uses the real desktop handshake. The current server is kept only as a control.
  • Routing to the owning server: a new test renders the real session hook against a fake paired server, with only the network call layer faked. History, subscribe, send, stop, approval and question answers, release, and the outline read all go to the session's own server. So do the capability questions behind Stop and answering. A local session and a paired session with the same id stay separate.
  • An existing launch-routing test on main that passed for the wrong reason now isolates what it means to check.
  • The cross-version CI job now also runs when the launch-route and capability files these tests depend on change.

Review method: three rounds. Breakages were deliberately injected into a scratch copy of the production code (25 in round 2): requests sent to the wrong runtime, the capability question answered by the wrong runtime, renamed capability names, and a key collision between same-id sessions. Every one now fails a test. The new hook test passed 11 consecutive runs (3 in shuffled order) with no warnings. The readiness checklist found no blocking issues.

CI status: on the previous head (e89ba285c0f), typecheck, cross-version wire, relay and 3 of 5 unit shards passed. The other two failed only in two renderer translation tests that main has since fixed. This head merges current main. Its CI stops early in the localization audit, on strings main itself added in #25472 (worktree-creation-hook-preparation.ts; that PR's own check failed the same way). So typecheck and the test jobs never ran on this head. They will run once main fixes that file and this branch merges main again. All touched tests pass locally, and the renderer typecheck shows only errors from a stale local install.

Not verified: no live paired server or real app. SSH and WSL structured launches still aren't supported; this PR doesn't change that.

@brennanb2025
brennanb2025 marked this pull request as ready for review October 5, 2026 21:02
@pullfrog

pullfrog Bot commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

This run was cancelled 🛑

The workflow was cancelled before completion. Please check the link below for details.

Pullfrog  | View workflow run | via Pullfrog | 𝕏

@coderabbitai

coderabbitai Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

🧰 Additional context used
📚 Code guidelines (1)
AGENTS.md — auto-discovered

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: d15329b6-af18-4785-b2fc-506ae2f1822b
📥 Commits

Reviewing files that changed from the base of the PR and between b354aab and 7197aac.

📒 Files selected for processing (5)
  • config/scripts/pr-code-change-scope-cross-version-launch-route.test.mjs
  • config/scripts/pr-code-change-scope.mjs
  • src/renderer/src/components/native-chat/use-structured-agent-session-paired-runtime.test.tsx
  • src/renderer/src/lib/agent-launch-routing.test.ts
  • tests/e2e/cross-version-wire/cross-version-paired-structured-launch.unit.test.ts

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


📝 Walkthrough

Walkthrough

The change adds tests for paired-server structured-agent sessions, including RPC routing, cancellation, cleanup, and isolation from local sessions. It also expands the paths that trigger the cross-version wire job and adds tests for launch routing with legacy and current server capabilities.

Priority: ⬇️ Low

Merge Risk: ⚪ Minimal · up to 7197a

No actionable merge-blocking risk is identified; the change is mergeable after normal checks.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 5 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: tests for paired-runtime native-chat launch compatibility.
Description check ✅ Passed The description covers the required sections and explains the change, motivation, testing, visual proof, and compatibility impact. The AI Disclosure section is blank, but the template says internal co…
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.
  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
  • Autopilot · 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.

@brennanb2025
brennanb2025 merged commit 7208be6 into main Oct 5, 2026
82 of 85 checks passed
brennanb2025 added a commit that referenced this pull request Oct 5, 2026
Brings main's squashes of #24991, #24988, #25072 and #24989 through the agent-registry
branch, which was re-merged against them; no conflicts here.
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