I used to have one local development environment per project. If I wanted to work on something else, I switched branches. But now, I don't really switch branches anymore. I create sessions.

"What if this site had a search?" - New session!

And to me, a session doesn't feel like a new branch. It feels like a new environment. A fresh copy of the project specifically for that thought. Dependencies already installed, the database ready and seeded, the dev server running. If I scrap the idea, I delete the whole thing. No cleanup ceremony, no ever-growing projects folder.

Spinning up a new environment is almost frictionless, and turning it down is just as simple.

Heaven for agents

Worktrees themselves aren't the revelation here. I could have created a separate environment for every issue years ago. What changed is that coding agents gave me a reason to have several of those environments alive and doing useful work at the same time.

The GitHub Copilot app is built around this exact workflow: Every session with an agent automatically comes with its own environment. Delete the session, delete the environment.

There's nothing fundamental here that requires GitHub Copilot. You can create worktrees and automate their setup yourself. Copilot is just the tool that removed enough friction for me to start treating them as disposable.

When I start a new session, Copilot automatically creates a worktree and runs my custom setup command. Usually I just dictate what I need, and the agent starts working. I can preview what that exact agent built, request changes, and improve it. And if I want to take over manually, it's still just a directory on my machine. When it's done, it creates a PR. I delete the session, and the entire environment disappears with it.

Disposable doesn't mean untouchable

The agent has its own environment, but it is not the agent's environment. It's ours.

Every environment is ultimately only a directory on my machine, so I can open it in my favorite IDE at any time. I can use the terminal, inspect logs, check the git status, or make and commit changes myself.

Sometimes it's just faster to change a component myself than to explain one specific CSS adjustment to the agent.

Then I hand it back: "I changed this bit, continue from here."

I'm not delegating ownership of the feature. Instead, I am delegating work inside an environment I can enter whenever I want.

The environment can become increasingly complete

Most of my projects are Laravel projects, so they usually come with a database seeder and SQLite driver. Turns out, that's the perfect foundation to make it even more complete!

composer install
npm install
copy .env.example .env
php artisan key:generate
touch database/database.sqlite
php artisan migrate:fresh --seed

At that point, the workspace doesn't just have its own code. It has its own application state too.

There isn't even shared development state anymore. The code, dependencies, app key and databases can all belong to that one disposable idea.

Even new data I create when testing the application is isolated to that session, and dies with that session.

You still have to care

Agents being isolated makes experimentation cheap, but not the judgment. And the more agents there are, the more important it is to have proper environments.

The agent can write a lot of code, but I still need to understand the architecture. I need to care whether the code belongs there and decide what feature is actually good. I can run multiple agents in parallel, but that makes judgment more important, not less.

The workspace is disposable. My responsibility for what comes out of it isn't.

Ultimately, I can delegate more because I haven't given up control.