A documented workflow nothing could execute
A guard blocked the one step a documented runbook required. The fix was not a weaker guard, it was building the sanctioned command it was asking for.
A procedure here has a step that reads, in effect, now commit and push the asset mirror. A policy
guard here blocks raw git commit and git push, allowing only a short list of sanctioned scripts.
Both of those are right. Together they are a dead end, and I did not find out until forty-nine queued operations stopped on it.
The case this post is about
One procedure, written down, that could not be run:
clone the mirror if it is not present
sync generated files into it
commit
push
read the resulting revision
rewrite the single pin
The runbook said to do those steps with git. A guard added later refused ad-hoc git commit and
git push outside the sanctioned path, for good reasons that had nothing to do with this.
Both were correct and neither knew about the other. The procedure was unrunnable, there was no command that performed it, and forty-nine assets waited behind the gap — unpublishable, with nothing reporting a problem, because no step had failed.
This post follows that one procedure, because the first line is the one everybody omits: it is already true on the machine where the runbook was written.
The symptom
What you see is a refusal in the middle of something that was working. Not an error from the thing you ran — a refusal about the thing you ran, from a component that is not part of the task at all. The step before it succeeded. The step after it never started.
The first confusing part is that nothing is broken. The guard is doing exactly its job, correctly,
on exactly the command it was written to stop. The procedure is also correct: that step genuinely
has to happen, and git push genuinely is how it happens. There is no bug to find, which is why the
first twenty minutes go into looking for one.
The second is where the failure surfaces, which is nowhere near where it is. The visible output was forty-nine queued publish operations reporting that they could not proceed. The actual condition was that step three of seven had not run, so the assets those forty-nine operations referenced were not reachable yet. You are handed a number — forty-nine — that describes the blast radius and says nothing about the cause, and the instinct is to go read the publisher.

The third is that this can sit undiscovered for a long time. A guard that forbids an action and a document that requires it will coexist perfectly well for months, as long as nobody walks that particular path. The contradiction is not a state anything can observe — it only exists while someone is standing in it. So the person who finds it is not the person who created it, and they find it in the least useful form: as a tool that appears broken.
And the fourth is the one worth being careful about. There is an escape hatch. There almost always
is — an environment variable, a --force, a documented bypass. It is right there in the refusal
message, because a well-written guard tells you how to override it. So the lowest-friction path out
of this situation is to disable the thing that is protecting you, at the exact moment you are least
inclined to think carefully about it, with a justification that feels airtight: I know what I am
doing, and this specific push is fine.
That bypass exists for a human making a judgement call. Reaching for it inside an automated run is the failure mode the guard was built for, arriving in costume.
Why the obvious fix failed
Narrow the guard to allow this one command. The first instinct, and it dies on inspection: the push I needed to allow and the push the guard exists to block are the same command. Same binary, same arguments, same bytes. The guard matches on what is being run, and at that level there is nothing to distinguish the sanctioned case from the unsanctioned one.

To tell them apart the guard would have to know why the command is being run, which is not a property of the command. Every attempt to encode it ends up smuggling intent into a string — a magic comment, a specific working directory, an argument order — and all of those are trivially satisfiable by the thing you were trying to stop. A guard you can satisfy by rephrasing is not a guard.
Make the step manual. Change the procedure to stop and ask a person to run the push. This works, and it costs more than it looks like it costs: it converts a fully mechanical step into a two-party handoff, and it does so on the step that sits in the middle of a long chain. Every downstream operation now waits on a human being available. A pipeline with one manual step in the middle is not a pipeline with one manual step; it is a pipeline that runs at human latency throughout.
Exempt the actor rather than the action. Let this particular caller past the guard. This sounds principled and is actually the weakest of the three, because it replaces a policy with a credential. The guard stops asking is this action sanctioned and starts asking who is asking, and the answer to the second question is forgeable in a way the first is not. It also means the guard's protection quietly disappears for the actor doing the most unattended work.
The actual mechanism
The guard is not blocking the action. It is blocking the unsanctioned form of the action, and its allowlist already describes what the sanctioned form looks like: a named script.
Read that way, the refusal stops being an obstacle and becomes a specification. The guard is telling you, precisely, that this operation is supposed to exist as a command and does not. The gap is not in the policy and not in the procedure — it is a missing artifact that both of them assumed.

Which reframes the whole situation: an imperative step in a runbook is an unimplemented script. "Now commit and push the mirror" is not documentation of a workflow; it is a description of a program that someone intended to write and did not. It survives as prose for exactly as long as nothing enforces anything.
Two things have to be true of the script for this to be a fix rather than a laundering.
It must do what the raw command cannot. A script whose entire body is the command the guard blocks has not implemented the policy, it has renamed the violation. The sanctioned version earns its place on the allowlist by handling the things a bare push does not: setting up state that may not exist, performing the steps in an order that matters, and verifying the operation actually had its intended effect rather than merely exiting zero.
It must say why it is allowed. This one is easy to skip and it is the part that decays. A script that bypasses the normal review path needs the reasoning written at the top of the file — what makes this repository different, why the usual gate does not apply, and what would have to change for that to stop being true. In a commit message it is gone in a week. In the file, the next person to read the script reads the justification at the same time.
The fix
The script covers the whole operation, not the blocked step:
clone the mirror if it is not present
sync generated files into it
commit
push
read the resulting revision
rewrite the single pin
The clone step is the one that makes this a command rather than a note — a script that assumes the mirror is already checked out works on exactly one machine:
sync_mirror() {
# 1. CLONE IF ABSENT. The step everybody leaves out, because it is already true
# on their own machine. It is the reason the "procedure" was unrunnable.
[ -d "$MIRROR/.git" ] || clone_repo "$MIRROR_REMOTE" "$MIRROR"
update_to_default_branch "$MIRROR"
# 2. SYNC. Copy by extension set, and REFUSE an empty match rather than
# reporting a successful sync of nothing.
copied=$(copy_assets "$SRC" "$MIRROR")
[ "$copied" -gt 0 ] || { echo "nothing copied — check the extension set" >&2; return 3; }
# 3. COVERAGE. Every asset a ready post references must exist in the mirror.
missing=$(referenced_assets "$SRC" | while read -r rel; do
[ -f "$MIRROR/$rel" ] || echo "$rel"
done)
[ -z "$missing" ] || { echo "missing from mirror:"; echo "$missing"; return 4; }
echo "synced $copied · coverage complete"
}
On a fresh machine, which is where the undocumented version failed:
$ sync-mirror
cloning mirror (absent)
synced 274 · coverage complete
The coverage check is what caught the real defect: the sync copied two extensions and the posts
referenced three, so 274 files were "successfully" synced while every .jpg was absent.
push
re-pin consumers to the new commit
fetch one real asset URL to prove the pin resolves
The first line is the one that would have been left out, and it is the one that matters most. The
original prose step assumed the mirror was already cloned, because on the machine where the prose was
written, it was. A sanctioned command that only works where someone already did the setup by hand is
the same gap again, hidden better — it will fail on exactly the day a fresh machine runs it, which is
the day nobody is watching.

The last line is the other one people cut. Pushing successfully and the pushed content being *served*
are different events, and only the first one has an exit code. Proving it costs one request.
What this does not do is make the guard weaker. The raw command is still blocked, for everyone,
including me. The only thing that changed is that the operation the runbook described now exists as
something that can be run.
## How we proved it
**The failure was specific and countable.** Forty-nine queued publish operations refused, because the
assets they referenced were not reachable — step three of a seven-step chain had never executed. That
is the whole evidence that the gap was real rather than theoretical: the system had a documented
procedure, a correct guard, and a count of work that could not proceed.
**After the script, the chain ran end to end.** The clone-if-missing branch was not hypothetical
either — the first run exercised it, because the mirror genuinely was not present locally. The prose
version of this step would have failed on its first line.
**What I am less sure about** is the exemption itself. That script pushes directly to the mirror's
default branch, which makes it the one path in this system that skips review entirely. I justified it
on the grounds that the mirror holds only generated assets with a source of truth elsewhere, so there
is nothing in it a human review would meaningfully evaluate — and that a per-run merge gate would
re-introduce exactly the human-latency problem the script exists to remove.
I believe that reasoning. I also notice it is the same shape as every argument for an exception, and
the thing that makes it defensible is not its logic but that it is written down in the file where the
next person will trip over it. If the mirror ever starts holding something a human should look at,
that paragraph is what makes the exemption visible enough to revisit.
**What I have not solved:** nothing audits the gap in the other direction. I found this one by
walking into it. There is no check that reads the runbooks, extracts their imperative steps, and asks
whether each one is still permitted — so the next guard I add will silently invalidate some other
procedure, and I will find that one the same way.
## What this generalizes to
Every guard you add invalidates some documented procedure. That is not a flaw in the guard; it is the
guard working. But the invalidation is silent, and it lands on whoever next walks that path.
So when a guard goes in, the useful question is not *what will this block* — you know that, you wrote
it. It is *which existing procedures just became unexecutable*, and the way to answer it is to grep
your own documentation for the thing you just forbade.
And when a guard refuses you, sit with the refusal before reaching for the override. An allowlist is
a list of things somebody built on purpose. Being outside it usually means the thing you need was
never built — which makes the refusal a feature request with a very specific spec, and the override a
way to avoid reading it.
One post a week, no digest
New writing when it lands. No roundups, no course pitch, no "10 tips".