Zed Turned Off Pull Requests. The Merge Gate Has to Go Somewhere.

If agents write most of your changes, review stops working in the pull request. The diff arrives without the reasoning behind it, and the queue grows faster than your reviewers can clear it. Zed replaces the pull request with a thread that keeps the reasoning attached. Take that part. Also keep the part that a thread cannot replace: a merge gate that the remote enforces, which no agent can talk its way past. This essay takes Delta apart and ends with a setup that keeps both.

On September 16, Zed opened the public beta of Delta. Delta is a multiplayer environment for coding with agents and reviewing what they build. The week before, the team disabled pull requests on Delta's own repository. Since then, 33 of them have landed 570 changes to main without opening one. Zed claims that the thread should replace the pull request as the unit of work. A thread is the running conversation between people, agents, and the code they edit.

That raises three concrete questions. What does a pull request carry? What does a Delta thread carry instead? And when you remove the pull request, where does the check that stopped bad merges go?


What a pull request is made of

Without the interface, a pull request is a request object with a fixed set of parts. There is a branch reference, a base, the diff between them, and the commits that produced it. There is a description the author wrote. There are comment threads, each anchored to a line number in a specific version of a file. There are status checks from CI and approvals from reviewers. There is a merge action, and the host refuses to run it until the branch protection rules pass.

Every one of those parts describes the result. The diff is the end state. The commits are checkpoints that the author chose to keep. The author writes the description after the work, and comments attach discussion to code that is already pushed. The object does not record the path to the result. That path includes the options tried and dropped, and the reason a lock is a Mutex and not an RwLock.

That reasoning lived in the author's head. For most of the pull request's history, that was fine. A reviewer could ask the author, and the author could remember.

The command line shows the same shape. Ask GitHub for everything that it stores about a pull request, and you get a list of results:

gh pr view 1234 --json body,commits,reviews,statusCheckRollup,files

Field names from the gh pr view manual. Of the five, only body is free text for reasoning, and the author writes it after the work.

Agents break both halves of that arrangement. Much of the code now comes from an agent session that ended hours ago, so there is no head to ask. The volume also went up.

Zed's post says: "with agents generating so much code, the diffs we're asking each other to review have mushroomed." A stack of branches makes a big change easier to navigate. But, as the post says, "the decisions behind the code still need review. Smaller diffs don't supply that context." Usually the reviewer pastes the diff into their own agent. That agent then "has to piece together decisions you already worked through."

What DeltaDB records instead

Delta runs on DeltaDB, which Zed introduced on June 11. Git stores a snapshot at each commit. DeltaDB stores every operation between commits as a fine-grained delta, with a stable identity for each one. So you can address any moment in the code's history, not only the moments that someone committed. DeltaDB records each message next to the edit that it produced.

The worktrees are conflict-free replicated. That lets several people and agents edit the same files at once from different machines. The files are real files. Agents work in them through a terminal, and you can mount the worktree to disk for your own tools.

For review, the important detail is anchoring. A pull request comment points at a line number in one version of a file. That is why comments go "outdated" when the code moves. A DeltaDB reference points at a delta. The delta keeps its identity through edits, so the reference survives when the code moves.

From a line in an old conversation, you can jump to that code as it is now. You can also see it as it was when the agent wrote it. From a line of code, you can find the conversation that produced it. It works like git blame with a finer grain and a second column. Blame tells you which commit last touched a line. A delta anchor tells you which operation touched it and what was said right before.

The commit stays. The Delta announcement says: "A commit remains the checkpoint you push, pull, and build from. DeltaDB retains the work between those checkpoints." So the design is an overlay. The Git history that you ship is still there, and the thread is extra data on top of it.

Two git remotes connect the thread to ordinary git. According to Delta & Git, each checkout that Delta creates from your project has two remotes. origin is the shared upstream, such as GitHub. local points at your own repository on your machine.

Work comes out through one of these remotes, never through the commit itself. Delta records file edits continuously "without creating Git commits," and an agent's commit lands in the repository of the managed checkout. To give yourself a branch without a round trip through GitHub, push it to local:

git push local <branch-name>
git switch <branch-name>

From Delta's Reviewing & Syncing Changes docs, not run here. A clean checkout of the same branch updates in place. Git rejects a push that would overwrite uncommitted edits.

Fig. 1 · one change, two containers

The same change, a lock swap in a worktree cache, packaged as a pull request and as a Delta thread. Flip the container and the author. Then ask the reviewer's question and see where the answer comes from. Rows marked why carry reasoning, not only results.

fix/worktree-cache-lockworktree_cache.rs · guard the map with a Mutex

    ...

    Artifact names follow GitHub's pull request model and Delta's docs (thread, deltas, change guide, review subthread, Approve / Request Changes, Pull Changes, Land subthread). The change itself is an illustrative example built on the Mutex vs RwLock question from Zed's announcement.

    Review becomes a fork of the conversation

    In a pull request, review is a separate activity on a frozen snapshot. In Delta, review is a subthread. You can invite a teammate to pick up your thread where you left off, or you can open a dedicated review subthread.

    According to Delta's review docs, a new review subthread asks the agent for a change guide. The docs call it "a structured walkthrough of the change in the order that explains it best, with focused inline diffs." The review gets its own isolated copy of the parent thread's worktrees. So the reviewer and their agents can examine the code and try changes without disturbing the original work.

    The reviewer finishes with one of two verdicts, Approve or Request Changes. If the reviewer fixed something, those edits do not merge back automatically. The author clicks Pull Changes on the verdict. That applies a snapshot of the review's edits at the time of the verdict. This is a good rule, because the author gets a fixed, reviewed state and no later drift from the review worktree.

    In Delta, the reviewer's questions go to the agent that holds the context. Zed's example is a teammate asking "the same agent why you chose a Mutex instead of an RwLock." In a pull request, that question reaches a human who might not remember. Or it reaches a fresh agent that builds a plausible answer from the diff. A plausible answer can differ from the real reason, and the reviewer cannot tell which one they got.

    You drive review from the composer. These are the documented entry points:

    /review            open a review thread for this thread's changes
    /change-guide      write a structured walkthrough of an existing change
    /approve           submit an approving verdict, with or without a review thread
    /request-changes   submit a changes-requested verdict

    Commands from Delta's review and skills docs, not run here. /review is also Cmd+Shift+R on macOS. You cannot review a review. Reviews start from a top-level thread.

    Teams that stay on pull requests can still ship the reasoning with the change. Add a pull request template with a short decision log, so that the body field carries the reasons. The template below is a pattern, not a GitHub feature. GitHub only supplies the file location.

    <!-- .github/pull_request_template.md -->
    ## What changed
    <one paragraph, written for the reviewer>
    
    ## Decisions
    | Question | Options considered | Chosen | Why |
    |---|---|---|---|
    | Lock for the cache map | Mutex, RwLock | Mutex | writes dominate; RwLock adds reader starvation risk |
    
    ## Agent session
    <link to the transcript or Delta thread, if one exists>
    
    ## How it was verified
    <the commands that passed>

    A pattern built for this essay. Keep the Decisions table short. The queue math below shows why: the table helps only when reading it costs less than rebuilding the reasons.

    The queue is the real problem

    Every review system is a queue. Changes arrive at some rate, and reviewers clear them at some rate. If arrivals are more than capacity for long enough, the backlog grows without limit. The wait for a review grows with it, and a better diff viewer does not change that. Agents raise the arrival rate, and nobody disputes that part.

    A reviewer spends time on two things per change. The first is reading the change. The second is rebuilding why it looks the way it does. Better diff tools make the first part faster. Delta bets on the second. If the reasoning ships with the change, rebuilding it costs less, and capacity goes up without new hires.

    Set both parts in the figure below and see what happens to a two-week backlog.

    Fig. 2 · the review queue

    Changes arrive each working day. Reviewers clear what their hours allow. Each column is the backlog at the end of a day. You can set all inputs. The presets are illustrative, not measured.

    40
    4
    2.0
    25
    30

    ...

    Capacity per day = reviewers × hours × 60 ÷ (reading + rebuilding minutes). Backlog(d) = max(0, backlog(d−1) + arrivals − capacity). Expected wait for a new change = backlog ÷ capacity, in working days.

    A worked example

    Take a team of four reviewers who each give two hours a day to review, 480 minutes in total. Reading a change takes 25 minutes, and rebuilding the reasons takes 30. So each change costs 55 minutes, and the team clears 480 ÷ 55 = 8.7 changes a day. These numbers are assumptions. Put your own numbers into Fig. 2.

    • People write the changes, 12 a day. The backlog grows 12 − 8.7 = 3.3 changes a day. After ten working days it holds 33 changes, and a new change waits 33 ÷ 8.7 = 3.8 working days for a first review.
    • Same 12 a day, with the reasoning attached. Say that an 8-minute change guide cuts the rebuild from 30 minutes to 8. A change now costs 25 + 8 + 8 = 41 minutes, and capacity rises to 480 ÷ 41 = 11.7 a day. The backlog grows 0.3 a day. After ten days, a new change waits a quarter of a working day. This line is the full case for Delta.
    • Agents open 40 a day, reasoning attached. The backlog grows 40 − 11.7 = 28.3 a day. After ten days, that is 283 changes and a 24-day wait. To keep up, you need 40 × 41 ÷ 120 = 13.7 reviewer-equivalents at two hours each. Context raises capacity by a third, but it cannot absorb a 3x rise in arrivals. The remaining option is a limit on how many agent changes can wait for review at once.

    Try the third preset and the limit is clear. Attached context helps only if reading it costs less than rebuilding it. One commenter raised that objection in the Hacker News thread: "does this mean that along with the burnout I'm feeling with talking to my own agents I now need to try and consume and understand my teammates conversations with agents? Why is this better than a good pr description that distills completed work and explains why it was required?"

    A raw transcript is long and full of dead ends. Delta answers with the change guide, a short walkthrough that the agent writes for the reviewer. The full thread is still there for specific questions. The beta will show whether the guide is faster to read than the rebuild it replaces. Another commenter took the other side. Compared to "3k lines of code in a PR with no history with vibes in the description," it "definitely 'feels' like something worth exploring."

    Where the merge gate lives

    A pull request is also a gate. The host will not run the merge until required checks pass and required approvals exist. That enforcement does not depend on anyone's judgment in the moment. It is a rule on the remote, and the person merging cannot talk their way past it.

    Delta moves landing into the thread. Land Changes opens a dedicated Land subthread and runs your project's landing workflow. That workflow is a skill that, in the docs' words, "defines your checks, merge strategy, and publication steps." If exactly one eligible skill exists, the agent runs it. If there are several, the agent lists them and you pick. If there are none, the agent offers to help write one, and asks for approval before it writes it.

    For now, the post says "an agent can trigger a run with an existing CI provider and check the results before landing the change." The post adds that content-based builds could bring CI-style verification into the thread later.

    The sharpest criticism in the thread is about this step. One reviewer wrote: "Having land as a skill seems weird to me. You could write in your land skill that it should make sure CI is passing, but I wouldn't want to leave it up to the LLM to decide if CI is passing. I'd rather that be a decision enforced by the git remote."

    The difference is between an instruction and an enforcement point. A skill tells an agent what to do. A branch protection rule decides what can happen. An agent that follows a skill can misread a log. It can retry a flaky job until the job goes green, or run a copy of the skill that someone edited in the thread. A remote rule reads nothing, so it has none of those failure modes.

    Fig. 3 · where the gate lives

    Six bad changes try to land. Select which gates exist, then run them. A gate either enforces (the remote refuses the push) or instructs (an agent is told to check). The scenarios are my construction, not reported Delta incidents.

      ...

      Run it with only the two instruction gates, and most of the bad changes land. In every scenario, an agent is wrong about something that it was told to check. Add the three remote rules, and only one bad change lands. That is the flaky suite that eventually goes green. No merge gate catches it, because the check really did pass once. That case needs flake quarantine, not a stricter gate.

      So the lesson is about layering, and Delta allows it. Nothing in Delta's design stops you from requiring passing checks and fast-forward-only merges on the Git remote underneath. The commenter reached the same conclusion: set the remote "to only allow fast forward merges with checks passing." Let the landing skill drive the process, and let the remote judge it.

      Start with the landing skill. One frontmatter field marks a skill as eligible for Land Changes. You write everything below the frontmatter. Write the body so that the skill drives the process and the remote makes the decision:

      ---
      name: land
      description: >-
        Land this project's changes only when explicitly requested.
        Do not use for review, preparation, or skill installation.
      metadata:
        delta-action: land
      ---
      
      1. Push the thread's branch: git push origin HEAD
      2. Open the pull request if none exists: gh pr create --fill
      3. Queue the merge and let the remote decide:
         gh pr merge --auto --rebase --match-head-commit "$(git rev-parse HEAD)"
      4. Report required checks without retrying failed jobs:
         gh pr checks --required --watch --fail-fast
      5. Never pass --admin. If a check fails, stop and report its name.

      Frontmatter from Delta's Configure a Land skill docs. The steps are ours, built from the gh pr merge and gh pr checks manuals. Not run here. --auto merges only after the branch meets its requirements. --match-head-commit refuses the merge if the branch moved after the agent looked at it.

      The requirements go in a ruleset on the default branch. A person with admin rights creates it once:

      gh api -X POST repos/OWNER/REPO/rulesets --input ruleset.json
      {
        "name": "agent-landing-gate",
        "target": "branch",
        "enforcement": "active",
        "conditions": { "ref_name": { "include": ["~DEFAULT_BRANCH"], "exclude": [] } },
        "rules": [
          { "type": "pull_request", "parameters": {
              "required_approving_review_count": 1,
              "dismiss_stale_reviews_on_push": true,
              "require_code_owner_review": true,
              "require_last_push_approval": true,
              "required_review_thread_resolution": false,
              "allowed_merge_methods": ["rebase"] } },
          { "type": "required_status_checks", "parameters": {
              "strict_required_status_checks_policy": true,
              "required_status_checks": [ { "context": "test", "integration_id": 15368 } ] } },
          { "type": "required_linear_history" },
          { "type": "non_fast_forward" }
        ]
      }

      Field names from GitHub's repository rulesets REST docs. 15368 is the GitHub Actions app ID (gh api /apps/github-actions). Not applied here. Replace test with the name of your check.

      Three fields do work that an agent cannot do. The integration_id field pins the check to the app that runs CI, so a status from another source does not count. With require_last_push_approval, the last pusher cannot supply the approval, even when the pusher is an agent's token. The strict_required_status_checks_policy field makes the check run against the latest main. That closes the gap where a change passed on a stale base. Next, protect the files that become agent instructions:

      # .github/CODEOWNERS
      /.agents/skills/   @your-org/platform
      /.agents/prepare   @your-org/platform
      /.delta/           @your-org/platform
      /AGENTS.md         @your-org/platform
      /.github/          @your-org/platform

      Syntax from GitHub's About code owners. The paths are the ones that Delta's Agentic Safety page lists as agent instructions or as code that runs on mount. With require_code_owner_review on, an edit to the land skill needs approval from the owning team before it can reach main.

      When it goes wrong

      Delta is in early access, and its safety page states the limits directly. It says "Delta does not have an agent permission system," and "Delta does not sandbox agents. An agent has unrestricted access to the device where it runs." Most failures to plan for come from those limits and from the thread-as-gate design.

      What goes wrongWhyFix
      The land skill merges on a misread CI logA skill is an instruction the agent interpretsRequired status checks pinned by integration_id. The skill uses gh pr merge --auto
      Someone edits the land skill or AGENTS.md in a threadSkills and rules files become agent instructions, per the safety docsCODEOWNERS on those paths with require_code_owner_review
      Opening a shared repository runs codeAn executable .agents/prepare runs when Delta first mounts a managed checkout. An .envrc runs through direnvRead those files before working in a repository you do not trust
      An agent runs a destructive commandNo permission system and no sandbox yetRun Delta on a machine or VM that holds no production credentials
      A secret you thought was ignored syncs to teammatesDelta imports tracked files even when they match an ignore rulegit rm --cached the file, then rotate the secret
      A reviewer's fixes never arrivePull Changes applies the snapshot saved with the verdict, not later editsSubmit a new verdict after late edits, then Pull Changes. If a pull fails, check the parent's files first
      A flaky suite goes green on the third tryNo merge gate can tell a real pass from a lucky oneQuarantine flaky tests. Keep the strict policy so that the pass is on the latest main

      Behaviors from Delta's Agentic Safety, Delta & Git, and review pages, checked September 25, 2026. The safety page says permissions, sandboxing, and worktree trust controls are on the roadmap.

      Git is still underneath

      If you plan to try Delta, one quiet sentence in the announcement matters most. The zed-industries/zed repository "will remain on GitHub for now because it's where our community finds issues and submits changes." Zed asks contributors to share Delta threads with their pull requests, and "teammates who never open Delta still see a normal Git repository." So a team can adopt it one person at a time, and the output is still commits on a branch.

      Zed also states the larger goal. The post calls pull requests "the first part of the GitHub workflow we're leaving behind." It names the replacement practice "continuous engineering," and says the next target is Git storage in DeltaDB. The team writes: "Most contenders promise better uptime on top of the same old primitives: branches, commits, and diffs." Delta is free during the beta. Zed promises paid plans for individuals and teams, and a free version that stays permanently.

      Adopting it without giving up the gate

      Do these steps in order. Each step assumes that the step before it is in place.

      1. Put the gate on the remote first. Create the ruleset on the default branch before any agent can land anything. From then on, nothing the thread decides can merge a failing change.
      2. Own the files that become instructions. Add the CODEOWNERS entries for .agents/skills/, .agents/prepare, .delta/, and AGENTS.md. Then a person must approve changes to the agent's instructions.
      3. Isolate the machine. Until Delta ships permissions and sandboxing, run it where an unrestricted agent cannot damage anything. Keep deploy keys and production credentials out of that environment.
      4. Write the land skill to queue, not to merge. The skill pushes, opens the pull request, and runs gh pr merge --auto. It watches the required checks and never passes --admin.
      5. Review in review threads. Ask for the change guide. Put the why questions to the agent that made the choices. Submit a verdict, then use Pull Changes.
      6. Keep GitHub as the meeting point. Zed's own repository stays on GitHub. When the agent opens a pull request, Delta can add a thread link. Teammates who never open Delta still review the same change.
      7. Watch the queue weekly. If agent changes arrive faster than your team clears them, attached context does not fix the backlog. Limit how many agent changes can wait at once.

      Teams that do not move to Delta can use steps 1, 2, and 7 unchanged. They can replace the review thread with the decision-log template. Zed bets that the thread becomes the unit of software work. Two parts of that bet hold no matter who wins. Keep the reasoning with the change. Put the gate where an agent cannot misread it.

      rg
      Rohit Ghumare

      CNCF Ambassador and Google Developer Expert. I build agent infrastructure and write about the fundamentals underneath the AI stack. Facts about Delta and DeltaDB come from Zed's September 16 announcement, the June 11 DeltaDB post, and Delta's review docs. Quotes from reviewers come from the Hacker News thread on the launch. Delta is in public beta and its landing and CI features are changing, so check the docs before you design a workflow around them.

      Related: The Harness, Not the Model · Harness Engineering · More posts · X