Skip to content

Clone workspaces from the repository and name containers per checkout - #852

Merged
Jack-Edwards merged 1 commit into
stablefrom
chore/pipeline-instances
Aug 6, 2026
Merged

Clone workspaces from the repository and name containers per checkout#852
Jack-Edwards merged 1 commit into
stablefrom
chore/pipeline-instances

Conversation

@Jack-Edwards

Copy link
Copy Markdown
Member

Workspaces now clone from CRYPTER_REPO_URL instead of a read-only mount of the host's .git, so a run builds and reviews what the repository holds rather than what the launching checkout happens to have fetched. Pull request heads come from refs/pull/{n}/head directly, which removes the host-side git fetch that used to stage them.

Containers are named crypter-pipeline-{slug}-{hash}, derived by the new .devcontainer/pipeline.sh from the checkout it sits in. Each checkout gets its own container, so two can run at once without one reaching the other's /plans and /runs. This is not what makes runs parallel — several runs already share a container, separated by their per-run workspaces.

Notes for review:

  • The pipeline no longer works offline. The container needed outbound network for the Anthropic API already; it now needs it for source too. It clones anonymously over https and holds no GitHub credential — branches still leave over the ext:: transport and are pushed from the host.
  • A git worktree can now host the pipeline. Its .git is a file rather than a directory, so mounting it gave git clone something it could not read. Verified by running a second instance from one.
  • docker compose -f .devcontainer/docker-compose.yml up now fails rather than creating a container. The container name is a required variable, so the old command cannot make one whose identity says nothing about its mounts. Use .devcontainer/pipeline.sh up.
  • The three named volumes are unchanged and still shared machine-wide, so Claude Code stays authenticated and the caches stay warm. They are external because a Compose-owned volume refuses to mount into a second project; pipeline.sh up creates them.
  • docker volume rm is now machine-wide rather than per-checkout. pipeline.sh list shows every instance and its checkout.
  • The origin/* fixup in workspace.sh is deleted. It existed only because cloning a checkout maps that checkout's local branches into origin/*; cloning the real remote does not. One consequence: origin/HEAD now resolves to main, the repository's actual default, rather than being pointed at the run's base. Nothing resolves a bare origin as a revision — every reference is an explicit origin/stable, origin/main or origin/{base}.
  • Existing crypter-pipeline containers are orphaned by the rename and can be removed by hand.

🤖 Generated with Claude Code

The pipeline container was welded to one checkout. Its mounts are relative
paths resolved at creation, and both the container and Compose project names
were hardcoded, so a second checkout running the pipeline reached the first
one's container: findings written under a repository nobody was looking at,
and workspaces cloned from a history nobody was reviewing.

Workspaces now clone from CRYPTER_REPO_URL rather than from a read-only mount
of the host's .git. A run sees the branch as the repository holds it, so the
launching checkout no longer decides what gets built or reviewed, and a stale
or unfetched host is no longer a way to start a run on the wrong base. Pull
request heads come from refs/pull/{n}/head directly, which removes the
host-side fetch that staged them. The origin/* fixup in workspace.sh goes with
it: it existed only because cloning a checkout maps that checkout's local
branches into origin/*, which cloning the real remote does not.

Dropping the mount also makes a git worktree a usable checkout for the
pipeline. Its .git is a file rather than a directory, so mounting it gave
git clone something it could not read.

Containers are now named crypter-pipeline-{slug}-{hash}, derived by
pipeline.sh from the checkout it sits in. A checkout resolves only to its own
name, so which container an orchestrator reaches is settled by where it runs
rather than by probing mounts, and recreating one leaves the others alone.
The three volumes stay shared machine-wide, so Claude Code is still
authenticated once and the caches warmed once; they are external because a
Compose-owned volume refuses to mount into a second project.

Compose requires the container name rather than defaulting it, so invoking
docker compose against the file directly now fails instead of quietly
creating a container whose identity says nothing about its mounts.

The container needs outbound network for source as well as for the API, so
the pipeline no longer works offline. It clones anonymously over https and
holds no GitHub credential; branches still leave over the ext:: transport and
are pushed from the host.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@Jack-Edwards
Jack-Edwards marked this pull request as ready for review August 6, 2026 14:40
@Jack-Edwards
Jack-Edwards merged commit 17e1708 into stable Aug 6, 2026
13 checks passed
@Jack-Edwards
Jack-Edwards deleted the chore/pipeline-instances branch August 7, 2026 01:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant