Skip to main content
ClaudeWave
Skill428 repo starsupdated today

commit-pr

The commit-pr skill enforces standardized pull request workflows for the OpenCode Swarm repository by requiring specific PR titles, body sections (Summary, Invariant audit, Test plan), and issue linkage before allowing commits and publication. Use this skill when creating or updating pull requests to ensure compliance with the project's engineering invariants and CI gates that validate PR structure and readiness.

Install in Claude Code
Copy
git clone --depth 1 https://github.com/ZaxbyHub/opencode-swarm /tmp/commit-pr && cp -r /tmp/commit-pr/.opencode/skills/commit-pr ~/.claude/skills/commit-pr
Then start a new Claude Code session; the skill loads automatically.

SKILL.md

# Commit & PR Protocol

Follow every step in order. Do not skip steps.

## Step -1 - Mandatory invariant audit

Before any build, test, push, or PR action, read:

1. [`../../../AGENTS.md`](../../../AGENTS.md)
2. [`../../../docs/engineering-invariants.md`](../../../docs/engineering-invariants.md)

For every touched invariant, prepare concrete evidence for the PR body. The PR body must include:

```md
## Invariant audit
- 1 (plugin init): touched / not touched - <evidence>
- 2 (runtime portability): touched / not touched - <evidence>
- 3 (subprocesses): touched / not touched - <evidence>
- 4 (.swarm containment): touched / not touched - <evidence>
- 5 (plan durability): touched / not touched - <evidence>
- 6 (test_runner safety): touched / not touched - <evidence>
- 7 (test writing): touched / not touched - <evidence>
- 8 (session state): touched / not touched - <evidence>
- 9 (guardrails/retry): touched / not touched - <evidence>
- 10 (chat/system msg): touched / not touched - <evidence>
- 11 (tool registration): touched / not touched - <evidence>
- 12 (release/cache): touched / not touched - <evidence>
```

If a touched invariant cannot be proven from source and test output, do not push.

### Required validations for touched invariants

If invariants 1, 2, or 3 are touched, run all three:

```bash
bun run build
node scripts/repro-704.mjs
node --input-type=module -e "await import('./dist/index.js'); console.log('dist import OK')"
```

If invariant 3 is touched, audit changed source files for subprocess use:

```bash
git diff --name-only origin/main..HEAD | xargs -r grep -nE "bunSpawn\(|spawn\(|spawnSync\(" || true
```

If invariant 11 is touched, run:

```bash
bun --smol test tests/unit/config --timeout 60000
for f in tests/unit/tools/*.test.ts; do bun --smol test "$f" --timeout 30000; done
```

If invariant 7 is touched, confirm the writing-tests skill was loaded and that new test seams avoid leaking `mock.module`.

## Step 0 - Session start hygiene

Run before publication work:

```bash
git fetch origin main
rm -f .swarm/evidence/*.json
git status --short
```

On Windows, prefer temporary save branches over `git stash`. If you must stash, use `git stash push --include-untracked` and verify the stash contents.

## Step 1 - Commit and PR titles

Use `<type>(<scope>): <description>` exactly.

- description is lowercase and does not end with a period
- allowed types: `feat`, `fix`, `perf`, `revert`, `docs`, `chore`, `refactor`, `test`, `ci`, `build`

Choose the PR title type by the main change:

- new capability -> `feat`
- bug fix only -> `fix`
- docs or chore only -> non-bump types

The squash merge commit message must match the PR title exactly.

> **Note:** The PR title MUST follow `<type>(<scope>): <description>` exactly — CI runs `action-semantic-pull-request` which will fail the `check-title` job if the format is wrong. Do not deviate from this format.

## Step 2 - Release note fragment

Create a pending release fragment and do not calculate a version manually.

Required file shape:

```text
docs/releases/pending/<unique-slug>.md
```

The fragment should cover:

- what changed
- why
- migration steps, if any
- breaking changes, if any
- known caveats

Do not manually edit:

- `package.json` version
- `CHANGELOG.md`
- `.release-please-manifest.json` — exception: reconciliation when the manifest desyncs from actual releases (see below)

### Release-please manifest desync

`.release-please-manifest.json` is the version source of truth for release-please. If it desyncs from the actual published release (e.g., `7.26.0` in manifest but `v7.27.1` on GitHub), release-please will propose a version that goes backwards.

**Common cause:** An older release PR (e.g., `chore(main): release 7.26.0`) merges after a newer one (`chore(main): release 7.27.1`). Both PRs modify the manifest, so the later one to merge wins — regardless of which version is higher.

**Detection:** If a release-please PR proposes a version that seems too low, check:
1. `gh release list --limit 5` — what's the latest published release?
2. `git show origin/main:.release-please-manifest.json` — what does the manifest say?
3. If different, the manifest is desynced.

**Fix:** Open a PR that updates `.release-please-manifest.json` to match the actual latest release (e.g., `"7.27.1"`). Close the incorrect release PR with explanation. After the manifest fix merges, release-please will auto-create a correct release PR.

## Step 3 - Mandatory validation suite

Run the full validation stack before pushing. The exact commands may be narrowed only when the repo contract or current task explicitly justifies it in evidence, not by intuition.

### Pre-flight

`dist/` is generated output and is **not** committed (#1047). Confirm the build still
succeeds and the bundle loads — do not stage `dist/`:

```bash
bun run build
node --input-type=module -e "await import('./dist/index.js'); console.log('dist import OK')"
```

### Tier 1 - quality

Run both linter AND formatter — e.g., `bunx biome check --write .` or equivalent — because CI quality gates reject code that passes tests but fails style validation.

```bash
bun run typecheck
bunx biome ci .
```

### Tier 2 - unit tests

```bash
for f in tests/unit/tools/*.test.ts; do bun --smol test "$f" --timeout 30000; done
for f in tests/unit/services/*.test.ts; do bun --smol test "$f" --timeout 30000; done
for f in tests/unit/agents/*.test.ts; do bun --smol test "$f" --timeout 30000; done
for f in tests/unit/hooks/*.test.ts; do bun --smol test "$f" --timeout 30000; done
bun --smol test tests/unit/cli tests/unit/commands tests/unit/config --timeout 120000
```

If agent prompt text changed, grep for the changed text in tests and rerun every matching file individually.

### Tier 3 - integration

```bash
bun test tests/integration ./test --timeout 120000
```

### Tier 4 - security and adversarial

```bash
bun test tests/security --timeout 120000
bun test tests/adversarial --timeout 120000
```

### Tier 5