---
title: Refactor a Repository (public)
description: Run Claude Code against one of your sandbox repositories on DigitalOcean Serverless Inference, approve its shell commands as it works, disconnect, and …
product: Managed Agents
url: https://docs.digitalocean.com/products/managed-agents/agent-harness-runtime/examples/refactor-a-repository/
last_updated: "2026-09-25"
---

> **For AI agents:** The documentation index is at [https://docs.digitalocean.com/llms.txt](https://docs.digitalocean.com/llms.txt). Markdown versions of pages use the same URL with `index.html.md` in place of the HTML page (for example, append `index.html.md` to the directory path instead of opening the HTML document).

# Refactor a Repository (public)

DigitalOcean Harness Runtime provides managed, hardware-isolated microVM sandboxes with built-in tools such as Chromium to run harnesses and execute arbitrary code. Rich lifecycle APIs preserve conversational history and working state across sessions, letting you pause, resume, and fork work to control costs and adapt to the nonlinear nature of agentic workflows. Scale complete agents such as Claude Code or use sandboxes independently for code execution, all through the same service. See [What You Can Build](https://docs.digitalocean.com/products/managed-agents/agent-harness-runtime/details/what-you-can-build/index.html.md) for example use cases.

A refactor is slow, and a laptop is a bad place to run one. This example uses Harness Runtime to start Claude Code on a repository in a sandbox, keep the workspace across disconnects, and ask you before it runs a shell command. You can close your laptop mid-refactor and pick the session back up from another machine.

This is the baseline example. The ones that follow change one thing about it at a time.

## Environment Spec

Save the following as `refactor.yaml`:

```yaml
name: checkout-refactor
agent: claude-code
size: mars-4vcpu-8gb
idle_timeout: 30m
repos:
  - your-org/your-service
env:
  HARNESS_INFERENCE_MODEL: anthropic-claude-5-sonnet
secrets:
  HARNESS_INFERENCE_API_KEY: ${HARNESS_INFERENCE_API_KEY}
  GITHUB_TOKEN: ${GITHUB_TOKEN}
egress:
  - github.com
  - api.github.com
  - registry.npmjs.org
permissions:
  default: ask
  rules:
    - tool: file.read
      action: allow
    - tool: file.write
      action: allow
    - tool: bash
      action: ask
    - tool: bash
      match: { command: "rm -rf *" }
      action: deny
```

Understand the following three choices in the spec before you copy it:

**The model comes from DigitalOcean, not from Anthropic.** `HARNESS_INFERENCE_MODEL` names a model from the [Serverless Inference catalog](https://docs.digitalocean.com/products/inference/details/models/index.html.md), and `HARNESS_INFERENCE_API_KEY` carries a [model access key](https://docs.digitalocean.com/products/inference/how-to/manage-model-access-keys/index.html.md), so Claude Code runs without an Anthropic account and its tokens bill through DigitalOcean. The two fields work the same way on every coding adapter, and the inference endpoint is added to the egress allowlist for you, which is why the `egress` list names only the hosts the agent itself reaches.

**`repos` does not clone anything.** It tells the agent which repositories it is meant to work on, and the list reaches the sandbox as the `HARNESS_WORKSPACE_REPOS` variable and the `workspace-repos` skill. The agent does the cloning itself, using `GITHUB_TOKEN` and the `github.com` egress entry. That is why the prompt below asks it to clone.

**Rule order matters.** For the agent’s own actions, the last matching rule wins, so the `rm -rf *` deny sits after the general `bash` rule in order to override it. Put the narrower rule last as a habit: some adapters resolve conflicts by taking the most restrictive rule regardless of order, and none of them surprise you when the specific deny comes after the broad allow. See [Permission Policies](https://docs.digitalocean.com/products/managed-agents/agent-harness-runtime/concepts/permissions/index.html.md).

## Run It

Make your model access key and a GitHub token available. The `${...}` form in the spec reads them from your shell at create time and stores them as write-only tenant secrets, so they never appear in the stored manifest.

```shell
export HARNESS_INFERENCE_API_KEY=<your-model-access-key>
export GITHUB_TOKEN=<your-github-token>
```

Start the session and attach to it:

```shell
doctl harness-runtime launch --spec refactor.yaml \
  --prompt "Clone your-org/your-service, then extract the checkout flow in src/checkout into its own service module. Keep the existing tests passing."
```

The agent starts working and streams to your terminal. When it wants to run a shell command, it pauses for approval: `y` approves, `n` rejects, `d` defers. Type `/pending` to see everything waiting on you.

Press `Ctrl+D` to disconnect. The session keeps running, and after 30 minutes of no activity it suspends and stops consuming compute. Reattach by name whenever you want:

```shell
doctl harness-runtime launch checkout-refactor
```

Before you let the agent try something risky, snapshot the workspace so you can get back:

```shell
doctl harness-runtime checkpoint create checkout-refactor --label before-refactor
```

## Adapt It

| To do this | Change this |
|---|---|
| Use Codex CLI or OpenCode instead | Set `agent` to `codex` or `opencode`. The two inference fields stay as they are, though a coding model such as `openai-gpt-5.3-codex` suits Codex CLI better. See [Use a Coding Adapter](https://docs.digitalocean.com/products/managed-agents/agent-harness-runtime/how-to/create-managed-agent/index.html.md). |
| Run a different model | Change `HARNESS_INFERENCE_MODEL` to another ID from [Available Models](https://docs.digitalocean.com/products/inference/details/models/index.html.md). Nothing else in the spec changes. |
| Bill the model to your own provider account | Drop both `HARNESS_INFERENCE_*` fields and declare `ANTHROPIC_API_KEY` under `secrets` instead, or `OPENAI_API_KEY` for `codex` and `opencode`. |
| Give a large repository more room | Raise `size`. Sizes run from `mars-1vcpu-1gb` to `mars-16vcpu-32gb`. |
| Let the build reach another registry | Add its host to `egress`. A host that is not listed is unreachable, and it usually fails as a timeout rather than a clear error. |
| Stop approving every shell command | Change the `bash` rule to `action: allow` and keep the targeted deny rules. Do this only when you trust the task. |
| Reuse this setup without the file | Save it as an Environment Config. See [Use Environment Configs](https://docs.digitalocean.com/products/managed-agents/agent-harness-runtime/how-to/use-agent-configs/index.html.md). |

## Related

- [Manage Sessions](https://docs.digitalocean.com/products/managed-agents/agent-harness-runtime/how-to/manage-sessions/index.html.md) for pause, resume, and cleanup.
- [Checkpoint, Fork, and Roll Back](https://docs.digitalocean.com/products/managed-agents/agent-harness-runtime/how-to/checkpoint-fork-rollback-sessions/index.html.md) to branch a warmed-up workspace or undo a bad change.
- [Environment Spec Reference](https://docs.digitalocean.com/products/managed-agents/agent-harness-runtime/reference/environment-spec/index.html.md) for every field above.