Skip to content

test(runtime): fail when Electron and orcad wire the runtime differently without a reason - #30212

Merged
nwparker merged 1 commit into
mainfrom
nwparker/r2-composition-parity
Oct 18, 2026
Merged

nwparker merged 1 commit into
mainfrom
nwparker/r2-composition-parity

Conversation

@nwparker

@nwparker nwparker commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor
Files Added Deleted Net
Test 1 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​343 0 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​343
Prod 0 0 0 0

ELI5

Orca builds its runtime in two places: the desktop app (Electron) and the headless server (orcad). Every piece the runtime can be given is optional, so one place can quietly forget a piece the other provides. This adds a test that lists what each place provides and fails when they differ without a written reason.

What Changed

  • New src/main/runtime/construction/runtime-composition-parity.test.ts. It reads both composition roots' source and records:
    • every key of the object passed to new OrcaRuntimeService(...), following spreads into their helper objects (agentHookRuntimeDeps, the Codex launch resolvers, orcad's account deps);
    • every option passed to new OrcaRuntimeRpcServer(...) (this is where fix(serve): orca serve on orcad serves the browser client and answers plain HTTP #30120's webClientRoot lives);
    • every runtime.set* / rpc.set* setter call, and whether SSH handlers are registered.
  • DECLARED_HOST_DIFFERENCES lists the 18 differences that exist today, each with a reason. An undeclared difference fails, and so does a declaration that no longer matches anything.
  • Two entries record capabilities orcad advertises but cannot serve (SSH target management, skill sharing). The test checks they are still advertised, so the list stays true; the typed refusal for them is a separate PR (D3).
  • No user-visible change. Test only.

Why

Round 2 class C2: the Electron and orcad roots drift and nothing compares them (#30120, #29209, #29881). The proposal suggested booting both roots with stubbed services. That needs about 40 module mocks for orcad and the Electron app object for desktop, and a mock list would drift like the roots do. Recording from the source catches the same thing (an option or dependency one root sets and the other doesn't), runs in milliseconds, and refactors nothing in orcad-entry.ts, which other agents are editing. An unknown spread fails with "teach SPREAD_SOURCES", so the recorder cannot silently miss a dependency.

Proof: deleting webClientRoot from orcad's OrcaRuntimeRpcServer options (the #30120 shape) fails two of the three tests.

Follow-up found while declaring: orcad never wires getPairedDeviceName, so client-hosted browser rows show no paired-device name there.

Linked Issue

Refs round-2 SSH/remote hardening S3 (C2). Regression guard for #30120.

Visual Proof

N/A: test only, no behaviour change.

Testing

  • pnpm test src/main/runtime/construction/ passes. With webClientRoot removed from orcad-entry.ts it fails.

  • The full static-analysis job, run locally.

  • Not verified live: nothing runtime-visible changed.

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

Review

Codex review (gpt-6.1-sol, high): no findings.

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, SSH, mobile or platform impact: test only.

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 18, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

📝 Walkthrough

Adds a Vitest test that parses Electron and orcad runtime-composition sources to collect constructor options, RPC options, runtime and RPC setters, and SSH-handler registration. The test checks six shared wiring entries, compares observed differences with declared host-specific differences, and verifies that declared reasons are nonempty. It also checks that listed advertised-but-unserved capabilities remain in RUNTIME_CAPABILITIES.

Priority: ⬇️ Low

Merge Risk: 🔵 Low · up to 6eef2

This change adds a test only and does not alter runtime behavior. In the rare case of a malformed scanned source file, the new test could hang instead of failing with a clear error. That is a small, bounded risk.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 6 functions across 1 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title clearly and concisely describes the main change: adding a test that detects unexplained runtime wiring differences between Electron and orcad.
Description check Passed The description is detailed and covers the change, rationale, testing, visual proof, review, scope, and checklist. The linked issue section references issues in text but does not include a direct issu…
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.
Full details: Description check

Explanation

The description is detailed and covers the change, rationale, testing, visual proof, review, scope, and checklist. The linked issue section references issues in text but does not include a direct issue link or a Fixes #... entry.

  • 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: eff6727a-ad93-4527-b3b7-a5d74c46fc12
📥 Commits

Reviewing files that changed from the base of the PR and between 553bde3 and 6eef235.

📒 Files selected for processing: 1
  • src/main/runtime/construction/runtime-composition-parity.test.ts

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

Comment on lines +168 to +169
} else if (char === '/' && source[i + 1] === '*') {
i = source.indexOf('*/', i + 2) + 1

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.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Fix the unterminated block comment handling in stripComments.

If source.indexOf('*/', i + 2) returns -1, the expression -1 + 1 sets i to 0. The for loop then increments i to 1. The loop restarts from the file start and never ends. This only happens for a source file with an unterminated /*. The result is a hung test run instead of a clear error. The same loop can also repeat on a /* inside a regex literal.

Throw an error when the terminator is missing.

Proposed fix
--- "a/src/main/runtime/construction/runtime-composition-parity.test.ts"
+++ "b/src/main/runtime/construction/runtime-composition-parity.test.ts"
@@ -165,8 +165,12 @@
         i++
       }
       out += '\n'
     } else if (char === '/' && source[i + 1] === '*') {
-      i = source.indexOf('*/', i + 2) + 1
+      const end = source.indexOf('*/', i + 2)
+      if (end === -1) {
+        throw new Error('unterminated block comment')
+      }
+      i = end + 1
     } else {
       if (char === "'" || char === '"' || char === '`') {
         quote = char
📝 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
} else if (char === '/' && source[i + 1] === '*') {
i = source.indexOf('*/', i + 2) + 1
} else if (char === '/' && source[i + 1] === '*') {
const end = source.indexOf('*/', i + 2)
if (end === -1) {
throw new Error('unterminated block comment')
}
i = end + 1

@nwparker
nwparker merged commit 8209d30 into main Oct 18, 2026
31 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