---
title: "Build Within Bounds"
description: "Create a Builder with its own sandbox, a structured result, and narrow Git tools that can work on factory branches without exposing credentials or touching protected branches."
canonical_url: "https://vercel.com/academy/creating-a-software-factory/build-within-bounds"
md_url: "https://vercel.com/academy/creating-a-software-factory/build-within-bounds.md"
docset_id: "vercel-academy"
doc_version: "1.0"
last_updated: "2026-08-29T01:48:00.701Z"
content_type: "lesson"
course: "creating-a-software-factory"
course_title: "Creating a Software Factory"
prerequisites:  []
---

<agent-instructions>
Vercel Academy — structured learning, not reference docs.
Lessons are sequenced.
Adapt commands to the human's actual environment (OS, package manager, shell, editor) — detect from project context or ask, don't assume.
The lesson shows one path; if the human's project diverges, adapt concepts to their setup.
Preserve the learning goal over literal steps.
Quizzes are pedagogical — engage, don't spoil.
Quiz answers are included for your reference.
</agent-instructions>

# Build Within Bounds

# Build within bounds

The Investigator found the bug and wrote a specification. The Builder receives only the approved scope, evidence, and tools required to implement it.

```text
approved specification + candidate branch + scoped tools
```

One station may edit code. Its permission begins at the supported specification and ends at a pushed factory branch.

## Give One Station the Write Tools

Create an isolated Builder that implements approved work without touching protected branches.

## Hands-on Exercise 4.1

Create `agent/subagents/builder/sandbox.ts` with the same repository helpers as the Investigator. This produces a fresh checkout. Disposable reproduction work cannot leak into implementation.

Now create `agent/subagents/builder/agent.ts`:

```ts title="agent/subagents/builder/agent.ts"
import { defineAgent } from "eve";
import { MODELS } from "../../lib/models.js";

export default defineAgent({
  description:
    "Implement an approved work order in an isolated checkout. Create a factory branch, make only the specified change, run checks, commit, and push.",
  model: MODELS.builder,
  outputSchema: {
    additionalProperties: false,
    properties: {
      base: { type: "string" },
      branch: { type: "string" },
      changes: {
        items: {
          additionalProperties: false,
          properties: {
            path: { type: "string" },
            summary: { type: "string" },
          },
          required: ["path", "summary"],
          type: "object",
        },
        type: "array",
      },
      deviations: { items: { type: "string" }, type: "array" },
      pushed: { type: "boolean" },
    },
    required: ["branch", "base", "pushed", "changes", "deviations"],
    type: "object",
  },
});
```

Create `agent/subagents/builder/tools/checkout_branch.ts` and `push_branch.ts`. Both tools validate the branch before opening a sandbox or minting a GitHub installation token:

```ts title="agent/subagents/builder/tools/push_branch.ts"
import { defineTool } from "eve/tools";
import { z } from "zod";
import { githubCredentials } from "../../../lib/github/credentials.js";
import {
  brokerPolicy,
  mintInstallationToken,
  REMOTE_URL,
  REPO_DIR,
  validateBranch,
} from "../../../lib/github/git-remote.js";

export default defineTool({
  description: "Push a committed factory feature branch. Protected branches are rejected before Git runs.",
  async execute(input, ctx) {
    const refusal = validateBranch(input.branch);
    if (refusal) {
      return { error: refusal, success: false as const };
    }

    const sandbox = await ctx.getSandbox();
    const token = await mintInstallationToken(githubCredentials);
    await sandbox.setNetworkPolicy(brokerPolicy(token));

    try {
      const result = await sandbox.run({
        command: `git -C ${REPO_DIR} push ${REMOTE_URL} 'refs/heads/${input.branch}:refs/heads/${input.branch}'`,
      });
      return result.exitCode === 0
        ? { branch: input.branch, success: true as const }
        : { error: String(result.stderr || result.stdout).trim(), success: false as const };
    } finally {
      await sandbox.setNetworkPolicy("allow-all");
    }
  },
  inputSchema: z.object({ branch: z.string().min(1) }),
});
```

These helpers come from the starter rather than an unshown library:

- `validateBranch` rejects malformed, ref-style, and protected branch names.
- `githubCredentials` reads short-lived credentials from the `GITHUB_CONNECTOR` configured in Lesson 3.1.
- `mintInstallationToken` resolves the connector's current installation token.
- `brokerPolicy` injects that token only into requests to `github.com`.
- `REPO_DIR` is `/workspace/repo`; `REMOTE_URL` is built from `FACTORY_REPO`.

Run one explicit Git ref while the broker policy is active, then restore `allow-all` in `finally`. Credentials never enter the prompt, repository files, or command arguments. Build `checkout_branch.ts` with the same validation and network-policy shape, using `git fetch` followed by `git checkout -B` instead of `git push`.

Add `agent/subagents/builder/instructions.md`:

```md title="agent/subagents/builder/instructions.md"
# Builder

You implement one approved work order in `/workspace/repo`. The delegation contains the source issue, route, evidence, specification, acceptance criteria, and any revision findings.

For fresh work, create `factory/<lane>-<short-slug>`. Change only what the approved scope requires. Match existing conventions. Run relevant tests and type checks, commit the finished change, and call `push_branch`.

You cannot push to `main` or `master`, open a pull request, or merge. If the specification cannot be implemented safely, leave `pushed` false and record the reason in `deviations`.
```

Add the Builder handoff to the root instructions. Send the approved specification and evidence, not the Investigator's hidden reasoning.

## Try It

Run the static checks:

```bash
pnpm typecheck
pnpm exec eve info
```

eve should report two subagents. Invoke the uppercase-channel issue:

```bash
pnpm exec eve invoke "$(cat fixtures/issues/bug-example.md)"
```

Inspect the Builder result. The branch must begin with `factory/`, `changes` should name only the relevant SDK files, and `pushed` should be true after the commit reaches GitHub.

Try `main` as a branch input. The tool should refuse it before requesting credentials or sandbox work.

\*\*Note: Add tempting cleanup\*\*

Include an unrelated formatting change in the Builder prompt. A bounded Builder should omit it or record the conflict as a deviation.

\*\*Warning: The Builder reuses investigation state\*\*

Keep a separate `sandbox.ts` under `builder/`. Shared state makes reproduction artifacts part of the candidate by accident.

\*\*Warning: A protected branch reaches Git\*\*

Call `validateBranch` before `ctx.getSandbox()` and `mintInstallationToken()`.

## Commit

```bash
git add agent/subagents/builder agent/instructions.md
git commit -m "feat(factory): build within approved bounds"
```

## Done-When

- [ ] The Builder receives a supported specification
- [ ] Implementation runs in a fresh sandbox
- [ ] Factory branches use the required prefix
- [ ] Protected branches fail before credential work
- [ ] The Builder cannot open or merge a pull request

The candidate branch exists inside its boundary. Its commands and results still need to travel with it.

## Solution

The complete protected execution shape appears in the exercise. Both branch tools validate first, apply the broker policy only around Git, and restore `allow-all` in `finally`; compare their files with the `solution` branch if either invariant fails.


---

[Full course index](/academy/llms.txt) · [Sitemap](/academy/sitemap.md)
