---
title: Orphaned Workspace Archive (reclaim the folder, keep the work)
---

# Orphaned Workspace Archive

## What it is

### What it is

A background job that reclaims the **folder** of a workspace whose session has been gone for 24 hours, while keeping its **branch** and every change on it.

Each agent session works in its own workspace — a git worktree, a full copy of the project on disk. When a session is archived or ends, its workspace usually stays behind. Most of those get tidied up automatically once their work lands on the main branch. The ones whose work never landed had nowhere to go: nothing would touch them, because the only tool available also deleted the branch, and deleting a branch that still holds unlanded commits is exactly what must never happen. So they piled up.

They add up quickly. A workspace carries its own dependency tree, so a few hundred of them occupy real disk — enough to fill the drive they sit on.

This job adds the missing third option: **free the disk, keep the work.**

## Where to find it

There is no screen for it: it reports through an **inbox note** at most once a day, and the live state of the workspaces it is tracking shows in the **Work in Flight** view of the **Dev Pipeline** panel.

## How it behaves

### What "archived" means here

- The **folder** is moved to a recycling area and deleted later in the background. That is the disk saving.
- The **branch stays**, with every commit on it.
- Any **uncommitted changes are committed to that branch first**, and also saved to a permanent recovery marker, before the folder goes anywhere.
- Nothing is verified by assumption. If the job cannot **prove** the work was saved, it leaves that workspace completely alone and says so.

Nothing is lost. Archiving a workspace is closer to closing a document than deleting it.

### Picking the work back up

A branch whose workspace was archived is not stuck — you get a fresh workspace carrying all of its work on demand:

```
POST http://127.0.0.1:19519/worktrees/create
{ "repo": "<repo root>", "baseBranch": "<the archived branch>",
  "branchPrefix": "recover", "taskTitle": "<what you are doing>" }
```

That makes a new folder on a **new branch forked from the archived one** and registers it, then provisions its dependencies in the **background** — the same paved road any new piece of work uses. Read `readinessWarning` on the reply before you work in it: a `200` does not mean usable, and a `202 status: 'creating'` means `path` is still being built, so poll `GET /worktrees/create/<ledgerId>` until it reports ready. Every commit and every auto-saved change is carried onto it, and the archived branch itself is left untouched. If a session resumes and finds its old folder gone, this one call is the whole recovery.

**Do not pass the archived branch as `branch`.** `branch` names the branch to _create_, and the create refuses a name that already exists (`409 branch-exists`, _"A branch with that name already exists. Use a different task title."_). That message is written for a naming collision, not for this situation — following it would rename you onto a brand-new empty branch and leave the preserved commits behind. The archived branch belongs in `baseBranch`, which is the "fork from here" field.

Uncommitted work that was auto-saved appears as a commit on the branch (message: `chore: auto-save WIP before worktree cleanup`) and is also reachable under `refs/amc/preserved-wip/`.

**That auto-save commit is a snapshot, not finished work — and it is never merged on its own.** When a session is archived (or the app restarts and replays a pending merge), the session-end merge-back skips a branch whose _latest_ commit is the auto-save, leaves a note on the session saying so, and keeps everything in place. To land the work: review the snapshot, commit real work on top of it, or tag the branch ready-to-merge after running the checks — any of those makes it landable again.

**A branch whose own recorded tests run says the work is broken is held for the same reason.** The merge-back also skips a branch when the last tests run it recorded carries a failure the runner traced back to _this_ branch's changes, leaves a note saying so, and keeps everything in place. This is the same promise as above from the other direction: a branch is merged on what was actually measured about it, not on the fact that its session has ended. A branch that ran nothing, or whose red is one master already has, is unaffected. To land the work: fix what the tests report, run them again at the branch tip, then either commit that or tag the branch ready-to-merge.

### What it will never archive

The job is deliberately narrow. A workspace is skipped — and the reason is reported — when any of these is true:

- **Someone is still working there.** Its session is running, waiting on you, paused, errored, or parked on a rate limit. A rate-limit park resumes on its own, so it is treated as live.
- **It is being reworked.** A workspace handed back for a merge conflict is in-flight work, not abandoned work.
- **You kept it.** Pinning a workspace is an answer, and the job does not re-ask. Pin one with the **Keep** control on its row in the Dev Pipeline panel's **Work in Flight** view, or `POST /worktrees/:id/pin` — which also sets the real git lock on the folder.
- **It has unsaved work the job cannot save** — files it cannot commit, or files under an ignored path.
- **It is locked, marked do-not-delete, or running a live command.**
- **It was created in the last few hours**, or something wrote to it recently.
- **It is one of the product's own scratch workspaces**, which the product manages itself.
- **Its work already landed** — those go through the normal post-landing tidy-up instead.

Every one of those checks is the same set the manual cleanup already honours, and the job cannot override a single one of them.

### Pinning now settles the other job too

"You kept it" above is the rule for _this_ job. Until 2026-09-12 the separate **Unmerged worktrees need inspection** inbox card did not follow it: it re-listed every pinned workspace and asked you to decide about it again, every day, so that card could never finish and clear itself. On the day it was fixed, six of the seven workspaces it was asking about were ones you had already pinned.

It follows the same rule now. A pinned workspace is not listed as a decision; it shows only as a quiet count at the bottom of the card — _"6 pinned worktree(s) are being kept on purpose"_ — so you can still see they exist without being asked again. When nothing else is left to decide, the card clears itself, pinned workspaces or not.

### The first run only reports

The very first time it runs, it changes nothing. It raises one inbox note listing exactly what it _would_ archive, so you can see the shape of it before anything moves. From the next run on, it acts.

### What you will see

At most **one inbox note per day**, and only when there was something to say. It reports:

- how many workspaces were archived (and that their branches were kept),
- how many were **held back by a safety check**, broken down by which check,
- how many are **waiting on their session rather than the clock**, broken down by session state.

That last number exists so a second, longer tier can be decided on real data — for example, giving workspaces whose session _you_ stopped 72 hours instead of 24 — rather than on a guess.

The note asks nothing of you. There is no action to take.

### Controls

- **Setting:** `orphanWorktreeArchiveEnabled` — on by default. Turn it off with
  `PATCH /settings { "orphanWorktreeArchiveEnabled": false }`.
- **Kill switch:** set `AMC_DISABLE_ORPHAN_WORKTREE_ARCHIVE=1`. Read live, so it takes effect on the next run with no restart.
- **Pace:** every 5 minutes, at most 25 workspaces per run, and it stands down while the worktree drives are busy. (It ran hourly until the cadence was raised — an hourly pass archived about 2 workspaces an hour while about 4.7 an hour were becoming eligible, so the backlog grew even while the job worked.)

### How it behaves under load

It never competes with you. The expensive part of freeing a folder — actually deleting thousands of files — is not this job's work at all; it hands the folder to the existing background cleaner, which already paces itself around disk and CPU. This job's own step is a few quick reads and one rename.

It does stand down while the drives are **busy**, but deliberately **not** because they are **full** — being full is the problem it exists to fix, and standing down then would keep it switched off forever on exactly the machine that needs it.

## For agents

### Where the record lives

Every archive and every skip is written to the workspace's own history with the reason and the evidence, so "what happened to my workspace?" has an answer days later. The **Work in Flight** view in the Dev Pipeline panel shows the live state — it is still **in development**, so reveal it in **Settings → Lab** (or set `AMC_SHOW_WORKTREE_LEDGER=1`) and turn on `worktreeLedgerEnabled`. The record itself is written either way; the view is only how you read it.

## Related

### See also

- [worktree-cleanup-skill.md](worktree-cleanup-skill.md) — the on-demand skill for reaping workspaces whose work has already landed.

