Stop CLI Polling for Empty Mirrors

Claude Code·Opus 4.8[1m]·stiak·3mo ago·27min·2 Checkpoints·7 file changes·+257/-35·59.2K tokens

We're most of the way through a change where the CLI will stop polling if the mirror is known to be empty

3mo ago·5m

Understood — leaving it test-free, consistent with the existing RunE-flow convention.

The change is complete and verified. Final state of the working tree:

  • cmd/entire/cli/repo_mirror.go — skip polling + message when created.Empty
  • internal/coreapi/oas_json_gen.go, oas_schemas_gen.go — empty field (regenerated clean)
  • internal/coreapi/spec/core.openapi.json, core.gen.json — empty required on CreatedMirror
  • oas_security_gen.go — reverted (the 147 KB artifact is gone)

go build ./..., mise run lint (0 issues), and coreapi + mirror tests all pass. Nothing is committed — let me know if you'd like me to commit, or run the full mise run check before you push.

commit

3mo ago·6m

Committed on dont-poll-empty-mirrors as 93735addc:

repo mirror create: skip clone polling when upstream is empty

All 5 files (CLI + regenerated coreapi client + spec) are in one commit. mise run check passed before committing (the earlier FAIL was a flake that didn't reproduce). Let me know if you'd like me to push or open a PR.

Cursor said: "Empty skip hides suspension hint Medium Severity

When created.Empty is true, mirror create returns immediately and never runs waitForMirrorClone. For an existing placement (created false), that bypasses the repo-scoped token exchange that triggers explainSuspendedMirror on suspended mirrors—users can see a success-style empty-upstream message instead of the resume guidance.

"

Copilot said: "The new created.Empty early-return path isn’t covered by tests. Since repo_mirror_test.go exists for this command set, it’d be good to add a regression test that simulates a CreateMirror response with empty: true and asserts the command prints the “nothing to clone” note and does not enter the clone-wait/polling path."

3mo ago·10m

Both review comments are addressed and committed as 499e9abd0.

Cursor (the real bug — medium): An existing, suspended mirror with an empty upstream now still gets diagnosed. The early-return on Empty used to skip waitForMirrorClone, which is the only place the repo-scoped token exchange runs (and that exchange's invalid_target/ErrRepoTargetUnknown is what explainSuspendedMirror keys on). I split the flow into finishMirrorCreate:

  • Fresh empty create → print "nothing to clone", no probe, no poll (can't be suspended — suspension follows upstream access loss).
  • Existing empty mirror → run the token-exchange probe (surfaces suspension → resume guidance), but skip the HEAD-poll loop, since an empty repo never advertises a HEAD and would just spin to the timeout. This also preserves the no-poll win for the "re-run create on an empty repo" case.
  • Non-empty → unchanged: poll via waitForMirrorClone, which detects suspension itself.
  • A non-suspension probe error (e.g. transient network) stays non-fatal — the placement exists and is genuinely empty.

Copilot (test): Splitting the decision out with the probe and wait injected made it unit-testable without the auth/control-plane stack. TestFinishMirrorCreate covers all eight branches — including asserting the empty path never polls, a fresh create never probes, and a suspended empty mirror returns a SilentError with resume guidance instead of the success note.

mise run fmt, mise run lint (0 issues), and mise run test:ci all pass. The branch now has two commits: the original feature + this fix.