Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Semver versioning rules for Squad SDK and CLI — prevents prerelease version incidents
.claude/skills/github-versioning-policy/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 46% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 48% | 0% |
| case-04 | ✗→✓ | ▲ Improved | 32% | 0% |
| case-05 | ✗→✓ | ▲ Improved | -34% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 20% | 0% |
Squad is a monorepo with two publishable npm packages (@bradygaster/squad-sdk and @bradygaster/squad-cli) managed via npm workspaces. Version mismatches and prerelease leaks have caused production incidents — most notably PR #640, where a -build.N prerelease version silently broke workspace dependency resolution.
This skill codifies the versioning rules every agent must follow.
All packages use strict semver: MAJOR.MINOR.PATCH
0.9.1, 1.0.0, 0.10.00.9.1-build.4, 0.9.1-preview.1, 0.8.6.1-previewNo prerelease suffixes on dev or main branches — ever.
The scripts/bump-build.mjs script creates -build.N versions (e.g., 0.9.1-build.4) for local development testing only.
Rules:
-build.N versions are created automatically during local npm run builddev or mainCI=true or SKIP_BUILD_BUMP=1)-build.N version in a PR diff, it is a bug — reject the PRBoth @bradygaster/squad-sdk and @bradygaster/squad-cli MUST have the same version at all times. The root package.json version must also match.
bump-build.mjs enforces this by updating all three package.json files in lockstep (root + packages/squad-sdk + packages/squad-cli).
If versions diverge, workspace resolution silently breaks (see §4).
The CLI depends on the SDK via a workspace dependency with a semver range:
json"@bradygaster/squad-sdk": ">=0.9.0"
Critical: Per the semver specification, >=0.9.0 does NOT match 0.9.1-build.4.
Semver prerelease versions (anything with a - suffix) are only matched by ranges that explicitly reference the same MAJOR.MINOR.PATCH base with a prerelease comparator. A bare >=0.9.0 range skips all prerelease versions.
What happens: When the local SDK has version 0.9.1-build.4, npm's workspace resolution fails to match the >=0.9.0 range. npm then silently installs a stale published version from the npm registry instead of using the local workspace link. The build succeeds but runs against old SDK code.
This is the root cause of the PR #640 incident, where workspace packages appeared linked but were actually running against stale registry versions.
Surgeon (Release Manager) owns all version bumps.
| Agent | May modify version in package.json? | |-------|---------------------------------------| | Surgeon | ✅ Yes — sole owner of version bumps | | Any other agent | ❌ No — unless explicitly fixing a prerelease leak |
If you discover a prerelease version committed to dev or main, you may fix it (revert to the clean release version) without Surgeon's approval. This is a safety escape hatch, not a license to manage versions.
┌─────────────────────────────────────────────────────────┐
│ Development phase │
│ Versions stay at current release: 0.9.1 │
│ bump-build.mjs creates -build.N locally (not committed)│
├─────────────────────────────────────────────────────────┤
│ Pre-release testing │
│ bump-build.mjs → 0.9.1-build.1, -build.2, ... │
│ Local only. Never committed. Never pushed. │
├─────────────────────────────────────────────────────────┤
│ Release │
│ Surgeon bumps to next version (e.g., 0.9.2 or 0.10.0) │
│ Tags, publishes to npm registry │
├─────────────────────────────────────────────────────────┤
│ Post-release │
│ Versions stay at the new release version (e.g., 0.9.2) │
│ Development continues on clean version │
└─────────────────────────────────────────────────────────┘The prerelease-version-guard CI gate blocks any PR to dev or main that contains prerelease version strings in package.json files.
package.json files for - in the version fieldskip-version-check label bypasses the gate — use only for the bump-build script's own PR (if applicable), and only with Surgeon's approvalPR #640 is the cautionary tale for this entire policy.
What happened: Prerelease versions (0.9.1-build.4) were committed to a branch. The workspace dependency >=0.9.0 failed to match the prerelease version per semver spec. npm silently installed a stale published SDK from the registry instead of linking the local workspace copy. Four PRs (#637–#640) attempted iterative patches before the root cause was identified.
Root cause: No versioning policy existed. Agents didn't know that prerelease versions break workspace resolution, or that only Surgeon should modify versions.
Resolution: This skill, the prerelease-version-guard CI gate, and the team decision to centralize version ownership under Surgeon.
| Rule | Summary | |------|---------| | Format | MAJOR.MINOR.PATCH — no prerelease on dev/main | | Prerelease | -build.N is local-only, never committed | | Sync | SDK + CLI + root must have identical versions | | Ownership | Surgeon bumps versions; others don't touch them | | CI gate | prerelease-version-guard blocks prerelease PRs | | Escape hatch | Any agent may revert a prerelease leak to clean version | | Footgun | >=0.9.0 does NOT match 0.9.1-build.4 per semver |
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 15,700 | 11,950 | -24% | 1 | 1 | 0% | 2,299 | 3,360 | +46% | 0 | 0 | — |
case-02 | fail→fail | 16,711 | 10,138 | -39% | 1 | 1 | 0% | 3,044 | 3,317 | +9% | 0 | 0 | — |
case-03 | fail→pass | 12,985 | 7,003 | -46% | 1 | 1 | 0% | 1,803 | 2,674 | +48% | 0 | 0 | — |
case-04 | fail→pass | 14,673 | 22,159 | +51% | 1 | 1 | 0% | 2,389 | 3,162 | +32% | 0 | 0 | — |
case-05 | fail→pass | 31,119 | 2,680 | -91% | 1 | 1 | 0% | 2,835 | 1,876 | -34% | 0 | 0 | — |
case-06 | fail→pass | 12,859 | 11,821 | -8% | 1 | 1 | 0% | 2,176 | 2,618 | +20% | 0 | 0 | — |
case-07 | fail→pass | 22,175 | 2,357 | -89% | 1 | 1 | 0% | 3,432 | 1,752 | -49% | 0 | 0 | — |
case-08 | fail→pass | 13,286 | 7,903 | -41% | 1 | 1 | 0% | 1,914 | 2,707 | +41% | 0 | 0 | — |
case-09 | fail→pass | 18,916 | 2,594 | -86% | 1 | 1 | 0% | 2,933 | 1,823 | -38% | 0 | 0 | — |
case-10 | fail→pass | 42,129 | 2,801 | -93% | 1 | 1 | 0% | 3,293 | 1,796 | -45% | 0 | 0 | — |
case-11 | fail→pass | 18,583 | 10,595 | -43% | 1 | 1 | 0% | 2,917 | 3,096 | +6% | 0 | 0 | — |
case-12 | pass→pass | 22,492 | 4,458 | -80% | 1 | 1 | 0% | 1,210 | 2,079 | +72% | 0 | 0 | — |
case-13 | fail→pass | 11,141 | 6,247 | -44% | 1 | 1 | 0% | 1,457 | 2,473 | +70% | 0 | 0 | — |
case-14 | fail→pass | 31,524 | 4,777 | -85% | 1 | 1 | 0% | 4,031 | 2,251 | -44% | 0 | 0 | — |
case-15 | pass→pass | 14,337 | 10,693 | -25% | 1 | 1 | 0% | 2,639 | 2,416 | -8% | 0 | 0 | — |
case-16 | fail→pass | 14,801 | 9,528 | -36% | 1 | 1 | 0% | 2,198 | 2,409 | +10% | 0 | 0 | — |
case-17 | pass→pass | 15,704 | 8,622 | -45% | 1 | 1 | 0% | 2,623 | 2,895 | +10% | 0 | 0 | — |
case-18 | pass→pass | 15,451 | 5,320 | -66% | 1 | 1 | 0% | 2,012 | 2,311 | +15% | 0 | 0 | — |
case-19 | fail→pass | 24,274 | 6,175 | -75% | 1 | 1 | 0% | 3,453 | 2,368 | -31% | 0 | 0 | — |
case-20 | pass→pass | 13,728 | 12,573 | -8% | 1 | 1 | 0% | 2,079 | 3,511 | +69% | 0 | 0 | — |
case-21 | pass→pass | 34,209 | 18,272 | -47% | 1 | 1 | 0% | 3,098 | 4,474 | +44% | 0 | 0 | — |
case-22 | pass→pass | 17,530 | 14,740 | -16% | 1 | 1 | 0% | 3,167 | 3,989 | +26% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 21 counted toward the lift figure. The other 1 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +64 percentage points is the difference between those two pass rates over the 21 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.