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/extensions — the 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

Activity

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

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