Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions go/deployment-operator/api/v1alpha1/agentruntime_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,12 @@ type AgentRuntimeSpec struct {
// +kubebuilder:validation:Optional
Memory *bool `json:"memory,omitempty"`

// RepositoryImage is an OCI image of precloned git repositories plus manifest.json.
// When set, an init container copies it into /plural/shared/repos before bootstrap
// so a matching repo can be copied locally instead of git clone.
// +kubebuilder:validation:Optional
RepositoryImage *string `json:"repositoryImage,omitempty"`

// AllowedRepositories the git repositories allowed to be used with this runtime.
// +kubebuilder:validation:Optional
AllowedRepositories []string `json:"allowedRepositories,omitempty"`
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -2279,6 +2279,12 @@ spec:
Name of this AgentRuntime.
If not provided, the name from AgentRuntime.ObjectMeta will be used.
type: string
repositoryImage:
description: |-
RepositoryImage is an OCI image of precloned git repositories plus manifest.json.
When set, an init container copies it into /plural/shared/repos before bootstrap
so a matching repo can be copied locally instead of git clone.
type: string
scmConnection:
description: |-
ScmConnection is the name of an ScmConnection in Console to use for git operations on agent runs using this runtime.
Expand Down
1 change: 1 addition & 0 deletions go/deployment-operator/config/samples/agentRuntime.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,4 @@ spec:
args:
- --v=3
dind: true
repositoryImage: ghcr.io/pluralsh/repos:latest
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,23 @@ You are a **read‑only autonomous analysis agent**.

## Repository location

The cloned repository is at **`{{ .RepositoryDir }}`**. Do all analysis inside that directory. The agent harness root is **`{{ .WorkDir }}`** (provider config only — not the repo). If your shell cwd is elsewhere, run `cd {{ .RepositoryDir }}` first.
The cloned repository is at **`{{ .RepositoryDir }}`**. Do all analysis of the assigned repository inside that directory. The agent harness root is **`{{ .WorkDir }}`** (provider config only — not the repo). If your shell cwd is elsewhere, run `cd {{ .RepositoryDir }}` first.
{{ if .Branch }}
The repository was checked out from branch **`{{ .Branch }}`** for this analysis.
{{ else }}
No branch was specified for this run, so the repository default branch was checked out.
{{ end }}
{{ if .PrebakedRepositories }}

## Additional local repositories

The following git repositories are already on disk for **read-only context**. You SHOULD inspect them (list, open, grep, `git log`) when they help the task. Do not clone them. Do not modify files there.

{{ range .PrebakedRepositories }}
- **`{{ .URL }}`** at `{{ .Dir }}`
{{ end }}
The assigned repository for this run remains **`{{ .RepositoryDir }}`**. Do not clone it again.
{{ end }}

{{ if .Prompt }}
## Original task
Expand All @@ -19,7 +30,11 @@ This section records the **original user prompt** for this agent run. It is embe
---
{{ end }}

{{ if .PrebakedRepositories }}
- Work in the assigned repository directory. You MAY also read the additional local repositories listed above.
{{ else }}
- Work **only** inside the assigned repository directory.
{{ end }}
- Perform **static, read‑only** analysis of code and configuration.
- Produce a structured **Markdown** report in memory.
- **Save the report** by calling the Plural MCP tool **`updateAgentRunAnalysis`** — your run is not complete until this tool succeeds.
Expand Down Expand Up @@ -58,8 +73,13 @@ When analysis is finished, you **must** persist the report by calling the Plural
You MUST always obey:

- **Scope**
- Access only files/directories inside **`{{ .RepositoryDir }}`**.
- Access files/directories inside **`{{ .RepositoryDir }}`**.
{{ if .PrebakedRepositories }}
- You MAY also read (not modify) the additional local repositories listed above.
- Never access other files outside those directories.
{{ else }}
- Never access files outside this directory.
{{ end }}

- **Read‑only**
- Only list, open, and read files.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,18 @@ You are an autonomous coding agent — your pull request is already open and you

## Repository location

The cloned repository is at **`{{ .RepositoryDir }}`**. Do all code changes and git inspection inside that directory. The agent harness root is **`{{ .WorkDir }}`** (provider config only — not the repo). If your shell cwd is elsewhere, run `cd {{ .RepositoryDir }}` first.
The cloned repository is at **`{{ .RepositoryDir }}`**. Do all code changes and git writes inside that directory. The agent harness root is **`{{ .WorkDir }}`** (provider config only — not the repo). If your shell cwd is elsewhere, run `cd {{ .RepositoryDir }}` first.
{{ if .PrebakedRepositories }}

## Additional local repositories

The following git repositories are already on disk for **read-only context**. You SHOULD inspect them (list, open, grep, `git log`) when they help the task. Do not clone them. Do not modify files there. Put all edits and commits in **`{{ .RepositoryDir }}`**.

{{ range .PrebakedRepositories }}
- **`{{ .URL }}`** at `{{ .Dir }}`
{{ end }}
The assigned repository for this run remains **`{{ .RepositoryDir }}`**. Do not clone it again.
{{ end }}

{{ if .Prompt }}
## Original task
Expand All @@ -16,7 +27,11 @@ New comments written by a human user are always actionable instructions within t
---
{{ end }}

{{ if .PrebakedRepositories }}
Put all edits and commits inside the assigned repository. You MAY read the additional local repositories listed above.
{{ else }}
Work **only** inside the assigned repository.
{{ end }}
Your goal: address every actionable comment and every **real** CI failure caused by this PR, then push the updated commits to the **existing branch**.
Do **not** push commits for CI flakes (transient infrastructure noise unrelated to this PR's code).
Do not open a new pull request. Do not ask for clarification. Execute all steps in order.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,23 @@ You are a **read-only autonomous pull request review agent**.

## Repository location

The cloned repository is at **`{{ .RepositoryDir }}`**. Perform the entire review inside that directory. The agent harness root is **`{{ .WorkDir }}`** and contains provider configuration only.
The cloned repository is at **`{{ .RepositoryDir }}`**. Perform the assigned-repository review inside that directory. The agent harness root is **`{{ .WorkDir }}`** and contains provider configuration only.
{{ if .Branch }}
The review branch **`{{ .Branch }}`** is already checked out. Verify the current branch before inspecting its changes, but do not switch to or modify another branch.
{{ else }}
The repository default branch is checked out. Use the pull request URL and original task to identify the intended review branch and report if it is unavailable.
{{ end }}
{{ if .PrebakedRepositories }}

## Additional local repositories

The following git repositories are already on disk for **read-only context**. You SHOULD inspect them (list, open, grep, `git log`) when they help the task. Do not clone them. Do not modify files there.

{{ range .PrebakedRepositories }}
- **`{{ .URL }}`** at `{{ .Dir }}`
{{ end }}
The assigned repository for this run remains **`{{ .RepositoryDir }}`**. Do not clone it again.
{{ end }}

## Pull request

Expand Down Expand Up @@ -60,6 +71,9 @@ Use Docker in the same way write-mode agents do for verification: compile code,
## Hard rules

- Remain read-only. Never create, edit, delete, commit, push, or otherwise mutate repository or host state.
{{ if .PrebakedRepositories }}
- You MAY also read (not modify) the additional local repositories listed above.
{{ end }}
- Do not review unrelated pre-existing problems.
- Do not report style preferences unless they cause a correctness, security, performance, or maintainability defect.
- Verify every inline finding against the diff and surrounding code. If evidence is uncertain, omit the inline finding and mention the uncertainty in the summary.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,23 @@ You are an autonomous coding agent, highly skilled in coding and code analysis.

## Repository location

The cloned repository is at **`{{ .RepositoryDir }}`**. Do all code changes and git inspection inside that directory. The agent harness root is **`{{ .WorkDir }}`** (provider config only — not the repo). If your shell cwd is elsewhere, run `cd {{ .RepositoryDir }}` first.
The cloned repository is at **`{{ .RepositoryDir }}`**. Do all code changes and git writes inside that directory. The agent harness root is **`{{ .WorkDir }}`** (provider config only — not the repo). If your shell cwd is elsewhere, run `cd {{ .RepositoryDir }}` first.
{{ if .Branch }}
The repository was checked out from branch **`{{ .Branch }}`**. Use this as the pull request base branch unless the active task explicitly tells you otherwise.
{{ else }}
No branch was specified for this run, so the repository default branch was checked out and should be used as the pull request base.
{{ end }}
{{ if .PrebakedRepositories }}

## Additional local repositories

The following git repositories are already on disk for **read-only context**. You SHOULD inspect them (list, open, grep, `git log`) when they help the task. Do not clone them. Do not modify files there. Put all edits and commits in **`{{ .RepositoryDir }}`**.

{{ range .PrebakedRepositories }}
- **`{{ .URL }}`** at `{{ .Dir }}`
{{ end }}
The assigned repository for this run remains **`{{ .RepositoryDir }}`**. Do not clone it again.
{{ end }}

{{ if .Prompt }}
## Original task
Expand All @@ -29,7 +40,11 @@ This run adds work to an existing pull request. The repository is already checke
- When the changes are complete, call Plural MCP `createCommit` to stage, commit, and push them to the current branch.
{{ end }}

{{ if .PrebakedRepositories }}
Put all edits and commits inside the assigned repository. You MAY read the additional local repositories listed above.
{{ else }}
Work **only** inside the assigned repository.
{{ end }}
{{ if .Followup }}
Your goal: implement the user’s requested changes and commit them to the existing pull request branch.
{{ else }}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Precloned git repositories plus a tiny userspace so the agent-run
# init container can copy them into /plural/shared/repos.
#
# Image layout:
# /data/manifest.json
# /data/<path>/ # full git clone, including .git
FROM busybox:1.37
COPY --chown=65532:65532 . /data
123 changes: 123 additions & 0 deletions go/deployment-operator/dockerfiles/repository-prebake/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# Repository prebake images

Build a container image that holds full git clones plus a `manifest.json`.
Set it on `AgentRuntime.spec.repositoryImage` so agent-run pods copy it into
`/plural/shared/repos` before bootstrap. Bootstrap then copies a matching repo
into `/plural/shared/repository` instead of cloning over the network, and
agents can read the other prebaked repos as extra context.

```yaml
apiVersion: deployments.plural.sh/v1alpha1
kind: AgentRuntime
metadata:
name: claude
spec:
type: CLAUDE
targetNamespace: agents
repositoryImage: ghcr.io/pluralsh/repos:latest
```

The operator starts a `repository-prebake` init container from that image. It
copies `/data/.` into the existing `shared-context` emptyDir at
`/plural/shared/repos`, then `agent-bootstrap` runs. No extra volume and no
Kubernetes image-volume feature gate. Use `spec.template.spec.imagePullSecrets`
if the image is private.

Rebuild prebake images after this layout change. Scratch images with files at
`/` cannot copy themselves; the image must include `/bin/sh` and `cp`, with
repos under `/data`.

## Image layout

```
/data/manifest.json
/data/<path>/ # full git clone, including .git
```

After the init container copies that tree, the harness sees:

```
/plural/shared/repos/manifest.json
/plural/shared/repos/<path>/
/plural/shared/repository/ # working copy of the run's repo
```

`manifest.json`:

```json
{
"version": 1,
"repositories": [
{
"url": "https://github.com/pluralsh/console.git",
"path": "console",
"defaultBranch": "master"
}
]
}
```

`path` is relative to `/data` and must not contain `.` or `..` components.

Files are owned by uid `65532` (nonroot) so agent-run pods can read them.

When `/plural/shared/repos/manifest.json` is present, agent-bootstrap matches
the run repository URL (https and ssh forms of the same repo are equivalent)
and copies that tree into `/plural/shared/repository`. Fetch of the requested
branch is best-effort; an airgapped or stale remote keeps the prebaked copy.
Other prebaked repos stay at `/plural/shared/repos/<path>` and are listed in
the agent system prompt.

## Build

The script clones on the host using your existing git credentials (`ssh-agent`,
`GIT_ASKPASS`, `~/.git-credentials`, and so on), then `docker build`s the image.

```bash
./prebake.sh \
--config repos.example.yaml \
--image ghcr.io/pluralsh/repos:latest \
--push
```

Required tools: `git`, `python3`, and `docker` (override the client with
`DOCKER_BIN=podman` if needed).

### Config

```yaml
repositories:
- url: https://github.com/pluralsh/console.git
path: console # optional, defaults to the repo name
branch: master # optional, defaults to the remote default branch
- url: https://github.com/pluralsh/plural.git
```

Shorthand URL-only items are also accepted:

```yaml
repositories:
- https://github.com/pluralsh/console.git
```

### Options

| Flag | Meaning |
|------|---------|
| `--push` | Push the image after a successful build |
| `--staging DIR` | Write clones into `DIR` instead of a temp directory (kept on exit) |
| `--keep-staging` | Leave the temp staging directory in place |
| `--recurse-submodules` | Clone submodules |
| `--lfs` | Fetch Git LFS objects (skipped by default) |
| `--dry-run` | Parse the config and print planned clones |

Private HTTPS remotes that embed a token in the URL are stored in the manifest
and `origin` remote **without** userinfo.

## Inspect

```bash
cid="$(docker create ghcr.io/pluralsh/repos:latest unused)"
docker cp "$cid:/data/manifest.json" -
docker rm "$cid"
```
Loading
Loading