# graft

> MCP-first operating guide for agent-written code.

Graft turns completed branch work into a verified result for current trunk. The authored diff is one implementation. The intent describes the behavior that must survive integration.

## Connect

Install and initialize Graft from the repository root on trunk. Graft currently requires the trunk branch to be named `main`.

```sh
curl -fsSL https://graftd.dev/install | bash
graft init
graft doctor
```

Requirements: Git with an author identity, macOS or Linux, and a ChatGPT login or OpenAI API key. Review `.graft/policy.toml`; its checks must match commands the repository already runs.

Register a local stdio MCP server. The client starts `graft mcp` when its tools are needed:

```json
{
  "mcpServers": {
    "graft": {
      "command": "graft",
      "args": ["mcp"]
    }
  }
}
```

Prefer MCP tools over equivalent shell commands. Always pass absolute paths:

- Use the exact feature worktree for `intent_draft`, `intent_submit`, `decisions_list`, and `decision_resolve`.
- Use any initialized worktree in the repository for `status`, `fix`, `retry`, `review_packet`, `merge`, `log`, and `why`.
- Never rely on the MCP process working directory.

Every MCP result contains `status`, `message`, `action`, and optional `data`. Branch states such as `changes-requested`, `environment-fault`, and `setup-failed` appear inside `data`; they are not top-level tool statuses. Branch on `status`, then follow `action`. Do not parse `message` to choose a mutation.

## Quick start

The shortest safe path for one committed branch:

1. Read repository instructions, CI, build files, and Git status. Work in an isolated, non-trunk worktree. Commit the completed implementation and leave no uncommitted product changes.
2. Call `intent_draft`. Inspect and edit the returned `body`, `assertions`, and `evidence`. This call does not write, commit, or submit anything.
3. Call `intent_submit` separately. Pass the returned `mode` and `intent_id` when present, set `origin` to `inferred`, and send the reviewed contract. Do not assume every submission is `new`.
4. Call `status` with the repository path and exact branch. Poll only while its top-level status is `busy`. Do not repeat a mutation while Graft is busy.
5. On `success`, inspect the branch state in `data`. If it is `solved`, call `review_packet` and inspect the authored diff, exact candidate, semantic delta, checks, and review evidence.
6. Call `merge` once only after inspecting that packet and only when policy permits. If the branch is already `landed`, skip the merge call and continue. If it is `already-satisfied`, skip the merge call, report the structured result and action, and stop unless Graft identifies an existing landing commit.
7. After a real landing, use `log` to find the explained commit, then call `why` to reconstruct what landed and why.

## Handle each result

- `busy`: wait briefly, then call `status` again. Do not repeat the preceding mutation.
- `stale`: the branch or its intent changed. If the contract remains valid, call `intent_submit` in `update` mode with the existing intent id and omit the contract fields. If behavior changed, call `intent_draft` again, inspect the revised contract, and submit the returned update.
- `decision_required`: call `decisions_list`. Use `decision_resolve` only when the selected option is within explicit delegated authority. MCP always records the resolver as an agent. Otherwise show the question and options to a person and stop.
- `held`: report the policy hold. Do not retry or call `merge` around it.
- `human_action_required`: stop and follow the returned action. For an `awaiting-review` branch, call `review_packet`, explain the exact candidate, review hash, and blocker, then wait for a person. MCP cannot approve human review. After the person explicitly judges that exact packet, an agent-operated shell may relay the response with `graft review approve|request-changes --as-human --reviewer <NAME> --review-hash <SHA256>`. Never infer or broaden the response; if the packet changed, show the fresh packet and ask again. Human-attributed decisions remain direct human CLI actions; agents and MCP must not invoke `graft decide --as-human`.
- `not_solved`: inspect the branch state and message inside `data` before acting:
  - `changes-requested`: read `review_packet`, implement the concrete findings in the feature worktree, run the relevant checks, commit, and call `intent_submit` in `update` mode. Omit the contract fields to preserve the current intent, or revise them deliberately.
  - `environment-fault`: report and correct the missing authentication, provider, runtime, or session dependency without exposing secrets. Then call `retry` once for the exact generation bound to that fault.
  - `setup-failed`: report and correct the worktree, diff, patch, candidate, or verification setup fault. Then call `retry` once for the exact generation bound to that fault.
  - any other state: follow the returned `action` and report the structured state upward if it does not name a safe supported operation.
- `failed`: follow the returned `action` and structured error code. Repeat a mutation only when the action explicitly says the committed result is reusable or the input failed before mutation. Otherwise report the ambiguity.

The ordinary fault guidance above uses `retry`. If the fault is the result of `fix`, preserve its repair context as described below.

If `merge` loses a trunk race, refresh `status` and follow the new result. Poll only while it is `busy`. If the branch becomes `solved` again, fetch and inspect a fresh `review_packet` before another merge call. Never reuse review evidence from a superseded candidate.

## One-shot recovery

- `retry` reruns only the unchanged submitted generation recorded with an `environment-fault` or `setup-failed` state. Correct the reported cause first, then call it once. A `retried` outcome contains the resulting branch state. A `no-op` means the generation or recovery context is no longer eligible, or the branch no longer needs retry. Refresh `status`; do not call `retry` again. If committed work changed, submit that new generation instead.
- `fix` asks Graft for one agent repair of a `decision` or `changes-requested` blocker. It returns `repaired`, `attempt-failed`, or `no-op` with the resulting branch state. On `no-op`, refresh `status` and do not repeat `fix`. If the repair itself reaches `environment-fault` or `setup-failed`, correct that cause and call `fix` once more so the repair context is preserved. Do not substitute `retry` in that case. The CLI fallback is `graft fix <branch>`.

Neither operation is a loop or a way around policy or human review. Inspect every returned `status`, `action`, outcome, and branch state before doing anything else.

## Operating rules

1. Keep `intent_draft` and `intent_submit` as separate explicit calls.
2. Treat a successful mutation as accepted work, not necessarily completed work. Follow its returned `action`.
3. Keep implementation fixes on the author's branch and submit a new exact generation after committing them.
4. Inspect the exact current candidate before every `merge` call.
5. Surface stop states honestly. Never replace missing authority or a missing product operation with a guessed command.
6. Keep provider sessions, local paths, transcripts, and raw command output out of intent evidence and decision prose. Use stable public references such as issue IDs when evidence is needed.

## What Graft owns

```text
ordinary branch + submitted intent
                 |
                 v
       solve against live trunk
                 |
                 v
       checks + candidate review
                 |
                 v
    one explained commit on trunk
```

Trunk movement is expected. Graft supersedes stale candidates and solves again. The author's branch is never moved by the solver.

## Authority boundary

Agents may implement, submit intent, inspect candidates, and resolve decisions within explicit delegated authority. Agents may not originate human approval, forge a human decision, use `--as-human` outside the exact candidate-review relay described above, expand resolver authority, discard unrelated work, or push without permission. MCP remains agent-only.

Use `graft why <commit>` to reconstruct what merged and why.
