Skip to content

dispatch-from-rescue: surface salvageRef and add rescueFromRunId to POST /runs #1241

Description

@jayminwest

The gap

When a run's work is rescued to a warren/rescue/<runId> branch after the agent failed to land it, nothing tells the operator the rescue exists and nothing lets them dispatch a follow-up run from it. Today the recovery is a hand sequence: find the run id, guess the branch name, fetch it, check it out, dispatch a new run, and paste the original prompt.

What exists:

  • src/runtime/salvage.ts:41-44 defines RESCUE_BRANCH_PREFIX = "warren/rescue/" and rescueBranchFor(runId). The reap path stamps salvageRef and salvagePath onto the run row (src/runs/reap/run.ts:298-311, and the pod-posted arm at :262-268).
  • The wire type carries both fields to the UI (src/ui/src/api/types.ts:178-180).

What does not:

  • No page under src/ui/src/pages/ and no command under src/cli/commands/ renders salvageRef or salvagePath (the only hits are null values in test fixtures).
  • POST /runs (src/server/handlers/runs/dispatch.ts:98-130) accepts continueFromRunId, cloneFromRunId, and existingBranch, but has no field that resolves a rescue.

Since PR #1166 an operator who knows the branch name can dispatch with existingBranch: "warren/rescue/<runId>", because resolveExistingBranch (src/runs/spawn/continuation.ts:36-52) checks the branch on the remote and starts the workspace there. Nothing suggests this, and nothing derives the name for them.

What to build

  1. Surface the rescue. On the run-detail page (src/ui/src/pages/run-detail/) and in warren show pretty output, when salvageRef is set, show the ref and the bundle path, with a one-line "re-dispatch from this rescue" hint that names the command below. Follow the existing field-rendering helpers in run-detail-format.ts.
  2. rescueFromRunId on POST /runs. Add it beside continueFromRunId in dispatch.ts:98-130. Resolve the source run, refuse with 400 when it has no salvageRef, and otherwise set existingBranch to that ref and fill agent, project, prompt, provider, model, and cost cap from the source run the way resolveCloneDefaults does for cloneFromRunId. Record parentRunId on the new run so the lineage is visible. Expose it as warren run --rescue-from <runId> and as a button next to the surfaced ref.
  3. Docs and generated files. bun run gen:docs, bun run gen:openapi, and bun run gen:cli-ref.

An automatic retry at reap time after dropped_commit, modelled on src/runs/retry/infra-lost-retry.ts, is a possible third step. It is a policy decision and is out of scope here.

Scope

Out of scope: the automatic retry above, and any change to how the rescue branch is created.

Tests: src/server/handlers/runs.dispatch.test.ts (the new field, the 400 on a run with no rescue, and mutual exclusion with continueFromRunId and existingBranch), src/runs/spawn/existing-branch.test.ts, src/runs/spawn/continuation.test.ts, the run-detail format tests, and src/cli/commands/show.test.ts and run.test.ts for the new output and flag. The fake forge used by the handler tests stands in for the remote.

Getting started

AGENTS.md covers setup and conventions, including the single-implementation rule (the resolution logic lives in src/runs/, and the handler, CLI, and UI consume it). Everything here is testable in-process with no cluster and no credentials. Run bun run check:all before pushing, and bun run build:ui for the UI half. Warnings count as failures.

Tracked internally as warren-1db0.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/runsRun lifecycle, events, streaming (src/runs/)area/serverHTTP API surface (src/server/, ROUTE_TABLE, handlers)area/uiReact/Vite SPA (src/ui/, @os-eco/warren-ui)effort/medium1-3 days of focused workgood first challengeLarger contributor-ready project: scoped, self-contained, gate-verifiedhelp wantedMaintainers welcome external contributions herepriority/P3Low: nice-to-have; pick up when capacity allowstype/featureNew user-facing capability

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions