Repository navigation
Name the Forge and move forge accounts into forge_identities - #1548
Closed
benrfairless wants to merge 3 commits into
Closed
benrfairless wants to merge 3 commits into
benrfairless wants to merge 3 commits into
Conversation
CONTEXT.md gains Forge (a service that hosts git repositories and authenticates their owners: GitHub or GitLab) and Forge identity (one Owner's account on one Forge), and Owner, Organization, Collaborator, Contributor and Scraper stop being defined in terms of GitHub. Two ADRs record the decisions behind #1546 that are hard to reverse and would puzzle a later reader: 0007, why GitLab repositories are reached through a preference order of credentials rather than one required kind; 0008, why an Owner can hold an identity on each forge while nickname stays the only slug. AGENTS.md and docs/agents/domain.md said there were no ADRs yet, which had been stale since 0001. Assisted-by: Claude Code:anthropic.claude-fable-5-1
An Owner's account on a forge (provider, uid, access_token) moves off the owners table into forge_identities, one row per Owner per forge, unique on (forge, uid) and on (owner_id, forge). This is what lets one Owner hold both a GitHub and a GitLab identity (ADR 0008). Existing rows are backfilled as GitHub identities; provider was only ever written as "github" and was nil on Organizations, so the uid alone decides. owners.nickname becomes unique, since it is the one slug behind every owner URL. The migration refuses to run if two Owners already share a nickname rather than choosing one silently. On scrapers, github_id becomes forge_repo_id, github_url becomes repo_url, and a forge column (default "github") says which forge the repository is on. User.find_for_github_oauth now finds a User by GitHub uid through the identity, and Organizations are found by GitHub id through Organization.find_or_create_from_github!, so a rename on GitHub no longer creates a second Owner. Assisted-by: Claude Code:anthropic.claude-fable-5-1
benrfairless
added this pull request to stack #1550
September 16, 2026 07:18
FactoryBot.lint with traits builds organization+on_github, whose GitHub identity takes its login from the nickname, and the factory had none. Assisted-by: Claude Code:anthropic.claude-fable-5-1
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.
Part of #1546. Second layer of the stack, on #1547.
What
Two commits. The first is words:
CONTEXT.mdgains Forge (a service that hosts git repositories and authenticates the people who own them: GitHub or GitLab) and Forge identity (one Owner's account on one Forge), and Owner, Organization, Collaborator, Contributor and Scraper stop being defined in terms of GitHub. Two ADRs record the decisions behind #1546 that are hard to reverse and would puzzle a later reader:nicknamestays the only slug. OAF needs to move scrapers from GitHub to GitLab without their URLs changing.The second is schema.
provider,uidandaccess_tokenmove offownersinto aforge_identitiestable, one row per Owner per forge, unique on(forge_key, uid)and(owner_id, forge_key). Existing rows are backfilled as GitHub identities.owners.nicknamebecomes unique, and the migration refuses to run if two Owners already share one rather than choosing silently. Onscrapers,github_idbecomesforge_repo_id,github_urlbecomesrepo_url, andforge_key(defaultgithub) says which forge the repository is on.User.find_for_github_oauthfinds a User by GitHub uid through the identity, and Organizations are found by GitHub id throughOrganization.find_or_create_from_github!, so a rename on GitHub no longer creates a second Owner.Verified
spec/models/forge_identity_spec.rbcovers sign-in creating and re-finding identities, uid collisions across forges, Organization lookup by GitHub id, and both uniqueness rules.make quick-testsgreen (853 examples, coverage 77.03%),rubocopclean.Notes for review
forge_key, notforge, so thatscraper.forgeandidentity.forgecan return the adapter object in Put a Forge seam between morph.io and GitHub #1549 without clashing with the attribute.AGENTS.mdanddocs/agents/domain.mdsaid there were no ADRs yet, which had been stale since 0001.Assisted-by: Claude Code:anthropic.claude-fable-5-1