fix(tooling): keep GitHub App auth when the agent gh shim delegates - #373
Merged
Conversation
`findRealGh` preferred `$T3_GITHUB_REAL_GH` over anything on PATH. That variable names the *unauthenticated* gh binary the GitHub App wrapper execs after it mints an installation token; hosts export it so a child that reorders PATH keeps minting config, not as an authenticated entry point. Delegating straight to it skipped minting, so every `gh` call the shim fronted failed with "gh auth login". Server-side that is invisible: the VCS spawn PATH includes each repo's `.tools/bin`, so `gh pr list` resolved to this shim, got exit 4, and surfaced as `SourceControlProviderError` behind "PR lookup failed; keeping last known PR state." Sidebar rows then render without a PR badge, while settled rows keep showing one because the settle freeze serves the last known value instead of looking up. Resolution order is now: AGENT_GH_REAL (this shim's own re-entry override) → PATH (the App-aware `gh`) → T3_GITHUB_REAL_GH as a last resort, so hosts without a wrapper still work. Verified against the exact failing invocation on the running server: `gh pr list --head <branch> --state all` under the server's environment goes from exit 4 to exit 0, returning the PR. Co-authored-by: Patrick Roza <42661+patroza@users.noreply.github.com>
patroza
added a commit
that referenced
this pull request
Aug 15, 2026
## Summary The PR panel mapped every unclassified `gh` exit to **GitHub CLI command failed.**, so the real guest-wrapper reason never reached the UI. That is what `pingdotgg#6613` (`pingdotgg/t3code`) showed this time. The live t3vm image already has ops #80 (host-qualified `--repo`). The product `#373` shim fix is still on `fork/dev`. App-only mint dies with: ``` t3-github-app-token: app is not installed on pingdotgg/t3code (or repo does not exist) ``` The App is installed on `patroza` / `macs-holding` / `effect-app` / `aaaomega` — not `pingdotgg`. This change passes through guest wrapper lines (`t3-github-app-token:` / `gh-app-wrapper:`) as the command-failed detail, and keeps raw provider stderr off the VCS error message (tokens stay out of logs). Installing the App on `pingdotgg` (or using a user/SSH token for those reads) is still required for the panel to actually load that PR. ## Test plan - [x] `vp test run apps/server/src/vcs/VcsProcess.test.ts apps/server/src/sourceControl/GitHubCli.test.ts` - [ ] After deploy: open a PR the App is not installed on and confirm the panel shows `app is not installed on …` instead of the generic CLI line - [ ] Confirm a `patroza/t3code` PR still loads on t3vm Co-authored-by: T3 Code PR Stack <41898282+github-actions[bot]@users.noreply.github.com>
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.
PR badges stopped appearing in sidebar v2 for active threads, while settled rows kept theirs.
Root-caused on the running server, fix verified against the exact failing invocation.
What was happening
The server's VCS shell-outs resolve
ghthrough each repo's.tools/bin— the agent policy shiminstalled by
scripts/install-git-hooks.mjs. Caught live off the server process:That shim resolves the binary to delegate to via
findRealGh, which preferred$T3_GITHUB_REAL_GHabove everything else. That variable names the unauthenticated
gh— the binary the GitHub Appwrapper execs after minting an installation token. The host exports it (see the server start
script: "still export REAL_GH / token paths so children that reorder PATH cannot lose minting
config") as configuration for the wrapper, not as an authenticated entry point.
So the shim skipped minting entirely and ran raw
gh:Exit 4 →
SourceControlProviderError→ the warning that has been filling the journal every 45s:Why settled rows still showed badges
That asymmetry is the tell. Settled worktrees take the durable settle freeze added in #362, which
returns
resolveLastKnownPr(...)without calling the provider at all. A frozen row can't fail alookup it never makes. Every active row goes down the live path, hits the auth failure, and falls
back to a last-known value that is empty — so the card renders with no badge.
Introduced by
2ef070919(2026-08-02, "enforce repository-owned agent ship gates"), which added theT3_GITHUB_REAL_GHbranch tofindRealGh.The fix
Resolution order becomes:
AGENT_GH_REAL— this shim's own re-entry override, unchanged.ghlives.T3_GITHUB_REAL_GH— last resort only, so hosts without a wrapper still work.Verification
The same command that returned exit 4, under the server's exact environment, after the change:
Regression test added to
scripts/agent-pre-push.test.mjspinning all three tiers of the order; itfails on the pre-fix implementation and passes after. Full file: 26 tests pass.
The deploy checkout was patched only to prove the fix live and has been restored to its released
state, so the fleet stays consistent with its deployed SHA until this lands.
Co-authored by @patroza
opened by Patrick Roza in chat thread Discord · Discord · T3