[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M77KBZJBGFSRPYTAS7YPM3AV":3,"skill-same:01M77KBZJBGFSRPYTAS7YPM3AV":44},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":19,"linkOnly":20,"markdownContent":21,"markdownBody":22,"frontMatter":23,"refName":24,"commitSha":25,"skillDirectory":26,"forksCount":14,"repositoryHtmlUrl":27,"repositoryHomepageUrl":6,"ownerHtmlUrl":28,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":29,"install":30,"resources":43},"01M77KBZJBGFSRPYTAS7YPM3AV","gh-repo-setup-public",null,"Promote a PRIVATE repo to genuinely PUBLIC: run the converge setup skills, re-assert the public posture (CODEOWNERS, conversation-resolution, issues\u002FPRs open to outside contributors, no unexpected collaborators), add public-facing docs\u002Fcommunity files, gate on history scrubbing, propose a clean rename, then flip visibility private -> public. The mirror skill is never run.","TheVoskamps\u002Fclaude-plugins-marketplace","TheVoskamps","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F235012489?v=4","01M77K5ZCP12QCJPQ85WVJSHTS","Irene and Edwin Voskamp","01M77K5ZDS7DB0PA1W8FM7G2QD",0,"GPL-3.0","https:\u002F\u002Fgithub.com\u002FTheVoskamps\u002Fclaude-plugins-marketplace\u002Fblob\u002Fmain\u002Fplugins\u002Fgithub-setup\u002Fskills\u002Fgh-repo-setup-public\u002FSKILL.md",[],[],"2026-11-15 14:19:17",false,"---\nname: gh-repo-setup-public\ndescription: \"Promote a PRIVATE repo to genuinely PUBLIC: run the converge setup skills, re-assert the public posture (CODEOWNERS, conversation-resolution, issues\u002FPRs open to outside contributors, no unexpected collaborators), add public-facing docs\u002Fcommunity files, gate on history scrubbing, propose a clean rename, then flip visibility private -> public. The mirror skill is never run.\"\n---\n\nYou are running the `\u002Fgh-repo-setup-public` skill. Your job is to\npromote the **current repo** (the repo `cd`-ed into when this skill was\ninvoked) from **private** to genuinely **public**: flip its visibility,\nrename it to a clean name, and nail down the public-appropriate posture.\n\nThis skill makes the **live repo itself** public. It is distinct from\n`\u002Frepo-public-mirror-setup`, which publishes a filtered, read-only\n*mirror* of a repo that stays private. The two are opposites — **this\nflow must never run `\u002Frepo-public-mirror-setup`.** This skill assumes\nno paired public mirror exists; retiring any mirror is the user's job\n(out of scope).\n\nFollow the steps in order. There are explicit **halts** where you wait\nfor the user. Do not skip them. The two consequential halts are the\n**scrub gate** (Step 5) and the **visibility flip** (Step 8); each\nrequires its own explicit approval.\n\n---\n\n## Owner identity\n\nThis skill's public posture pins a single code-owner: **`@evoskamp`**\n(whole-repo `* @evoskamp` CODEOWNERS). That handle is the canonical\nowner for repos this skill promotes; do not substitute the inferred\nrepo owner login for it. If a future caller needs a different\ncode-owner, that is a deliberate edit to this skill, not an inference.\n\n## Template payload (community files)\n\nThe community-file starters this skill installs — `LICENSE`,\n`PATENTS`, `PRIOR_ART.md` — are **reused from the\n`repo-public-mirror-setup` payload** rather than reinvented, per the\nissue. They live as templates under\n`${CLAUDE_PLUGIN_ROOT}\u002Fpayload\u002Frepo-public-mirror-setup\u002F`, following the\nbundled-payload convention (see `${CLAUDE_PLUGIN_ROOT}\u002Fpayload\u002FREADME.md`\nfor the placeholder\u002Frender\u002Fexistence-check contract). Treat that\ndirectory as `$PAYLOAD` for the rest of this skill.\n\n`README.md` and `CONTRIBUTORS` are **not** reused from that payload:\nthe mirror's versions carry a read-only banner and state \"PRs are not\naccepted\", which is exactly wrong for a live public repo that *welcomes*\nforks and PRs. This skill renders public-facing versions of those two\nitself (Step 4), and reuses only the content-appropriate\n`LICENSE` \u002F `PATENTS` \u002F `PRIOR_ART.md` starters.\n\nPlaceholders used by the reused templates:\n\n- `__GH_OWNER_NAME__` — human owner name in the `PATENTS` \u002F\n  `PRIOR_ART.md` prior-art notice. Prompted from the user (cannot be\n  inferred).\n- `__RELEASE_DATE__` — public-release date in the `PATENTS` \u002F\n  `PRIOR_ART.md` prior-art notice. Use today's date by default; confirm\n  with the user.\n\nRender with simple string substitution (the\n`${CLAUDE_PLUGIN_ROOT}\u002Fpayload\u002FREADME.md` reference recipe): read a\ntemplate with `Read`, replace each `__PLACEHOLDER__` with its resolved\nvalue, and write the result with `Write`. Never write a rendered file\nthat still contains a `__...__` placeholder — abort per the\n`${CLAUDE_PLUGIN_ROOT}\u002Fpayload\u002FREADME.md` \"Resolving placeholder values\"\nrule if any remains.\n\n---\n\n## Step 0: Payload\n\nThe community-file template payloads this skill reuses ship with the\nplugin at `${CLAUDE_PLUGIN_ROOT}\u002Fpayload\u002Frepo-public-mirror-setup\u002F`\n(`$PAYLOAD`). The placeholder\u002Frender convention is documented in\n`${CLAUDE_PLUGIN_ROOT}\u002Fpayload\u002FREADME.md`. If `$PAYLOAD` is missing,\nabort with the standard `${CLAUDE_PLUGIN_ROOT}\u002Fpayload\u002FREADME.md`\nexistence-check message.\n\n## Step 1: Pre-flight — repo root, auth, visibility\n\nVerify you are inside a git working tree and capture the root:\n\n```bash\ngit rev-parse --show-toplevel\n```\n\nTreat the path printed by this command as the **repo root** for the\nrest of the skill. The skill operates on the repo the user invoked it\nfrom. Do **not** assume `~\u002F.claude` or any other path.\n\nIf the command fails (non-zero exit, \"not a git repository\"), abort\nwith:\n\n> `\u002Fgh-repo-setup-public` must be run from inside a git repository.\n> The current directory is not a git working tree.\n\nVerify `gh` is authenticated (needed to read\u002Fedit settings, manage\ncollaborators, and flip visibility):\n\n```bash\ngh auth status\n```\n\nIf `gh` reports the user is not authenticated, abort and tell them to\nrun `gh auth login` first (with `repo` scope and admin rights on the\ntarget repo, since renaming and visibility changes require admin).\n\nRead the repo's current visibility:\n\n```bash\ngh repo view --json visibility -q .visibility\n```\n\n- If the value is `PRIVATE`: this is the intended use. Note it and\n  continue.\n- If the value is `PUBLIC`: the repo is already public. Report that the\n  visibility flip is already done, and ask whether the user still wants\n  to re-assert the public posture (Steps 2–4) and\u002For propose a rename\n  (Step 6). Do not re-flip. Skip the scrub gate (Step 5) and the flip\n  (Step 8) — there is nothing private left to expose.\n- If the value is `INTERNAL`: treat like `PRIVATE` for posture purposes\n  but surface that the flip will be `internal -> public`; confirm the\n  user intends a fully public repo before the Step 8 flip.\n\nCapture the owner and short name for later steps:\n\n```bash\ngh repo view --json owner,name -q '.owner.login + \"\u002F\" + .name'\n```\n\n## Step 2: Run the converge setup skills\n\nRun the two idempotent converge skills against this repo. They are\n**idempotent**, so just run them — do **not** add any \"has this been\nrun before?\" detection. **Do NOT** run `\u002Frepo-public-mirror-setup`.\n\n1. Run `\u002Fgh-repo-setup-protection`. This converges the Security &\n   Quality surface and the `protect-main` ruleset, including\n   `require_code_owner_review: true` and\n   `required_review_thread_resolution: true` — the conversation-\n   resolution and code-owner-review requirements this skill also owns\n   (Step 3 re-asserts them regardless).\n2. Run `\u002Fgh-repo-setup-pr-automation`. This installs the PR-automation\n   workflows.\n\nEach skill applies its remote settings directly and reports its own\nchanges; let it. **Do not assume a sub-skill leaves files uncommitted\nfor this orchestrator to bundle** — that assumption is gone. A sub-skill\nowns its own rendered files: it may render-and-commit them into its own\nPR, or it may leave them uncommitted, and which it does is the\nsub-skill's concern, not this orchestrator's. This orchestrator's job is\nto **adapt** to whatever each sub-skill did (Step 2a).\n\nIf either skill aborts on a pre-flight (e.g. missing GitHub App identity\nfor PR automation), surface its abort verbatim and stop — the user\nresolves it, then re-runs `\u002Fgh-repo-setup-public`.\n\n### Step 2a: For each sub-skill, detect whether it produced a PR\n\nAfter **each** sub-skill above returns, detect whether that sub-skill\n**opened a PR** for its own rendered files, and adapt:\n\n- **`\u002Fgh-repo-setup-protection`** opens a PR for its rendered files on\n  the `gh-repo-setup-protection` branch (a single approval covers its\n  commit, push, and PR; see that skill's Step 7). On a converged no-op\n  run it opens none.\n- **`\u002Fgh-repo-setup-pr-automation`** opens a PR for its rendered files on\n  the `gh-repo-setup-pr-automation` branch (a single approval covers its\n  commit, push, and PR; see that skill's Step 6b). On a converged no-op\n  run (no file changes) it opens none. This same detect-and-adapt path\n  covers it with no change here.\n\nDetect a sub-skill's PR generically — do not hard-code one skill's\nbranch name. The sub-skill reports its PR URL when it opens one; you can\nalso confirm against the live list of open PRs and match the branch the\nsub-skill is named after:\n\n```bash\n# Open PRs and their head branches; match the branch the sub-skill names\n# itself after (e.g. gh-repo-setup-protection), or the URL the sub-skill\n# reported.\ngh pr list --state open --json number,url,headRefName,title\n```\n\nFor each sub-skill **that produced a PR**, run the merge-decision prompt\n(Step 2b). A sub-skill that produced **no** PR (a converged no-op run,\nor a skill that does not yet open PRs) needs no such handling — there is\nnothing to merge — so skip the prompt for it.\n\n### Step 2b: Prompt to merge each sub-skill PR (proper merge, never blind)\n\nFor each detected sub-skill PR, ask the user whether this skill should\nmerge it now or leave it for the user:\n\n```text\n\u002F\u003Csub-skill> opened a PR for its rendered files:\n\n  \u003CPR URL>  (branch: \u003Chead-branch>)\n\n  (m) Merge it now — I will use the repo's configured merge method and\n      WAIT for required checks to pass before it merges.\n  (l) Leave it — you will merge it yourself.\n```\n\n- **If the user chooses leave** (`l`): record the PR URL for the\n  completion checklist (Step 9) and move on. Do not merge.\n- **If the user chooses merge** (`m`): perform a **proper** merge —\n  **never** a blind immediate merge. \"Proper\" means: respect the repo's\n  configured merge method and do not merge until required checks pass.\n  The repo's converged posture is merge-commit-only\n  (`\u002Fgh-repo-setup-protection` Step 4e sets `allow_squash_merge=false` \u002F\n  `allow_rebase_merge=false`, leaving merge-commit), so use the merge\n  method (`--merge`), and gate on checks via `--auto`:\n\n  ```bash\n  # Enable auto-merge with the repo's merge method; GitHub merges it\n  # only once required status checks pass and review requirements are\n  # met. This respects protect-main's required checks rather than\n  # bypassing them.\n  gh pr merge \u003CPR number or URL> --merge --auto\n  ```\n\n  If the repo does not have auto-merge enabled for some reason (it is\n  enabled by `\u002Fgh-repo-setup-protection` Step 4e), fall back to\n  poll-checks-then-merge: wait for the PR's required checks to report\n  success (`gh pr checks \u003CPR> --watch`), then `gh pr merge \u003CPR> --merge`.\n  Either way, **wait for checks** — do not merge a PR with pending or\n  failing required checks.\n\n  Report the outcome: \"merged (auto-merge enabled; will merge once checks\n  pass)\" or \"merged\" once it lands.\n\nThis detect-then-prompt-to-merge path is **generic** — it applies to any\nsub-skill that produces a PR, present or future. Both\n`\u002Fgh-repo-setup-protection` and `\u002Fgh-repo-setup-pr-automation` open their\nown PRs today, and each flows through this same path with no change here.\n\n## Step 3: Re-assert the public posture this skill owns\n\nThis skill is the **last word** on the settings that must be correct\nfor a public repo, regardless of what the setup skills left them at.\nDouble-ownership with `\u002Fgh-repo-setup-protection` is fine — re-assert\nanyway so this skill is self-contained.\n\nMost \"keep control\" guarantees are **free by default** on a public\nrepo: outside contributors are read-only. They can fork, open PRs (from\ntheir fork), file issues, and comment, but **cannot** push to branches,\nmerge, or edit\u002Fclose\u002Frelabel\u002Fassign issues — all of which need write\naccess this skill grants to nobody new. So this step mostly **verifies**\nrather than sets.\n\n### 3a. CODEOWNERS — whole-repo `* @evoskamp`\n\nEnsure a `CODEOWNERS` file exists with a single whole-repo rule\nassigning ownership to `@evoskamp`. The conventional location is\n`.github\u002FCODEOWNERS` (root and `docs\u002F` are also valid GitHub\nlocations). Read whichever exists; if none does, write\n`.github\u002FCODEOWNERS`. The required content is exactly:\n\n```text\n* @evoskamp\n```\n\nIf a `CODEOWNERS` exists with different content, report the difference\nand converge it to `* @evoskamp` (this skill's posture is whole-repo\nsingle-owner). Write the file uncommitted — the user reviews and\ncommits (global rule §0). Code-owner review is **required** via the\n`protect-main` ruleset's `require_code_owner_review: true`, which\n`\u002Fgh-repo-setup-protection` already set in Step 2; verify that rule is\npresent (read the ruleset back as that skill documents) and report if\nit is not.\n\n### 3b. Conversation resolution required before merge\n\nVerify the `protect-main` ruleset's `pull_request` rule has\n`required_review_thread_resolution: true` (\"Require conversation\nresolution before merging\"). `\u002Fgh-repo-setup-protection` sets this in\nStep 2; read the ruleset back and report `present`\u002F`missing`. If\nmissing (e.g. the protection skill was skipped or an org rule stripped\nit), re-assert it by PUTting the ruleset with the flag set, following\nthe protection skill's ruleset-converge shape — do not invent a new\nruleset.\n\n### 3c. Issues enabled and open to outside contributors\n\nEnsure Issues are enabled:\n\n```bash\ngh repo edit \u003Cowner>\u002F\u003Cshort> --enable-issues=true\n```\n\nOn a public repo, issue **filing** and **commenting** are open to any\nlogged-in GitHub user by default — that is the desired posture. Leave\nissue comments **open**: do **not** set an interaction limit. The\ninteraction-limit lever is blunt and would also block legitimate\nissue-filing, which defeats the purpose of a public repo. Outside\nusers still **cannot** edit, close, relabel, or assign issues without\nwrite access — those stay controlled for free.\n\n### 3d. PRs open to outside contributors\n\nPRs from forks are open to any user by default on a public repo;\nnothing to set. Outside contributors open PRs from their own fork and\n**cannot** push to this repo's branches or merge without write access.\nNo action beyond confirming the repo is not configured to forbid forks\n(forking is on by default; do not disable it).\n\n### 3e. Verify no unexpected outside collaborators\n\nThe real control check: confirm that no unexpected collaborators have\nwrite (or higher) access, since write access is what would let an\noutside party bypass every guarantee above. List direct collaborators\nand their permission:\n\n```bash\ngh api repos\u002F\u003Cowner>\u002F\u003Cshort>\u002Fcollaborators \\\n  --jq '.[] | {login: .login, permission: .role_name}'\n```\n\nReport the full list to the user. Expected: the owner (`admin`) and any\nintentional maintainers. **Do not remove anyone on your own\ninitiative** — flag any unexpected collaborator (especially `write`,\n`maintain`, or `admin` roles held by accounts the user does not\nrecognize) and ask the user whether to remove them. Removing a\ncollaborator is a posture decision the user owns. This step **verifies**\nand surfaces; it does not silently mutate the collaborator set.\n\n## Step 4: Add public-facing docs and community files\n\nRender or update the public-facing files below in the repo root (all\nuncommitted — the user reviews and commits). The two that are reused\nfrom the mirror payload (`LICENSE`, `PATENTS`, `PRIOR_ART.md`) are\ncontent-appropriate; `README.md` and `CONTRIBUTORS` are written here\nwith **public-repo** wording, not the mirror's read-only wording.\n\n### 4a. `README.md` — public contribution instructions\n\nIf `README.md` exists, **append** a public-facing \"Contributing\"\nsection rather than overwriting the existing content (preserve the\nproject's own README body). If it does not exist, create a minimal one.\nThe section tells outside contributors how to participate:\n\n```markdown\n## Contributing\n\nThis is a public repository. Contributions are welcome:\n\n- **Fork** the repository and create a feature branch from the default\n  branch.\n- **Open a pull request** from your fork. PRs require a passing CI run,\n  code-owner review (`@evoskamp`), and all review conversations\n  resolved before they can merge.\n- **File an issue** to report a bug or propose a change. Any logged-in\n  GitHub user can open and comment on issues.\n\nOutside contributors have read access: you can fork, open PRs from your\nfork, and file\u002Fcomment on issues. Push access, merging, and issue\ntriage are reserved for maintainers.\n```\n\nIf the repo already has a CONTRIBUTING.md or a contribution section,\nreconcile rather than duplicate — report what you found and converge to\nthe public-facing instructions above.\n\n### 4b. `CONTRIBUTORS` — public-facing version\n\nThe mirror payload's `CONTRIBUTORS.template` says \"Contributions are\nnot accepted in this mirror\", which is wrong for a live public repo.\nWrite a public-facing `CONTRIBUTORS` instead:\n\n```text\n# Contributors\n\nThis is a public repository and contributions are welcome — see the\n\"Contributing\" section of README.md for how to fork, open a pull\nrequest, and file issues.\n\nThis file deliberately does not embed a frozen contributor list: that\ndata is reproducible from the repository's own history and would go\nstale on every commit. To list contributors from the current history,\nrun:\n\n    git shortlog -sne\n```\n\n### 4c. `LICENSE` — reuse the mirror payload\n\nIf the repo already has a `LICENSE`, leave it as-is and report it. If\nit does not, render `$PAYLOAD\u002FLICENSE` (GPL v3, no placeholders) to\n`\u003Crepo-root>\u002FLICENSE`.\n\n### 4d. `PATENTS` and `PRIOR_ART.md` — reuse the mirror payload\n\nFor each of `PATENTS` and `PRIOR_ART.md`: if the repo already has the\nfile, leave it as-is and report it. If it does not, render the\ncorresponding `$PAYLOAD\u002FPATENTS` \u002F `$PAYLOAD\u002FPRIOR_ART.md` starter,\nsubstituting `__GH_OWNER_NAME__` (prompt the user) and `__RELEASE_DATE__`\n(default today's date; confirm). After rendering, confirm no `__...__`\nplaceholder remains.\n\n## Step 5: Halt — gate on history scrubbing\n\n**This halt must clear before the visibility flip (Step 8).** Once a\nrepo is public, its history is exposed instantly and irreversibly:\nGitHub caches, forks, crawlers, and the GH Archive dataset can all\ncapture it within minutes. Scrubbing **after** the flip does not\nun-expose what was already public. So the scrub must happen **before**\nthe flip, not after.\n\nAsk the user explicitly:\n\n```text\nBefore this repo goes public, its ENTIRE git history becomes visible —\nevery commit, every diff, every old file version, forever (caches,\nforks, crawlers).\n\nDoes this repo's history contain anything that must NOT be public?\nFor example:\n  - leaked secrets \u002F credentials \u002F tokens (these must also be ROTATED)\n  - private names, emails, or identifiers\n  - internal-only content, customer data, or paths\n\n  (y) Yes — history needs scrubbing first. I will STOP here.\n  (n) No — history is clean; proceed to rename and flip.\n```\n\n- If the user answers **yes** (history needs scrubbing): **hard-stop.**\n  Do not rename, do not flip. Point them at `\u002Fgh-repo-scrub-history`\n  (issue #93) to rewrite history before exposure, and tell them to\n  re-run `\u002Fgh-repo-setup-public` once the scrub is done:\n\n  > Stopping before the visibility flip. Run `\u002Fgh-repo-scrub-history`\n  > to rewrite the history (and ROTATE any leaked credential — a\n  > rewrite is not a substitute for rotation), then re-run\n  > `\u002Fgh-repo-setup-public`. The flip must not happen until the history\n  > is clean, because going public exposes the unscrubbed history\n  > immediately and irreversibly.\n\n  This skill does **not** perform the scrub itself — scrubbing lives\n  entirely in `\u002Fgh-repo-scrub-history`; this skill only gates on it.\n\n- If the user answers **no** (history is clean): record the explicit\n  confirmation and continue to Step 6. The flip in Step 8 is permitted\n  only because the user has confirmed here that no scrub is needed.\n\nDo not flip visibility until this gate is cleared with an explicit \"no\".\n\n## Step 6: Propose a cleaned repo name\n\nPropose a public-appropriate name by stripping private-signaling\nsuffixes from the current short name. Common suffixes to strip\n(case-insensitive, including a leading `-`):\n\n- `-private`\n- `-source`\n- `-mirrored-to-public`\n- `-mirror`, `-internal`, `-source-of-truth`, and similar\n  private\u002Finternal markers.\n\nCompute the proposed new name, then show the rename as `old -> new` and\nlet the user accept or edit:\n\n```text\nProposed rename (GitHub-side only):\n\n  \u003Cowner>\u002F\u003Cold-short>  ->  \u003Cowner>\u002F\u003Cnew-short>\n\nAccept this name, give me a different one, or say \"keep\" to leave the\nname unchanged.\n```\n\nIf stripping the suffixes leaves the name unchanged (no private-\nsignaling suffix present), say so and offer to keep the current name.\nWait for the user's choice. The rename is **GitHub-side only** — see\nStep 7.\n\n## Step 7: Rename the repo on GitHub (if the user chose a new name)\n\nIf the user accepted a new name in Step 6, rename the repo on GitHub:\n\n```bash\ngh repo rename \u003Cnew-short> --repo \u003Cowner>\u002F\u003Cold-short>\n```\n\nThis is a **GitHub-side rename only**. Do **not** touch the user's\nlocal checkout, remote, or directory. After the rename, tell the user\nto fix their local remote themselves:\n\n```text\nRenamed on GitHub: \u003Cowner>\u002F\u003Cold-short> -> \u003Cowner>\u002F\u003Cnew-short>\n\nUpdate your local clone's remote yourself (GitHub auto-redirects the\nold URL for a while, but update it to be safe):\n\n    git remote set-url origin git@github.com:\u003Cowner>\u002F\u003Cnew-short>.git\n\nRenaming the local directory is also up to you; this skill does not\ntouch your local checkout.\n```\n\nIf the user chose \"keep\", skip the rename and continue.\n\n## Step 8: Halt — flip visibility private -> public\n\nThis is the irreversible, consequential action. It runs **only after**\nthe scrub gate (Step 5) cleared with an explicit \"no\" and the rename\n(Steps 6–7) is settled. Confirm explicitly:\n\n```text\nAbout to flip \u003Cowner>\u002F\u003Cshort> from \u003Ccurrent-visibility> to PUBLIC.\n\nThis exposes the repo and its ENTIRE git history to the world,\nimmediately and irreversibly (caches\u002Fforks\u002Fcrawlers). You confirmed\nearlier that the history needs no scrubbing.\n\nPosture re-asserted:\n  - CODEOWNERS: * @evoskamp (code-owner review required)\n  - Conversation resolution required before merge\n  - Issues enabled, open to outside contributors (no interaction limit)\n  - PRs open to outside contributors (read-only; no write granted)\n  - Collaborators verified (no unexpected write access)\n\nFlip to PUBLIC now? (y to flip, or no to stop)\n```\n\nWait for explicit `y`\u002F`yes`. On approval, flip:\n\n```bash\ngh repo edit \u003Cowner>\u002F\u003Cshort> --visibility public --accept-visibility-change-consequences\n```\n\nThe `--accept-visibility-change-consequences` flag is required by `gh`\nto perform a private→public change non-interactively.\n\nIf the user declines, stop and leave the repo private — all the\nposture\u002Fdocs work from Steps 2–4 is still valid and uncommitted for the\nuser to review.\n\n## Step 9: Print the completion checklist\n\nAfter a successful flip, print:\n\n```text\nRepo is now PUBLIC.\n\nDone on GitHub:\n  - Visibility flipped to public (\u003Cowner>\u002F\u003Cshort>)\n  - \u003Crenamed to \u003Cnew-short> | name kept>\n  - Protection + PR-automation converged (gh-repo-setup-protection,\n    gh-repo-setup-pr-automation)\n  - Posture verified: CODEOWNERS * @evoskamp, conversation-resolution\n    required, issues\u002FPRs open to outside contributors, collaborators\n    checked\n\nSub-skill PRs:\n  - gh-repo-setup-protection:  \u003Cmerged | auto-merge enabled | left: URL | none>\n  - gh-repo-setup-pr-automation: \u003Cmerged | auto-merge enabled | left: URL | none>\n\nUncommitted in this repo (review and commit when ready):\n  - .github\u002FCODEOWNERS                 (if added\u002Fchanged)\n  - README.md                          (Contributing section)\n  - CONTRIBUTORS, LICENSE, PATENTS, PRIOR_ART.md   (as needed)\n  - any files a sub-skill left uncommitted (those that do not open a PR)\n\nNext steps:\n  1. Review the diff:    git status && git diff\n  2. Commit and push the docs\u002Fcommunity files and CODEOWNERS.\n  3. Merge any sub-skill PR you chose to leave (Step 2b).\n  4. Update your local remote if you renamed:\n       git remote set-url origin git@github.com:\u003Cowner>\u002F\u003Cnew-short>.git\n  5. If you retired a paired public mirror, do that by hand — this skill\n     does not touch mirrors.\n```\n\n---\n\n## Halts and approval gates (summary)\n\nThe skill **must** halt and wait for explicit user confirmation at:\n\n- **Step 2b — sub-skill PR merge prompt.** For each sub-skill that\n  produced a PR, the user chooses merge-now (proper merge, gated on\n  required checks) or leave-for-me. A sub-skill that produced no PR has\n  no prompt.\n- **Step 5 — scrub gate.** A hard-stop if the user says history needs\n  scrubbing; points at `\u002Fgh-repo-scrub-history`. The flip cannot\n  proceed without an explicit \"no, history is clean\".\n- **Step 6 — propose-rename.** The user accepts, edits, or keeps the\n  name before any rename.\n- **Step 8 — visibility flip.** The irreversible private→public change.\n  A separate approval from every prior step; \"yes\" earlier never\n  implies the flip.\n\nWhen the repo is already `PUBLIC` at Step 1, the scrub gate and the\nflip are skipped (there is nothing private left to expose); the rename\nand posture re-assertion are still offered.\n\n---\n\n## Hard constraints\n\n- **Never run `\u002Frepo-public-mirror-setup`.** This skill makes the live\n  repo public; the mirror skill publishes a read-only *mirror* of a\n  repo that stays private. They are opposites. Running the mirror skill\n  here is always wrong.\n- **Run the two converge skills unconditionally and without \"has it\n  run?\" detection.** `\u002Fgh-repo-setup-protection` and\n  `\u002Fgh-repo-setup-pr-automation` are idempotent — just run them\n  (Step 2).\n- **Adapt to each sub-skill's PR; never assume uncommitted bundling.**\n  A sub-skill owns its own rendered files. This orchestrator does **not**\n  assume a sub-skill leaves files uncommitted for it to bundle. After\n  each sub-skill runs, detect whether it produced a PR (Step 2a) and, if\n  it did, prompt the user to merge-now or leave (Step 2b). Never suppress\n  a sub-skill's PR with a flag. The detection is generic — it covers any\n  sub-skill that produces a PR (both `\u002Fgh-repo-setup-protection` and\n  `\u002Fgh-repo-setup-pr-automation` do so today).\n- **Merge a sub-skill PR only with a proper merge, never blind.** When\n  the user chooses to have this skill merge a sub-skill PR, respect the\n  repo's configured merge method (merge-commit, per the converged\n  posture) and **wait for required checks to pass** — `gh pr merge\n  --merge --auto`, or poll-checks-then-merge. Never an immediate blind\n  merge that bypasses `protect-main`'s required checks.\n- **Scrub before flip, never after.** The Step 5 scrub gate must clear\n  with an explicit \"no\" before the Step 8 flip. Going public exposes\n  the unscrubbed history immediately and irreversibly; scrubbing after\n  the flip does not un-expose it. This skill only gates on scrubbing —\n  the scrub itself lives in `\u002Fgh-repo-scrub-history` (issue #93).\n- **CODEOWNERS owner is `@evoskamp`.** Whole-repo `* @evoskamp`, with\n  code-owner review required via the `protect-main` ruleset. Do not\n  substitute the inferred repo-owner login.\n- **Leave issue comments open — no interaction limit.** The blunt\n  interaction-limit lever would also block legitimate issue-filing.\n  Outside users are read-only by default and cannot triage issues\n  without write access, which is the real control.\n- **Verify collaborators; never remove one on your own initiative.**\n  Step 3e lists collaborators and flags unexpected write access, but\n  removal is a posture decision the user owns.\n- **Reuse the mirror payload for `LICENSE` \u002F `PATENTS` \u002F `PRIOR_ART.md`;\n  write public-facing `README.md` \u002F `CONTRIBUTORS` yourself.** The\n  mirror's README\u002FCONTRIBUTORS say \"PRs not accepted\" — wrong for a\n  live public repo.\n- **GitHub-side rename only.** Step 7 renames on GitHub and tells the\n  user to fix their local remote\u002Fdirectory themselves. The skill never\n  touches the local checkout.\n- **Never write or commit this skill's own files for the user.** Steps\n  3–4 write *this skill's* files (CODEOWNERS, README section, community\n  files) uncommitted; the user reviews the diff and commits (global rule\n  §0). This is about the files this orchestrator renders itself — it does\n  not govern a sub-skill's own files, which the sub-skill owns and may\n  commit into its own PR (handled by Step 2a\u002F2b). Remote settings (issues\n  toggle, visibility flip, collaborator listing) are applied directly\n  because they are remote state, not file edits — and each consequential\n  remote change has its own halt.\n- **Never edit anything outside the current repo.** File writes go\n  under `\u003Crepo-root>\u002F` (`.github\u002FCODEOWNERS`, root `README.md`,\n  `CONTRIBUTORS`, `LICENSE`, `PATENTS`, `PRIOR_ART.md`). Templates are\n  **read** from `${CLAUDE_PLUGIN_ROOT}\u002Fpayload\u002Frepo-public-mirror-setup\u002F`\n  (read-only). Scratch work, if any, goes under\n  `\u003Crepo-root>\u002F.claude\u002Ftmp\u002Fgh-repo-setup-public\u002F`, never `\u002Ftmp\u002F`.\n\n---\n\n## Out of scope\n\n- **History scrubbing itself.** Lives in `\u002Fgh-repo-scrub-history`\n  (issue #93). This skill only gates on it (Step 5) and points at it;\n  it never rewrites history.\n- **Mirror handling.** This skill assumes no paired public mirror\n  exists. Retiring any mirror (`\u003Crepo>-public` and its plumbing) is the\n  user's job, done by hand.\n- **Local checkout cleanup.** The rename (Step 7) is GitHub-side only.\n  Fixing the local remote URL and directory name is the user's job.\n- **Credential rotation.** If the scrub gate surfaces a leaked\n  credential, the user rotates it (and runs `\u002Fgh-repo-scrub-history`);\n  the skill reminds but does not rotate.\n- **The converge skills' own scope.** GHAS toggles, Dependabot, CodeQL,\n  the `protect-main` ruleset, and the PR-automation workflows are owned\n  by `\u002Fgh-repo-setup-protection` and `\u002Fgh-repo-setup-pr-automation`;\n  this skill runs them (Step 2) but does not re-implement them.\n","You are running the `\u002Fgh-repo-setup-public` skill. Your job is to\npromote the **current repo** (the repo `cd`-ed into when this skill was\ninvoked) from **private** to genuinely **public**: flip its visibility,\nrename it to a clean name, and nail down the public-appropriate posture.\n\nThis skill makes the **live repo itself** public. It is distinct from\n`\u002Frepo-public-mirror-setup`, which publishes a filtered, read-only\n*mirror* of a repo that stays private. The two are opposites — **this\nflow must never run `\u002Frepo-public-mirror-setup`.** This skill assumes\nno paired public mirror exists; retiring any mirror is the user's job\n(out of scope).\n\nFollow the steps in order. There are explicit **halts** where you wait\nfor the user. Do not skip them. The two consequential halts are the\n**scrub gate** (Step 5) and the **visibility flip** (Step 8); each\nrequires its own explicit approval.\n\n---\n\n## Owner identity\n\nThis skill's public posture pins a single code-owner: **`@evoskamp`**\n(whole-repo `* @evoskamp` CODEOWNERS). That handle is the canonical\nowner for repos this skill promotes; do not substitute the inferred\nrepo owner login for it. If a future caller needs a different\ncode-owner, that is a deliberate edit to this skill, not an inference.\n\n## Template payload (community files)\n\nThe community-file starters this skill installs — `LICENSE`,\n`PATENTS`, `PRIOR_ART.md` — are **reused from the\n`repo-public-mirror-setup` payload** rather than reinvented, per the\nissue. They live as templates under\n`${CLAUDE_PLUGIN_ROOT}\u002Fpayload\u002Frepo-public-mirror-setup\u002F`, following the\nbundled-payload convention (see `${CLAUDE_PLUGIN_ROOT}\u002Fpayload\u002FREADME.md`\nfor the placeholder\u002Frender\u002Fexistence-check contract). Treat that\ndirectory as `$PAYLOAD` for the rest of this skill.\n\n`README.md` and `CONTRIBUTORS` are **not** reused from that payload:\nthe mirror's versions carry a read-only banner and state \"PRs are not\naccepted\", which is exactly wrong for a live public repo that *welcomes*\nforks and PRs. This skill renders public-facing versions of those two\nitself (Step 4), and reuses only the content-appropriate\n`LICENSE` \u002F `PATENTS` \u002F `PRIOR_ART.md` starters.\n\nPlaceholders used by the reused templates:\n\n- `__GH_OWNER_NAME__` — human owner name in the `PATENTS` \u002F\n  `PRIOR_ART.md` prior-art notice. Prompted from the user (cannot be\n  inferred).\n- `__RELEASE_DATE__` — public-release date in the `PATENTS` \u002F\n  `PRIOR_ART.md` prior-art notice. Use today's date by default; confirm\n  with the user.\n\nRender with simple string substitution (the\n`${CLAUDE_PLUGIN_ROOT}\u002Fpayload\u002FREADME.md` reference recipe): read a\ntemplate with `Read`, replace each `__PLACEHOLDER__` with its resolved\nvalue, and write the result with `Write`. Never write a rendered file\nthat still contains a `__...__` placeholder — abort per the\n`${CLAUDE_PLUGIN_ROOT}\u002Fpayload\u002FREADME.md` \"Resolving placeholder values\"\nrule if any remains.\n\n---\n\n## Step 0: Payload\n\nThe community-file template payloads this skill reuses ship with the\nplugin at `${CLAUDE_PLUGIN_ROOT}\u002Fpayload\u002Frepo-public-mirror-setup\u002F`\n(`$PAYLOAD`). The placeholder\u002Frender convention is documented in\n`${CLAUDE_PLUGIN_ROOT}\u002Fpayload\u002FREADME.md`. If `$PAYLOAD` is missing,\nabort with the standard `${CLAUDE_PLUGIN_ROOT}\u002Fpayload\u002FREADME.md`\nexistence-check message.\n\n## Step 1: Pre-flight — repo root, auth, visibility\n\nVerify you are inside a git working tree and capture the root:\n\n```bash\ngit rev-parse --show-toplevel\n```\n\nTreat the path printed by this command as the **repo root** for the\nrest of the skill. The skill operates on the repo the user invoked it\nfrom. Do **not** assume `~\u002F.claude` or any other path.\n\nIf the command fails (non-zero exit, \"not a git repository\"), abort\nwith:\n\n> `\u002Fgh-repo-setup-public` must be run from inside a git repository.\n> The current directory is not a git working tree.\n\nVerify `gh` is authenticated (needed to read\u002Fedit settings, manage\ncollaborators, and flip visibility):\n\n```bash\ngh auth status\n```\n\nIf `gh` reports the user is not authenticated, abort and tell them to\nrun `gh auth login` first (with `repo` scope and admin rights on the\ntarget repo, since renaming and visibility changes require admin).\n\nRead the repo's current visibility:\n\n```bash\ngh repo view --json visibility -q .visibility\n```\n\n- If the value is `PRIVATE`: this is the intended use. Note it and\n  continue.\n- If the value is `PUBLIC`: the repo is already public. Report that the\n  visibility flip is already done, and ask whether the user still wants\n  to re-assert the public posture (Steps 2–4) and\u002For propose a rename\n  (Step 6). Do not re-flip. Skip the scrub gate (Step 5) and the flip\n  (Step 8) — there is nothing private left to expose.\n- If the value is `INTERNAL`: treat like `PRIVATE` for posture purposes\n  but surface that the flip will be `internal -> public`; confirm the\n  user intends a fully public repo before the Step 8 flip.\n\nCapture the owner and short name for later steps:\n\n```bash\ngh repo view --json owner,name -q '.owner.login + \"\u002F\" + .name'\n```\n\n## Step 2: Run the converge setup skills\n\nRun the two idempotent converge skills against this repo. They are\n**idempotent**, so just run them — do **not** add any \"has this been\nrun before?\" detection. **Do NOT** run `\u002Frepo-public-mirror-setup`.\n\n1. Run `\u002Fgh-repo-setup-protection`. This converges the Security &\n   Quality surface and the `protect-main` ruleset, including\n   `require_code_owner_review: true` and\n   `required_review_thread_resolution: true` — the conversation-\n   resolution and code-owner-review requirements this skill also owns\n   (Step 3 re-asserts them regardless).\n2. Run `\u002Fgh-repo-setup-pr-automation`. This installs the PR-automation\n   workflows.\n\nEach skill applies its remote settings directly and reports its own\nchanges; let it. **Do not assume a sub-skill leaves files uncommitted\nfor this orchestrator to bundle** — that assumption is gone. A sub-skill\nowns its own rendered files: it may render-and-commit them into its own\nPR, or it may leave them uncommitted, and which it does is the\nsub-skill's concern, not this orchestrator's. This orchestrator's job is\nto **adapt** to whatever each sub-skill did (Step 2a).\n\nIf either skill aborts on a pre-flight (e.g. missing GitHub App identity\nfor PR automation), surface its abort verbatim and stop — the user\nresolves it, then re-runs `\u002Fgh-repo-setup-public`.\n\n### Step 2a: For each sub-skill, detect whether it produced a PR\n\nAfter **each** sub-skill above returns, detect whether that sub-skill\n**opened a PR** for its own rendered files, and adapt:\n\n- **`\u002Fgh-repo-setup-protection`** opens a PR for its rendered files on\n  the `gh-repo-setup-protection` branch (a single approval covers its\n  commit, push, and PR; see that skill's Step 7). On a converged no-op\n  run it opens none.\n- **`\u002Fgh-repo-setup-pr-automation`** opens a PR for its rendered files on\n  the `gh-repo-setup-pr-automation` branch (a single approval covers its\n  commit, push, and PR; see that skill's Step 6b). On a converged no-op\n  run (no file changes) it opens none. This same detect-and-adapt path\n  covers it with no change here.\n\nDetect a sub-skill's PR generically — do not hard-code one skill's\nbranch name. The sub-skill reports its PR URL when it opens one; you can\nalso confirm against the live list of open PRs and match the branch the\nsub-skill is named after:\n\n```bash\n# Open PRs and their head branches; match the branch the sub-skill names\n# itself after (e.g. gh-repo-setup-protection), or the URL the sub-skill\n# reported.\ngh pr list --state open --json number,url,headRefName,title\n```\n\nFor each sub-skill **that produced a PR**, run the merge-decision prompt\n(Step 2b). A sub-skill that produced **no** PR (a converged no-op run,\nor a skill that does not yet open PRs) needs no such handling — there is\nnothing to merge — so skip the prompt for it.\n\n### Step 2b: Prompt to merge each sub-skill PR (proper merge, never blind)\n\nFor each detected sub-skill PR, ask the user whether this skill should\nmerge it now or leave it for the user:\n\n```text\n\u002F\u003Csub-skill> opened a PR for its rendered files:\n\n  \u003CPR URL>  (branch: \u003Chead-branch>)\n\n  (m) Merge it now — I will use the repo's configured merge method and\n      WAIT for required checks to pass before it merges.\n  (l) Leave it — you will merge it yourself.\n```\n\n- **If the user chooses leave** (`l`): record the PR URL for the\n  completion checklist (Step 9) and move on. Do not merge.\n- **If the user chooses merge** (`m`): perform a **proper** merge —\n  **never** a blind immediate merge. \"Proper\" means: respect the repo's\n  configured merge method and do not merge until required checks pass.\n  The repo's converged posture is merge-commit-only\n  (`\u002Fgh-repo-setup-protection` Step 4e sets `allow_squash_merge=false` \u002F\n  `allow_rebase_merge=false`, leaving merge-commit), so use the merge\n  method (`--merge`), and gate on checks via `--auto`:\n\n  ```bash\n  # Enable auto-merge with the repo's merge method; GitHub merges it\n  # only once required status checks pass and review requirements are\n  # met. This respects protect-main's required checks rather than\n  # bypassing them.\n  gh pr merge \u003CPR number or URL> --merge --auto\n  ```\n\n  If the repo does not have auto-merge enabled for some reason (it is\n  enabled by `\u002Fgh-repo-setup-protection` Step 4e), fall back to\n  poll-checks-then-merge: wait for the PR's required checks to report\n  success (`gh pr checks \u003CPR> --watch`), then `gh pr merge \u003CPR> --merge`.\n  Either way, **wait for checks** — do not merge a PR with pending or\n  failing required checks.\n\n  Report the outcome: \"merged (auto-merge enabled; will merge once checks\n  pass)\" or \"merged\" once it lands.\n\nThis detect-then-prompt-to-merge path is **generic** — it applies to any\nsub-skill that produces a PR, present or future. Both\n`\u002Fgh-repo-setup-protection` and `\u002Fgh-repo-setup-pr-automation` open their\nown PRs today, and each flows through this same path with no change here.\n\n## Step 3: Re-assert the public posture this skill owns\n\nThis skill is the **last word** on the settings that must be correct\nfor a public repo, regardless of what the setup skills left them at.\nDouble-ownership with `\u002Fgh-repo-setup-protection` is fine — re-assert\nanyway so this skill is self-contained.\n\nMost \"keep control\" guarantees are **free by default** on a public\nrepo: outside contributors are read-only. They can fork, open PRs (from\ntheir fork), file issues, and comment, but **cannot** push to branches,\nmerge, or edit\u002Fclose\u002Frelabel\u002Fassign issues — all of which need write\naccess this skill grants to nobody new. So this step mostly **verifies**\nrather than sets.\n\n### 3a. CODEOWNERS — whole-repo `* @evoskamp`\n\nEnsure a `CODEOWNERS` file exists with a single whole-repo rule\nassigning ownership to `@evoskamp`. The conventional location is\n`.github\u002FCODEOWNERS` (root and `docs\u002F` are also valid GitHub\nlocations). Read whichever exists; if none does, write\n`.github\u002FCODEOWNERS`. The required content is exactly:\n\n```text\n* @evoskamp\n```\n\nIf a `CODEOWNERS` exists with different content, report the difference\nand converge it to `* @evoskamp` (this skill's posture is whole-repo\nsingle-owner). Write the file uncommitted — the user reviews and\ncommits (global rule §0). Code-owner review is **required** via the\n`protect-main` ruleset's `require_code_owner_review: true`, which\n`\u002Fgh-repo-setup-protection` already set in Step 2; verify that rule is\npresent (read the ruleset back as that skill documents) and report if\nit is not.\n\n### 3b. Conversation resolution required before merge\n\nVerify the `protect-main` ruleset's `pull_request` rule has\n`required_review_thread_resolution: true` (\"Require conversation\nresolution before merging\"). `\u002Fgh-repo-setup-protection` sets this in\nStep 2; read the ruleset back and report `present`\u002F`missing`. If\nmissing (e.g. the protection skill was skipped or an org rule stripped\nit), re-assert it by PUTting the ruleset with the flag set, following\nthe protection skill's ruleset-converge shape — do not invent a new\nruleset.\n\n### 3c. Issues enabled and open to outside contributors\n\nEnsure Issues are enabled:\n\n```bash\ngh repo edit \u003Cowner>\u002F\u003Cshort> --enable-issues=true\n```\n\nOn a public repo, issue **filing** and **commenting** are open to any\nlogged-in GitHub user by default — that is the desired posture. Leave\nissue comments **open**: do **not** set an interaction limit. The\ninteraction-limit lever is blunt and would also block legitimate\nissue-filing, which defeats the purpose of a public repo. Outside\nusers still **cannot** edit, close, relabel, or assign issues without\nwrite access — those stay controlled for free.\n\n### 3d. PRs open to outside contributors\n\nPRs from forks are open to any user by default on a public repo;\nnothing to set. Outside contributors open PRs from their own fork and\n**cannot** push to this repo's branches or merge without write access.\nNo action beyond confirming the repo is not configured to forbid forks\n(forking is on by default; do not disable it).\n\n### 3e. Verify no unexpected outside collaborators\n\nThe real control check: confirm that no unexpected collaborators have\nwrite (or higher) access, since write access is what would let an\noutside party bypass every guarantee above. List direct collaborators\nand their permission:\n\n```bash\ngh api repos\u002F\u003Cowner>\u002F\u003Cshort>\u002Fcollaborators \\\n  --jq '.[] | {login: .login, permission: .role_name}'\n```\n\nReport the full list to the user. Expected: the owner (`admin`) and any\nintentional maintainers. **Do not remove anyone on your own\ninitiative** — flag any unexpected collaborator (especially `write`,\n`maintain`, or `admin` roles held by accounts the user does not\nrecognize) and ask the user whether to remove them. Removing a\ncollaborator is a posture decision the user owns. This step **verifies**\nand surfaces; it does not silently mutate the collaborator set.\n\n## Step 4: Add public-facing docs and community files\n\nRender or update the public-facing files below in the repo root (all\nuncommitted — the user reviews and commits). The two that are reused\nfrom the mirror payload (`LICENSE`, `PATENTS`, `PRIOR_ART.md`) are\ncontent-appropriate; `README.md` and `CONTRIBUTORS` are written here\nwith **public-repo** wording, not the mirror's read-only wording.\n\n### 4a. `README.md` — public contribution instructions\n\nIf `README.md` exists, **append** a public-facing \"Contributing\"\nsection rather than overwriting the existing content (preserve the\nproject's own README body). If it does not exist, create a minimal one.\nThe section tells outside contributors how to participate:\n\n```markdown\n## Contributing\n\nThis is a public repository. Contributions are welcome:\n\n- **Fork** the repository and create a feature branch from the default\n  branch.\n- **Open a pull request** from your fork. PRs require a passing CI run,\n  code-owner review (`@evoskamp`), and all review conversations\n  resolved before they can merge.\n- **File an issue** to report a bug or propose a change. Any logged-in\n  GitHub user can open and comment on issues.\n\nOutside contributors have read access: you can fork, open PRs from your\nfork, and file\u002Fcomment on issues. Push access, merging, and issue\ntriage are reserved for maintainers.\n```\n\nIf the repo already has a CONTRIBUTING.md or a contribution section,\nreconcile rather than duplicate — report what you found and converge to\nthe public-facing instructions above.\n\n### 4b. `CONTRIBUTORS` — public-facing version\n\nThe mirror payload's `CONTRIBUTORS.template` says \"Contributions are\nnot accepted in this mirror\", which is wrong for a live public repo.\nWrite a public-facing `CONTRIBUTORS` instead:\n\n```text\n# Contributors\n\nThis is a public repository and contributions are welcome — see the\n\"Contributing\" section of README.md for how to fork, open a pull\nrequest, and file issues.\n\nThis file deliberately does not embed a frozen contributor list: that\ndata is reproducible from the repository's own history and would go\nstale on every commit. To list contributors from the current history,\nrun:\n\n    git shortlog -sne\n```\n\n### 4c. `LICENSE` — reuse the mirror payload\n\nIf the repo already has a `LICENSE`, leave it as-is and report it. If\nit does not, render `$PAYLOAD\u002FLICENSE` (GPL v3, no placeholders) to\n`\u003Crepo-root>\u002FLICENSE`.\n\n### 4d. `PATENTS` and `PRIOR_ART.md` — reuse the mirror payload\n\nFor each of `PATENTS` and `PRIOR_ART.md`: if the repo already has the\nfile, leave it as-is and report it. If it does not, render the\ncorresponding `$PAYLOAD\u002FPATENTS` \u002F `$PAYLOAD\u002FPRIOR_ART.md` starter,\nsubstituting `__GH_OWNER_NAME__` (prompt the user) and `__RELEASE_DATE__`\n(default today's date; confirm). After rendering, confirm no `__...__`\nplaceholder remains.\n\n## Step 5: Halt — gate on history scrubbing\n\n**This halt must clear before the visibility flip (Step 8).** Once a\nrepo is public, its history is exposed instantly and irreversibly:\nGitHub caches, forks, crawlers, and the GH Archive dataset can all\ncapture it within minutes. Scrubbing **after** the flip does not\nun-expose what was already public. So the scrub must happen **before**\nthe flip, not after.\n\nAsk the user explicitly:\n\n```text\nBefore this repo goes public, its ENTIRE git history becomes visible —\nevery commit, every diff, every old file version, forever (caches,\nforks, crawlers).\n\nDoes this repo's history contain anything that must NOT be public?\nFor example:\n  - leaked secrets \u002F credentials \u002F tokens (these must also be ROTATED)\n  - private names, emails, or identifiers\n  - internal-only content, customer data, or paths\n\n  (y) Yes — history needs scrubbing first. I will STOP here.\n  (n) No — history is clean; proceed to rename and flip.\n```\n\n- If the user answers **yes** (history needs scrubbing): **hard-stop.**\n  Do not rename, do not flip. Point them at `\u002Fgh-repo-scrub-history`\n  (issue #93) to rewrite history before exposure, and tell them to\n  re-run `\u002Fgh-repo-setup-public` once the scrub is done:\n\n  > Stopping before the visibility flip. Run `\u002Fgh-repo-scrub-history`\n  > to rewrite the history (and ROTATE any leaked credential — a\n  > rewrite is not a substitute for rotation), then re-run\n  > `\u002Fgh-repo-setup-public`. The flip must not happen until the history\n  > is clean, because going public exposes the unscrubbed history\n  > immediately and irreversibly.\n\n  This skill does **not** perform the scrub itself — scrubbing lives\n  entirely in `\u002Fgh-repo-scrub-history`; this skill only gates on it.\n\n- If the user answers **no** (history is clean): record the explicit\n  confirmation and continue to Step 6. The flip in Step 8 is permitted\n  only because the user has confirmed here that no scrub is needed.\n\nDo not flip visibility until this gate is cleared with an explicit \"no\".\n\n## Step 6: Propose a cleaned repo name\n\nPropose a public-appropriate name by stripping private-signaling\nsuffixes from the current short name. Common suffixes to strip\n(case-insensitive, including a leading `-`):\n\n- `-private`\n- `-source`\n- `-mirrored-to-public`\n- `-mirror`, `-internal`, `-source-of-truth`, and similar\n  private\u002Finternal markers.\n\nCompute the proposed new name, then show the rename as `old -> new` and\nlet the user accept or edit:\n\n```text\nProposed rename (GitHub-side only):\n\n  \u003Cowner>\u002F\u003Cold-short>  ->  \u003Cowner>\u002F\u003Cnew-short>\n\nAccept this name, give me a different one, or say \"keep\" to leave the\nname unchanged.\n```\n\nIf stripping the suffixes leaves the name unchanged (no private-\nsignaling suffix present), say so and offer to keep the current name.\nWait for the user's choice. The rename is **GitHub-side only** — see\nStep 7.\n\n## Step 7: Rename the repo on GitHub (if the user chose a new name)\n\nIf the user accepted a new name in Step 6, rename the repo on GitHub:\n\n```bash\ngh repo rename \u003Cnew-short> --repo \u003Cowner>\u002F\u003Cold-short>\n```\n\nThis is a **GitHub-side rename only**. Do **not** touch the user's\nlocal checkout, remote, or directory. After the rename, tell the user\nto fix their local remote themselves:\n\n```text\nRenamed on GitHub: \u003Cowner>\u002F\u003Cold-short> -> \u003Cowner>\u002F\u003Cnew-short>\n\nUpdate your local clone's remote yourself (GitHub auto-redirects the\nold URL for a while, but update it to be safe):\n\n    git remote set-url origin git@github.com:\u003Cowner>\u002F\u003Cnew-short>.git\n\nRenaming the local directory is also up to you; this skill does not\ntouch your local checkout.\n```\n\nIf the user chose \"keep\", skip the rename and continue.\n\n## Step 8: Halt — flip visibility private -> public\n\nThis is the irreversible, consequential action. It runs **only after**\nthe scrub gate (Step 5) cleared with an explicit \"no\" and the rename\n(Steps 6–7) is settled. Confirm explicitly:\n\n```text\nAbout to flip \u003Cowner>\u002F\u003Cshort> from \u003Ccurrent-visibility> to PUBLIC.\n\nThis exposes the repo and its ENTIRE git history to the world,\nimmediately and irreversibly (caches\u002Fforks\u002Fcrawlers). You confirmed\nearlier that the history needs no scrubbing.\n\nPosture re-asserted:\n  - CODEOWNERS: * @evoskamp (code-owner review required)\n  - Conversation resolution required before merge\n  - Issues enabled, open to outside contributors (no interaction limit)\n  - PRs open to outside contributors (read-only; no write granted)\n  - Collaborators verified (no unexpected write access)\n\nFlip to PUBLIC now? (y to flip, or no to stop)\n```\n\nWait for explicit `y`\u002F`yes`. On approval, flip:\n\n```bash\ngh repo edit \u003Cowner>\u002F\u003Cshort> --visibility public --accept-visibility-change-consequences\n```\n\nThe `--accept-visibility-change-consequences` flag is required by `gh`\nto perform a private→public change non-interactively.\n\nIf the user declines, stop and leave the repo private — all the\nposture\u002Fdocs work from Steps 2–4 is still valid and uncommitted for the\nuser to review.\n\n## Step 9: Print the completion checklist\n\nAfter a successful flip, print:\n\n```text\nRepo is now PUBLIC.\n\nDone on GitHub:\n  - Visibility flipped to public (\u003Cowner>\u002F\u003Cshort>)\n  - \u003Crenamed to \u003Cnew-short> | name kept>\n  - Protection + PR-automation converged (gh-repo-setup-protection,\n    gh-repo-setup-pr-automation)\n  - Posture verified: CODEOWNERS * @evoskamp, conversation-resolution\n    required, issues\u002FPRs open to outside contributors, collaborators\n    checked\n\nSub-skill PRs:\n  - gh-repo-setup-protection:  \u003Cmerged | auto-merge enabled | left: URL | none>\n  - gh-repo-setup-pr-automation: \u003Cmerged | auto-merge enabled | left: URL | none>\n\nUncommitted in this repo (review and commit when ready):\n  - .github\u002FCODEOWNERS                 (if added\u002Fchanged)\n  - README.md                          (Contributing section)\n  - CONTRIBUTORS, LICENSE, PATENTS, PRIOR_ART.md   (as needed)\n  - any files a sub-skill left uncommitted (those that do not open a PR)\n\nNext steps:\n  1. Review the diff:    git status && git diff\n  2. Commit and push the docs\u002Fcommunity files and CODEOWNERS.\n  3. Merge any sub-skill PR you chose to leave (Step 2b).\n  4. Update your local remote if you renamed:\n       git remote set-url origin git@github.com:\u003Cowner>\u002F\u003Cnew-short>.git\n  5. If you retired a paired public mirror, do that by hand — this skill\n     does not touch mirrors.\n```\n\n---\n\n## Halts and approval gates (summary)\n\nThe skill **must** halt and wait for explicit user confirmation at:\n\n- **Step 2b — sub-skill PR merge prompt.** For each sub-skill that\n  produced a PR, the user chooses merge-now (proper merge, gated on\n  required checks) or leave-for-me. A sub-skill that produced no PR has\n  no prompt.\n- **Step 5 — scrub gate.** A hard-stop if the user says history needs\n  scrubbing; points at `\u002Fgh-repo-scrub-history`. The flip cannot\n  proceed without an explicit \"no, history is clean\".\n- **Step 6 — propose-rename.** The user accepts, edits, or keeps the\n  name before any rename.\n- **Step 8 — visibility flip.** The irreversible private→public change.\n  A separate approval from every prior step; \"yes\" earlier never\n  implies the flip.\n\nWhen the repo is already `PUBLIC` at Step 1, the scrub gate and the\nflip are skipped (there is nothing private left to expose); the rename\nand posture re-assertion are still offered.\n\n---\n\n## Hard constraints\n\n- **Never run `\u002Frepo-public-mirror-setup`.** This skill makes the live\n  repo public; the mirror skill publishes a read-only *mirror* of a\n  repo that stays private. They are opposites. Running the mirror skill\n  here is always wrong.\n- **Run the two converge skills unconditionally and without \"has it\n  run?\" detection.** `\u002Fgh-repo-setup-protection` and\n  `\u002Fgh-repo-setup-pr-automation` are idempotent — just run them\n  (Step 2).\n- **Adapt to each sub-skill's PR; never assume uncommitted bundling.**\n  A sub-skill owns its own rendered files. This orchestrator does **not**\n  assume a sub-skill leaves files uncommitted for it to bundle. After\n  each sub-skill runs, detect whether it produced a PR (Step 2a) and, if\n  it did, prompt the user to merge-now or leave (Step 2b). Never suppress\n  a sub-skill's PR with a flag. The detection is generic — it covers any\n  sub-skill that produces a PR (both `\u002Fgh-repo-setup-protection` and\n  `\u002Fgh-repo-setup-pr-automation` do so today).\n- **Merge a sub-skill PR only with a proper merge, never blind.** When\n  the user chooses to have this skill merge a sub-skill PR, respect the\n  repo's configured merge method (merge-commit, per the converged\n  posture) and **wait for required checks to pass** — `gh pr merge\n  --merge --auto`, or poll-checks-then-merge. Never an immediate blind\n  merge that bypasses `protect-main`'s required checks.\n- **Scrub before flip, never after.** The Step 5 scrub gate must clear\n  with an explicit \"no\" before the Step 8 flip. Going public exposes\n  the unscrubbed history immediately and irreversibly; scrubbing after\n  the flip does not un-expose it. This skill only gates on scrubbing —\n  the scrub itself lives in `\u002Fgh-repo-scrub-history` (issue #93).\n- **CODEOWNERS owner is `@evoskamp`.** Whole-repo `* @evoskamp`, with\n  code-owner review required via the `protect-main` ruleset. Do not\n  substitute the inferred repo-owner login.\n- **Leave issue comments open — no interaction limit.** The blunt\n  interaction-limit lever would also block legitimate issue-filing.\n  Outside users are read-only by default and cannot triage issues\n  without write access, which is the real control.\n- **Verify collaborators; never remove one on your own initiative.**\n  Step 3e lists collaborators and flags unexpected write access, but\n  removal is a posture decision the user owns.\n- **Reuse the mirror payload for `LICENSE` \u002F `PATENTS` \u002F `PRIOR_ART.md`;\n  write public-facing `README.md` \u002F `CONTRIBUTORS` yourself.** The\n  mirror's README\u002FCONTRIBUTORS say \"PRs not accepted\" — wrong for a\n  live public repo.\n- **GitHub-side rename only.** Step 7 renames on GitHub and tells the\n  user to fix their local remote\u002Fdirectory themselves. The skill never\n  touches the local checkout.\n- **Never write or commit this skill's own files for the user.** Steps\n  3–4 write *this skill's* files (CODEOWNERS, README section, community\n  files) uncommitted; the user reviews the diff and commits (global rule\n  §0). This is about the files this orchestrator renders itself — it does\n  not govern a sub-skill's own files, which the sub-skill owns and may\n  commit into its own PR (handled by Step 2a\u002F2b). Remote settings (issues\n  toggle, visibility flip, collaborator listing) are applied directly\n  because they are remote state, not file edits — and each consequential\n  remote change has its own halt.\n- **Never edit anything outside the current repo.** File writes go\n  under `\u003Crepo-root>\u002F` (`.github\u002FCODEOWNERS`, root `README.md`,\n  `CONTRIBUTORS`, `LICENSE`, `PATENTS`, `PRIOR_ART.md`). Templates are\n  **read** from `${CLAUDE_PLUGIN_ROOT}\u002Fpayload\u002Frepo-public-mirror-setup\u002F`\n  (read-only). Scratch work, if any, goes under\n  `\u003Crepo-root>\u002F.claude\u002Ftmp\u002Fgh-repo-setup-public\u002F`, never `\u002Ftmp\u002F`.\n\n---\n\n## Out of scope\n\n- **History scrubbing itself.** Lives in `\u002Fgh-repo-scrub-history`\n  (issue #93). This skill only gates on it (Step 5) and points at it;\n  it never rewrites history.\n- **Mirror handling.** This skill assumes no paired public mirror\n  exists. Retiring any mirror (`\u003Crepo>-public` and its plumbing) is the\n  user's job, done by hand.\n- **Local checkout cleanup.** The rename (Step 7) is GitHub-side only.\n  Fixing the local remote URL and directory name is the user's job.\n- **Credential rotation.** If the scrub gate surfaces a leaked\n  credential, the user rotates it (and runs `\u002Fgh-repo-scrub-history`);\n  the skill reminds but does not rotate.\n- **The converge skills' own scope.** GHAS toggles, Dependabot, CodeQL,\n  the `protect-main` ruleset, and the PR-automation workflows are owned\n  by `\u002Fgh-repo-setup-protection` and `\u002Fgh-repo-setup-pr-automation`;\n  this skill runs them (Step 2) but does not re-implement them.\n",{"name":5,"description":7},"main","4b187366f06afb374243166f6a0f5fc1514fa579","plugins\u002Fgithub-setup\u002Fskills\u002Fgh-repo-setup-public","https:\u002F\u002Fgithub.com\u002FTheVoskamps\u002Fclaude-plugins-marketplace","https:\u002F\u002Fgithub.com\u002FTheVoskamps","2026-11-14 13:16:57",{"source":8,"skillName":5,"commands":31,"prompt":41,"zipAvailable":42},[32,35,38],{"tool":33,"command":34},"npx","npx skills add TheVoskamps\u002Fclaude-plugins-marketplace --skill gh-repo-setup-public",{"tool":36,"command":37},"bunx","bunx skills add TheVoskamps\u002Fclaude-plugins-marketplace --skill gh-repo-setup-public",{"tool":39,"command":40},"pnpm","pnpm dlx skills add TheVoskamps\u002Fclaude-plugins-marketplace --skill gh-repo-setup-public","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FTheVoskamps\u002Fclaude-plugins-marketplace\u002Fblob\u002Fmain\u002Fplugins\u002Fgithub-setup\u002Fskills\u002Fgh-repo-setup-public\u002FSKILL.md",true,[],[45,52,59,66,73,80],{"skillNo":46,"name":47,"nameZh":6,"description":48,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":49,"categories":50,"keywords":51,"publishedAt":19},"01M77KH3GAXPPXNQS96KDEEZBS","mask-inappropriate-language","Replace inappropriate language (profanity, slurs, strong insults) in provided text or a file with asterisks, character-for-character, preserving everything else.","https:\u002F\u002Fgithub.com\u002FTheVoskamps\u002Fclaude-plugins-marketplace\u002Fblob\u002Fmain\u002Fplugins\u002Fwriting-tools\u002Fskills\u002Fmask-inappropriate-language\u002FSKILL.md",[],[],{"skillNo":53,"name":54,"nameZh":6,"description":55,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":56,"categories":57,"keywords":58,"publishedAt":19},"01M77KGY5TZDQT8QR23Y0R8P7A","theorem-agents-interface","The interface between the sdlc reviewer and the theorem agents it spawns — what each double-dash brief parameter means, and what each consequence class means. Preloaded into every theorem agent (sdlc:theorem-generator, the disprover, and the verifier) via its skills frontmatter, and read by name by the sdlc:theorem-based-pr-reviewer agent for what its briefs' parameters mean; not invoked from the user's slash menu.","https:\u002F\u002Fgithub.com\u002FTheVoskamps\u002Fclaude-plugins-marketplace\u002Fblob\u002Fmain\u002Fplugins\u002Fsdlc\u002Fskills\u002Ftheorem-agents-interface\u002FSKILL.md",[],[],{"skillNo":60,"name":61,"nameZh":6,"description":62,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":63,"categories":64,"keywords":65,"publishedAt":19},"01M77KGT5HW0XAE500WSSM0PZY","sdlc-config-user","Interactively create or merge-update the repo user sdlc config, `\u003Crepo-root>\u002F.sdlc\u002Fuser-config.yml` (tier 3 — this user, this repo, never committed), and add it to the repo's tracked `.gitignore`.","https:\u002F\u002Fgithub.com\u002FTheVoskamps\u002Fclaude-plugins-marketplace\u002Fblob\u002Fmain\u002Fplugins\u002Fsdlc\u002Fskills\u002Fsdlc-config-user\u002FSKILL.md",[],[],{"skillNo":67,"name":68,"nameZh":6,"description":69,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":70,"categories":71,"keywords":72,"publishedAt":19},"01M77KGQGQVB0NYZX0WJRJPDEK","sdlc-config-repo","Interactively create or merge-update the shared repo sdlc config, `\u003Crepo-root>\u002F.sdlc\u002Frepo-config.yml` (tier 2 — tracked, every user of this repo).","https:\u002F\u002Fgithub.com\u002FTheVoskamps\u002Fclaude-plugins-marketplace\u002Fblob\u002Fmain\u002Fplugins\u002Fsdlc\u002Fskills\u002Fsdlc-config-repo\u002FSKILL.md",[],[],{"skillNo":74,"name":75,"nameZh":6,"description":76,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":77,"categories":78,"keywords":79,"publishedAt":19},"01M77KGKPEN7C5RCEDSEP3Z1XB","sdlc-config-global","Interactively create or merge-update the global user sdlc config, `$XDG_CONFIG_HOME\u002Fsdlc\u002Fuser-config.yml` (tier 1 — this user, every repo on this machine).","https:\u002F\u002Fgithub.com\u002FTheVoskamps\u002Fclaude-plugins-marketplace\u002Fblob\u002Fmain\u002Fplugins\u002Fsdlc\u002Fskills\u002Fsdlc-config-global\u002FSKILL.md",[],[],{"skillNo":81,"name":82,"nameZh":6,"description":83,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":84,"categories":85,"keywords":86,"publishedAt":19},"01M77KGFX95J2XEQBBD49QHTXK","pr-read-cli-interface","The contract for sdlc's PR-read CLIs — sdlc-pr-round, sdlc-pr-adjustments, sdlc-fixer-brief and sdlc-records-chain — their arguments, exit codes and output grammar. Preloaded into sdlc:theorem-based-pr-reviewer, sdlc:issue-fixer, sdlc:docs-writer and sdlc:pr-finalizer via their skills frontmatter; not invoked from the user's slash menu.","https:\u002F\u002Fgithub.com\u002FTheVoskamps\u002Fclaude-plugins-marketplace\u002Fblob\u002Fmain\u002Fplugins\u002Fsdlc\u002Fskills\u002Fpr-read-cli-interface\u002FSKILL.md",[],[]]