Skip to content

fix(automations): a scheduled run never starts a stopped WSL distro - #35857

Merged
nwparker merged 2 commits into
mainfrom
nwparker/wsl-automation-stopped-distro-skip
Oct 29, 2026
Merged

nwparker merged 2 commits into
mainfrom
nwparker/wsl-automation-stopped-distro-skip

Conversation

@nwparker

@nwparker nwparker commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor
Files Added Deleted Net
Test 1 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​170 0 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​170
Prod 17 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​73 $\color{#cf222e}{\Huge{\mathbf{−}}}$​8 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​65

ELI5

If an automation is scheduled to run against a project inside a WSL distro, and that distro is stopped, Orca would start the distro just to run it. Nobody asked for that at that moment, and it is the kind of background wake E9 forbids. Now a scheduled run on a stopped distro is skipped with a clear reason, "The WSL distro Ubuntu is stopped…". The next scheduled run tries again. "Run now" is still your own act, so it still starts the distro.

User risk: low. This only affects scheduled runs whose project is on a \\wsl.localhost path while that distro is stopped, or while Orca can't confirm it's running.

What Changed

  • Before: a scheduled run dispatched as usual. Its precheck, its worktree creation and its agent terminal each touch the distro, and any of them starts it.
  • After:
    • Before dispatch, describeStoppedWslDistroRefusal asks the existing E9 gate (blockedWslDistroForPath) about the run's target path. For a host-path project whose Git runs in WSL, it also passes the project's distro (getLocalProjectWorktreeGitOptions(store, repo).wslDistro, as fix(wsl): don't start a stopped distro to read a repo's default base ref #35778 does). If the distro is stopped or unverifiable, the run is skipped with a new coded failure, wslDistroStopped, that names the distro.
    • This happens at two points:
      • at the scheduler tick, via describeScheduledTickRefusal, before a run row is created, so repeated stopped ticks fold into one skip;
      • again in requestAutomationDispatch, for scheduled runs only, in case the distro stopped in between.
    • Manual runs ("Run now") are never refused by this check.
  • Copy: the new code wslDistroStopped is added to the shared English table, en.json, en-runtime-required.json and the 10 other locales, each keeping {{distro}}. The renderer translates it by code and fills in the distro.
    • automationRunFailure now substitutes any {{param}} placeholder; the existing setup-state message is unaffected.

Why

The automation itself starts from the window on the desktop, and its precheck and worktree creation reach the distro before any terminal does. So the gate belongs at dispatch, not at terminal spawn. This is one of the follow-ups noted on #35813. The main-side terminal gate is a separate PR.

Linked Issue

N/A (maintainer change; follow-up to #35813)

Visual Proof

N/A: there's no new UI. The skip shows in the automation's run history with the new message.

Testing

  • I manually tested these changes locally
  • Automated tests added/updated:
    • automation-wsl-distro-stopped-refusal.test.ts, with a real store and service:
      • a scheduled run on a stopped distro is skipped with the coded reason, and repeated ticks fold into one skip, with nothing sent to the window;
      • once the distro runs, the run dispatches;
      • Run now isn't refused.
    • a host-path project with a WSL runtime is gated by its project's distro.
    • The five localization verifiers pass (verify:localization-catalogs, -catalog, -runtime-catalog, -extraction, -coverage).
  • Ran pnpm tc, pnpm run typecheck:ci, oxlint, the anti-slop lint, check:code-quality:changed, the ast-grep test and gates, and the automation, automation-copy and i18n tests.
    • One i18n test, language-detection-reconciliation, failed once under load and passes alone.

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

  • SSH and orcad hosts: wslDistroForPath is null off Windows, so the check never fires there.
  • Mixed versions: errorCode and errorParams are optional fields. Older clients show the stored English.

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

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 38 seconds.

Check out review usage here.

View limit details

Limit details: You’ve used all 10 included reviews currently available.

Learn how review limits work.

Review configuration:

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: ab1bdd70-1a42-46f4-819b-0eeb91aef289
Commits

Reviewing files that changed from the base of the PR and between bccdb02 and 3ba063e.

Files selected for processing: 18
  • src/main/automations/automation-dispatch-request.ts
  • src/main/automations/automation-wsl-distro-stopped-refusal.test.ts
  • src/main/automations/dispatch-refusal.ts
  • src/main/automations/service.ts
  • src/renderer/src/components/automations/automation-run-error-copy.ts
  • src/renderer/src/i18n/en-runtime-required.json
  • src/renderer/src/i18n/locales/de.json
  • src/renderer/src/i18n/locales/en.json
  • src/renderer/src/i18n/locales/es.json
  • src/renderer/src/i18n/locales/fr.json
  • src/renderer/src/i18n/locales/ja.json
  • src/renderer/src/i18n/locales/ko.json
  • src/renderer/src/i18n/locales/pt.json
  • src/renderer/src/i18n/locales/ru.json
  • src/renderer/src/i18n/locales/tr.json
  • src/renderer/src/i18n/locales/zh-Hant.json
  • src/renderer/src/i18n/locales/zh.json
  • src/shared/automation-run-failure-copy.ts
  • 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.

@greptile-apps

greptile-apps Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 3/5

[Medium impact] The change reaches scheduled automation runs that use WSL on Windows.

Do not merge yet: scheduled runs can still start stopped WSL distros.

Findings

  1. P1 Scheduled agents still wake WSL ▶
  2. P1 Scheduled runs still wake WSL ▶

Summary

Adds stopped-distro checks before scheduled automation dispatch.

  • Scheduled runs skip stopped WSL distros instead of starting them.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Scheduled occurrence] --> B[Resolve target]
  B --> C[Check WSL distro]
  C -->|Blocked| D[Record or fold skip]
  C -->|Allowed| E[Create pending run]
  E --> F[Check WSL distro again]
  F -->|Blocked| D
  F -->|Allowed| G[Dispatch to agent]
  H[Run now] --> E
  H -.-> I[Bypasses stopped-distro checks]
Loading

Reviews (2) · Last reviewed commit: "fix(automations): gate host-path WSL pro..." · Reviewed by Greptile

export async function describeStoppedWslDistroRefusal(
cwd: string
): Promise<AutomationRunFailure | null> {
const blocked = await blockedWslDistroForPath(cwd)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Scheduled runs still wake WSL

describeStoppedWslDistroRefusal uses the gate's default 60-second running lease. If Ubuntu was observed running, then stops without a stop notification before a scheduled run, both new checks can reuse that old observation and allow dispatch. The precheck or worktree creation can then start the stopped distro.

Pass { leaseMs: 0 } to require a fresh running check, and add a test with an old running observation followed by a stopped distro.

Suggested change
const blocked = await blockedWslDistroForPath(cwd)
const blocked = await blockedWslDistroForPath(cwd, undefined, { leaseMs: 0 })

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Scheduled runs whose target is on a stopped (or unverifiable) WSL distro skip with a coded, retryable wslDistroStopped reason naming the distro, checked at the tick and again at dispatch; repeated ticks fold into one skip. Run now is the user's act and still starts it.
…ate the skip

A host-path project whose Git runs in WSL passes its project distro to the stopped-distro check (as #35778 does). wslDistroStopped is translated into the 10 other locales.
@nwparker
nwparker force-pushed the nwparker/wsl-automation-stopped-distro-skip branch from 7575a2e to 3ba063e Compare October 29, 2026 10:33
): Promise<AutomationRunFailure | null> {
let wslDistro: string | undefined
try {
wslDistro = getLocalProjectWorktreeGitOptions(store, target.repo).wslDistro

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Scheduled agents still wake WSL

For a Windows-path project configured with { kind: 'wsl', distro: 'Ubuntu', git: 'windows-host' }, getLocalProjectWorktreeGitOptions returns no distro. Both scheduled checks therefore allow the run without checking Ubuntu. The agent still launches through wsl.exe, which starts Ubuntu even when it is stopped.

Read the project's execution runtime as well as its Git options, and check its WSL distro before dispatch.

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