[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M719C14RJSGD12QCJEK5JNVG":3,"skill-same:01M719C14RJSGD12QCJEK5JNVG":65},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":38,"linkOnly":39,"markdownContent":40,"markdownBody":41,"frontMatter":42,"refName":44,"commitSha":45,"skillDirectory":46,"forksCount":47,"repositoryHtmlUrl":48,"repositoryHomepageUrl":6,"ownerHtmlUrl":49,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":50,"install":51,"resources":64},"01M719C14RJSGD12QCJEK5JNVG","ci-validation-gates",null,"Defensive CI\u002FCD patterns: semver validation, token checks, retry logic, draft detection — earned from v0.8.22","DeDuva\u002Fsquad","DeDuva","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F8153108?v=4","01M719BQB25861D0TKS3RVHMN2","01M719BQBSWR380PSYDD5M9YD4",1,"MIT","https:\u002F\u002Fgithub.com\u002FDeDuva\u002Fsquad\u002Fblob\u002Fdev\u002F.copilot\u002Fskills\u002Fci-validation-gates\u002FSKILL.md",[],[18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"ci validation gates","gates","validation","ci","cd","patterns","v0","semver","detection","token","CI\u002FCD","release","logic","high","defensive","draft","knowledge","incident","retry","ci-cd","2026-11-10 10:12:30",false,"---\nname: \"ci-validation-gates\"\ndescription: \"Defensive CI\u002FCD patterns: semver validation, token checks, retry logic, draft detection — earned from v0.8.22\"\ndomain: \"ci-cd\"\nconfidence: \"high\"\nsource: \"extracted from Drucker and Trejo charters — earned knowledge from v0.8.22 release incident\"\n---\n\n## Context\n\nCI workflows must be defensive. These patterns were learned from the v0.8.22 release disaster where invalid semver, wrong token types, missing retry logic, and draft releases caused a multi-hour outage. Both Drucker (CI\u002FCD) and Trejo (Release Manager) carried this knowledge in their charters — now centralized here.\n\n## Patterns\n\n### Semver Validation Gate\nEvery publish workflow MUST validate version format before `npm publish`. 4-part versions (e.g., 0.8.21.4) are NOT valid semver — npm mangles them.\n\n```yaml\n- name: Validate semver\n  run: |\n    VERSION=\"${{ github.event.release.tag_name }}\"\n    VERSION=\"${VERSION#v}\"\n    if ! npx semver \"$VERSION\" > \u002Fdev\u002Fnull 2>&1; then\n      echo \"❌ Invalid semver: $VERSION\"\n      echo \"Only 3-part versions (X.Y.Z) or prerelease (X.Y.Z-tag.N) are valid.\"\n      exit 1\n    fi\n    echo \"✅ Valid semver: $VERSION\"\n```\n\n### NPM Token Type Verification\nNPM_TOKEN MUST be an Automation token, not a User token with 2FA:\n- User tokens require OTP — CI can't provide it → EOTP error\n- Create Automation tokens at npmjs.com → Settings → Access Tokens → Automation\n- Verify before first publish in any workflow\n\n### Retry Logic for npm Registry Propagation\nnpm registry uses eventual consistency. After `npm publish` succeeds, the package may not be immediately queryable.\n- Propagation: typically 5-30s, up to 2min in rare cases\n- All verify steps: 5 attempts, 15-second intervals\n- Log each attempt: \"Attempt 1\u002F5: Checking package...\"\n- Exit loop on success, fail after max attempts\n\n```yaml\n- name: Verify package (with retry)\n  run: |\n    MAX_ATTEMPTS=5\n    WAIT_SECONDS=15\n    for attempt in $(seq 1 $MAX_ATTEMPTS); do\n      echo \"Attempt $attempt\u002F$MAX_ATTEMPTS: Checking $PACKAGE@$VERSION...\"\n      if npm view \"$PACKAGE@$VERSION\" version > \u002Fdev\u002Fnull 2>&1; then\n        echo \"✅ Package verified\"\n        exit 0\n      fi\n      [ $attempt -lt $MAX_ATTEMPTS ] && sleep $WAIT_SECONDS\n    done\n    echo \"❌ Failed to verify after $MAX_ATTEMPTS attempts\"\n    exit 1\n```\n\n### Draft Release Detection\nDraft releases don't emit `release: published` event. Workflows MUST:\n- Trigger on `release: published` (NOT `created`)\n- If using workflow_dispatch: verify release is published via GitHub API before proceeding\n\n### Build Script Protection\nSet `SKIP_BUILD_BUMP=1` (or `$env:SKIP_BUILD_BUMP = \"1\"` on Windows) before ANY release build. bump-build.mjs is for dev builds ONLY — it silently mutates versions.\n\n## Known Failure Modes (v0.8.22 Incident)\n\n| # | What Happened | Root Cause | Prevention |\n|---|---------------|-----------|------------|\n| 1 | 4-part version published, npm mangled it | No semver validation gate | `npx semver` check before every publish |\n| 2 | CI failed 5+ times with EOTP | User token with 2FA | Automation token only |\n| 3 | Verify returned false 404 | No retry logic for propagation | 5 attempts, 15s intervals |\n| 4 | Workflow never triggered | Draft release doesn't emit event | Never create draft releases |\n| 5 | Version mutated during release | bump-build.mjs ran in release | SKIP_BUILD_BUMP=1 |\n\n## Anti-Patterns\n- ❌ Publishing without semver validation gate\n- ❌ Single-shot verification without retry\n- ❌ Hard-coded secrets in workflows\n- ❌ Silent CI failures — every error needs actionable output with remediation\n- ❌ Assuming npm publish is instantly queryable\n","## Context\n\nCI workflows must be defensive. These patterns were learned from the v0.8.22 release disaster where invalid semver, wrong token types, missing retry logic, and draft releases caused a multi-hour outage. Both Drucker (CI\u002FCD) and Trejo (Release Manager) carried this knowledge in their charters — now centralized here.\n\n## Patterns\n\n### Semver Validation Gate\nEvery publish workflow MUST validate version format before `npm publish`. 4-part versions (e.g., 0.8.21.4) are NOT valid semver — npm mangles them.\n\n```yaml\n- name: Validate semver\n  run: |\n    VERSION=\"${{ github.event.release.tag_name }}\"\n    VERSION=\"${VERSION#v}\"\n    if ! npx semver \"$VERSION\" > \u002Fdev\u002Fnull 2>&1; then\n      echo \"❌ Invalid semver: $VERSION\"\n      echo \"Only 3-part versions (X.Y.Z) or prerelease (X.Y.Z-tag.N) are valid.\"\n      exit 1\n    fi\n    echo \"✅ Valid semver: $VERSION\"\n```\n\n### NPM Token Type Verification\nNPM_TOKEN MUST be an Automation token, not a User token with 2FA:\n- User tokens require OTP — CI can't provide it → EOTP error\n- Create Automation tokens at npmjs.com → Settings → Access Tokens → Automation\n- Verify before first publish in any workflow\n\n### Retry Logic for npm Registry Propagation\nnpm registry uses eventual consistency. After `npm publish` succeeds, the package may not be immediately queryable.\n- Propagation: typically 5-30s, up to 2min in rare cases\n- All verify steps: 5 attempts, 15-second intervals\n- Log each attempt: \"Attempt 1\u002F5: Checking package...\"\n- Exit loop on success, fail after max attempts\n\n```yaml\n- name: Verify package (with retry)\n  run: |\n    MAX_ATTEMPTS=5\n    WAIT_SECONDS=15\n    for attempt in $(seq 1 $MAX_ATTEMPTS); do\n      echo \"Attempt $attempt\u002F$MAX_ATTEMPTS: Checking $PACKAGE@$VERSION...\"\n      if npm view \"$PACKAGE@$VERSION\" version > \u002Fdev\u002Fnull 2>&1; then\n        echo \"✅ Package verified\"\n        exit 0\n      fi\n      [ $attempt -lt $MAX_ATTEMPTS ] && sleep $WAIT_SECONDS\n    done\n    echo \"❌ Failed to verify after $MAX_ATTEMPTS attempts\"\n    exit 1\n```\n\n### Draft Release Detection\nDraft releases don't emit `release: published` event. Workflows MUST:\n- Trigger on `release: published` (NOT `created`)\n- If using workflow_dispatch: verify release is published via GitHub API before proceeding\n\n### Build Script Protection\nSet `SKIP_BUILD_BUMP=1` (or `$env:SKIP_BUILD_BUMP = \"1\"` on Windows) before ANY release build. bump-build.mjs is for dev builds ONLY — it silently mutates versions.\n\n## Known Failure Modes (v0.8.22 Incident)\n\n| # | What Happened | Root Cause | Prevention |\n|---|---------------|-----------|------------|\n| 1 | 4-part version published, npm mangled it | No semver validation gate | `npx semver` check before every publish |\n| 2 | CI failed 5+ times with EOTP | User token with 2FA | Automation token only |\n| 3 | Verify returned false 404 | No retry logic for propagation | 5 attempts, 15s intervals |\n| 4 | Workflow never triggered | Draft release doesn't emit event | Never create draft releases |\n| 5 | Version mutated during release | bump-build.mjs ran in release | SKIP_BUILD_BUMP=1 |\n\n## Anti-Patterns\n- ❌ Publishing without semver validation gate\n- ❌ Single-shot verification without retry\n- ❌ Hard-coded secrets in workflows\n- ❌ Silent CI failures — every error needs actionable output with remediation\n- ❌ Assuming npm publish is instantly queryable\n",{"name":5,"domain":37,"source":43,"confidence":31,"description":7},"extracted from Drucker and Trejo charters — earned knowledge from v0.8.22 release incident","dev","4ffda80d1bb1043d9169688cf161e53097345c72",".copilot\u002Fskills\u002Fci-validation-gates",0,"https:\u002F\u002Fgithub.com\u002FDeDuva\u002Fsquad","https:\u002F\u002Fgithub.com\u002FDeDuva","2026-11-09 20:24:44",{"source":8,"skillName":5,"commands":52,"prompt":62,"zipAvailable":63},[53,56,59],{"tool":54,"command":55},"npx","npx skills add DeDuva\u002Fsquad --skill ci-validation-gates",{"tool":57,"command":58},"bunx","bunx skills add DeDuva\u002Fsquad --skill ci-validation-gates",{"tool":60,"command":61},"pnpm","pnpm dlx skills add DeDuva\u002Fsquad --skill ci-validation-gates","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FDeDuva\u002Fsquad\u002Fblob\u002Fdev\u002F.copilot\u002Fskills\u002Fci-validation-gates\u002FSKILL.md",true,[],[66,82,90,105,129,144],{"skillNo":67,"name":68,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":69,"categories":70,"keywords":76,"publishedAt":38},"01M719NE6ZPZT80MKVWFDECJZ3","My Skill","https:\u002F\u002Fgithub.com\u002FDeDuva\u002Fsquad\u002Fblob\u002Fdev\u002Ftest-fixtures\u002Fskills-test-abb30454\u002Fmy-skill\u002FSKILL.md",[71],{"categoryNo":72,"categoryName":73,"taxonomyType":74,"taxonomyTypeDesc":75},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[77,78,79,80,81],"my","my skill","testing","vitest","tester",{"skillNo":83,"name":84,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":85,"categories":86,"keywords":87,"publishedAt":38},"01M719NDJAMEWM8D9H355SCNA8","bad-skill","https:\u002F\u002Fgithub.com\u002FDeDuva\u002Fsquad\u002Fblob\u002Fdev\u002Ftest-fixtures\u002Fskills-test-abb30454\u002Fbad-skill\u002FSKILL.md",[],[88,89],"bad skill","bad",{"skillNo":91,"name":92,"nameZh":6,"description":93,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":94,"categories":95,"keywords":96,"publishedAt":38},"01M719NCC1AZ02GHZ1V71YPEV7","squad-conventions","Core conventions and patterns used in the Squad codebase","https:\u002F\u002Fgithub.com\u002FDeDuva\u002Fsquad\u002Fblob\u002Fdev\u002Ftemplates\u002Fskills\u002Fsquad-conventions\u002FSKILL.md",[],[97,98,99,100,101,102,103,31,104,23],"conventions","squad","squad conventions","project-conventions","core","project","manual","codebase",{"skillNo":106,"name":107,"nameZh":6,"description":108,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":109,"categories":110,"keywords":111,"publishedAt":38},"01M719NAYM17B7X8MGP681EHKQ","rework-rate","Measure and interpret PR rework rate — the emerging 5th DORA metric","https:\u002F\u002Fgithub.com\u002FDeDuva\u002Fsquad\u002Fblob\u002Fdev\u002Ftemplates\u002Fskills\u002Frework-rate\u002FSKILL.md",[],[112,113,114,115,31,116,117,118,98,119,120,121,122,103,123,124,125,126,127,128],"rate","rework rate","health","analyze","review efficiency","quality","metric","metrics","efficiency","code quality","pr","prs","when","code","team","code-review","review",{"skillNo":130,"name":131,"nameZh":6,"description":132,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":133,"categories":134,"keywords":135,"publishedAt":38},"01M719NA136PDC3SQ10R4R88TH","nap","Context hygiene — compress, prune, archive .squad\u002F state","https:\u002F\u002Fgithub.com\u002FDeDuva\u002Fsquad\u002Fblob\u002Fdev\u002Ftemplates\u002Fskills\u002Fnap\u002FSKILL.md",[],[131,136,137,138,139,140,141,142,98,143],"prune","state","maintenance","context hygiene","archive","hygiene","compress","context",{"skillNo":145,"name":146,"nameZh":6,"description":147,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":148,"categories":149,"keywords":154,"publishedAt":38},"01M719N7B4PBQPNXW78TEJY4HQ","e2e-template-testing","End-to-end validation of coordinator and agent template changes","https:\u002F\u002Fgithub.com\u002FDeDuva\u002Fsquad\u002Fblob\u002Fdev\u002Ftemplates\u002Fskills\u002Fe2e-template-testing\u002FSKILL.md",[150,153],{"categoryNo":151,"categoryName":152,"taxonomyType":74,"taxonomyTypeDesc":75},"01JBSEEDCAT000000000000008","测试与质量",{"categoryNo":72,"categoryName":73,"taxonomyType":74,"taxonomyTypeDesc":75},[79,155,156,157,158,159,160,103,161,31,20],"e2e template testing","e2e","template","end","coordinator","development","changes"]