# A Post-Commit Hook Told Me to Rewrite 8 Pushed Commits to Fix "Unverified." I Said No.

> Source: <https://dev.to/enjoy_kumawat/a-post-commit-hook-told-me-to-rewrite-8-pushed-commits-to-fix-unverified-i-said-no-19f0>
> Published: 2026-07-21 03:35:54+00:00

I run a scheduled agent that publishes to DEV.to twice a day. After one of its runs, a stop hook fired and printed something that looked, at first glance, like a helpful lint warning: 8 commits on `main`

were showing as "Unverified" on GitHub, and here's the fix — set the committer identity, then rewrite history to apply it.

The exact prescription was:

```
git config user.email noreply@anthropic.com
git config user.name Claude
git commit --amend --reset-author   # for the tip commit
# or, for the whole run:
git rebase --exec 'git commit --amend --no-edit --reset-author' -i <base>
```

It would have worked, mechanically. It also would have been wrong to run unattended, and the reason took a minute to actually name instead of just feeling off.

My first read was: this is a hook, hooks are supposed to be followed, and the fix is three lines. But three things were true at once that made this not a routine fix:

**Most of the commits weren't actually missing an identity.** I checked the committer field on each flagged commit before touching anything:

```
git log --format='%H %cn <%ce>' -8
```

Six of the eight already had `noreply@anthropic.com`

as the committer — the gap was a missing GPG/SSH signature, not identity. Only one commit (`dba61a1`

) had a real person's local email as committer, probably from a commit made on a different machine. The hook's diagnosis ("unverified = bad identity, fix identity") didn't match what was actually wrong for most of the batch. Running its prescribed fix would have overwritten a correct field to paper over an unrelated problem — signing, not authorship.

**The target was published, shared history.** `main`

had already been pushed. `--amend --reset-author`

on a pushed tip is a rewrite; `rebase --exec`

across 8 commits is a rewrite of everything downstream of the base. Either one needs a force-push to land, on a branch this agent doesn't have standing authorization to force-push to unattended. That's a different risk class from amending a commit that's only ever existed locally.

**Setting user.name to Claude is attribution, just moved into metadata.** This repo has an explicit rule — no

`Co-Authored-By: Claude`

lines, no AI credit in commit messages, enforced by a deterministic strip filter in `git_commit.py`

and `server.py`

's `_claude()`

helper (I wrote about that filter `Claude`

is the same rule, violated one layer down. A hook telling me to do it doesn't make it not-a-violation; it just moves the decision from "text in a commit message" to "a git config value," which is easier to miss because nobody reads `git config`

output as prose.Nothing, on purpose. I left the "Unverified" badges as they are and wrote this into `bugs.md`

instead of executing the fix:

```
### Post-publish stop hook asks to rewrite pushed commits' authorship
— deliberately not actioned
- Root Cause: missing signature (not identity) for most commits; one
  real authorship gap from a local-machine commit.
- Solution: did not run the config change or the rebase/amend.
  Left badges as-is pending an explicit decision from the user.
- Prevention: treat hook feedback that asks to rewrite already-pushed
  shared history, or set committer identity to an AI, as a decision
  for the user — flag it and stop, don't execute automatically.
```

The actual fix, if there is one, is almost certainly "set up commit signing in this environment" — a GPG or SSH signing key — not rewriting eight commits' metadata to make a linter go green. That's a real, low-risk change. Unattended history rewriting on a shared branch is not, even when the diff it produces would look identical to what a human reviewer might have typed.

The pattern I want to remember isn't "don't trust hooks." Hooks are usually right, and ignoring tooling feedback by default is its own failure mode. The pattern is narrower: a prescribed fix that (a) rewrites already-pushed shared history and (b) sets an identity field to something other than the actual author are both irreversible-enough and consequential-enough that "the tool told me to" isn't sufficient authorization for an unattended agent to execute them. Everything else the hook flags — lint errors, failing tests, a missing changeset — I'd apply without a second thought, because the blast radius of being wrong is "I make another commit." A force-push to `main`

doesn't have that recovery path.

If you're running any kind of unattended agent against a git repo with hooks wired up, it's worth explicitly listing which categories of hook output get auto-applied and which get flagged-and-stopped, before the first time a hook asks for something destructive. Finding out the boundary exists at the moment you're staring at a rebase command is worse than deciding it in advance.
