chore: add pre-merge identity guard - #20
Open
Sentinel-Bluebuilder wants to merge 2 commits into
Open
Conversation
…-failover Merging the RPC self-healing failover work. Tested against mainnet with real money: 4/4 funded writes landed with the live endpoint benched each time, all 33 changed routes driven live (52/52), full regression suite green. Keplr/Privy client-signed paths remain untested — see the PR body.
The merge commit for PR #19 (`8f5b0f2`) landed on master authored as a personal email, even though every commit inside the PR was correctly authored as the bot. This was NOT a wrong-account mistake. GitHub's record for PR #19 shows `merged_by: Sentinel-Bluebuilder` — the correct bot account performed the merge. The actual cause: 1. `gh pr merge` builds the merge commit SERVER-SIDE. Local git config is ignored, and no client-side hook can intercept it because no local commit ever happens. 2. GitHub stamps that commit with the merging account's PRIMARY email. 3. The bot account did not have "Keep my email addresses private" enabled, so its primary email was a personal address. The real fix is that GitHub setting (browser-only — there is no API for it; `PATCH user/email/visibility` only controls PUBLIC PROFILE display and does NOT change what server-side commits are stamped with). This script is the enforcement check for it: node scripts/check-merge-identity.mjs && gh pr merge <N> --merge Note it reads `gh api user/emails` (the real primary), NOT `gh api user`.email — the latter is the PUBLIC profile email and is null whenever the profile email is unset, which reads as "safe" while the primary is still personal. A first version of this script used that field and gave a false PASS on the exact account that caused the leak; it now fails closed when it cannot read the deciding value, rather than guessing. Verified: blocks on the bot account (primary email personal), and blocks on a token lacking the `user` scope rather than reporting safe. Claude-Session: https://claude.ai/code/session_01LQj6ekufSijMXPcXUD3596
Sentinel-Bluebuilder
force-pushed
the
master
branch
from
August 10, 2026 16:22
8f5b0f2 to
50ded31
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The merge commit for PR #19 (
8f5b0f2) landed onmasterauthored with a personal email, even though every one of the five commits inside that PR was correctly authored as the bot.This was not a wrong-account mistake. GitHub's own record shows
merged_by: Sentinel-Bluebuilder— the correct bot account performed the merge. The actual cause:gh pr mergebuilds the merge commit server-side. Localuser.emailis ignored, and no client-side git hook can intercept it, because no local commit ever happens.The real fix is a GitHub setting, not this script
Signed in as the bot → Settings → Emails → "Keep my email addresses private" → https://github.com/settings/emails
There is no API for it.
PATCH user/email/visibilityreturnsvisibility: privatebut only controls public profile display — it does not change what server-side merge commits are stamped with. Verified during this work.This affects every repo the bot merges, not just this one.
What this script adds
Enforcement for that setting:
The
&&is what makes it load-bearing rather than advisory.One implementation note worth reading
It reads
gh api user/emails(the true primary), notgh api user.email. The latter is the public profile email and isnullwhenever unset — which reads as "safe" while the primary is still personal.My first version used that field and gave a false PASS on the exact account that caused the leak. It now fails closed when it cannot read the deciding value (e.g. a token missing the
userscope) rather than guessing.Verified: blocks on the bot account while its primary email is personal, and blocks on a scope-less token.
Merging before the GitHub setting is enabled would stamp another personal email onto a new merge commit — reproducing the bug this PR exists to prevent. Enable the setting first, run the guard, then merge.
https://claude.ai/code/session_01LQj6ekufSijMXPcXUD3596