Every import path requires that the source repository's GitHub owner is you, or
an organization whose namespace you hold. There is no way to bring in a public
repository someone else owns.
Where the gate is
Three layers, and only the third is the real one:
- The picker lists only your own.
OpenAgents.GitHub.repository_page/3
requests /user/repos with
affiliation=owner,collaborator,organization_member
(lib/openagents/github.ex:182), so RepositoryImportLive cannot show a
repository you have no affiliation with.
- Resolution does not gate.
GitHubProjection.import_source/2
(lib/openagents/repositories/github_projection.ex:71) takes any
owner/name and reads it with your token, so a public repository resolves
fine. This is not where the refusal happens.
- Creation gates on owner identity.
Repositories.create_user_import/4
requires source_owner_id == user.github_id
(lib/openagents/repositories.ex:288), and the organization path requires
source_owner_id == namespace.provider_account_id
(lib/openagents/repositories.ex:310). Otherwise
:source_namespace_mismatch.
Confirmed against production:
$ openagents repo import tobi/walgit --public
openagents: tobi is not an eligible GitHub namespace for this account.
$ openagents api user/repos/imports --method POST \
--input body.json -H "Idempotency-Key: $(uuidgen)"
HTTP 403 source_namespace_mismatch "Source namespace is not eligible"
The CLI message names the wrong thing — it reports the destination namespace
as ineligible when the destination was the personal namespace and the source
owner is what failed.
Why this is a decision, not a missing flag
Relaxing the check to "any repository your token can read" would let a public
repository owned by someone else become a repository owned by you on this
forge, with your name on it, no upstream recorded, and no statement of where
it came from. That is wrong in a way a flag does not fix.
What the forge is missing is a distinct upstream mirror: a repository whose
content comes from a public source it does not own, which
- names the upstream on every surface that shows the repository, so a reader is
never misled about origin,
- is one-way by construction. There is no push to
tobi/walgit, and nothing
should imply there is. Local pushes to a mirror must be refused rather than
silently diverging,
- carries the upstream's license, or records that none was found,
- keeps its own refs honest against
EXIT-004: a mirror is still a forge
repository, and a clone of it must serve. See #179 for what happens when a
repository arrives by a path that does not record its own boundary.
Whether a mirror refreshes on a schedule, on demand, or once is a second
question. Once is enough to close this issue; say what the others would need.
Done when
- A public repository owned by another account can be brought in through the
CLI and the API, as a mirror, with the upstream recorded and shown.
- The distinction between an owned repository and a mirror is visible in the
API response and on the repository page, not only in the database.
- A push to a mirror is refused with a message that says why.
openagents repo import reports the source owner when the source is what
failed, rather than naming the destination namespace.
- The existing owner-identity gate still refuses a source owned by someone else
for a normal import, and a proof asserts a mirror cannot be created by that
path.
Every import path requires that the source repository's GitHub owner is you, or
an organization whose namespace you hold. There is no way to bring in a public
repository someone else owns.
Where the gate is
Three layers, and only the third is the real one:
OpenAgents.GitHub.repository_page/3requests
/user/reposwithaffiliation=owner,collaborator,organization_member(
lib/openagents/github.ex:182), soRepositoryImportLivecannot show arepository you have no affiliation with.
GitHubProjection.import_source/2(
lib/openagents/repositories/github_projection.ex:71) takes anyowner/nameand reads it with your token, so a public repository resolvesfine. This is not where the refusal happens.
Repositories.create_user_import/4requires
source_owner_id == user.github_id(
lib/openagents/repositories.ex:288), and the organization path requiressource_owner_id == namespace.provider_account_id(
lib/openagents/repositories.ex:310). Otherwise:source_namespace_mismatch.Confirmed against production:
The CLI message names the wrong thing — it reports the destination namespace
as ineligible when the destination was the personal namespace and the source
owner is what failed.
Why this is a decision, not a missing flag
Relaxing the check to "any repository your token can read" would let a public
repository owned by someone else become a repository owned by you on this
forge, with your name on it, no upstream recorded, and no statement of where
it came from. That is wrong in a way a flag does not fix.
What the forge is missing is a distinct upstream mirror: a repository whose
content comes from a public source it does not own, which
never misled about origin,
tobi/walgit, and nothingshould imply there is. Local pushes to a mirror must be refused rather than
silently diverging,
EXIT-004: a mirror is still a forgerepository, and a clone of it must serve. See #179 for what happens when a
repository arrives by a path that does not record its own boundary.
Whether a mirror refreshes on a schedule, on demand, or once is a second
question. Once is enough to close this issue; say what the others would need.
Done when
CLI and the API, as a mirror, with the upstream recorded and shown.
API response and on the repository page, not only in the database.
openagents repo importreports the source owner when the source is whatfailed, rather than naming the destination namespace.
for a normal import, and a proof asserts a mirror cannot be created by that
path.