Skip to content

Wait for editor ownership before listing remote Markdown - #26590

Merged
OrcaWin merged 1 commit into
mainfrom
nwparker/remote-markdown-conversion-testing
Oct 9, 2026
Merged

OrcaWin merged 1 commit into
mainfrom
nwparker/remote-markdown-conversion-testing

Conversation

@nwparker

@nwparker nwparker commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor
Files Added Deleted Net
Test 4 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​330 $\color{#cf222e}{\Huge{\mathbf{−}}}$​3 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​327
Prod 5 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​59 $\color{#cf222e}{\Huge{\mathbf{−}}}$​13 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​46

ELI5

While an old SSH editor tab moved onto its managed server, Orca briefly asked this computer to list the remote Markdown files. This computer rejected the remote path. Markdown now waits until the editor has taken its new host, then asks that host.

What Changed

Markdown document listing reuses the content loader’s existing restored-editor ownership check and waits when the workspace owner is still missing. It subscribes to the existing connection-owner selector so a catalog update resumes listing even when the workspace path stays the same. The ownership check accepts only the file fields it reads; its behavior is unchanged. Callback dependencies stay scoped to routing fields, so ordinary editor updates do not restart scans.

A real conversion regression is routed to the CI job that builds its server template. The existing Docker lane contract is extracted unchanged and recognizes that job.

Why

File content already waited for ownership migration, but its document-link metadata started independently from the old tab’s saved owner. Reusing that decision keeps both reads on the same host without a second routing policy, polling, or treating missing ownership as local.

Linked Issue

Found while validating #26483. Independent fix against OrcaWin/phase35.

Visual Proof

Baseline conversion context at the failing desktop metadata request. The attached baseline log records fs:listMarkdownDocuments rejecting the remote path; this screenshot captures the timing of that request.

markdown-conversion-before.png

Corrected flow: the retained README loads from the host, and its preview link opens the host-only sibling document.

markdown-conversion-after.png

Baseline failure: markdown-conversion-runtime-red.log

Corrected run: markdown-conversion-runtime-green.log

Testing

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

Hidden macOS Electron client and real Linux Docker SSH host with the exact installed 1.4.223-adhoc.20261008080519 server template. Repeated baseline conversions fail the wrong-host request assertion; corrected flow passes in 10.1 seconds, including positive host document listing and rendered preview-link navigation. No Windows runtime claim.

93 tests across 10 files pass: managed and folder-workspace migration, missing-owner hydration without a path change, explicit remote ownership before catalog hydration, existing navigation, request deduplication, selector scaling, and CI routing. Full pnpm tc, pnpm lint, changed quality, fresh Electron E2E build, final affected lint, and commit hooks pass.

Review

The existing content loader completes the owner change; Markdown waits for it and resumes from the same store. File saving, server publication, and transport behavior are unchanged.

Agent skill upstream boundary

  • Not applicable; no upstream skill-installer content copied.

Notes

The runtime logs also show pre-existing hosted-review reconnect errors and duplicate same-ID editor entries. A rich-editor document link can remain visually marked missing even though its preview link works. These are separate investigations, not fixed or suppressed here. A superseded listing error may be logged without publishing a toast; this PR does not claim every baseline conversion shows a visible error message.

No wire or platform-specific changes. Missing ownership delays a read; it does not authorize a desktop fallback. Existing contact-loss verdicts are preserved.

Checklist

  • This PR is small and focused
  • Explained before/after, mechanism, and why
  • Real runtime logs and screenshots attached
  • Self-reviewed for correctness, security, and performance
  • Cross-platform, SSH, folder workspace, and compatibility impact considered
  • Local tests, typecheck, lint, quality, and build pass

@OrcaWin
OrcaWin force-pushed the nwparker/remote-markdown-conversion-testing branch from acd0044 to 2bf93f3 Compare October 9, 2026 02:22
@OrcaWin
OrcaWin changed the base branch from OrcaWin/phase35 to main October 9, 2026 02:22
@coderabbitai

coderabbitai Bot commented Oct 9, 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: 58a94999-ca07-4e8a-84c4-890d7a80b4df
📥 Commits

Reviewing files that changed from the base of the PR and between ffb449690229dbcf099df7dcc19f64e05744f3d7 and 2e95086.

📒 Files selected for processing (4)
  • .github/workflows/e2e.yml
  • config/scripts/ci-e2e-job-selection.mjs
  • config/scripts/ci-e2e-job-selection.test.mjs
  • config/scripts/pr-e2e-source-routing.mjs

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


📝 Walkthrough

Walkthrough

The Markdown document hook now checks restored workspace ownership and runtime availability before requesting document listings. New tests cover ownership resolution for retained editors, SSH repositories, and folder workspaces. A Docker-gated E2E test checks Markdown listing and link navigation after conversion and session retention. CI source routing, job selection, and workflow configuration now select and run this test.

Priority: ➖ Normal

Merge Risk: ⚪ Minimal · up to 2e950

The ownership transitions inspected provide a retry for Markdown listing, and relevant editor changes select the dedicated conversion E2E job. No concrete current-head regression remains to block merging.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 9 files. (1 skipped: 1… 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 identifies the primary behavior change: Markdown listing waits for editor ownership before querying remote files.
Description check Passed The description is complete and focused. It includes the required explanation, change details, rationale, issue reference, visual proof, testing results, review notes, compatibility considerations, an…
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: Docstring Coverage

Explanation

Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 9 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
  • 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.

@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: 3671e1f1-f241-41cb-a63f-b5ea9da96ae9
📥 Commits

Reviewing files that changed from the base of the PR and between d191386 and 2bf93f3.

📒 Files selected for processing (11)
  • .github/workflows/e2e.yml
  • config/scripts/ci-e2e-job-selection.mjs
  • config/scripts/ci-e2e-job-selection.test.mjs
  • config/scripts/pr-e2e-docker-lane-contract.test.mjs
  • config/scripts/pr-e2e-gate-contract.test.mjs
  • config/scripts/pr-e2e-source-routing.mjs
  • src/renderer/src/components/editor/restored-editor-workspace-runtime-owner.ts
  • src/renderer/src/components/editor/useMarkdownDocuments.navigation.test.ts
  • src/renderer/src/components/editor/useMarkdownDocuments.ownership.test.tsx
  • src/renderer/src/components/editor/useMarkdownDocuments.ts
  • tests/e2e/ssh-orcad-markdown-conversion.spec.ts
💤 Files with no reviewable changes (1)
  • config/scripts/pr-e2e-gate-contract.test.mjs

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 +82 to +100
const state = useAppStore.getState()
const settings = settingsForRuntimeOwner(state.settings, activeFile.runtimeEnvironmentId)
// The content loader reowns retained tabs before metadata may use their new host.
if (
findRestoredEditorWorkspaceRuntimeOwner(
state,
{
worktreeId,
filePath: activeFile.filePath,
externalSshTargetId: activeFile.externalSshTargetId,
operationProvenance: activeFile.operationProvenance,
runtimeEnvironmentId: activeFile.runtimeEnvironmentId
},
worktreeId
) ||
(connectionId === undefined && !settings?.activeRuntimeEnvironmentId?.trim())
) {
return
}

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:

#!/bin/bash
rg -nP -C3 'findRestoredEditorWorkspaceRuntimeOwner\s*\(' src/renderer
rg -nP -C5 'function getExplicitRuntimeEnvironmentIdForWorktree' src/renderer

Repository: stablyai/orca

Length of output: 3455


🏁 Script executed:

set -u
printf '%s\n' '--- useMarkdownDocuments ---'
nl -ba src/renderer/src/components/editor/useMarkdownDocuments.ts | sed -n '1,180p'
printf '%s\n' '--- restored owner helper ---'
nl -ba src/renderer/src/components/editor/restored-editor-workspace-runtime-owner.ts | sed -n '1,180p'
printf '%s\n' '--- runtime owner resolver ---'
nl -ba src/renderer/src/lib/worktree-runtime-owner.ts | sed -n '1,180p'
printf '%s\n' '--- related hook and tests ---'
rg -n -F --glob '*.{ts,tsx}' -- 'useMarkdownDocuments' src/renderer
rg -n -F --glob '*.{ts,tsx}' -- 'runtimeEnvironmentId:' src/renderer/src/components/editor src/renderer/src | head -120

Repository: stablyai/orca

Length of output: 36534


🏁 Script executed:

nl -ba src/renderer/src/components/editor/useMarkdownDocuments.ts | sed -n '1,180p'
nl -ba src/renderer/src/components/editor/restored-editor-workspace-runtime-owner.ts | sed -n '1,180p'
nl -ba src/renderer/src/lib/worktree-runtime-owner.ts | sed -n '1,180p'
rg -n -F --glob '*.{ts,tsx}' -- 'useMarkdownDocuments' src/renderer

Repository: stablyai/orca

Length of output: 21385


🏁 Script executed:

set -u
printf '%s\n' '--- remaining useMarkdownDocuments ---'
nl -ba src/renderer/src/components/editor/useMarkdownDocuments.ts | sed -n '178,280p'
printf '%s\n' '--- connection context ---'
rg -n -F --glob '*.ts' -- 'function getConnectionIdFromState' src/renderer/src
rg -n -F --glob '*.ts' -- 'getConnectionIdFromState' src/renderer/src/lib src/renderer/src/store | head -80
printf '%s\n' '--- active runtime setting updates ---'
rg -n -P --glob '*.{ts,tsx}' -C4 'activeRuntimeEnvironmentId\s*:' src/renderer/src | head -240
printf '%s\n' '--- ownership test ---'
nl -ba src/renderer/src/components/editor/useMarkdownDocuments.ownership.test.tsx | sed -n '1,230p'

Repository: stablyai/orca

Length of output: 38510


🏁 Script executed:

nl -ba src/renderer/src/components/editor/useMarkdownDocuments.ts | sed -n '178,280p'
rg -n -F --glob '*.ts' -- 'function getConnectionIdFromState' src/renderer/src
rg -n -F --glob '*.ts' -- 'getConnectionIdFromState' src/renderer/src/lib src/renderer/src/store | head -80
rg -n -P --glob '*.{ts,tsx}' -C4 'activeRuntimeEnvironmentId\s*:' src/renderer/src | head -240
nl -ba src/renderer/src/components/editor/useMarkdownDocuments.ownership.test.tsx | sed -n '1,230p'

Repository: stablyai/orca

Length of output: 35796


🏁 Script executed:

nl -ba src/renderer/src/lib/connection-owner-resolution.ts | sed -n '1,145p'
printf '%s\n' '--- active workspace route ---'
rg -n -F --glob '*.ts' -- 'function resolveActiveWorkspaceRoute' src/renderer/src/lib
rg -n -F --glob '*.ts' -- 'resolveActiveWorkspaceRoute' src/renderer/src/lib/worktree-operation-route.ts src/renderer/src/lib | head -80
printf '%s\n' '--- editor owner restamping ---'
rg -n -P --glob '*.{ts,tsx}' -C5 'runtimeEnvironmentId\s*=\s*.*activeRuntimeEnvironmentId|runtimeEnvironmentId:\s*.*activeRuntimeEnvironmentId|set.*runtimeEnvironmentId|update.*runtimeEnvironmentId' src/renderer/src/components/editor src/renderer/src/store | head -240

Repository: stablyai/orca

Length of output: 32767


🏁 Script executed:

nl -ba src/renderer/src/lib/connection-owner-resolution.ts | sed -n '1,145p'
rg -n -F --glob '*.ts' -- 'function resolveActiveWorkspaceRoute' src/renderer/src/lib
rg -n -F --glob '*.ts' -- 'resolveActiveWorkspaceRoute' src/renderer/src/lib/worktree-operation-route.ts src/renderer/src/lib | head -80
rg -n -P --glob '*.{ts,tsx}' -C5 'runtimeEnvironmentId\s*=\s*.*activeRuntimeEnvironmentId|runtimeEnvironmentId:\s*.*activeRuntimeEnvironmentId|set.*runtimeEnvironmentId|update.*runtimeEnvironmentId' src/renderer/src/components/editor src/renderer/src/store | head -240

Repository: stablyai/orca

Length of output: 32508


🏁 Script executed:

nl -ba src/renderer/src/components/editor/useEditorPanelFileContentLoader.ts | sed -n '80,210p'
rg -n -P --glob '*.{ts,tsx}' -C5 'migrateRestored|reown|restored.*owner|runtimeEnvironmentId.*openFile|updateOpenFile|setOpenFile' src/renderer/src/components/editor src/renderer/src/store/slices/editor* src/renderer/src/store | head -260

Repository: stablyai/orca

Length of output: 35643


Wake Markdown listing when the focused runtime owner changes.

refreshMarkdownDocuments does not depend on settings.activeRuntimeEnvironmentId or the explicit workspace owner. Focusing the workspace’s owning runtime can clear findRestoredEditorWorkspaceRuntimeOwner without changing activeFile.runtimeEnvironmentId or connectionId, so the effect does not retry and the document list can remain empty.

Subscribe to the focused runtime and owner-route state, or otherwise trigger refreshMarkdownDocuments when those values change. Do not rely on the content loader to restamp this case: it intentionally skips reownership when the restored owner is the focused runtime.

@OrcaWin
OrcaWin force-pushed the nwparker/remote-markdown-conversion-testing branch from 2bf93f3 to ffb4496 Compare October 9, 2026 05:04
@OrcaWin
OrcaWin force-pushed the nwparker/remote-markdown-conversion-testing branch from ffb4496 to 2e95086 Compare October 9, 2026 05:28
@OrcaWin
OrcaWin merged commit 45a969f into main Oct 9, 2026
39 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.

2 participants