I used to create at least six staging sites for serious client projects. One staging site was rarely enough once two feature branches needed review at the same time.

Review order was the constraint, not server capacity: a branch could be technically ready on Monday, wait for client feedback until Thursday, and still need to remain visible while another branch moved forward on Tuesday. If both branches share one staging URL, every deploy overwrites somebody else's review context.

Agents can get more branches to the review point in the same week, but the client, designer, product owner, or senior engineer still needs a stable place to inspect each branch, so the queue moves from implementation to review.

Why One Staging Site Fails

The simple model is one production site and one staging site. Developers build a feature, deploy it to staging, someone reviews it, and then it goes live. For a small change with one reviewer, that can work.

Branch A might start first and finish third. Branch B might start later but be ready for review today. Branch C might need client feedback before it can continue. Branch D might be technically finished but waiting on content. Branch E might be a refactor that cannot be shown usefully until another branch lands. Branch F might be ready, blocked only by a stakeholder who is away for two days. A delivery plan has to assume those orders will diverge: start order, finish order, review order, and release order are four different sequences.

With one staging site, every deploy becomes a coordination event. Put Branch B on staging and Branch A disappears from review. Put Branch C on staging and Branch B can no longer be checked by the person who finally found time to look at it. If a reviewer reports a bug, the developer has to ask which branch was deployed at the time. If two people are looking at different features, one of them is almost certainly looking at stale or irrelevant state.

I have often solved that by scripting multiple staging or development sites before the project needed them. Six came from the shape of the work: three parallel workflows, with two review surfaces each. One environment was for direct client review. The other was for external stakeholders, so a client could keep checking a feature while an outside reviewer looked at a related branch without either group overwriting the other.

The Old Solution Was Useful But Heavy

The older approach was straightforward: create a scripted server environment that could stand up a set of staging sites before the project needed them. Each site had its own URL, database, filesystem area, and configuration. When a branch needed review, it could be assigned to one of those slots.

That made review independent. A client could keep looking at one feature while another feature moved forward somewhere else. A developer could fix a branch without accidentally replacing the environment someone else was using. The project manager did not have to remember which feature was currently occupying staging because staging was no longer singular. The environments existed whether they were being used or not, and someone had to name them, allocate them, clean them up, and remember which slot matched which branch.

For a traditional project pace, that tradeoff was acceptable. The number of active branches was limited by the number of people writing code, the amount of client attention available, and the cost of manual setup.

AI-assisted delivery changes the load on that fixed pool of pre-built slots. More branches can become reviewable in the same week. Some are small. Some are entire worktrees. Some are experiments that should exist for a day and then vanish. A fixed pool of manually named environments still has to be allocated, remembered, and cleaned up by hand.

The Unit Of Review Has Changed

If the feature branch is abandoned, merged, or superseded, the environment should disappear with it. That was the target on this project: automatic deploy and teardown keyed to a feature of any size. A small ticket should be reviewable without borrowing a shared site. A larger feature worktree should be reviewable without asking which staging URL is free.

The convention built into the setup is deliberately plain: a named worktree with the review/ prefix is the deploy signal. Push that worktree and the system treats it as reviewable. The branch name carries the instruction, so the deployment rule does not live in a separate ticket field or a message someone has to remember.

That keeps the review environment attached to the same artifact as the implementation. A branch such as review/content-editor can map to a container name, database name, review URL, teardown target, and visible branch/build label. In practice, buying a domain name for review sites is usually cheap compared with the time spent explaining, reallocating, and debugging unclear staging URLs.

Isolation Is The Useful Part

The implementation on one branch should not overwrite another branch. The database state for one review should not be polluted by another review. A seed-data change in Branch B should not make Branch A look broken. A rollback test should not damage the state someone else is inspecting.

The architecture here uses containers to keep the environments cheap enough to be disposable. Each review branch gets its own container environment and its own database, while sharing the underlying database server and infrastructure resources.

Cleanup has to follow the branch lifecycle: when the branch is merged, abandoned, or replaced, the container stops, the database is dropped or archived, and the proxy or DNS route is removed.

Secrets need to line up. Seed data needs to exist. Dumps and restores need to be repeatable. The environment needs to show clearly which branch and build it is serving, so a reviewer does not file a bug against a build that is no longer the branch. Teardown needs to be reliable enough that the system does not accumulate forgotten branches. A slice that needs seeded data, branch-visible build metadata, or a teardown rule has review infrastructure in its delivery-plan scope.

What The Automation Adds

Staging sites, seeded data, stable review URLs, branch labels, and cleanup rules are not new. The change I wanted was to remove the upfront work of creating a fixed pool of review sites, and the follow-up work of adding more whenever the pool ran out.

A pushed review/* worktree should create the environment, seed the data, expose a stable URL, show the branch and build being reviewed, and remove the environment when the branch is merged, abandoned, or replaced.

Put It In The Spec

The next version of the feature spec needs a review-environment section alongside the usual screens, entities, permissions, and tests. That is where the untracked staging dependency becomes concrete: branch name, review URL, seed data source, database isolation, visible branch/build label, teardown trigger, and owner.

For some slices, the answer will be trivial. They can share an existing environment or be reviewed by tests and screenshots. For others, especially anything involving data migration, workflow changes, permissions, or stakeholder feedback, the environment is part of done.