Glass Box Terrarium, explained from the inside

Last updated · Latest source on GitHub ↗

Git & GitHubLesson

Pull requests

A change pushed straight to the main branch is seen only after it has landed. A pull request puts the change where people and machines can look at it first, and Terrarium sends every change, an agent's included, through one, bar a session's own log.

Know pull requests already? Skip to In Terrarium.

Outside the box · General

The concept

A pull request (PR) proposes to merge the commits on one branch, the head, into another, the base. It gathers what a reviewer needs in one place: a description, the diff, comments and reviews, and the results of automated checks. Nothing reaches the base branch until someone merges the PR.

GitHub describes two ways to work with PRs. In the shared repository model, everyone who changes the code has push access to one repository and opens a PR from a topic branch there. In the fork and pull model, a contributor without push access copies the repository into a fork, pushes there, and opens a PR back to the original. Either way the merge is the one step that changes the base branch, so it is where checks and review belong.

A PR only helps while someone works on it. One that nobody opens stays invisible to review, and one that nobody follows goes stale while its base branch moves on.

Full referenceGitHub Docs: Pull requests

Looking inside

In Terrarium

Terrarium uses the shared repository model for its own agents, which push branches to the repository itself. docs/agents/pr-workflow.md holds the steps; in short:

  1. Before the branch's first push, the agent runs the code-review Skill on its diff and runs pnpm gate:scoped, the local run of the . A simple change, such as a typo or a broken link, gets the agent's own read of its diff instead; that doc says what counts as simple.
  2. It pushes and opens the PR straight away.
  3. It subscribes to the PR's activity and answers comments and failed checks.
  4. It posts its verdict: a PR comment with what its review found, ending in a Reviewed: <sha> line that names the commit it reviewed.
  5. It lands the PR through scripts/github/merge-pr.ts, the only merge path, which waits for the checks and refuses the PRs a person must merge (Merge gate).

The script merges only if one of this session's verdicts on the PR names the head commit. It finds the commit in each verdict with this pattern, a line holding only Reviewed: and a commit id of 7 to 40 hex characters, and accepts a short id that the head commit starts with:

scripts/github/merge-pr.ts ↗151–151as of
151const REVIEWED_LINE_RE = /^Reviewed: `?([0-9a-f]{7,40})`?\s*$/gim

The one change that skips a PR is the , the record a session writes about its own work: scripts/session/log-session.ts commits that single file straight to main. Session logs follows it there.

Why it's built this way

  • Review before landing. Agents change their own tools (Skills, hooks, checks), so a bad change pushed straight to main can break the next agent unnoticed. A PR keeps changes reviewable and easy to undo, and is where the runs. The cost: even a one-word fix needs a branch, PR and CI run; only session logs skip it (Session logs). ADR-0003 (docs/adr/0003-agent-operating-model-and-governance.md).
  • Always open the PR. Asking "shall I open a PR?" stalled unwatched runs, and a system prompt's "no PR unless asked" once stranded finished work on a branch. Opening a PR merges nothing, since the Gate and merge rules decide, so agents always open one. The cost: if someone asks a session only for a review but it pushes a branch, a PR opens anyway. ADR-0003 (docs/adr/0003-agent-operating-model-and-governance.md).
  • The script checks the verdict. An agent merges its own PR on green (Merge gate) after posting a verdict, but the written order failed once. So the merge script refuses until this session's verdict names the commit reviewed. The cost: a fresh verdict after every push. scripts/github/merge-pr.ts.

What to watch for

  • A green check isn't an event. A session subscribed to a PR hears about comments and failed checks, not a passing one, so Terrarium's CI posts a comment when the Gate is green.
  • Closing keywords close everything they name. Closes #N in a PR description closes that issue when the PR merges, so Terrarium uses it only for an issue the PR completes and writes "relates to #N" otherwise. The merge script refuses a PR whose keywords would close an open issue that is not labelled ready-for-agent.
  • The description is part of the change. Reviewers judge a PR by what its description says it does, so a push that changes what the PR does updates its title and description too.
  • A PR from outside is a different case. A PR from a fork or a author is never merged by an agent; Author trust explains why.

Try it in your project

Give your agent one written rule: every change goes on a branch, and the agent opens the PR itself as soon as it pushes. Then name what it does next, such as answering review comments and fixing failed checks, until the PR is merged or closed.

Where next

Walkthroughs through this Lesson

Last updated · Latest source on GitHub ↗

Something went wrong

This content couldn’t be loaded. Reloading the page usually fixes it.

Technical details
route: /t/glassbox/guide/git-github/every-change-a-pr