Static site with the same datasheet hero: https://jordannewell.github.io/git-hygiene/ (enable Pages from repo settings β main branch root, see docs/superpowers/plans/2026-07-30-git-hygiene-site-branding.md Task 7).
Source: index.html + assets/site.css. Regenerate brand assets with python tools/render_brand_assets.py.
Tools don't get co-author credit.
Every repo I worked in slowly accumulated Co-Authored-By: Claude and π€ Generated with Claude Code trailers in the log. Sometimes the setting got reverted, sometimes a collaborator's setup differed. Commit history is the one artifact future employers, acquirers, and collaborators read to evaluate how you work β a log full of AI trailers reads as performative, the opposite of how senior operators signal taste. You don't credit DeWalt on the shed you built with their drill.
For regulated industries (defense, finance, health), AI-assisted code is becoming a real disclosure question. A clean history sidesteps the question; a dirty one raises it.
Two git hooks, zero dependencies beyond bash/grep/awk/git. gitleaks is optional β adds ~700 secret detectors when installed.
commit-msgstrips AI-attribution trailers (Co-Authored-By,Generated with,AI-assisted). Legitimate human co-authors preserved.pre-commitscans staged files in three layers: high-precision regex, gitleaks (if installed), and an optional OPSEC content scan for machine-level identifiers.
Runs locally against your staged files. No telemetry, no SaaS, no third-party scans.
Three positions, held firmly:
- AI tools are tools. Claude, Copilot, Cursor, Gemini, ChatGPT β they're how the work gets done, not who did the work. The author is the human; the tool is the tool.
- Secrets stay out of git. API keys, tokens, passwords β pre-commit catches the high-precision patterns before they land in your object store.
- Local enforcement, no SaaS dependency. The hooks run on your machine against your staged files. No telemetry, no cloud calls, no third-party scans.
hooks/
βββ commit-msg # Strips AI-attribution trailers + OPSEC scan on subject
βββ pre-commit # Scans staged files: credential patterns + OPSEC content
βββ opsec-scan.sh # Sourceable library: builds $opsec_patterns from .local files
βββ opsec-patterns.local.example # Template for user's gitignored opsec-patterns.local
Strips lines matching any of these patterns (case-insensitive):
Co-Authored-By: <anything>Claude/Copilot/Cursor/Gemini/ChatGPT/GitHub Copilot/anthropicCo-Authored-By: <AIorCo-Authored-By: ...AIGenerated with Claude/Copilot/Cursor/Gemini(catches theπ€ Generated with Claude Codestandard trailer too β emoji not required in the pattern, survives grep locale issues)Generated-with: ClaudeWritten by Claude/Created by ClaudeAI-assisted:noreply@anthropic.com/noreply@github.com ... copilot
Legitimate human co-authors (Co-Authored-By: Jane Doe <jane@example.com>) are preserved. Body content referencing Claude Code as a tool ("the Claude Code agent was mangling whitespace") is preserved β only trailer-shaped patterns are stripped.
Three-layer scan: credential patterns, broad secret detection, and OPSEC content scan.
Layer 1 β regex (always on, no dependencies). High-precision patterns for known secret shapes:
- AWS access keys (
AKIA...) and secret keys - OpenAI (
sk-or-...), GitHub (ghp_/gho_/ghu_/ghs_/ghr_/github_pat_...), Slack (xoxb-/xoxp-) tokens - Bearer tokens, generic API keys / passwords / secrets matching
key="..."assignments
Layer 2 β gitleaks (when installed). Drops in automatically if gitleaks is on $PATH. Adds ~700 built-in detectors (Stripe live keys, GCP service account JSON, private keys, database URLs, etc.) that the regex layer doesn't know about. If gitleaks isn't installed, the hook prints a one-line warning and falls back to regex-only β still safe to commit.
Layer 3 β OPSEC content scan (when ~/.config/opsec-patterns.local or ./.opsec-patterns.local is present). Sources the same opsec-scan.sh library as commit-msg and scans added lines of staged files (plus filenames) for your machine-level + repo-level OPSEC patterns β hostnames, agent handles, codenames, tailnet name. Catches what credential-shaped regex can't: a fleet hostname in a comment, an agent handle in a docstring, a tailnet suffix in a URL.
- Diff-only scan. Unchanged prose with legitimate mentions isn't resurfaced β only newly-added lines are checked. Historical mentions stay a separate cleanup problem.
- Same path skipping as Layers 1 + 2. Test fixtures,
*.example/*.templateextensions,node_modules/, etc. are exempt. - Same opt-out as commit-msg.
git config opsec.scan disablesilences this layer too. - Graceful no-op. If neither
.localfile is present (the default OSS-contributor setup), Layer 3 is skipped β only the hardcoded baseline (session IDs + Tailscale CGNAT IPs) runs, which is rarely useful for content and never blocks legitimate code.
Install gitleaks (optional but recommended):
# macOS
brew install gitleaks
# Debian/Ubuntu
apt install gitleaks
# Other platforms β grab a release
# https://github.com/gitleaks/gitleaks/releasesPath skipping. All three layers skip staged paths that are known to contain realistic-looking fake keys: node_modules/, vendor/, third_party/, *.min.js/*.min.css, test[s]//spec//fixtures//__tests__/, example[s]//sample[s]//demo//docs/, and *.example/*.sample/*.template/*.dist template extensions. Real secrets live in source/config files.
Sourceable library that builds a $opsec_patterns regex from up to three layers:
- Hardcoded baseline (tracked) β session IDs (
Sxxxconvention) + Tailscale CGNAT IPs (100.x.x.x). Safe for everyone. - Machine-level β
$HOME/.config/opsec-patterns.local(gitignored). Your real hostnames, tailnet name, codenames, agent handles. Defined once per machine, applies to every repo you commit to. - Repo-local β
./.opsec-patterns.local(gitignored). Optional extras for project-specific patterns.
The .local files are gitignored by convention β they contain real infrastructure identifiers that are themselves OPSEC-sensitive. See hooks/opsec-patterns.local.example for the contract.
commit-msg sources this library and scans the commit subject (first line) for matches. Bodies are not scanned β legitimate prose may mention collaborators by name. If no .local files are present, only the hardcoded baseline runs (safe default for OSS contributors).
Pattern word boundaries are added automatically β ada won't false-match inside readable or metadata.
git clone https://github.com/JordanNewell/git-hygiene.git ~/git-hygiene
# Symlink into your global hooks path
mkdir -p ~/.githooks
ln -s ~/git-hygiene/hooks/commit-msg ~/.githooks/commit-msg
ln -s ~/git-hygiene/hooks/pre-commit ~/.githooks/pre-commit
chmod +x ~/.githooks/*
# Tell git to use that hooks path globally
git config --global core.hooksPath ~/.githookscd /path/to/repo
git config core.hooksPath /path/to/git-hygiene/hooks# Test commit-msg
echo "Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>" > /tmp/msg
echo "test subject" >> /tmp/msg
git commit -F /tmp/msg --allow-empty # trailer should be stripped from the result
git log -1 --format='%B'
# Test pre-commit
echo "AWS_SECRET_ACCESS_KEY=abcd1234..." > /tmp/secret
git add /tmp/secret # should fail or warnIf you commit to public repos from a machine that also hosts internal infrastructure (homeserver, agent fleet, internal codenames), enable the OPSEC scan:
# 1. Create your machine-level patterns file
mkdir -p ~/.config
cp ~/git-hygiene/hooks/opsec-patterns.local.example ~/.config/opsec-patterns.local
# 2. Edit ~/.config/opsec-patterns.local β replace examples with your real values
# (hostnames, tailnet name, agent handles, codenames, internal service names)
# 3. Test β commit-msg will now block subjects containing your patterns
echo "S100: test session id" > /tmp/msg
git commit -F /tmp/msg --allow-empty # should FAIL with OPSEC leak messageRepos that want project-specific patterns on top of the machine-level set can add a ./.opsec-patterns.local file (don't forget to gitignore it).
If a repo's history legitimately references internal codenames that match your OPSEC patterns (e.g. an internal infrastructure repo whose commits use feat(fleet-cabinet-ops): ... as subject scope), opt out per-repo:
cd /path/to/internal-repo
git config opsec.scan disable
git config opsec.scan # should print: disableThe opt-out:
- Lives in
.git/configβ never accidentally committed. - Accepts
disable,off,false,no,0(case-insensitive) β pick whichever feels natural. - Disables the OPSEC pattern scan ONLY. The AI-attribution strip in
commit-msgand the secret scan inpre-commit(regex + gitleaks) are unaffected. - Use it for internal repos whose commits never reach a public remote. Don't use it on repos that push to GitHub/GitLab publicly.
Verify it's active with git config opsec.scan. When enabled, commit-msg emits a single-line notice to stderr: OPSEC scan skipped (opsec.scan=disable).
The hook is one of three layers. Belt, suspenders, and a third belt.
- Editor / agent setting β Claude Code's
~/.claude/settings.jsonhasincludeCoAuthoredBy: false. Stops the trailer from being emitted in the first place. Copilot, Cursor, etc. have their own equivalents. - This hook β
commit-msgcatches what slips through. Doesn't care which tool emitted the trailer. - CLAUDE.md / AGENTS.md instruction β behavioral rule for AI agents operating in the repo.
Each layer fails open independently. The three together are robust.
Copyright / IP. Mixing AI co-authorship into commit metadata muddies who owns the code. Some jurisdictions are starting to litigate AI-assisted work; clean attribution history is a defense.
Hiring signals. Future employers, acquirers, contributors read your commit history. A repo where every commit says Co-Authored-By: Claude reads as performative β "look, I use AI!" β which is the opposite of how senior operators signal taste.
Audit trails. For regulated industries (defense, finance, health), AI-assisted code is a real disclosure question. Some orgs prohibit it entirely. A clean commit history that doesn't carry AI attribution sidesteps the question; a dirty one raises it.
- Not a watermark / steganography tool
- Not a supply-chain attestation framework (look at SLSA / Sigstore for that)
- Not a replacement for
pre-commitframework, Husky, GitGuardian, or TruffleHog as a service - Not a policy engine for org-level enforcement (use GitHub push rules for that)
It's a small, focused set of hooks for individual operators who want clean local commit hygiene without depending on a SaaS.
MIT Β© Jordan Newell
This repo follows the Jordan Newell code-signature pattern. PGP fingerprint: 67567DC5E7C5353F85F2AF0DAC05D3F3E0EFA32A. Verify commits with git verify-commit HEAD.

