docs(github): plan for a multi-org company bot - #800
Merged
Conversation
The bot lane collapses to one org today: `ensureBotToken` persists a single `github_installation_id` and, when unset, resolves it as `installations[0]` — whichever install GitHub returns first. With the App on two orgs the bot acts on one of them and 404s every repo in the other, with nothing failing at launch (the token is valid, it just doesn't cover that repo), so it reads to a human as "the agent can't see our repo". The stale-id retry re-picks `[0]` too, so a reinstall can flip which org works with no setting touched. The plan: an installation registry alongside the existing primary id (both plain settings rows — no migration, single-org tenants unchanged), a vault token cache keyed per installation, and a per-repo git credential helper that resolves the org out of git's `path=` (via `useHttpPath`) through a session-secret loopback route. The member OAuth lane already spans orgs and is deliberately left alone — the route refuses to hand a bot token to a run with a linked human, since that would re-author their PRs as the bot the moment they touched a second org. Also names the `gh` gap: `gh` ignores git credential helpers, so it needs its own tool (then, later, a shim). Docs only. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UfJRSqtHhuk7x51Cqy4NB5
This was referenced Sep 10, 2026
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.
The defect
GithubIdentity.ensureBotToken(src/edge/github-identity.ts:162) persists a singlegithub_installation_idand, when it is unset, resolves it asinstallations[0]— whichever installGET /app/installationshappens to return first — then caches one token blob under one vault key.With the App installed on two orgs the bot acts on exactly one of them and 404s every repo in the other. Nothing fails at launch (the token is valid, it just doesn't cover that repo), so it reads to a human as "the agent can't see our repo". The stale-id retry path re-picks
[0]as well, so a reinstall can flip which org works without anyone touching a setting.The per-member OAuth lane is unaffected — a user-to-server token already spans every org that member can reach.
What the plan specs
github_installationssetting alongside the existinggithub_installation_id, which keeps its exact meaning as the primary. Both are plainsettingsrows: no migration, and a one-org tenant behaves bit-for-bit as today.github_bot_token:<installationId>, with the legacy key migrated to the primary's suffixed key on first read.credential.https://github.com.useHttpPath=truemakes git passpath=<org>/<repo>to the helper, which resolves the right token through a new session-secret loopback route (modelled on/api/agent/github/refresh). Any failure falls back to$GH_TOKEN.agent-os[bot]the moment they touched a second org.ghgap, named —ghreadsGH_TOKENand ignores git credential helpers, so the helper fixesgitfor both orgs but notgh. Answer now is agithub_token({ org })MCP tool; a PATH shim that resolves the org fromoriginis sketched as a later PR.Four phases, each its own PR, plus the tests to add to
test:governance.Docs only — no behaviour change, no version bump (CHANGELOG note under Unreleased).
🤖 Generated with Claude Code
https://claude.ai/code/session_01UfJRSqtHhuk7x51Cqy4NB5