A Branch Name Is Not an Instruction: Stop Your Coding Agent Guessing Intent

A pattern keeps showing up in developer complaints about remote coding agents: the agent checks out a branch called fix-auth-timeout, looks around, and decides the job is to fix the auth timeout. Nobody asked for that. The branch was created three weeks ago for a different person’s experiment, and the actual task was “update the README badges.”

The agent was not malfunctioning. It was doing what language models do: inferring intent from the strongest available signal. When the task is vague and the environment is full of labels, the labels win.

This is a workflow design problem, and it is fixable without a smarter model.

Why names become commands

An agent dropped into a repo has very little ground truth. It has your prompt, the file tree, git metadata, and whatever it finds in READMEs and issue trackers. Of those, names are the cheapest and most legible signals:

  • Branch names read like a one-line task description.
  • Commit messages read like a history of intent.
  • Folder names like legacy/, deprecated/, or migrate-v2/ read like instructions about what is safe to touch.
  • TODO comments read like a queue the agent has been invited to drain.

Humans treat these as hints that might be stale. Models treat them as evidence, and when your own prompt is thin, evidence fills the vacuum. The thinner the prompt, the more the environment steers.

The failure modes are boring and expensive

None of these make headlines, but they eat real time:

  1. Scope creep by inference. You ask for a one-file change, the agent sees refactor-payments as the branch and rewrites half a module.
  2. Wrong target. The branch name describes the last task, the agent finishes the last task again, and you get a duplicate PR.
  3. Unsafe confidence. A folder named scratch/ or old/ gets deleted because the name implied it was disposable.
  4. Stale authority. A TODO written by a contractor in 2024 gets executed because it looked like an open ticket.

Each one is a case of an unverified label being promoted to a directive.

Fix 1: Write the task contract before the agent reads the repo

Every dispatched job should carry an explicit contract that states what the job is, so the agent never has to infer it. Keep it short and structured:

  • Goal: one sentence, in the imperative.
  • Allowed paths: the files or directories the agent may modify.
  • Forbidden paths: anything it must not touch, even if it looks related.
  • Done condition: the observable check that proves the task is finished.
  • Stop condition: what to do when the repo state does not match the contract.

That last item matters most. A contract with no stop condition just tells the agent what to do when everything goes well.

Fix 2: State that environment labels are not authority

Put one explicit line in your standing agent instructions: names of branches, commits, folders, and comments describe history, not the current task. The only source of task authority is the contract.

This sounds redundant, and it works anyway. Models follow a stated precedence rule far more reliably than they follow an unstated one. If the contract and the branch name disagree, the contract wins, and the agent should note the mismatch in its report instead of silently picking one.

Fix 3: Create a fresh branch per job, named by you

Do not let an agent inherit a branch. Create a clean one from the intended base, and name it after the job ID rather than a description of the work: job-2026-10-17-readme-badges beats fix-stuff.

A job-ID branch carries almost no semantic payload, so there is nothing for the agent to over-read. You also get a free audit trail, because the branch maps one-to-one to a contract in your log.

Fix 4: Make the agent echo its understanding first

Before any edit, require a one-paragraph restatement: “I will change X in files Y to achieve Z, and I will not touch W.” Compare that against the contract, automatically if you can.

This catches the misreading at the cheapest possible moment. A wrong restatement costs you a few seconds of review. A wrong implementation costs you a PR, a revert, and some trust.

A simple gate works well here: if the restated plan names any file outside the allowed paths, the run stops before it writes anything.

Fix 5: Diff against the contract, not against vibes

At the end of the run, check the actual diff against the allowed-paths list. This is a mechanical check, not a model judgment:

  • Any modified file outside the allowed paths fails the run.
  • Any deleted file fails the run unless deletion was explicitly allowed.
  • A diff far larger than the contract implied gets flagged for human review.

The goal is to make scope a property you verify, not a property you hope for.

What this looks like in practice

Say you run a small automation shop and dispatch coding jobs to a remote agent overnight. Your dispatch template is five lines of contract plus the standing rule about labels. Each job gets its own job-ID branch. The agent’s first output is the restatement, which a small script compares to the allowed paths. The last step is a diff check.

When something does go wrong, the failure is legible. You can see which contract line was missing or ignored, and you fix the template rather than arguing with the model.

Compare that with the default setup, where you type “clean up the auth stuff” into a prompt and hope the repo context lines up with what you meant. That setup works until the day the branch name says something different from what you wanted, and then it does confidently the wrong thing.

The takeaway

Models read everything in front of them as potentially meaningful, and branch names are right in front of them. If you want an agent to do exactly one thing, say that one thing explicitly, say what is off limits, say how to know it is done, and say what to do when reality disagrees.

Names are for humans scanning a git log. Instructions belong in the contract. Keep the two separate and your overnight agents stop surprising you in the morning.

More from the build log

Suggested

Want the full MarketMai stack?

Get the core MarketMai guides and operator playbooks in one premium bundle for $49.

View Bundle