Skip to content

venfork setup: --fork-name is ignored; unrelated pre-existing repo at default fork name is silently reused #25

Description

@cabljac

Repro

Pre-state: an unrelated repo exists at invertase/extensions (last updated 2021, not a fork of anything, empty description).

cd /tmp/venfork-test
venfork setup git@github.com:firebase/extensions.git firebase-extensions-private \\
  --org invertase \\
  --fork-name firebase-extensions

Actual

venfork reports success:

◇  Public fork created
...
◇  Git Remote Configuration
│  origin    git@github.com:invertase/firebase-extensions-private.git (fetch/push)
│  public    git@github.com:invertase/extensions.git (fetch/push)
│  upstream  git@github.com:firebase/extensions.git (fetch)
│  upstream  DISABLE (push)
  • The private mirror invertase/firebase-extensions-private is correctly created and seeded from upstream. ✅
  • The `public` remote points at invertase/extensionsthe unrelated pre-existing repo, not a fork. ❌
  • invertase/firebase-extensions was never created, even though I passed --fork-name firebase-extensions.

Verify:

$ gh repo view invertase/extensions --json isFork,parent,updatedAt
{\"isFork\":false,\"parent\":null,\"updatedAt\":\"2021-05-21T09:15:43Z\"}

So invertase/extensions is confirmed not a fork of firebase/extensions (or anything). venfork silently "reused" it.

Expected

One of:

  1. `--fork-name` is actually passed through to `gh repo fork`, creating invertase/firebase-extensions as requested.
  2. If venfork's idempotent "reuse" path is triggered, it should verify the existing repo is a fork of the requested upstream before treating it as the public fork. If it isn't, error out loudly.

Both would be defensible; silently binding the local `public` remote to an unrelated repo is the worst of both.

Likely cause

Looks like the gh repo fork invocation in the "create public fork" step doesn't forward the --fork-name flag to gh, so gh repo fork falls back to the default fork name (upstream basename = extensions). GitHub returns "already exists" for invertase/extensions, venfork catches it as an idempotent success, and stores that URL as the public remote without further validation.

Impact

  • Low for my case: the cablclaw agent never pushes to public, so the misconfiguration is a latent footgun for future venfork stage calls rather than an immediate blocker.
  • Higher for any team that relies on venfork stage to promote work to the intended public fork — they'd silently push work to the wrong repo, or hit a permissions error, or (worst case) expose internal work to the wrong audience.

Suggested fixes (in order of minimum-viable):

  1. Pass --fork-name through to gh repo fork unconditionally when set.
  2. On the idempotent-reuse path, call gh repo view <fork-url> --json isFork,parent and refuse if parent.nameWithOwner != upstream.nameWithOwner.
  3. When neither of the above is possible (e.g. gh repo fork can't honor --fork-name for cross-org forks for some reason), fail loudly with a message like "cannot create public fork: invertase/extensions exists and is not a fork of firebase/extensions; pass --fork-name <different-name>".

Environment

  • venfork installed via npm install -g venfork on Node 22.20.0
  • macOS
  • gh 2.x

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions