# How Disposable Worktree Isolation in no-mistakes Protects Your Local Git Repository

> Learn how no-mistakes disposable worktree isolation shields your local Git repository from pipeline disruptions. Keep your workdir safe from rebases and force-pushes.

- Repository: [Kun Chen/no-mistakes](https://github.com/kunchenguid/no-mistakes)
- Tags: deep-dive
- Published: 2026-06-27

---

**no-mistakes runs every pipeline step inside a temporary Git worktree under `~/.no-mistakes/worktrees/<repo-id>/<run-id>`, ensuring that rebases, force-pushes, and temporary commits never touch your local working directory.**

Automated CI/CD pipelines often perform destructive Git operations like rebasing and force-pushing, but executing these directly against your local repository risks corrupting branch history or overwriting uncommitted changes. The **no-mistakes** open-source tool solves this by implementing **disposable worktree isolation**, a pattern that creates ephemeral Git worktrees for every pipeline execution. This architecture guarantees that all automated operations happen inside a completely separate directory tree that is destroyed after the run, leaving your local Git state pristine.

## What Is Disposable Worktree Isolation?

Disposable worktree isolation is a sandboxing strategy that leverages Git’s built-in worktree feature to create temporary checkouts that share the same object database as your real repository but live in entirely separate directories.

### The Bare "Gate" Repository Pattern

When no-mistakes initializes a repository, it mirrors your real repo into a **bare "gate" repository** that acts as the object storage backend. The disposable worktree is then created using standard Git commands:

- The worktree is created with `git worktree add` from this bare repository
- The worktree’s `.git` file becomes a pointer to the bare repo rather than a full `.git` directory
- All normal Git commands (`git diff`, `git commit`, `git rebase`, `git push`) operate on the worktree and never on your original working tree

As documented in `internal/pipeline/steps/execution_context.go:18-22`, agents receive an explicit prompt explaining this context: *"You are running inside an isolated git worktree … the worktree’s `.git` is a pointer file … treat it as the project’s source of truth."* This ensures AI agents and automated scripts understand they are operating inside a disposable environment.

## How the Isolation Mechanism Works

The implementation relies on three coordinated components that manage the lifecycle of the temporary worktree from creation to destruction.

### Worktree Creation and Path Resolution

Each pipeline run receives a deterministic, unique directory path generated by the `WorktreeDir(repoID, runID)` function in `internal/paths/paths.go:46-48`. This places the worktree under:

```

~/.no-mistakes/worktrees/<repo-id>/<run-id>

```

By using a function like `paths.WithRoot(NMHome).WorktreeDir(repo.ID, run.ID)`, the system guarantees that parallel runs never share the same filesystem location, preventing cross-run contamination.

### Execution Context and the Work Directory

The pipeline executor documented in `internal/pipeline/executor.go:111-112` accepts a `workDir` parameter that points to this temporary worktree. All step implementations—whether running linters, tests, rebases, or pushes—read and write files relative to this directory exclusively.

When steps execute, they launch from this isolated path, meaning:
- File system changes affect only the disposable directory
- Git operations target the temporary checkout's index and HEAD
- The original repository's working tree remains untouched and available for developer use

### Cleanup and Disposal

After a run finishes or aborts, the daemon removes the worktree to prevent permanent pollution of the developer's filesystem. According to `internal/daemon/daemon.go:287`, the cleanup strategy uses:

1. `git worktree remove --force <path>` as the primary removal method
2. A fallback to `os.RemoveAll(wd)` if the Git command fails

This ensures that even if Git processes are lingering or permissions issues occur, the temporary directory is obliterated, guaranteeing that no temporary commits, rebased branches, or generated artifacts leak into your local environment.

## Safety Guarantees for Local Development

The disposable worktree architecture provides specific protections against common automation risks:

- **Accidental rebases on local branches:** Rebase steps fetch `origin/<default>` into the worktree and rebase only that temporary checkout. Your local `main` or feature branches remain untouched regardless of rebase conflicts or resolutions.

- **Safe force-push decisions:** The force-push logic (`resolveForcePushDecision`) examines the remote HEAD that the worktree last saw, not your local refs. Because the worktree fetches fresh state for each step, force-push safety calculations use live remote data rather than stale local branch positions.

- **Process isolation prevents repository locking:** All subprocesses launch via `shellenv.ConfigureShellCommand`, which places them in separate process groups. When a run cancels, the entire process group (including lingering Git processes) terminates, preventing the worktree from staying locked by zombie processes.

- **Filesystem pollution prevention:** Any files created by agents—documentation, evidence, or fixes—write into the worktree path. Since the worktree is deleted post-run, your developer working directory remains free of automation debris.

- **Parallel execution safety:** Each run receives a unique worktree directory via `paths.WorktreeDir()`, ensuring simultaneous pipeline executions never share state or overwrite each other's files.

## Implementation Example: Worktree Lifecycle in Go

The following simplified snippet demonstrates how no-mistakes orchestrates the worktree lifecycle:

```go
// 1. Create a worktree for a run
wtDir := paths.WithRoot(NMHome).WorktreeDir(repo.ID, run.ID)
// → ~/.no-mistakes/worktrees/<repo>/<run>
gitCmd(t, wtDir, "worktree", "add", "--detach", wtDir, "origin/"+branch)

// 2. Executor runs steps inside that directory
executor.Execute(ctx, run, repo, wtDir) // workDir = wtDir

// 3. After the run finishes, clean up
gitCmd(ctx, wtDir, "worktree", "remove", "--force", wtDir)
// Fallback if git fails
os.RemoveAll(wtDir)

```

This pattern appears throughout the codebase, from the production daemon to the end-to-end test harness in `internal/e2e/harness.go:367-385`, which creates and removes worktrees for test fixtures.

## Summary

- **no-mistakes** creates disposable Git worktrees under `~/.no-mistakes/worktrees/<repo-id>/<run-id>` for every pipeline execution.
- The worktree points to a bare "gate" repository, ensuring all Git commands operate on the temporary checkout while preserving the original working tree.
- The `WorktreeDir()` function in [`internal/paths/paths.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/paths/paths.go) generates unique, deterministic paths to prevent cross-run contamination.
- Cleanup uses `git worktree remove --force` with an `os.RemoveAll()` fallback to guarantee deletion even if Git commands fail.
- Process groups managed by `shellenv.ConfigureShellCommand` prevent repository locking when runs cancel.
- This isolation prevents accidental rebases, unsafe force-pushes, and filesystem pollution in your local development environment.

## Frequently Asked Questions

### Where does no-mistakes store temporary worktrees?

Temporary worktrees live under `~/.no-mistakes/worktrees/<repo-id>/<run-id>`, generated by the `WorktreeDir(repoID, runID)` function in `internal/paths/paths.go:46-48`. Each run receives a unique directory path to ensure complete isolation from your working repository and from other concurrent runs.

### What happens if the worktree cleanup fails?

The daemon in `internal/daemon/daemon.go:287` implements a two-stage cleanup. It first attempts `git worktree remove --force`, and if that Git command fails, it falls back to `os.RemoveAll()` to forcibly delete the directory. This guarantees that temporary files never persist indefinitely, even if Git processes hold locks or permissions issues occur.

### How does the tool ensure agents don't modify my real repository?

Before execution, agents receive a context prompt from `internal/pipeline/steps/execution_context.go:18-22` explaining that they operate inside an isolated worktree where the `.git` file is merely a pointer to a bare repository. The pipeline executor documented in `internal/pipeline/executor.go:111-112` passes this worktree path as the sole working directory, ensuring all file operations and Git commands target the disposable location exclusively.

### Can multiple pipeline runs execute simultaneously without conflicts?

Yes. Because each run receives its own unique path via `paths.WorktreeDir()`, parallel executions operate in completely separate directory trees. This prevents file system race conditions and ensures that one run's temporary commits or rebases never interfere with another run's operations or with your local repository state.