Implementation specialist that reads triaged issues, implements fixes or features following repository conventions, runs tests and linters, and commits to a local feature branch.
No additional setup is required beyond the standard fullsend configuration.
- Triaged issues can go from "ready" to "PR open" without human involvement.
- Implementation follows repo conventions because the agent reads existing code, tests, and linter configs before writing.
- The agent cannot push arbitrary code — all changes are gated before reaching the repository.
The code agent is triggered when the ready-to-code label is applied to an issue, or via the /fs-code command.
| Command | Where | Effect |
|---|---|---|
/fs-code |
Issue comment | Triggers the code agent on the issue |
Requires write-level repository permission (admin, maintain, or write).
The /fs-code command accepts an optional --force flag. It can only be used
on issues (not PRs).
| Label | Meaning |
|---|---|
ready-to-code |
Triggers the code agent. Applied by the triage agent for low-risk categories (bug, documentation, performance), or manually by a human for feature work after prioritization. Not applied when the triage result sets requires_workflow_changes, since the code agent cannot modify workflow files. |
ready-for-review |
Applied by the code agent after pushing a PR. In per-repo installs, triggers the review agent when applied to a PR. Also marks workflow state for humans and the retro agent. |
See Customizing with AGENTS.md and Customizing with Skills.
| Variable | Description | Default | Valid values |
|---|---|---|---|
CODE_ALLOWED_TARGET_BRANCHES |
Restricts which branches the code agent can target when pushing. The post-code script validates the agent's chosen target branch against this variable before pushing. Set via env.runner in harness/code.yaml (never injected into the sandbox). |
Repo default branch (auto-detected via forge API; falls back to main) |
Comma-separated branch names (e.g. main,develop) or * for any branch |
FULLSEND_FORGE |
Forge platform. Set automatically by the harness forge.<platform>.env section. |
(set by harness) | "github", "gitlab" |
CODE_AUTO_MERGE |
Set to "true" to enable auto-merge on PRs/MRs created by the code agent. On GitHub, uses gh pr merge --auto; on GitLab, uses merge_when_pipeline_succeeds. Requires branch protection with required reviews or status checks on the target branch. Read directly from the runner environment (not declared in env.runner). |
"" (disabled) |
"true" to enable |
CODE_AUTO_MERGE_METHOD |
Merge method for auto-merge: "squash", "rebase", or "merge". When unset, auto-detected from the repo's allowed merge methods (prefers squash). Omitted automatically when the target branch uses a merge queue. Ignored unless CODE_AUTO_MERGE is "true". |
Auto-detected (prefers squash) | "squash", "rebase", "merge" |
The code agent follows a three-phase pipeline: pre-script, sandbox execution, post-script.
- Pre-script validates inputs on the runner before sandbox creation. It also checks for open PRs linked to the issue.
- Sandbox — the agent reads the issue, explores the codebase, writes code, runs tests and linters, and commits locally. It has restricted network access (enforced by OpenShell).
- Post-script runs on the runner: it performs protected path checks, secret scanning, pre-commit checks, pushes the branch, creates the PR, and best-effort assigns the PR to a human owner (latest
/fs-codeinvoker, else issue assignee, else issue author).
This separation ensures the agent never has direct write access to the repository.
The code agent runs inside a sandbox container built from the universal
ghcr.io/fullsend-ai/fullsend-code:latest image. This image ships common
build tools (Go, Python, Node 22, npm, pip, git, pre-commit, gitleaks,
shellcheck, jq) but cannot cover every project's toolchain. If your
project requires tools that are not pre-installed — for example a
different Node version, pnpm, Rust, or project-specific CLI tools — you
need a custom image.
- The project's contributing guide requires a tool that is not in the universal image (e.g., Node 24, pnpm, Bazel, Rust toolchain).
- Tests or linters depend on system packages not present in the sandbox.
- The agent logs show it cannot run the project's test or lint command because a required binary is missing.
A custom image must work within the constraints enforced by the sandbox
policy (policies/base.yaml), network
profiles (profiles/), and forge-specific policy
(policies/gitlab/code.yaml for GitLab):
| Requirement | Detail |
|---|---|
| Base image | Extend from ghcr.io/fullsend-ai/fullsend-code:latest to inherit the agent runtime, pre-installed tools, and security scanning binaries. |
| User/group | The sandbox runs as sandbox:sandbox. Installed tools must be executable by this user. |
| Filesystem layout | The working directory is /sandbox/workspace. Read-write access is limited to /sandbox and /tmp. System paths (/usr, /lib, /etc) are read-only at runtime — install packages at build time, not in an entrypoint. |
| Network access | The sandbox restricts outbound network to specific hosts and binaries (Vertex AI, forge API, package registries). Arbitrary HTTP access is blocked. Tools that phone home at startup may fail. |
| Required binaries | git, scan-secrets, pre-commit must remain on PATH. On GitHub, gh is also required; on GitLab, curl is used instead. Do not remove or shadow them. |
Create a Dockerfile in your project repository that extends the base
image and adds project-specific tooling:
FROM ghcr.io/fullsend-ai/fullsend-code:latest
# Example: install Node 24 and pnpm
RUN curl -fsSL https://deb.nodesource.com/setup_24.x | bash - \
&& apt-get install -y nodejs \
&& npm install -g pnpm
# Example: install a Rust toolchain
# RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | \
# sh -s -- -y --default-toolchain stable
# ENV PATH="/root/.cargo/bin:${PATH}"Build and push the image to a container registry accessible from your CI runners:
docker build -t ghcr.io/<org>/<repo>-code:latest .
docker push ghcr.io/<org>/<repo>-code:latestCreate a custom harness for the code agent at .fullsend/code.yaml
overriding the image with your's:
# .fullsend/code.yaml
base: https://raw.githubusercontent.com/fullsend-ai/agents/<SHA>/harness/code.yaml#sha256=<sha256sum>
image: ghcr.io/<org>/<repo>-code:latestTo get the <SHA> and <sha256sum> values use:
SHA=$(curl -s https://api.github.com/repos/fullsend-ai/agents/commits/main | jq -r '.sha')
HASH=$(curl -sL "https://raw.githubusercontent.com/fullsend-ai/agents/${SHA}/harness/code.yaml" | sha256sum | awk '{print $1}')
echo "https://raw.githubusercontent.com/fullsend-ai/agents/${SHA}/harness/code.yaml#sha256=${HASH}"And then reference that harness in your .fullsend/config.yaml:
# .fullsend/config.yaml
agents:
- name: code
source: code.yamlThe same field exists in harness/fix.yaml (the fix agent
shares the sandbox image). Update both if your project uses the fix
agent.
The post-script assigns a human owner to each PR it creates. When no human candidate is found, the PR is unassigned. The idea behind this is that the assignee takes care of the PR as it cares about its contents.
The precedence is as follows:
/fs-codeinvoker.- First assignee of the issue.
- Issue author.
Note: bots are filtered (*[bot], app/*, dependabot). The resolution logic lives in
scripts/lib/pr-assignee.lib.sh.
The code agent supports both GitHub and GitLab. The harness
forge.<platform> sections configure platform-specific policies,
skills, env vars, and scripts. Key differences from single-forge
setup:
FULLSEND_FORGEis required. Set automatically by the harnessforge.<platform>.envsection ("github"or"gitlab").ISSUE_URLreplacesGITHUB_ISSUE_URLin scripts. The per-forge env file (env/github/code.envorenv/gitlab/code.env) maps the platform-specific variable toISSUE_URL.- Policy is per-forge:
policies/base.yaml(GitHub) orpolicies/gitlab/code.yaml(GitLab). Custom harnesses usingbase:composition should override at the forge level if needed. - GitLab uses
curlinstead ofghfor API access. The GitLab sandbox policy allowscurlforgitlab_apiendpoints only. - GitLab host allowlist —
forge_validate_issue_urlinscripts/lib/gitlab-code-ops.lib.shand the network policy inpolicies/gitlab/code.yamlboth maintain an allowlist of GitLab hosts. To support a self-hosted GitLab instance, update both files.
If this agent needs to reach hosts beyond the defaults, see the custom network policy guide.