{"slug": "a-post-commit-hook-told-me-to-rewrite-8-pushed-commits-to-fix-unverified-i-said", "title": "A Post-Commit Hook Told Me to Rewrite 8 Pushed Commits to Fix \"Unverified.\" I Said No.", "summary": "A developer running a scheduled agent that publishes to DEV.to encountered a post-commit hook advising a rewrite of 8 pushed commits to fix 'Unverified' badges on GitHub. The developer declined, finding the hook's diagnosis misidentified the issue—missing GPG/SSH signatures, not identity—and that the prescribed fix would rewrite shared history and set the committer name to 'Claude,' violating the repo's rule against AI attribution in metadata.", "body_md": "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`\n\nwere showing as \"Unverified\" on GitHub, and here's the fix — set the committer identity, then rewrite history to apply it.\n\nThe exact prescription was:\n\n```\ngit config user.email noreply@anthropic.com\ngit config user.name Claude\ngit commit --amend --reset-author   # for the tip commit\n# or, for the whole run:\ngit rebase --exec 'git commit --amend --no-edit --reset-author' -i <base>\n```\n\nIt 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.\n\nMy 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:\n\n**Most of the commits weren't actually missing an identity.** I checked the committer field on each flagged commit before touching anything:\n\n```\ngit log --format='%H %cn <%ce>' -8\n```\n\nSix of the eight already had `noreply@anthropic.com`\n\nas the committer — the gap was a missing GPG/SSH signature, not identity. Only one commit (`dba61a1`\n\n) 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.\n\n**The target was published, shared history.** `main`\n\nhad already been pushed. `--amend --reset-author`\n\non a pushed tip is a rewrite; `rebase --exec`\n\nacross 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.\n\n**Setting user.name to Claude is attribution, just moved into metadata.** This repo has an explicit rule — no\n\n`Co-Authored-By: Claude`\n\nlines, no AI credit in commit messages, enforced by a deterministic strip filter in `git_commit.py`\n\nand `server.py`\n\n's `_claude()`\n\nhelper (I wrote about that filter `Claude`\n\nis 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`\n\noutput as prose.Nothing, on purpose. I left the \"Unverified\" badges as they are and wrote this into `bugs.md`\n\ninstead of executing the fix:\n\n```\n### Post-publish stop hook asks to rewrite pushed commits' authorship\n— deliberately not actioned\n- Root Cause: missing signature (not identity) for most commits; one\n  real authorship gap from a local-machine commit.\n- Solution: did not run the config change or the rebase/amend.\n  Left badges as-is pending an explicit decision from the user.\n- Prevention: treat hook feedback that asks to rewrite already-pushed\n  shared history, or set committer identity to an AI, as a decision\n  for the user — flag it and stop, don't execute automatically.\n```\n\nThe 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.\n\nThe 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`\n\ndoesn't have that recovery path.\n\nIf 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.", "url": "https://wpnews.pro/news/a-post-commit-hook-told-me-to-rewrite-8-pushed-commits-to-fix-unverified-i-said", "canonical_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_at": "2026-07-21 03:35:54+00:00", "updated_at": "2026-07-21 03:59:24.641071+00:00", "lang": "en", "topics": ["developer-tools", "ai-agents", "ai-ethics"], "entities": ["DEV.to", "GitHub", "Anthropic", "Claude"], "alternates": {"html": "https://wpnews.pro/news/a-post-commit-hook-told-me-to-rewrite-8-pushed-commits-to-fix-unverified-i-said", "markdown": "https://wpnews.pro/news/a-post-commit-hook-told-me-to-rewrite-8-pushed-commits-to-fix-unverified-i-said.md", "text": "https://wpnews.pro/news/a-post-commit-hook-told-me-to-rewrite-8-pushed-commits-to-fix-unverified-i-said.txt", "jsonld": "https://wpnews.pro/news/a-post-commit-hook-told-me-to-rewrite-8-pushed-commits-to-fix-unverified-i-said.jsonld"}}