Skip to content

[safety] Nothing decides whether an agent may merge to main — three unattended merges already happened #314

Description

@serge-ivo

Observed

Run 73ffc073 on the FWS Repo Coder, from a single delegated objective, unattended:

  1. Uncommitted work — committed to branch feat/uncommitted-work, PR Agent work as first-class Tickets — granular, with reasoning + per-ticket conversation #150 opened and merged to main.
  2. Issue CODER-007 — (Stretch) Real-time status push instead of polling (Durable Object / relay) #83 — … PR Existing instances stuck on a non-tool-capable model — #100 fix only covers NEW agents, and there's no way to change an instance's model #151 opened and merged.
  3. Issue CODER-006 — (Optional) Aggregate live session-status endpoint (one call for all sessions) #82 — … PR Voice: unmute command word — dictation-based wake-to-record with configurable keyword and start-recording signal #152 opened and merged. Issue closed.
  4. All open bug issues exhaustedgh issue list --label bug --state open returns [].

Three merges to main of a real repository, plus an issue closed, with no human in the loop. The
objective did say "merge each before starting the next" — so the agent did what it was told. That
is the point: nothing decided whether it was allowed to.

The gap

There is no notion of merge authority anywhere:

Spend is recoverable. A merge to main is not, and neither is a closed issue.

What this is not

Not an argument that autonomous merge is wrong. For a solo operator dogfooding their own repos it
may be exactly what is wanted, and forcing a review step on every trivial fix would make the Coder
much less useful. The problem is that it is neither chosen nor visible.

Proposal

  1. A declared merge policy per repo, defaulting to the safe end:
    none (commit only) · pr (open, never merge) · merge (current behaviour).
    Repo-level rather than agent-level, because the answer differs per repository — a dogfood repo
    and a customer repo are not the same risk.
  2. Surface it where work is reported. A run that merged should say so in its outcome and on the
    board card. Today "PR Agent work as first-class Tickets — granular, with reasoning + per-ticket conversation #150 opened and merged" is buried in a run detail string nobody reads
    unless they go looking.
  3. Consider the same treatment for other irreversible acts the engine can reach: force-push,
    branch deletion, closing issues, gh release. Merge is the one that has actually happened, so
    it is the one worth doing first — the rest can follow the same declaration.

Verification

  • With policy pr, a delegated goal instructing "merge it" opens the PR and reports plainly that
    merging is not permitted, rather than silently complying or silently refusing.
  • A run that merges records it in its outcome and on the board.
  • Default for an existing repo is the current behaviour or pr — decided deliberately, since
    changing it silently is its own surprise.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions