> ## Documentation Index
> Fetch the complete documentation index at: https://jig.fapost.in/llms.txt
> Use this file to discover all available pages before exploring further.

# Letting the agent ship

> Let the agent commit, push and open the pull request for a finished task or a specification's epic — how to turn it on, what happens, and what stays yours.

By default a finished task waits in your working tree: you read the diff, commit it and open the
pull request yourself. If you trust the process, you can let the agent do that part. You then get a
finished task back as an open pull request, and your review happens there.

This is a personal setting. It changes what the agent does in **your** copy of the repository only,
and never what a colleague's agent does.

## Turn it on

The easiest way: ask your agent to *"set up Jig for me"*. It asks how far it may go, shows you the
file and writes it after your yes ([Let the agent ask you](/configuration#let-the-agent-ask-you)).
To do it by hand:

1. Create `.ai/config.local.yaml` in your project if it does not exist, and add one line:

   ```yaml theme={null}
   agent.git: pr
   ```

   The file is yours: Git ignores it, and `jig init` adds it to `.gitignore` if an older project
   does not ignore it yet.

2. For `pr`, the agent opens the pull request with GitHub's `gh` or GitLab's `glab`. Install the one
   for your host and sign in once:

   ```bash theme={null}
   gh auth login
   ```

   Without a signed-in tool the agent still commits and pushes, then tells you the pull request is
   yours to open.

3. Check it took effect:

   ```bash theme={null}
   jig status
   ```

   ```text theme={null}
   agent.git: pr (review queue: open pull requests)
   ```

Putting `agent.git` in the committed `.ai/config.yaml` does nothing: that file is shared with
everyone, and a shared value would switch every contributor's agent on. `jig status` and
`jig doctor` warn when they find it there.

## Choose how far it goes

| Level            | The agent                                         | What waits for you                                              |
| ---------------- | ------------------------------------------------- | --------------------------------------------------------------- |
| `none` (default) | Leaves the change uncommitted.                    | Uncommitted files: review, commit, push, open the pull request. |
| `commit`         | Commits to the task's branch.                     | Unpushed commits: push and open the pull request.               |
| `push`           | Commits and pushes the task's branch.             | A pushed branch: open the pull request.                         |
| `pr`             | Commits, pushes and opens the pull request.       | An open pull request: review and merge.                         |
| `merge`          | Also merges the pull request once your CI passed. | Pull requests it left open, each with the reason.               |

Up to `pr`, merging is your decision. The same levels apply to a specification's epic
([Specs and epics](#specs-and-epics)).

## The `merge` level

With `agent.git: merge`, `jig task ship` opens the pull request, waits for its checks and merges it —
only when at least one check ran and every check passed (it waits up to `agent.ci_timeout` minutes,
30 by default, set in the same file), the review left nothing serious open, the pull request is not
a draft and it is exactly the commit that was shipped. It merges the way your repository allows: a
merge commit, else squash, else rebase.

It never uses an administrator's override and never asks the host to "merge when ready" later. When
your repository's branch protection refuses — a required review, for example — the pull request
stays open and `ship` says why:

```text theme={null}
pr https://github.com/acme/app/pull/42
not merged: the forge refused: At least 1 approving review is required
```

That is not an error: protection on your main branch is the limit your team keeps over one person's
setting. The level works the same with GitLab. Together with `autopilot.unattended: true` it is how a
run finishes without you ([Autopilot: without stops](/autopilot#without-stops)).

## What happens at the end of a task

Nothing changes until the task is done. The agent still sizes the work, and for a risky task it
still stops and waits for you to approve the design ([Working with tasks](/working-with-tasks)).
Git rights do not skip that approval.

When the work is finished and checked, the agent:

1. records what the project should remember from the task — or that there is nothing;
2. stages the task's own changes, and only those — if other work sits in the same folder, it stays
   out of the commit;
3. writes the commit message: the first line becomes the pull request's title, the rest its
   description — what the task was for and how it was checked;
4. runs `jig task ship`, which does the Git part as far as your level allows and reports each step:

   ```text theme={null}
   committed f20a7aa
   pushed task/csv-export
   pr https://github.com/acme/app/pull/42
   ```

   At a lower level it says where it stopped, for example
   `stopped at push: the pull request is the human's`.

The pull request goes into the branch the task was cut from: your main branch, or the epic branch
of a specification released at once ([New project](/greenfield)). You do not have to pick it.

## Specs and epics

The same setting covers the work of a [specification released at once](/greenfield): the spec
reaching your main branch, the epic branch, and the epic's final pull request. The agent runs
`jig spec ship <id>`, which works out which of the three it is from where your repository stands,
prints it (`mode: declare`, `mode: epic` or `mode: final`) and goes as far as your level allows:

| Step                                                              | `none` | `commit`                 | `push`     | `pr`                         |
| ----------------------------------------------------------------- | ------ | ------------------------ | ---------- | ---------------------------- |
| The spec and its epic line reach the main branch                  | yours  | committed on `spec/<id>` | and pushed | and a pull request into main |
| The epic branch, after it is cut or after main was merged into it | yours  | yours                    | pushed     | pushed                       |
| The finished epic: the spec's removal with the version bump       | yours  | committed on the epic    | and pushed | and a pull request into main |

What stays yours at every level:

* **Finishing.** The agent finishes an epic only when you say every phase is in.
* **The version.** You choose patch, minor or major when the epic is declared; at the finish the
  agent raises the version by that choice, or proposes one and waits for your yes when none was
  recorded.
* **Merging.** Merging the epic's final pull request is the release. Only an unattended run at
  `merge` does it — with a merge commit, once CI passed and every roadmap item is done — and never
  for a `major` release, which it opens as a draft for you.

`jig spec ship` keeps the limits of `jig task ship` below: it never force-pushes or skips hooks,
never merges a spec reaching main, merges the epic only as above, commits only what was staged, and refuses when task notes or runtime files are staged. A spec
reaching main is committed on a branch of its own, never on main itself, and may stage nothing but
the spec. The epic is pushed only as a fast-forward: when someone else moved it on the server, the
push is refused and the agent tells you. The final pull request is refused until the epic holds the
latest main.

## Review, fix, merge

Review the pull request as you would any other. When you ask for a change, the agent makes it in
the same task and runs `jig task ship` again: it commits the fix, pushes it, and reports the
pull request that is already open instead of opening a second one.

After you merge, the task is not closed yet — a fix may still follow. At the start of a later
session the agent names the merged task and asks whether it can be closed. Nothing is closed
without your yes.

## What `jig task ship` will not do

It is a script, so these limits hold whatever the agent intends:

* it never force-pushes and never skips your Git hooks, and it merges only at `merge`, only on
  green checks and never past your repository's protection;
* it commits only what was staged, never "everything in the folder";
* it refuses, changing nothing, until the task's knowledge decision is recorded;
* it refuses on any branch but the task's own, and on the main branch itself;
* it refuses when task notes (`.ai/workspace/`) or Jig's runtime files (`.ai/runtime/`) are staged —
  those never leave your machine.

When it refuses, the message says why and what to run. At `none` it does nothing at all, and the
agent tells you the change is ready for your review.

## Turn it off

```bash theme={null}
jig config unset agent.git --local
```

That removes the line, so the default — `none` — applies again; setting `agent.git: none` explicitly
does the same thing. The next task ends in your working tree again. The same command takes back
`autopilot.unattended`, and `jig config show --local` prints what is left
([Configuration](/configuration#or-set-a-value-yourself)).
