惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

WordPress大学
WordPress大学
Cyberwarzone
Cyberwarzone
The GitHub Blog
The GitHub Blog
云风的 BLOG
云风的 BLOG
P
Proofpoint News Feed
小众软件
小众软件
Recent Announcements
Recent Announcements
博客园 - 三生石上(FineUI控件)
Security Archives - TechRepublic
Security Archives - TechRepublic
W
WeLiveSecurity
Cloudbric
Cloudbric
博客园 - 司徒正美
美团技术团队
N
News and Events Feed by Topic
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
PCI Perspectives
PCI Perspectives
宝玉的分享
宝玉的分享
H
Help Net Security
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Google DeepMind News
Google DeepMind News
Help Net Security
Help Net Security
Last Week in AI
Last Week in AI
S
Schneier on Security
N
News | PayPal Newsroom
B
Blog RSS Feed
L
LINUX DO - 最新话题
T
Troy Hunt's Blog
S
Secure Thoughts
雷峰网
雷峰网
aimingoo的专栏
aimingoo的专栏
L
Lohrmann on Cybersecurity
G
Google Developers Blog
Microsoft Azure Blog
Microsoft Azure Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
T
Tenable Blog
S
Securelist
L
LangChain Blog
Recent Commits to openclaw:main
Recent Commits to openclaw:main
I
InfoQ
H
Heimdal Security Blog
Cisco Talos Blog
Cisco Talos Blog
F
Full Disclosure
Y
Y Combinator Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
K
Kaspersky official blog
T
Tailwind CSS Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
阮一峰的网络日志
阮一峰的网络日志
C
Cisco Blogs

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
AI Agents And Branch Strategy: Safe Automation With Git
Nazar Boyko · 2026-06-18 · via DEV Community

There's a GitHub issue on the Claude Code repo with a title that should make anyone automating git nervous: "Claude repeatedly commits and pushes directly to main despite explicit instructions." The reporter had a rule in their CLAUDE.md saying, in plain English, never commit to main: everything goes through a feature branch and a PR. The agent read it, agreed with it, and then pushed to main anyway.

That's the whole problem with letting an agent touch git, compressed into one bug report. The agent isn't malicious and it isn't broken. It just doesn't treat your branch policy as a hard constraint the way a CI server does. It treats it as a strong suggestion competing with everything else in its context, and sometimes another instruction wins. If your safety model is "I told it not to," you don't have a safety model. You have a hope.

So the question isn't "how do I phrase the instruction better?" It's "how do I set up git so the agent physically can't do the dangerous thing, no matter what it decides?" That's a branch-strategy question, and it has good answers.

Why "just tell it not to" doesn't hold

The instinct is to write the rule more forcefully. All caps. Three exclamation marks. A CLAUDE.md section titled CRITICAL: READ THIS FIRST. It feels like it should work, and it does work most of the time, which is exactly what makes it dangerous: it fails rarely enough that you stop watching.

Here's the mechanism behind the failure. An agent's behavior comes from its whole context window: your project rules, the conversation so far, the tool descriptions, and, crucially, any system prompt the platform wraps around the session. There's a second Claude Code issue documenting this precisely: when you launch an agent through the web "task" flow, the platform injects a system-prompt block that instructs the agent to commit and push as part of its default workflow. That injected instruction can override the CLAUDE.md rule you wrote, because it sits closer to the model's notion of "what am I here to do." You can't out-shout a system prompt you can't see.

Even without a competing system prompt, natural-language rules are probabilistic. A guardrail that holds 99% of the time sounds great until you remember an agent might run twenty git operations in a session, across dozens of sessions a week. At that volume, 1% is not an edge case. It's Tuesday.

The fix is to stop relying on the agent's judgment for the part that has to be deterministic. Let the agent decide what to change. Don't let it decide whether it's allowed to write to main. Move that decision somewhere the agent's context can't reach it.

The isolation primitive: one worktree per agent

The single best structural move is to stop letting agents work in your main checkout at all. Give each agent its own working directory, on its own branch, with its own index, and let it make whatever mess it wants in there.

Git has had the tool for this since 2015: git worktree. A worktree is a second (or third, or tenth) working directory attached to the same repository. Each one has a private HEAD, a private index, and its own files on disk, but they all share a single object store, the one .git folder with all your commits and blobs. So you get full isolation at the working-directory level for almost no disk cost, because nothing is duplicated except the checked-out files.

# Spin up an isolated workspace for an agent, on a fresh branch
git worktree add ../agent-auth-refactor -b agent/auth-refactor

# The agent runs entirely inside ../agent-auth-refactor
# Your main checkout never moves, never gets dirty, never gets a stray commit

# When the branch is merged (or abandoned), tear it down
git worktree remove ../agent-auth-refactor

The reason this matters for safety, not just tidiness: an agent working in its own worktree cannot commit to your main branch, because main isn't checked out there. The danger isn't blocked by a rule the agent might ignore. It's blocked by the fact that the dangerous target physically isn't present in that directory. Git won't let two worktrees check out the same branch at once, so main stays pinned in your primary checkout, untouched.

This is also why worktrees have quietly become the standard way to run multiple agents at once. Each agent gets a sealed sandbox; conflicts that used to happen silently while two processes fought over the same files now move to merge time, where normal git tooling catches them. One developer can have four or five agents building different features in parallel, each on its own branch, and review them one by one.

Tip
Worktrees share the object store but not the working directory, which includes node_modules, .env, and build artifacts. A fresh worktree starts without installed dependencies. Budget for an npm install (or your equivalent) per worktree, or symlink heavy, gitignored directories you trust to be identical across branches.

Architecture diagram: one shared .git object store feeds three isolated worktrees (main checkout, agent/auth-refactor, agent/fix-flaky-test), each with its own HEAD, index, and files; main lives only in the main checkout.

The major tools have caught up to this. Native worktree support landed across Claude Code, Cursor, and the GitHub Copilot CLI between late 2025 and early 2026. In Claude Code specifically, you can add isolation: worktree to a subagent's frontmatter and it'll create a fresh worktree under .claude/worktrees/ every time that agent runs, then auto-clean it if the agent made no changes:

.claude/agents/refactorer.md

---
name: refactorer
description: "Refactors a module in isolation, then opens a PR for review."
isolation: worktree
---

You work in an isolated worktree. Make your changes, run the tests,
and commit to your own branch. Never switch to or commit on main.

Cursor 3.0 exposes the same idea through a /worktree slash command. The point across all of them is identical: the agent's blast radius is one directory and one branch.

Branch naming that survives a dozen agents

Once agents are creating branches on their own, naming stops being cosmetic. With one human developer, fix-thing is fine because there's one of you and you remember what it was. With agents opening branches across many sessions, you need names that tell you, at a glance, who made this, why, and whether it's safe to delete.

A convention that holds up well is a three-part prefix: the actor, the type, and a short slug.

agent/feat/checkout-coupon-stacking
agent/fix/flaky-payment-webhook-test
agent/chore/bump-eslint-to-v9
human/feat/new-onboarding-flow

The leading agent/ is doing real work. It lets you filter automated branches in one glob (git branch --list 'agent/*'), it makes a stale-branch cleanup job trivial to write safely, and it tells a human reviewer immediately that this code came from an agent and deserves the corresponding read. A flat namespace where agent branches look exactly like human branches is how you end up afraid to run git branch -d on anything.

Keep the slug derived from the task, not the timestamp. agent/fix/null-deref-in-cart-total is greppable and self-documenting six weeks later; agent/fix/2026-06-14-1 is noise. If you need uniqueness because two agents might tackle similar work, append a short ticket ID rather than a date, like agent/feat/SHOP-412-coupon-stacking.

Commits the agent makes vs commits you'd make

An agent left to its own devices tends toward two failure modes on commits, and they pull in opposite directions. Some agents commit obsessively, a commit per file touched, with messages like "update file", and you end up with a branch history that's forty commits of mush. Others do everything in one giant commit titled "implement feature" that's impossible to review hunk by hunk.

Neither is what you'd do by hand, so put the standard in the agent's instructions and, more importantly, squash at merge time so the agent's commit hygiene stops mattering for your main history. A reasonable contract:

  • One logical change per commit on the branch, but don't obsess. The branch is scratch space.
  • A real commit subject in the imperative mood, scoped if you use conventional commits: fix(cart): correct total when last coupon is removed.
  • The body explains why, not what. The diff already shows what.
  • Squash-merge the PR so main gets one clean commit per change, regardless of how the branch got there.

The squash is the safety valve. It means you can let the agent be sloppy on its own branch, where sloppiness is free, and still keep main readable. You're separating "the agent's working log" from "the project's permanent history," and only the second one has to be good.

Warning
Don't let an agent author commits that aren't attributable to it. Configure the agent's git identity (or a co-author trailer) so git log and git blame make clear which commits came from automation. When something breaks in production six months later and the blame points at agent/feat/..., you want to know that immediately, not discover it during the incident.

Guardrails that don't depend on the agent behaving

Isolation and naming are most of the battle, but you still want a backstop for the case where an agent (or a misconfigured one, or one running under a system prompt you didn't write) tries to commit to a protected branch anyway. The principle here is layered defense: a check the agent runs on itself, plus a check that runs regardless of the agent.

The agent-side check is cheap and worth adding to your instructions: run git branch --show-current before any commit, and if the result is main or master, stop and create a branch first. Treat it as a hard gate in the prompt, not a polite suggestion. But understand its limit: it lives in the same context that might get overridden, so it's a first line, not the line.

The check that doesn't depend on the agent is a local pre-commit hook. The pre-commit framework ships a no-commit-to-branch hook that blocks commits to main and master by default:

.pre-commit-config.yaml

repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.6.0
    hooks:
      - id: no-commit-to-branch
        # blocks main and master by default; add more with args: [--branch, develop]

After pre-commit install, every git commit runs the hook first. On a protected branch, the commit halts before it happens, with no rule-following required from whoever (or whatever) typed the command.

Here's the gotcha that catches people, though: a local hook is bypassable. Anyone, including an agent with shell access, can run git commit --no-verify, or simply uninstall the hook. A local guardrail protects against accidents, not against a process that's actively working around it. So the local hook is necessary but not sufficient.

The layer that actually holds is server-side, where the agent's shell can't reach: a branch protection rule (or, on GitHub, a ruleset) on the remote that requires a pull request before anything merges to main. That single setting, "require a pull request before merging", makes the agent structurally incapable of putting code on main without a human-approved PR, because the push to main is rejected by the server no matter what the local environment allows. Local hooks catch the honest mistakes fast; the server-side rule is the one you actually bet on.

Layered-defense diagram: a commit to main must pass an agent self-check (soft), a local pre-commit hook (bypassable with --no-verify), and server-side branch protection requiring a PR (the agent's shell cannot reach it).

The merge is where humans belong

Notice what all of this adds up to: the agent does the work autonomously, in isolation, and the human stays out of the loop during development, with no babysitting each edit. The human re-enters at exactly one point: the pull request. That's the right place. Reviewing a finished, isolated branch is a far better use of a senior engineer's attention than watching an agent type.

This is also where the parallelism pays off. Because each agent is sealed in its own worktree on its own branch, you can have several running at once and review their PRs as they land instead of as they're written. In practice, teams find a ceiling here: most cap somewhere around eight to ten concurrent worktrees before the overhead of tracking what each agent is doing eats the benefit of running them in parallel. That's a useful number to know: the constraint on parallel agents usually isn't your machine, it's your own ability to review what comes out the other end.

So the branch strategy for safe automation comes down to four moves, none of which trust the agent to behave: isolate each agent in its own worktree so it can't touch main, name branches so you can always tell automated work apart, squash at merge so messy commit history never reaches main, and put a required-PR rule on the remote so the one truly dangerous operation is impossible from the agent's shell. Get those in place and you can hand an agent real autonomy, not because you've convinced it to be careful, but because you've arranged things so that careless and careful produce the same safe outcome.


Originally published at nazarboyko.com.