Skip to content

Repository identity has no forge dimension, so a repository that moves keeps answering from the host it left #133

Description

@jakewan

Context

Surfaced while planning a repository migration off GitHub onto a self-hosted forge, by an operator who drives this server from project-management skills that pass owner/repo. The question that produced it was what those skills would report once a repository no longer lives on GitHub. Deferred out of that planning work — nothing here has been observed in production.

Problem

A repository is addressed as owner/repo and resolved against exactly one host, and that host is not part of the address. The README states both halves: tools "resolve a single explicit owner/repo against that repo's manifest conventions", and issues are fetched "in-process from the GitHub GraphQL API" using "the operator's existing gh credentials". No host, base URL, or forge appears anywhere in a repository's identity.

Two consequences follow, and the second is the one worth filing.

No coverage for a repository hosted anywhere else. A repository on a self-hosted forge cannot be surveyed at all. This is the obvious gap, and it announces itself — a call fails, or returns nothing.

A repository that moves keeps answering, from a copy that stopped changing. This one does not announce itself. Where a migration leaves the GitHub repository in place — archived, or simply abandoned — the slug still resolves, and GitHub serves reads against an archived repository. So the server returns a complete, well-formed issue graph: milestones, dependency edges, staleness signals, recommendation inputs. Every field is populated. Every field is frozen at the moment that repository stopped being the live one. A consumer cannot distinguish that reading from a reading of the live project, because the two have identical shape.

The first consequence is a failure. The second is a wrong answer wearing a correct answer's clothes, which is the one that survives review.

Evidence

  • Tools "resolve a single explicit owner/repo against that repo's manifest conventions" (README).
  • Issues are fetched "in-process from the GitHub GraphQL API", authenticated with "the operator's existing gh credentials" (README).
  • Neither the README nor the tool surface exposes a host, base URL, or forge parameter.

What bounds any approach

Stated as constraints rather than as a design, because they change what each option costs:

  • The query layer is GraphQL. Forgejo and Gitea expose REST only, so a second backend is not a base-URL swap — composite reads become several calls each.
  • The credential path is gh. The GitHub CLI's host override targets GitHub Enterprise, so it does not reach a Forgejo instance; a second backend needs its own auth path rather than a redirected one.
  • The two halves separate cleanly. Knowing which forge a repository is on is a much smaller change than being able to talk to a second one — and it is the half that stops the silent-stale answer, since a repository marked as living elsewhere can be refused rather than answered wrongly, before any second backend exists.

Suggested approaches (options, not a prescription)

  • Carry the forge in a repository's identity — a host or forge field on the manifest entry — and refuse rather than answer when a repository is marked as living somewhere this server cannot reach.
  • Add a second backend behind the existing tool surface, so the reductions keep their shape across forges.
  • Neither, and document the boundary instead: state that a slug is resolved against GitHub unconditionally, so a consumer knows a stale-but-complete answer is possible.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions