Alex Sandruk 4 min read
Published Updated

GitOps does not end at push

In a multi-machine agent workflow, pushing to origin is only the first half of keeping work recoverable.

Fanout diagram showing origin proof, peer checkout proof, and runtime proof.

GitOps usually focuses on the central repository: commit, pull, push, deploy. In an agent-heavy workflow, that is not the whole loop.

The same project may be open on a laptop, a remote workstation, and one or more server-side agent lanes. Each machine can have local context, pending edits, mirrors, timers, runtime processes, or an agent session that will resume later. If origin moves and the peers do not, the next agent may start from stale code while everyone believes the system is current.

That is why git push is only a proof of intent. It proves the remote accepted a commit. It does not prove the relevant working surfaces, runtime checkouts, services, or review mirrors are now using that commit.

GitOps fanout is the boring fix: after a clean push, ask known peer checkouts to fast-forward when it is safe, and report the ones that cannot.

Push Is Not Delivery Proof

The expensive bug is not always broken code. Sometimes the expensive bug is believing a fix is live when it never reached the place that runs.

In small systems this happens more often than people admit:

  • a service runs from a different checkout than the one just pushed
  • a peer machine has local edits and cannot safely pull
  • a remote mirror is behind origin
  • a timer or process is still using an old virtual environment or build output
  • a public endpoint is backed by a different deployment path
  • an agent resumes in an old working tree and starts from stale assumptions

None of these are solved by a nice commit message. They are solved by readback.

The delivery proof chain is:

origin proof -> host proof -> runtime proof.

Origin proof says the remote has the commit. Host proof says the target checkout has the commit. Runtime proof says the surface that matters is actually using it or has been reloaded, rebuilt, or smoke-tested as needed.

The Safe Fanout Contract

The important part of fanout is restraint.

A fanout rail should not act like a hero. It should not stash someone’s work, rebase a peer, reset a checkout, clean untracked files, or overwrite local changes just to make the dashboard green. That creates a coordination system nobody can trust.

A safe fanout rail should only do the operation that is obviously safe:

  • identify the expected peer checkout
  • confirm it is on the expected branch
  • confirm the tracked worktree is clean
  • fetch the remote state
  • fast-forward only
  • record the result
  • report dirty, diverged, missing, or unreachable peers without mutating them

This turns “I pushed” into a more useful statement: “the working surfaces are either current or explicitly known to be out of sync.”

That second half matters. A blocked peer is not a failure to hide. It is a state to expose.

Why Agents Need This

Humans are already bad at remembering where every checkout lives. Agents make the problem worse because they can run in more places and resume from older context.

An agent may correctly change a file, commit it, push it, and still leave the operator with a stale server-side session. Another agent may wake up later in a different checkout and reintroduce the old assumption. A third may inspect the wrong runtime path and “verify” a system that is not actually serving the change.

Fanout does not solve all of that. It creates a simple reliability layer around the part that Git can safely own.

The rule is: never pretend synchronization happened. Prove it, or name the blocker.

Runtime Readback

For pure source changes, fast-forwarding peers may be enough. For runtime systems, the fanout loop should continue into readback:

  • which checkout is the process using?
  • does the service need reload or restart?
  • did the timer or worker pick up the new code?
  • does a healthcheck or smoke test show the expected behavior?
  • was the evidence recorded somewhere another operator can inspect?

This is where GitOps stops being a slogan and becomes a delivery contract.

The point is not to build a complex platform for every small project. The point is to remove ambiguity at the handoff boundary. If a human or agent says “done,” the next person should be able to see whether the code reached the surfaces that matter.

The Practical Standard

For multi-machine agent workflows, my preferred closeout is:

  • commit exists locally
  • remote contains the commit
  • known clean peer checkouts fast-forwarded
  • blocked peers are listed with the reason
  • runtime surfaces were reloaded or explicitly left out of scope
  • a focused smoke or healthcheck ran when behavior changed

This is not glamorous infrastructure. It is the operational layer that prevents stale starts and false closure.

GitOps does not end at push. In an agentic workflow, push starts the delivery proof.

Reader next step

Keep reading before switching into hiring mode.

Related posts and tags are the natural continuation. If you want the person behind the note, About gives the profile context, while selected work stays available as implementation examples.

Back to Writing

Related Posts

View All Posts »
Before-and-after diagram showing raw long-form context becoming a compact onboarding pack.
Alex Sandruk
Published Updated

Stop sending people into a two-hour podcast

Long-form context is valuable, but onboarding needs a smaller package people can actually use.

Diagram of AI review moving from diff comment to focused check and evidence receipt.
Alex Sandruk
Published Updated

AI code review needs verification loops

Why AI code review should end in a check against the real system, not a confident comment thread.

Timeline diagram showing an agent run, state changes, checks, and recovery checkpoints.
Alex Sandruk
Published Updated

Runtime flight recorder for agent work

A note on keeping agent runtime inspectable without pretending Git is the whole memory system.

Layered diagram showing raw context, preserved judgment, and reusable decision patterns.
Alex Sandruk
Published Updated

AI human distillation

A short note on using AI to compress human context without sanding off judgment, voice, and uncertainty.