---
name: copy-github-collaboration-history
description: Copy GitHub repositories while reproducing native issues, pull requests, comments and their relationships with accurate provenance. Use for upstream-to-personal mirrors, collaboration-history imports, or repairing copies that contain Git history but lack GitHub discussions.
---

# Copy GitHub Collaboration History

Deliver actual issues, PRs and comments in the destination when requested. A Git
mirror, JSON archive or release attachment preserves useful data but does not
create GitHub collaboration objects. Keep private exports as recovery evidence;
do not substitute them for a requested native import.

## Resolve the intended copy

- Establish explicit `source owner/repo → destination owner/repo` pairs, access,
  destination visibility and whether the target already contains work. Do not
  guess upstreams from matching names or assume every repository in an account
  belongs to the same batch. Continue known pairs while clarifying unknown ones.
- Read destination instructions and preserve its existing branches, issues and
  unrelated work. Capture default-branch SHAs before writes. This skill does not
  authorize access expansion, public release, history rewriting or production
  merges beyond the user's request.
- Explain the key choice once: ordinary GitHub creation APIs cannot preserve
  native issue/PR/comment authors or backdate their timestamps. Original Git
  commit objects retain author/committer identities and dates. If original
  native metadata is required, investigate supported migration tooling and its
  account/organization requirements before creating approximate replacements.
- Agree on PR state handling: preserve original state by default. If the user
  explicitly wants all copied PRs merged, use isolated archive targets and retain
  original upstream status in the attribution. Do not convert an upstream
  unmerged PR into evidence of a historical merge, approval or CI pass.

## Inventory before mutation

Use authenticated `gh`, a GitHub connector, or equivalent APIs. The bundled
read-only helper works with `gh` and Python's standard library:

```bash
python3 scripts/inventory.py --repo OWNER/REPO --output /private/work/inventory.json
```

Run for each source and destination. It accounts for all paginated issue/PR
numbers, issue closing references and closing events, and ordered PR commits.
It does **not** export full descriptions, comments, review threads or binaries;
retrieve those separately using [the API procedure](references/api-procedure.md).

GitHub issues and PRs share one number sequence. Query **all states**, paginate
everything, distinguish the REST issues API's `pull_request` entries, and report
zero-result repositories explicitly. A jump from PR #8 to #30 may represent
issues #9–29, not missing PRs. Inaccessible/deleted objects remain coverage gaps.

Export required original bodies, comments, reviews, review comments, labels,
milestones and timelines to a private workspace before reconstruction. Preserve
source IDs/URLs, dates, states, actor identities and commit SHAs. Strip credentials
such as repository `temp_clone_token` recursively from raw API exports. Scan
content before publishing it; never reintroduce secrets removed from a cleaned
destination. If histories were rewritten, use a verified old→new SHA mapping and
report changed SHAs rather than claiming identical original commits.

## Reproduce with a complete mapping

1. Preserve necessary Git objects and refs using an isolated clone/bundle. Copy
   selected branches/tags without overwriting target refs. Audit accessible PR
   head/base/merge objects separately; `git push --mirror` does not create PRs and
   can delete destination refs. Never force-push merely to make an import work.
2. Maintain a durable per-object mapping containing source URL/type/number/node
   ID, destination URL/number/node ID, content fingerprint and completion state.
   Use a stable hidden marker in each imported body/comment. On rerun, find and
   verify that marker before creating anything. On an ambiguous write timeout,
   reread remote state before retrying; duplicate markers require investigation.
3. Allocate issues and PRs before the final reference-remapping pass. In a new,
   empty target, chronological shared-number creation can reduce renumbering,
   but do not promise exact numbers or create filler objects to imitate gaps.
   Existing target numbers cannot be reassigned through ordinary APIs.
4. Restore original titles and rendered Markdown. Add one small attribution
   line with upstream link, original author, original date and original status.
   Retain extra original dates in a hidden metadata comment if needed. Avoid
   repeated caveats, import headings, generated intent sections and wrapping the
   entire original description in a code fence when faithful copying is the goal.
5. Copy comments chronologically with one source/author/date line. Represent
   original approval/rejection as an attributed historical review, not a fresh
   approval by an impersonated reviewer. Preserve inline review path, line,
   original commit and thread context where supported; otherwise disclose a
   clearly attributed ordinary-comment fallback. Do not silently drop replies.
6. Remap bare `#N`, qualified `owner/repo#N`, URLs, comment anchors and commit
   references using the complete mapping. Preserve code samples and literals.
   Keep attribution links pointing **upstream**. If a comment/review has no native
   equivalent, use its mapped ordinary-comment anchor; never retain an upstream
   numeric comment ID on a destination URL. Uncopied references stay upstream.
   Use profile links for historical mentions to avoid unnecessary notifications.
   Resolve relative Markdown links/images against their original repository/ref;
   verify that the mapped file exists and renders. Retain an absolute source link
   when its asset was not copied instead of leaving a broken relative link.
7. Restore issue states and supported state reasons, labels and milestones.
   Avoid assigning or requesting fresh reviews from people just because they
   appeared historically. Record unsupported metadata as a coverage limitation.

### PR branches and merges

For each reconstructed PR, fetch/verify its original base and head commits and
compare the destination PR's **ordered commit list** against the source list.
Use separate `archive/upstream-pr-N/base` and `/head` branches when archival
merges are authorized. This preserves independent comparisons and keeps default
branches unchanged. Missing history, conflict, branch protection or failed
comparison is a real blocker; do not fabricate commits, resolve conflicts by
discarding code, disable protections, or claim success from branch creation.

Inspect branch-triggered workflows before pushing historical code: old workflow
files may execute even on an archive branch. Do not weaken Actions protections
to complete an import. Merge through the supported API only when explicitly
authorized; verify resulting merged state and commit set. New archive merge
commits have new identities and timestamps. Retain the original merge SHA in
private evidence, even when an old test-merge object is unavailable.

### Correct issue-to-PR relationships

Read `references/api-procedure.md` for exact queries and mutation examples.

- Use source `closedByPullRequestsReferences` for linked closing PRs and
  `ClosedEvent.closer` for what actually caused closure. Despite its name,
  `closedByPullRequestsReferences` can list a **still-open** proposed closing PR.
- Distinguish manual closure, commit-triggered closure, a merged closing PR, a
  proposed closing PR, and mere mentions. A commit appearing in a PR does not
  prove that PR closed the issue. Preserve the closing commit link and describe
  containing PRs as related unless stronger source evidence establishes closure.
- Map source relationship node IDs to destination IDs. Use
  `addCloseIssueReferences` for verified native Development links when supported.
  Do not invent a closing relationship for manually closed issues.
- Preserve the issue's original state after linking. An upstream-open issue stays
  open even if its copied PR was merged only for archival purposes. Check this
  immediately after mutation and again after PR-body reference updates.
- GitHub's historical closing actor/time and timeline events cannot be replayed
  by ordinary issue creation. Preserve them in concise attribution rather than
  claiming the new event is the original event.

## Verify and deliver

- Reread every destination title, body, comment, state/reason, label and relationship
  against the expected mapped source content. Compare ordered commit SHAs; equal
  SHAs establish equal intrinsic Git commit metadata. Verify desired merge state
  and unchanged protected/default refs.
- Reconcile a per-repository matrix: source/native issues, PRs, ordinary comments,
  reviews, inline threads, closing links, unavailable objects and unsupported
  surfaces. Reread sources for drift or identify the export cutoff explicitly.
- Check representative rendered issues/PRs and their Development links. API
  success or an archive upload alone is not evidence of a complete native copy.
- Deliver paired original/copy links, counts, and only material limitations.
  Leave incomplete repositories explicitly incomplete. Do not add skill-private
  source snapshots, credentials or personal data to a shareable skill package.
