[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6XDMVHGG3H6NKBARY588C58":3,"skill-same:01M6XDMVHGG3H6NKBARY588C58":85},{"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":39,"linkOnly":40,"markdownContent":41,"markdownBody":42,"frontMatter":43,"refName":65,"commitSha":66,"skillDirectory":67,"forksCount":14,"repositoryHtmlUrl":68,"repositoryHomepageUrl":6,"ownerHtmlUrl":69,"ownerBlogUrl":6,"ownerDescription":70,"updatedAt":71,"install":72,"resources":84},"01M6XDMVHGG3H6NKBARY588C58","release-conductor",null,"Gate the open release-please PR before merging: verify CI green, feature PRs landed, no release blockers, changelog reflects intent. One-word approval, then merge. Reports the resulting release.yml run URL. release-please owns the changelog\u002Fbump\u002Ftag; release.yml owns OIDC npm publish — this skill only gates the merge in between. Triggers on: \"ship a release\", \"cut a release\", \"merge the release PR\", \"is the release ready\", \"verify the release\".","kaiohenricunha\u002Fdotbabel","kaiohenricunha","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F69804490?v=4","01M6XCZD37W0KPCDGEA40Y610V","Kaio Cunha","01M6XCZD7SX714D114H3ZPNW09",0,"MIT","https:\u002F\u002Fgithub.com\u002Fkaiohenricunha\u002Fdotbabel\u002Fblob\u002Fmain\u002Fskills\u002Frelease-conductor\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38],"release conductor","release","conductor","ready","URL","false","please","green","intent","reports","bump","review","only","Bash","open","publish","ci","actions","changelog","run","2026-11-10 10:12:30",false,"---\nid: release-conductor\nname: release-conductor\ntype: skill\nversion: 1.0.0\ndomain:\n  - devex\nplatform:\n  - github-actions\ntask:\n  - review\n  - runtime-ops\nmaturity: draft\nowner: \"@kaiohenricunha\"\ncreated: 2026-05-26T00:00:00.000Z\nupdated: 2026-08-07T00:00:00.000Z\ndescription: |\n  Gate the open release-please PR before merging: verify CI green, feature PRs landed, no release blockers, changelog reflects intent. One-word approval, then merge. Reports the resulting release.yml run URL. release-please owns the changelog\u002Fbump\u002Ftag; release.yml owns OIDC npm publish — this skill only gates the merge in between. Triggers on: \"ship a release\", \"cut a release\", \"merge the release PR\", \"is the release ready\", \"verify the release\".\nargument-hint: \"[verify \u003Ctag>]\"\nmodel: sonnet\nuser-invocable: true\ndisable-model-invocation: true\nheadless_safe: false\nallowed-tools: Read Bash Grep Glob\ndotbabel:\n  compute:\n    mode: inherit\n    binding: consumer\n---\n\nGate the open release-please PR before merging. release-please drafts the changelog and version bump; `release.yml` handles OIDC npm publish on tag push. This skill is the human-in-the-loop step between them: verifies the PR is safe to merge, then merges it.\n\nTrigger: when the user says \"ship a release\", \"cut a release\", \"merge the release PR\", \"is the release ready\", or invokes `\u002Frelease-conductor`. Also `\u002Frelease-conductor verify \u003Ctag>` for post-publish smoke test.\n\nArguments: `$ARGUMENTS` — optional subcommand:\n\n- (empty) — full gate + merge flow on the currently open release-please PR.\n- `verify \u003Ctag>` — post-publish smoke test for a published tag (e.g. `verify v2.8.0`).\n\n**Lifecycle:**\n\n```\nfeature PRs merged → release-please opens release PR → \u002Frelease-conductor (gate + merge) → release.yml (OIDC publish) → \u002Frelease-conductor verify \u003Ctag>\n```\n\n## Steps\n\n### 0. Refresh local refs, then branch on subcommand\n\nIf `$ARGUMENTS` starts with `verify`, jump to the **`verify` subcommand** section below — it reads only from `gh` and needs no local git state.\n\nOtherwise refresh before anything reads local git state:\n\n```bash\ngit fetch origin main --tags --prune-tags\n```\n\n**This is load-bearing — do not skip it.** Steps 4 and 5 derive `LAST_TAG` from local tags and diff against `origin\u002Fmain`. On a clone whose tags are stale, every downstream number is wrong _and still looks plausible_: the bump comparison, the \"PRs merged since last tag\" list, and the commit-type check all describe the wrong release window, and nothing blocks — the gate reports READY on a false picture.\n\nObserved in practice: a clone three tags behind reported the bump as `2.10.0 → 2.13.0` with 23 landed PRs, when the truth was `2.12.0 → 2.13.0` with 3.\n\nThen continue with the gate + merge flow.\n\n### 1. Find the open release-please PR\n\n```bash\ngh pr list --state open --search \"head:release-please--\" \\\n  --json number,title,headRefName,mergeable,mergeStateStatus,labels,body\n```\n\n- **Zero matches.** Check what's accumulated since the last tag:\n\n  ```bash\n  # Requires the step 0 fetch — stale tags here mean the wrong commit window.\n  LAST_TAG=$(git tag --list 'v*' --sort=-version:refname | head -1)\n  [ -n \"$LAST_TAG\" ] || { echo \"no v* tag found — run: git fetch origin --tags\"; exit 1; }\n  git log \"$LAST_TAG\"..origin\u002Fmain --oneline --no-merges\n  ```\n\n  If the log contains `feat:` \u002F `fix:` \u002F `perf:` \u002F `refactor:` commits but no PR is open, suggest:\n\n  ```bash\n  gh run list --workflow=release-please.yml --limit 3\n  ```\n\n  release-please may have failed or not run. STOP and surface the most recent run.\n\n  If the log contains only `chore:` \u002F `style:` \u002F `test:` \u002F `build:` \u002F `ci:` \u002F `docs:` commits, report:\n  `no shippable changes — release-please correctly held off.` STOP.\n\n- **One match.** Record `RELEASE_PR=$pr_number` and continue.\n\n- **Multiple matches.** STOP and ask the user which to ship — this signals a release-please config issue (multi-package monorepo without `include-component-in-tag`, etc.).\n\n### 2. Show what's being shipped\n\n```bash\ngh pr view $RELEASE_PR --json title,body | jq -r '.title, .body'\ngh pr diff $RELEASE_PR -- CHANGELOG.md | head -120\ngh pr view $RELEASE_PR --json files --jq '.files[].path'\n```\n\nReport:\n\n- PR title (release-please format: `chore(main): release X.Y.Z`)\n- The changelog section being added (first ~120 lines of the diff)\n- Files changed by the PR (should be `CHANGELOG.md`, `package.json`, `.release-please-manifest.json`, and any post-bump regen — `index\u002F`, `docs\u002F` stamps)\n\n### 3. Verify CI on the release PR\n\n```bash\ngh pr checks $RELEASE_PR\n```\n\n- Any check `failing` → STOP. Print the failing check names; tell the user to address them before re-running.\n- Any check `pending` → STOP. Tell the user to wait for CI to finish.\n- All checks pass → continue.\n\nSanity check on `main`:\n\n```bash\ngh run list --branch main --limit 5 --json conclusion,name,createdAt\n```\n\nIf the most recent run on `main` is failing, surface as **WARNING** (not blocking) — release.yml will run against the tag, not `main`, so a stale main failure won't break publish, but it's worth knowing.\n\n### 4. Verify no release blockers and feature PRs landed\n\n```bash\n# Requires the step 0 fetch. A stale tag here silently shifts the whole\n# release window: wrong bump, wrong landed-PR list, wrong commit-type check.\nLAST_TAG=$(git tag --list 'v*' --sort=-version:refname | head -1)\n[ -n \"$LAST_TAG\" ] || { echo \"no v* tag found — run: git fetch origin --tags\"; exit 1; }\nLAST_TAG_DATE=$(git log -1 --format=%cI \"$LAST_TAG\")\n\n# Feature PRs merged since last tag\ngh pr list --state merged --search \"merged:>$LAST_TAG_DATE base:main\" \\\n  --limit 50 --json number,title,headRefName,labels\n\n# Open PRs flagged as blockers\ngh pr list --state open --search \"label:release-blocker,do-not-release,wip\" \\\n  --json number,title,labels\n```\n\n- Report count of feature PRs merged since `$LAST_TAG`.\n- Any open PR with `release-blocker` or `do-not-release` label → STOP. Surface the PR numbers.\n- Any **merged** PR with those labels (mistakes happen) → surface as WARNING.\n\n### 5. Sanity-check the bump\n\n```bash\nPREV_VERSION=${LAST_TAG#v}\nNEW_VERSION=$(gh pr view $RELEASE_PR --json title --jq .title \\\n  | grep -oE '[0-9]+\\.[0-9]+\\.[0-9]+' | head -1)\necho \"Bump: $PREV_VERSION → $NEW_VERSION\"\n```\n\nInspect conventional-commit types since last tag:\n\n```bash\ngit log \"$LAST_TAG\"..origin\u002Fmain --pretty=format:'%s%n%b' --no-merges \\\n  | grep -E '^(feat|fix|perf|refactor|docs)(\\(.+\\))?!?:|BREAKING CHANGE:' \\\n  | sort -u\n```\n\nExpected bump (post-1.0):\n\n- `feat!:` or `BREAKING CHANGE:` anywhere → **major**\n- `feat:` (no breaking) → **minor**\n- `fix:` \u002F `perf:` \u002F `refactor:` only → **patch**\n\nFor pre-1.0 packages, read `release-please-config.json` — `bump-minor-pre-major` promotes major→minor; `bump-patch-for-minor-pre-major` promotes minor→patch.\n\nIf release-please's bump diverges from expectation, surface as **WARNING** with the divergence (likely config). Do not block — release-please's config is the source of truth.\n\n### 6. Go\u002Fno-go summary\n\n```\nRelease-conductor: PR #$RELEASE_PR — $PREV_VERSION → $NEW_VERSION\n\n  Step 2 — Files:           CHANGELOG.md, package.json, .release-please-manifest.json, …\n  Step 3 — CI release PR:   ✓ green\n                         |  ✗ failing: \u003Cnames> (BLOCKED)\n                         |  ⏳ pending (BLOCKED — wait)\n  Step 3 — CI main:         ✓ green\n                         |  ⚠ recent failures (not blocking publish)\n  Step 4 — Blockers:        none\n                         |  ✗ open: PR #N (label) (BLOCKED)\n  Step 4 — Landed PRs:      N feature PRs since $LAST_TAG\n  Step 5 — Bump:            ✓ matches commit types\n                         |  ⚠ release-please chose $NEW_VERSION, expected $EXPECTED (\u003Creason>)\n\nStatus: READY — say \"ship\" to merge PR #$RELEASE_PR (squash) and trigger release.yml.\n     |  BLOCKED — \u003Creason>. Fix and re-run \u002Frelease-conductor.\n```\n\n### 7. Merge on explicit approval\n\nWait for the user to say `ship`, `merge`, `go`, or `lgtm`. CI green alone is not authorization.\n\nOn approval:\n\n```bash\ngh pr merge $RELEASE_PR --squash --delete-branch\n```\n\nIf the repo overrides merge method (check `.github\u002Fsettings.yml` or repo settings UI), follow the override and note it in the report.\n\n### 8. Report the publish pipeline run\n\nrelease-please's GitHub Action creates the `v$NEW_VERSION` tag immediately after merge; the tag push fires `release.yml`. Report the most recent runs so the user can track:\n\n```bash\nTAG=\"v$NEW_VERSION\"\ngh run list --workflow=release.yml --limit 3 \\\n  --json url,headBranch,status,conclusion,createdAt\n```\n\nDo not poll. Print:\n\n```\nMerged PR #$RELEASE_PR ($PREV_VERSION → $NEW_VERSION)\nTag should appear shortly: $TAG\nTrack release.yml above. Once it shows ✓ success:\n  \u002Frelease-conductor verify $TAG\n```\n\n## `verify \u003Ctag>` subcommand\n\nPost-publish verification. No gating, no merge — three registry checks, plus\ndeploy status and smoke checks when the repository declares a deploy target.\n\n```bash\nTAG=$(echo \"$ARGUMENTS\" | awk '{print $2}')\nVERSION=${TAG#v}\nPKG=$(node -p \"require('.\u002Fpackage.json').name\")\n\n# 1. release.yml conclusion for this tag\ngh run list --workflow=release.yml --branch \"$TAG\" --limit 1 \\\n  --json conclusion,url,databaseId\n\n# 2. npm has the version\nnpm view \"$PKG@$VERSION\" version dist.tarball\n\n# 3. GitHub release exists\ngh release view \"$TAG\" --json url,publishedAt,name\n```\n\nThen deploy status and smoke (Flow 5). **Do not gate this on\n`.claude\u002Fdeploy-targets.json`** — the helper also auto-discovers targets from\n`.vercel\u002Fproject.json` and `fly.toml`, so a file-existence gate would report\nSKIPPED for a Vercel or Fly repository that has a real, checkable deployment.\nLet the helper decide what exists and report its verdict:\n\n```bash\n# 4 + 5. Deploy status, then smoke — the published artifact existing is not\n# the same as the deployed thing answering. Status runs FIRST: it establishes\n# which revision is live, and a smoke pass against a drifted revision is a\n# pass for the wrong artifact.\n#\n# The same three-branch resolution deploy-status and smoke-test use. The\n# `elif` guard and the `exit 2` branch are both load-bearing: without the\n# guard this would run a CWD-relative script the checked-out repository\n# controls, and without the exit a missing helper would fall through to the\n# FAIL path and recommend rolling back a healthy deployment.\nif [ -f \"$HOME\u002F.claude\u002Fskills\u002Fdeploy-status\u002Fscripts\u002Fdeploy-ops.mjs\" ]; then\n  DEPLOY_OPS=\"$HOME\u002F.claude\u002Fskills\u002Fdeploy-status\u002Fscripts\u002Fdeploy-ops.mjs\"\nelif [ -f \"skills\u002Fdeploy-status\u002Fscripts\u002Fdeploy-ops.mjs\" ]; then\n  DEPLOY_OPS=\"skills\u002Fdeploy-status\u002Fscripts\u002Fdeploy-ops.mjs\"\nelse\n  echo \"deploy-status helper not found; re-run dotbabel bootstrap or dotbabel init\" >&2\n  exit 2\nfi\n\nnode \"$DEPLOY_OPS\" status\nnode \"$DEPLOY_OPS\" smoke\n```\n\nReport PASS \u002F FAIL per check. Specifics:\n\n- **release.yml conclusion** — `success` = PASS. `in_progress` = \"still running, retry in ~60s.\" `failure` = FAIL, print URL.\n- **npm view** — exit 0 = PASS. 404 = \"not yet propagated (npm CDN lag, up to ~60s).\" Other error = FAIL.\n- **gh release view** — exit 0 = PASS. `release not found` = FAIL.\n- **deploy status** — exit 0 = PASS. Drift (exit 1) = FAIL. Discovery finding no target, or the helper itself being unavailable (**exit 2**) = **SKIPPED**, never FAIL: a tool-availability problem is not a production problem, and reporting it as one would recommend rolling back a deployment that is fine.\n- **smoke** — read the `verdict`, not only the exit code. `pass` = PASS. `fail` = FAIL. `not_configured` (no target declares checks) and `not_run` (a dry run) = **SKIPPED**, never PASS: both exit 0 without having verified anything.\n\n**When no deploy target exists, report deploy status and smoke as SKIPPED** —\nnever as PASS. The helper decides that, not a file-existence check: it reports\nexit 2 when discovery finds nothing and a `not_configured` verdict when no\ntarget declares smoke checks. Either way nothing was checked, so nothing\npassed. Reporting PASS for a check that never ran is the failure mode this\nwhole subcommand exists to avoid, and it is invisible in the output.\n\nOn any FAIL from deploy status or smoke, **recommend `\u002Frollback-prod` and\nstop** (KD-13). Do not invoke it: rolling back is a production change and needs\nan explicit human instruction, and `\u002Frollback-prod` requires its own typed\nconfirmation on top of that.\n\n## Rules\n\n- **Never reimplement release-please.** This skill does not write CHANGELOG.md, bump versions, or create tags. release-please owns that; this skill only gates the merge of release-please's PR.\n- **Never publish to npm directly.** OIDC publish happens in `release.yml` on tag push. The skill stops at `gh pr merge`.\n- **Require explicit verbal approval.** `ship` \u002F `merge` \u002F `go` \u002F `lgtm`. CI green alone is not authorization.\n- **One release PR at a time.** Multiple open `release-please--*` PRs → stop and ask. Likely a config issue.\n- **Squash merge by default.** Matches `\u002Fmerge-pr` convention. Repo override (if any) wins, but record it.\n- **No polling.** Print the run URL and exit. Use `verify \u003Ctag>` later.\n- **Never roll back from this skill.** `verify` recommends `\u002Frollback-prod` on a failure and stops; the rollback itself stays an explicit human call.\n- **Never report an unrun check as PASS.** Absent deploy targets, a `not_configured` smoke verdict, and a dry run are all SKIPPED.\n- **Pre-1.0 bump checks read config.** Don't assume semver — `release-please-config.json` may have `bump-minor-pre-major` flags that alter the expected bump.\n- **Always fetch tags before reading them.** `LAST_TAG` comes from the local tag list; a stale clone yields a wrong release window that still reports READY. Step 0's fetch is not optional.\n","Gate the open release-please PR before merging. release-please drafts the changelog and version bump; `release.yml` handles OIDC npm publish on tag push. This skill is the human-in-the-loop step between them: verifies the PR is safe to merge, then merges it.\n\nTrigger: when the user says \"ship a release\", \"cut a release\", \"merge the release PR\", \"is the release ready\", or invokes `\u002Frelease-conductor`. Also `\u002Frelease-conductor verify \u003Ctag>` for post-publish smoke test.\n\nArguments: `$ARGUMENTS` — optional subcommand:\n\n- (empty) — full gate + merge flow on the currently open release-please PR.\n- `verify \u003Ctag>` — post-publish smoke test for a published tag (e.g. `verify v2.8.0`).\n\n**Lifecycle:**\n\n```\nfeature PRs merged → release-please opens release PR → \u002Frelease-conductor (gate + merge) → release.yml (OIDC publish) → \u002Frelease-conductor verify \u003Ctag>\n```\n\n## Steps\n\n### 0. Refresh local refs, then branch on subcommand\n\nIf `$ARGUMENTS` starts with `verify`, jump to the **`verify` subcommand** section below — it reads only from `gh` and needs no local git state.\n\nOtherwise refresh before anything reads local git state:\n\n```bash\ngit fetch origin main --tags --prune-tags\n```\n\n**This is load-bearing — do not skip it.** Steps 4 and 5 derive `LAST_TAG` from local tags and diff against `origin\u002Fmain`. On a clone whose tags are stale, every downstream number is wrong _and still looks plausible_: the bump comparison, the \"PRs merged since last tag\" list, and the commit-type check all describe the wrong release window, and nothing blocks — the gate reports READY on a false picture.\n\nObserved in practice: a clone three tags behind reported the bump as `2.10.0 → 2.13.0` with 23 landed PRs, when the truth was `2.12.0 → 2.13.0` with 3.\n\nThen continue with the gate + merge flow.\n\n### 1. Find the open release-please PR\n\n```bash\ngh pr list --state open --search \"head:release-please--\" \\\n  --json number,title,headRefName,mergeable,mergeStateStatus,labels,body\n```\n\n- **Zero matches.** Check what's accumulated since the last tag:\n\n  ```bash\n  # Requires the step 0 fetch — stale tags here mean the wrong commit window.\n  LAST_TAG=$(git tag --list 'v*' --sort=-version:refname | head -1)\n  [ -n \"$LAST_TAG\" ] || { echo \"no v* tag found — run: git fetch origin --tags\"; exit 1; }\n  git log \"$LAST_TAG\"..origin\u002Fmain --oneline --no-merges\n  ```\n\n  If the log contains `feat:` \u002F `fix:` \u002F `perf:` \u002F `refactor:` commits but no PR is open, suggest:\n\n  ```bash\n  gh run list --workflow=release-please.yml --limit 3\n  ```\n\n  release-please may have failed or not run. STOP and surface the most recent run.\n\n  If the log contains only `chore:` \u002F `style:` \u002F `test:` \u002F `build:` \u002F `ci:` \u002F `docs:` commits, report:\n  `no shippable changes — release-please correctly held off.` STOP.\n\n- **One match.** Record `RELEASE_PR=$pr_number` and continue.\n\n- **Multiple matches.** STOP and ask the user which to ship — this signals a release-please config issue (multi-package monorepo without `include-component-in-tag`, etc.).\n\n### 2. Show what's being shipped\n\n```bash\ngh pr view $RELEASE_PR --json title,body | jq -r '.title, .body'\ngh pr diff $RELEASE_PR -- CHANGELOG.md | head -120\ngh pr view $RELEASE_PR --json files --jq '.files[].path'\n```\n\nReport:\n\n- PR title (release-please format: `chore(main): release X.Y.Z`)\n- The changelog section being added (first ~120 lines of the diff)\n- Files changed by the PR (should be `CHANGELOG.md`, `package.json`, `.release-please-manifest.json`, and any post-bump regen — `index\u002F`, `docs\u002F` stamps)\n\n### 3. Verify CI on the release PR\n\n```bash\ngh pr checks $RELEASE_PR\n```\n\n- Any check `failing` → STOP. Print the failing check names; tell the user to address them before re-running.\n- Any check `pending` → STOP. Tell the user to wait for CI to finish.\n- All checks pass → continue.\n\nSanity check on `main`:\n\n```bash\ngh run list --branch main --limit 5 --json conclusion,name,createdAt\n```\n\nIf the most recent run on `main` is failing, surface as **WARNING** (not blocking) — release.yml will run against the tag, not `main`, so a stale main failure won't break publish, but it's worth knowing.\n\n### 4. Verify no release blockers and feature PRs landed\n\n```bash\n# Requires the step 0 fetch. A stale tag here silently shifts the whole\n# release window: wrong bump, wrong landed-PR list, wrong commit-type check.\nLAST_TAG=$(git tag --list 'v*' --sort=-version:refname | head -1)\n[ -n \"$LAST_TAG\" ] || { echo \"no v* tag found — run: git fetch origin --tags\"; exit 1; }\nLAST_TAG_DATE=$(git log -1 --format=%cI \"$LAST_TAG\")\n\n# Feature PRs merged since last tag\ngh pr list --state merged --search \"merged:>$LAST_TAG_DATE base:main\" \\\n  --limit 50 --json number,title,headRefName,labels\n\n# Open PRs flagged as blockers\ngh pr list --state open --search \"label:release-blocker,do-not-release,wip\" \\\n  --json number,title,labels\n```\n\n- Report count of feature PRs merged since `$LAST_TAG`.\n- Any open PR with `release-blocker` or `do-not-release` label → STOP. Surface the PR numbers.\n- Any **merged** PR with those labels (mistakes happen) → surface as WARNING.\n\n### 5. Sanity-check the bump\n\n```bash\nPREV_VERSION=${LAST_TAG#v}\nNEW_VERSION=$(gh pr view $RELEASE_PR --json title --jq .title \\\n  | grep -oE '[0-9]+\\.[0-9]+\\.[0-9]+' | head -1)\necho \"Bump: $PREV_VERSION → $NEW_VERSION\"\n```\n\nInspect conventional-commit types since last tag:\n\n```bash\ngit log \"$LAST_TAG\"..origin\u002Fmain --pretty=format:'%s%n%b' --no-merges \\\n  | grep -E '^(feat|fix|perf|refactor|docs)(\\(.+\\))?!?:|BREAKING CHANGE:' \\\n  | sort -u\n```\n\nExpected bump (post-1.0):\n\n- `feat!:` or `BREAKING CHANGE:` anywhere → **major**\n- `feat:` (no breaking) → **minor**\n- `fix:` \u002F `perf:` \u002F `refactor:` only → **patch**\n\nFor pre-1.0 packages, read `release-please-config.json` — `bump-minor-pre-major` promotes major→minor; `bump-patch-for-minor-pre-major` promotes minor→patch.\n\nIf release-please's bump diverges from expectation, surface as **WARNING** with the divergence (likely config). Do not block — release-please's config is the source of truth.\n\n### 6. Go\u002Fno-go summary\n\n```\nRelease-conductor: PR #$RELEASE_PR — $PREV_VERSION → $NEW_VERSION\n\n  Step 2 — Files:           CHANGELOG.md, package.json, .release-please-manifest.json, …\n  Step 3 — CI release PR:   ✓ green\n                         |  ✗ failing: \u003Cnames> (BLOCKED)\n                         |  ⏳ pending (BLOCKED — wait)\n  Step 3 — CI main:         ✓ green\n                         |  ⚠ recent failures (not blocking publish)\n  Step 4 — Blockers:        none\n                         |  ✗ open: PR #N (label) (BLOCKED)\n  Step 4 — Landed PRs:      N feature PRs since $LAST_TAG\n  Step 5 — Bump:            ✓ matches commit types\n                         |  ⚠ release-please chose $NEW_VERSION, expected $EXPECTED (\u003Creason>)\n\nStatus: READY — say \"ship\" to merge PR #$RELEASE_PR (squash) and trigger release.yml.\n     |  BLOCKED — \u003Creason>. Fix and re-run \u002Frelease-conductor.\n```\n\n### 7. Merge on explicit approval\n\nWait for the user to say `ship`, `merge`, `go`, or `lgtm`. CI green alone is not authorization.\n\nOn approval:\n\n```bash\ngh pr merge $RELEASE_PR --squash --delete-branch\n```\n\nIf the repo overrides merge method (check `.github\u002Fsettings.yml` or repo settings UI), follow the override and note it in the report.\n\n### 8. Report the publish pipeline run\n\nrelease-please's GitHub Action creates the `v$NEW_VERSION` tag immediately after merge; the tag push fires `release.yml`. Report the most recent runs so the user can track:\n\n```bash\nTAG=\"v$NEW_VERSION\"\ngh run list --workflow=release.yml --limit 3 \\\n  --json url,headBranch,status,conclusion,createdAt\n```\n\nDo not poll. Print:\n\n```\nMerged PR #$RELEASE_PR ($PREV_VERSION → $NEW_VERSION)\nTag should appear shortly: $TAG\nTrack release.yml above. Once it shows ✓ success:\n  \u002Frelease-conductor verify $TAG\n```\n\n## `verify \u003Ctag>` subcommand\n\nPost-publish verification. No gating, no merge — three registry checks, plus\ndeploy status and smoke checks when the repository declares a deploy target.\n\n```bash\nTAG=$(echo \"$ARGUMENTS\" | awk '{print $2}')\nVERSION=${TAG#v}\nPKG=$(node -p \"require('.\u002Fpackage.json').name\")\n\n# 1. release.yml conclusion for this tag\ngh run list --workflow=release.yml --branch \"$TAG\" --limit 1 \\\n  --json conclusion,url,databaseId\n\n# 2. npm has the version\nnpm view \"$PKG@$VERSION\" version dist.tarball\n\n# 3. GitHub release exists\ngh release view \"$TAG\" --json url,publishedAt,name\n```\n\nThen deploy status and smoke (Flow 5). **Do not gate this on\n`.claude\u002Fdeploy-targets.json`** — the helper also auto-discovers targets from\n`.vercel\u002Fproject.json` and `fly.toml`, so a file-existence gate would report\nSKIPPED for a Vercel or Fly repository that has a real, checkable deployment.\nLet the helper decide what exists and report its verdict:\n\n```bash\n# 4 + 5. Deploy status, then smoke — the published artifact existing is not\n# the same as the deployed thing answering. Status runs FIRST: it establishes\n# which revision is live, and a smoke pass against a drifted revision is a\n# pass for the wrong artifact.\n#\n# The same three-branch resolution deploy-status and smoke-test use. The\n# `elif` guard and the `exit 2` branch are both load-bearing: without the\n# guard this would run a CWD-relative script the checked-out repository\n# controls, and without the exit a missing helper would fall through to the\n# FAIL path and recommend rolling back a healthy deployment.\nif [ -f \"$HOME\u002F.claude\u002Fskills\u002Fdeploy-status\u002Fscripts\u002Fdeploy-ops.mjs\" ]; then\n  DEPLOY_OPS=\"$HOME\u002F.claude\u002Fskills\u002Fdeploy-status\u002Fscripts\u002Fdeploy-ops.mjs\"\nelif [ -f \"skills\u002Fdeploy-status\u002Fscripts\u002Fdeploy-ops.mjs\" ]; then\n  DEPLOY_OPS=\"skills\u002Fdeploy-status\u002Fscripts\u002Fdeploy-ops.mjs\"\nelse\n  echo \"deploy-status helper not found; re-run dotbabel bootstrap or dotbabel init\" >&2\n  exit 2\nfi\n\nnode \"$DEPLOY_OPS\" status\nnode \"$DEPLOY_OPS\" smoke\n```\n\nReport PASS \u002F FAIL per check. Specifics:\n\n- **release.yml conclusion** — `success` = PASS. `in_progress` = \"still running, retry in ~60s.\" `failure` = FAIL, print URL.\n- **npm view** — exit 0 = PASS. 404 = \"not yet propagated (npm CDN lag, up to ~60s).\" Other error = FAIL.\n- **gh release view** — exit 0 = PASS. `release not found` = FAIL.\n- **deploy status** — exit 0 = PASS. Drift (exit 1) = FAIL. Discovery finding no target, or the helper itself being unavailable (**exit 2**) = **SKIPPED**, never FAIL: a tool-availability problem is not a production problem, and reporting it as one would recommend rolling back a deployment that is fine.\n- **smoke** — read the `verdict`, not only the exit code. `pass` = PASS. `fail` = FAIL. `not_configured` (no target declares checks) and `not_run` (a dry run) = **SKIPPED**, never PASS: both exit 0 without having verified anything.\n\n**When no deploy target exists, report deploy status and smoke as SKIPPED** —\nnever as PASS. The helper decides that, not a file-existence check: it reports\nexit 2 when discovery finds nothing and a `not_configured` verdict when no\ntarget declares smoke checks. Either way nothing was checked, so nothing\npassed. Reporting PASS for a check that never ran is the failure mode this\nwhole subcommand exists to avoid, and it is invisible in the output.\n\nOn any FAIL from deploy status or smoke, **recommend `\u002Frollback-prod` and\nstop** (KD-13). Do not invoke it: rolling back is a production change and needs\nan explicit human instruction, and `\u002Frollback-prod` requires its own typed\nconfirmation on top of that.\n\n## Rules\n\n- **Never reimplement release-please.** This skill does not write CHANGELOG.md, bump versions, or create tags. release-please owns that; this skill only gates the merge of release-please's PR.\n- **Never publish to npm directly.** OIDC publish happens in `release.yml` on tag push. The skill stops at `gh pr merge`.\n- **Require explicit verbal approval.** `ship` \u002F `merge` \u002F `go` \u002F `lgtm`. CI green alone is not authorization.\n- **One release PR at a time.** Multiple open `release-please--*` PRs → stop and ask. Likely a config issue.\n- **Squash merge by default.** Matches `\u002Fmerge-pr` convention. Repo override (if any) wins, but record it.\n- **No polling.** Print the run URL and exit. Use `verify \u003Ctag>` later.\n- **Never roll back from this skill.** `verify` recommends `\u002Frollback-prod` on a failure and stops; the rollback itself stays an explicit human call.\n- **Never report an unrun check as PASS.** Absent deploy targets, a `not_configured` smoke verdict, and a dry run are all SKIPPED.\n- **Pre-1.0 bump checks read config.** Don't assume semver — `release-please-config.json` may have `bump-minor-pre-major` flags that alter the expected bump.\n- **Always fetch tags before reading them.** `LAST_TAG` comes from the local tag list; a stale clone yields a wrong release window that still reports READY. Step 0's fetch is not optional.\n",{"id":5,"name":5,"task":44,"type":46,"model":47,"owner":48,"domain":49,"created":51,"updated":52,"version":53,"dotbabel":54,"maturity":58,"platform":59,"description":61,"allowed-tools":62,"argument-hint":63,"headless_safe":40,"user-invocable":64,"disable-model-invocation":64},[30,45],"runtime-ops","skill","sonnet","@kaiohenricunha",[50],"devex",1779753600000,1786060800000,"1.0.0",{"compute":55},{"mode":56,"binding":57},"inherit","consumer","draft",[60],"github-actions","Gate the open release-please PR before merging: verify CI green, feature PRs landed, no release blockers, changelog reflects intent. One-word approval, then merge. Reports the resulting release.yml run URL. release-please owns the changelog\u002Fbump\u002Ftag; release.yml owns OIDC npm publish — this skill only gates the merge in between. Triggers on: \"ship a release\", \"cut a release\", \"merge the release PR\", \"is the release ready\", \"verify the release\".\n","Read Bash Grep Glob","[verify \u003Ctag>]",true,"main","91c337164997b99943fbcc64e8e362577b67bc81","skills\u002Frelease-conductor","https:\u002F\u002Fgithub.com\u002Fkaiohenricunha\u002Fdotbabel","https:\u002F\u002Fgithub.com\u002Fkaiohenricunha","I'm a Platform\u002FInfra engineer who happens to work in cybersec and write Go code.","2026-10-26 14:12:51",{"source":8,"skillName":5,"commands":73,"prompt":83,"zipAvailable":64},[74,77,80],{"tool":75,"command":76},"npx","npx skills add kaiohenricunha\u002Fdotbabel --skill release-conductor",{"tool":78,"command":79},"bunx","bunx skills add kaiohenricunha\u002Fdotbabel --skill release-conductor",{"tool":81,"command":82},"pnpm","pnpm dlx skills add kaiohenricunha\u002Fdotbabel --skill release-conductor","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fkaiohenricunha\u002Fdotbabel\u002Fblob\u002Fmain\u002Fskills\u002Frelease-conductor\u002FSKILL.md",[],[86,116,147,168,190,213],{"skillNo":87,"name":88,"nameZh":6,"description":89,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":90,"categories":91,"keywords":97,"publishedAt":39},"01M6XDQ7QMASPFZ355MYKCD06T","yolo","Start temporary autonomy for the current task or an explicit scope with a required --for expiry. Codex permits scoped pushes, merges, deploys, and releases after strict testing and validation; Full access is a separate runtime setting. Claude Code uses a session permission hook with a protected-action denylist.","https:\u002F\u002Fgithub.com\u002Fkaiohenricunha\u002Fdotbabel\u002Fblob\u002Fmain\u002Fskills\u002Fyolo\u002FSKILL.md",[92],{"categoryNo":93,"categoryName":94,"taxonomyType":95,"taxonomyTypeDesc":96},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[88,98,99,100,101,102,103,104,105,106,107,108,109,110,50,111,112,113,114,115],"testing","merge","code","start","access","session","ops","autonomy","releases","permission","full","runtime","scope","hook","true","action","for","scoped",{"skillNo":117,"name":118,"nameZh":6,"description":119,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":120,"categories":121,"keywords":130,"publishedAt":39},"01M6XDQ1N21VE4KH98JWGZ7GN9","veracity-audit","Audit a data pipeline for Veracity and Value. Dispatches data-scientist, compliance-auditor, and data-engineer agents with project context injected at dispatch time. All source paths are supplied via flags — no defaults, no project assumptions. Subcommands: audit (full pipeline walk), score-check (scoring math only), gate-check (gate coverage only), source-trace \u003Clabel> (single source end-to-end). Invoke when: \"audit pipeline\", \"veracity check\", \"scoring math correct?\", \"check gates\", \"trace source\", \"verify quality gates\", \"formula correct?\".","https:\u002F\u002Fgithub.com\u002Fkaiohenricunha\u002Fdotbabel\u002Fblob\u002Fmain\u002Fskills\u002Fveracity-audit\u002FSKILL.md",[122,127],{"categoryNo":123,"categoryName":124,"taxonomyType":125,"taxonomyTypeDesc":126},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",{"categoryNo":128,"categoryName":129,"taxonomyType":95,"taxonomyTypeDesc":96},"01JBSEEDCAT000000000000037","律师与法务",[131,132,98,30,133,134,32,135,136,31,137,138,139,140,141,142,143,144,145,146],"audit","veracity audit","data pipeline","pipeline","math","coverage","engineer","formula","scoring","time","project","worker","end","at","invoke","when",{"skillNo":148,"name":149,"nameZh":6,"description":150,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":151,"categories":152,"keywords":153,"publishedAt":39},"01M6XDPVDKBR376C06CEK9BC5S","validate-spec","Audit an already-implemented spec against the codebase. Walks each constraint (ARCH-N, PERF-N, KD-N, etc.) and acceptance criterion, grounds findings in file:line evidence, runs the spec.json acceptance_commands, and writes a single audit doc to docs\u002Faudits\u002F. Use whenever the user asks to \"validate a spec\", \"audit a spec\", \"check if spec is implemented\", \"verify the spec is done\", \"is this spec really done\", or otherwise wants closure on spec-driven work. Read-only against the spec — produces an audit, never modifies the spec itself.","https:\u002F\u002Fgithub.com\u002Fkaiohenricunha\u002Fdotbabel\u002Fblob\u002Fmain\u002Fskills\u002Fvalidate-spec\u002FSKILL.md",[],[154,155,156,98,30,38,157,131,32,158,159,160,31,161,162,163,164,165,166,167],"spec","validate","validate spec","acceptance","work","read","never","max","done","arch","line","2025","spec-driven","closure",{"skillNo":169,"name":170,"nameZh":6,"description":171,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":172,"categories":173,"keywords":177,"publishedAt":39},"01M6XDPMMECH82RAW553Y94HDS","terragrunt-specialist","Deep-dive Terragrunt hierarchy review, DRY pattern audits, and run-all orchestration analysis. Use for structured investigations of multi-environment Terragrunt layouts, dependency graphs, remote state config, and hook correctness. Triggers on: \"Terragrunt audit\", \"run-all review\", \"dependency block\", \"DRY pattern review\", \"env hierarchy audit\", \"mock_outputs\", \"terragrunt hooks\".","https:\u002F\u002Fgithub.com\u002Fkaiohenricunha\u002Fdotbabel\u002Fblob\u002Fmain\u002Fskills\u002Fterragrunt-specialist\u002FSKILL.md",[174],{"categoryNo":175,"categoryName":176,"taxonomyType":125,"taxonomyTypeDesc":126},"01JBSEEDCAT000000000000011","运维与部署",[178,179,180,30,181,182,38,131,183,32,159,184,185,161,186,187,165,188,144,189],"terragrunt","specialist","terragrunt specialist","orchestration","debugging","analysis","dependency","hooks","deep","dry","remote","hierarchy",{"skillNo":191,"name":192,"nameZh":6,"description":193,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":194,"categories":195,"keywords":203,"publishedAt":39},"01M6XDPFJS2HGSE13RXF1HV8S7","terraform-specialist","Deep-dive Terraform architecture review, module design, state management, and migration. Use for structured investigations of Terraform workspaces, provider configuration, module coupling, import workflows, and test coverage. Triggers on: \"Terraform audit\", \"module review\", \"state management\", \"Terraform import\", \"workspace design\", \"provider config review\", \"Terraform testing\".","https:\u002F\u002Fgithub.com\u002Fkaiohenricunha\u002Fdotbabel\u002Fblob\u002Fmain\u002Fskills\u002Fterraform-specialist\u002FSKILL.md",[196,199,200],{"categoryNo":197,"categoryName":198,"taxonomyType":125,"taxonomyTypeDesc":126},"01JBSEEDCAT000000000000008","测试与质量",{"categoryNo":175,"categoryName":176,"taxonomyType":125,"taxonomyTypeDesc":126},{"categoryNo":201,"categoryName":202,"taxonomyType":125,"taxonomyTypeDesc":126},"01JBSEEDCAT000000000000015","视觉设计",[204,205,179,98,206,30,207,208,209,182,131,32,159,136,210,211,186,212,165,144],"terraform","terraform specialist","design","workflows","architecture","architecture review","test coverage","workspaces","problem",{"skillNo":214,"name":154,"nameZh":6,"description":215,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":216,"categories":217,"keywords":222,"publishedAt":39},"01M6XDP7V6H8WYPSXVEKYE6HJ6","Create structured engineering specs through interactive pairing. Use when the user wants to create a spec, design doc, technical specification, architecture document, RFC, or engineering plan. Triggers on \"let's spec this out\", \"create a spec\", \"design doc\", \"write a technical plan\", \"plan the architecture\". Works for greenfield and brownfield projects. Outputs to docs\u002Fspecs\u002F.","https:\u002F\u002Fgithub.com\u002Fkaiohenricunha\u002Fdotbabel\u002Fblob\u002Fmain\u002Fskills\u002Fspec\u002FSKILL.md",[218,219],{"categoryNo":201,"categoryName":202,"taxonomyType":125,"taxonomyTypeDesc":126},{"categoryNo":220,"categoryName":221,"taxonomyType":95,"taxonomyTypeDesc":96},"01JBSEEDCAT000000000000032","设计师",[154,206,223,208,224,225,226,227,228,229,230,231,232,233,234,114,235,236,237,238],"component","create","plan","projects","write","interactive","use","document","specification","triggers","opus","technical specification","trade-offs","technical plan","outputs","frontier"]