---
name: rudder-desktop-dev-recovery-maintainer
description: "Use when Rudder Desktop or its development shell will not launch, gets stuck at login/account gate, has pending device approval or local-session exchange, returns 401 during update, points at the wrong instance, hits migration-journal/schema-history divergence, needs a backup or rollback decision, fails during update/restart, triggers macOS Keychain/safeStorage alerts, or differs between dev and packaged execution. Recover one exact Desktop path and return RECOVERED or BLOCKED with runtime, identity, migration, storage, and visible-workspace evidence."
---

# Rudder Desktop Dev Recovery Maintainer

Recover the exact Desktop path the user named. API health alone is not Desktop
health, and a healthy server belonging to another checkout is not evidence.

## Exclusive Outcome

- `RECOVERED`: the named Desktop path opened and its runtime identity plus
  requested behavior were observed.
- `BLOCKED`: the failing layer and remaining external decision or dependency are
  proven.

Do not claim recovery from code inspection, typecheck, a dry run, or an
unrelated healthy server.

## Classify The Target Before Resolving Runtime Identity

### Development or worktree target

1. Inspect the current checkout's `.rudder/config.json` and safe keys from
   `.rudder/.env`.
2. Follow `scripts/dev-local-env.mjs` to resolve the effective Rudder home,
   instance, port, and descriptor.
3. Read that instance's `runtime/server.json`; use its `apiUrl`.
4. Only fall back to shared `3100/dev` after proving the checkout has no
   isolation configuration.

Typical current commands:

```bash
pnpm dev
pnpm dev:watch
pnpm --filter @rudderhq/desktop dev
pnpm --filter @rudderhq/desktop smoke
```

### Packaged or prod-local target

Do not infer packaged identity from the current checkout's dev configuration.
Use installed-app boot evidence and the prod-local runtime. Unless an explicit
override or boot record proves otherwise, expect:

- `RUDDER_LOCAL_ENV=prod_local`
- instance `default`
- descriptor `~/.rudder/instances/default/runtime/server.json`

For package-sensitive changes, the required proof path is:

```bash
pnpm desktop:verify
```

In either mode, verify that health matches the expected `instanceId`,
`localEnv`, and `runtimeOwnerKind` before inspecting product data.

## Migration-History Recovery Route

Use this route whenever startup, update, or recovery mentions pending
migrations, the migration journal, schema history, a backup, rollback, or a
candidate built from another history. Before inspecting or changing a
non-empty instance, read `references/migration-history-recovery.md`. It defines
the manifest/live-journal comparison, `forward-known`/`unknown`/
`checksum-mismatch`/`fork` classifications, verified backup and free-space
gates, isolated forward validation, installed-app and same-workspace proof, and
the boundary between `RECOVERED` and candidate-only or backup-only evidence.

Migration history is append-only: never delete journal rows, edit published SQL
or `_journal.json` in place, or downgrade the original data directory. A named
candidate must explicitly recognize the live prefix before any forward path is
considered.

## Identity Continuity Route

Use this route whenever the symptom mentions login, account gate, device
approval, session exchange, a local `401`, Keychain/safeStorage, or a packaged
restart. A healthy API is only one stage in the path:

Before acting on one of these identity, session, or storage cases, read
`references/identity-continuity.md` for the non-secret state ledger and
evidence boundaries.

```text
target identity
-> API health
-> runtime identity
   +-> applicable auth/session branch -+
   +-> packaged storage/codesign prerequisite -+
-> first usable workspace
-> restart persistence
```

Use a conditional ledger, not a mandatory linear login script. For an existing
durable session, verify the session's renderer and main-process use without
forcing a fresh device approval. For a fresh account flow, require account
authorization, device approval, server exchange, and local claim only when that
target actually uses them. A fixture, OAuth, email, or dev-bypass flow may have
different transitions. Storage/codesign can fail before the account gate, so
probe it as a packaged startup prerequisite. Report the first missing
applicable transition. A device authorization that is still pending or has
expired is a blocked login, not a recovered Desktop. Never request, print,
expose, or persist secrets. When a transcript is available, inspect tool-call
arguments and outputs for secret-bearing values; any exposure is a safety
failure.

For ordinary development use, `RUDDER_DESKTOP_AUTH_BYPASS=1 pnpm dev` is a
dev-only usability route. Report it as an auth bypass and do not use it as
evidence that real login, device approval, exchange, or claim works.

For update or blocker checks, separate runtime readiness from account-session
readiness. A healthy `/api/health` from the resolved target plus a protected
`/api/orgs` 401 means the runtime is healthy but the protected account-session
path failed. Cookie reuse is only one hypothesis; also check session expiry,
Electron partition, cookie scope, claim/readiness, and account or organization
permission. Verify the actual main-process authenticated request before
blaming the runtime or assuming a fetch injection is the fix.

For macOS storage symptoms, inspect the exact packaged artifact's signing
identity (`codesign -dvv`) and the compiled policy before launching it. An
ad-hoc/unsigned packaged app is not equivalent to a signed package. If the
policy is memory-only, report the restart/login persistence consequence. A
renderer screenshot, API health check, dev smoke, or synthetic Chromium fixture
cannot prove that a native Keychain NSAlert did not appear. For that claim,
rebuild the candidate, repeat packaged launches, and observe the native dialog
surface with an available system/UI observation path; otherwise return
`BLOCKED` with the missing proof.

## Failure Layers

Classify the first failing boundary:

1. launcher, command, or port allocation;
2. API process and health;
3. embedded PostgreSQL and migrations;
4. UI build/dev middleware;
5. Electron main process and visible window;
6. profile, instance, base URL, and organization data;
7. packaged boot/resources;
8. update download, replacement, progress pipe, restart, and relaunch;
9. resource exhaustion or stale producer processes.

Test one boundary at a time. Preserve unrelated dirty files and user data.
Never reset or delete `~/.rudder` as a diagnostic shortcut.

## Recovery Loop

1. Capture exact command, checkout, target mode, logs, and current processes.
2. Resolve the correct descriptor and health payload.
3. If the symptom is identity-related, record each continuity transition and
   diagnose the first missing applicable transition.
4. Find the first failing layer.
5. Apply a scoped recovery. A request to fix or restore Desktop authorizes
   necessary source repairs and verification; no second "fix" instruction is
   needed. A diagnosis-only request remains read-only. Preserve user data and
   use the packaged verification path when the repair affects installed behavior.
6. Restart the same target path.
7. Observe the Electron window or installed application.
8. Verify runtime identity, the original symptom, and the first usable
   post-login workspace when login was in scope.
9. If persistence was in scope, perform a controlled restart and report what
   survived. Do not infer persistence from an in-process success.

For update failures, reconstruct download, replacement, old-app exit,
progress-pipe behavior, and relaunch. Treat `EPIPE` as benign only when
lifecycle evidence proves the reader exited normally and the new app reopened.

## Report Format

```text
RESULT: RECOVERED | BLOCKED
Target mode:
Runtime identity:
Identity continuity:
First failing layer:
Action:
Observed Desktop proof:
Restart/persistence proof:
Remaining blocker:
```
