Repository navigation
Description
docs/ceilings.md records that vcs.account (internal/project/ghaccount.go) puts one account's token in GH_TOKEN for every gh call lich makes for a project, while a push still rides the remote's ssh key and signs with the global user.email. A pull request can therefore be read by one account and its commits land under another, with no error anywhere.
It is the one ceiling in that file whose damage is public and cannot be taken back: the wrong author is in the repository's history, on a pull request other people have already read.
Why the obvious fix is refused today
The Version Control pane prints both identities and never compares them, because a naive mismatch warning is a false-positive farm: noreply forms (12345+user@users.noreply.github.com), vanity domains and org aliases all read as different strings for the same person. lich also never writes user.email, so it cannot fix what it detects.
What compounds it
A project opened from outside the window is matched by the spelling of its path (internal/project/project.go, Identify). A symlink or a bind mount of the same checkout opens a second project with its own id, and every path-addressed lookup, vcs.account included, answers with whichever the query reached first. Two tabs on one directory can run gh as two different accounts, and nothing on screen says the two are one checkout.
What done looks like
A reading a stranger can act on, not a warning that cries wolf. Two routes worth measuring before picking one:
- Compare against what the account owns rather than against the string.
gh api user/emailslists the verified addresses and the noreply form for the account whose token is inGH_TOKEN, which turns equality into set membership and kills most of the false positives at once. - Say it where the consequence is, at the push or at the pull request, rather than in a pane nobody has open at that moment.
Open
user/emailsneeds theuser:emailscope, which a project token may not carry. What does the pane show when the call is refused, and is a refusal distinguishable from a match?- Is the signing identity in scope (
user.signingkey, a commit signed by a key the account does not list), or is the author line enough for a first pass?
Activity