·3 min read

Why we make every blog draft a pull request

Review tools already exist for code. They're called pull requests. Here's what happens when you point that same machinery at content — and why it changes the tone of AI-assisted writing.

BA
Beka A.
Founder
git merge
— branchpost/main ←

Every AI writing tool I've tried in the last two years has the same problem: it spits out a finished-looking document, and then asks me to figure out what to do with it. Sometimes the output is good. More often, it's almost right — and "almost right" is the hardest kind of writing to fix, because the structure is committed before you've had a chance to push back on it.

When we started building Branchpost, we tried the same shape: a dashboard with a "Generate" button that produced a draft you could copy out. It felt wrong for a reason I couldn't articulate at first. Then it hit me: developers already have a much better review surface than any AI app's chat window. It's called a pull request.

PRs are the review surface we already trust

A pull request isn't really about merging code. It's about structured disagreement. You get diffs, line comments, suggested changes, requested reviewers, status checks, and a single button that ends the conversation. None of those primitives exist in a chat thread with an AI assistant. None of them exist in a Google Doc, either.

The shift

Code review didn't make code better by itself. It made it reviewable. That's the more useful thing.

What changes when the draft is a PR

Three things shift, almost immediately:

  • Tone of feedback. You stop saying "regenerate this" and start saying "this paragraph is wrong, here's a suggestion." The model gets specific signal, not another round of vague prompting.
  • Cost of saying no. Closing a PR is cheap and zero-blame. Throwing away a finished Notion doc feels like waste. Cheap rejection means more honest rejection.
  • Where the work lives. Posts sit next to your code, on the branch they belong to, alongside the release they describe. They don't drift into a separate CMS that nobody opens.

An example, end to end

Here's a real Branchpost run from earlier this week. The repo is our marketing site; the topic was suggested from saved publication context. The draft opens on a branch:

POST /v1/drafts
{
  "repo": "acme/marketing-site",
  "topic": "Landing page principles…",
  "context_id": "ctx_2A91",
  "open_pr": true
}
 
201 Created
→ branch: blog/landing-page-principles
→ pr: #247

What you get back is a PR you'd recognize as content review, not as a chat transcript. The diff is the article. Suggested changes are paragraph-level edits. The merge button is the publish step.

Treating publishing as a code-shaped activity isn't a metaphor. The reason it works is that the surface is genuinely the same — text in files, diffs over time, reviewers attached to changes.

Two reasonable objections

"Most writers don't know git." True. We mostly don't optimize for that audience. Branchpost is for teams whose codebase already produces their site, and whose blog lives in the same repo. If your blog lives in a CMS, this isn't the tool for you.

"PRs are slow." They're as slow as you make them. A trial repo with one reviewer can ship a draft from queue to merged in under ten minutes. A team with stricter review takes longer, which is what they want.

What we're still figuring out

Per-section regeneration inside the PR (so reviewers can request a rewrite of just one paragraph). A better diff view for prose. And a way to capture review comments back into claims_to_avoid so the next draft doesn't repeat the same mistakes.

If you have opinions on any of those, the issue tracker is the right place. We read everything.

posts/why-prs-are-the-review-surface.mdx