# Commit Message

> Guide for writing clear, consistent git commit messages following this repository's conventions

- Skill: `evolvinglmms-lab/commit-message` (Agent Skill)
- Install (CLI): `npx skillmds@latest add evolvinglmms-lab/commit-message`
- Raw SKILL.md: https://api.skillmd.com/api/skills/evolvinglmms-lab/commit-message/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: evolvinglmms-lab (https://skillmd.com/u/evolvinglmms-lab)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/evolvinglmms-lab/commit-message

---


## Purpose

Use this skill when writing git commit messages. It enforces a formal Conventional Commits style suitable for open-source collaboration and future changelog generation, while still keeping messages aligned with this repository's tone.

---

## Format

```
<type>: <subject>
```

- **Default style**: formal Conventional Commits (`feat:`, `fix:`, `docs:`, `test:`, `chore:`, etc.)
- **No scope parentheses by default** — this repo usually does not use `type(scope):` style; add a scope only if the user explicitly asks
- **Subject**: imperative mood, lowercase first word, no trailing period, max ~72 chars
- **Body** (optional): blank line after subject, wrap at 72 chars, explain *why* not *what*

---

## Types

| Type | When to use | Example |
|---|---|---|
| `feat` | New user-visible feature or capability | `feat: add packed SFT dataset assembly workflow` |
| `fix` | Bug fix | `fix: prevent cross-sample attention leakage in packed runs` |
| `docs` | Documentation, README, guides, skills, comments-only docs | `docs: explain cu_lengths attention boundaries` |
| `test` | Tests, fixtures, consistency checks, validation scripts | `test: add HF/Megatron consistency checks for PP=2` |
| `refactor` | Code restructuring, no behavior change | `refactor: move patch position block layout into task encoder` |
| `chore` | Maintenance, internal cleanup, generated metadata, repo hygiene | `chore: remove internal-only skill references` |
| `perf` | Performance improvement without behavior change | `perf: reduce token length scan overhead` |
| `build` | Build system, dependencies, Docker, packaging | `build: update flash attention to v2.7.0` |
| `ci` | CI/CD configuration and automation | `ci: add packed dataset smoke test job` |
| `style` | Formatting-only changes, no code behavior change | `style: format offline packing scripts` |

**Notes:**
- `feat` and `fix` are strongly preferred for code changes
- Use `docs` for skill files under `.opencode/skills/`
- Avoid legacy bare messages like `updated`, `missing _extra_state`, or `add OV2 SP` unless the user explicitly asks to preserve old repo style
- `Revert` and `Merge` are generated by git — don't manually write these types

---

## Rules

### 1. Subject Line

- **Imperative mood**: "add", "fix", "refactor" — NOT "added", "fixes", "refactoring"
- **Lowercase** after type prefix: `feat: add ...` not `feat: Add ...`
- **No period** at the end
- **Max 72 characters** (hard limit for git log formatting)
- **What changed**, not how: `fix: correct rotary_base override in 8B config` not `fix: changed value from 1000000 to 8000000`

### 2. Body (when needed)

Use a body when:
- The change is non-obvious (e.g., subtle bug fix, architectural decision)
- There are constraints or caveats others should know
- The PR has multiple commits and each needs context

```
feat: add YaRN RoPE scaling to Megatron training path

Wire YarnRotaryEmbedding into QwenModel when --rope-type=yarn is set.
All default parameters match the official Qwen3-8B config.

Affected files:
- qwen_model.py: construct YarnRotaryEmbedding, return (emb, mscale) tuple
- attention.py: extract mscale before RoPE application
- arguments.py: add 7 CLI args for YaRN configuration
```

### 3. PR-linked Commits

When a commit will be part of a PR (most cases in this repo):
- The commit message should be self-contained — don't rely on PR description
- Reference issue numbers if applicable: `fix: loading dataloader (#121)`
- The `(#N)` suffix is added by GitHub on squash-merge — don't add it manually in local commits

### 4. Squash / Reword / Multi-author Rules

When cleaning up commit history before a PR:

- Prefer squashing small fixup commits by **day**: one coherent commit per day of work, unless a day contains clearly unrelated changes that should stay separate.
- If a squashed commit includes work from multiple authors, the final commit message **must** preserve every contributor with `Co-authored-by` trailers.
- Use each contributor's canonical Git name and email from the original commits.
- Rewording a commit message normally preserves the original `Author`; do **not** use `--reset-author` unless the user explicitly requests it.
- If the branch was already pushed, any squash/reword rewrites history and must be pushed with `--force-with-lease`, never plain `--force`.

Example multi-author squash commit:

```text
docs: explain distributed offline packing workflow

Group one day of packing notes into a single guide so the PR history stays
reviewable while preserving each contributor from the original commits.

Co-authored-by: Alice Zhang <alice@example.com>
Co-authored-by: Bob Chen <bob@example.com>
```

### 5. Multi-file Changes

For commits touching many files, the subject should describe the *intent*, not list files:

```
# GOOD
feat: add YaRN RoPE support to QwenModel

# BAD
update qwen_model.py, attention.py, arguments.py, provider.py, config.py, model.py, mid_training.sh
```

### 6. What NOT to Write

- **No generic messages**: "update code", "fix bug", "misc changes"
- **No WIP commits to main**: "wip", "temp", "test" (use branches)
- **No file lists as subject**: "update foo.py and bar.py"
- **No past tense**: "fixed", "added", "updated" — use imperative
- **No emoji** unless the repo uses them (this repo does not)

---

## Decision Tree

```
Is it a new capability?
  YES → feat: <what it enables>
  NO ↓

Is it a bug fix?
  YES → fix: <what was broken>
  NO ↓

Is it restructuring without behavior change?
  YES → refactor: <what was reorganized>
  NO ↓

Is it adding a new file/script/example?
  YES → docs: if documentation/skill, test: if test fixture, chore: if repo maintenance, feat: if user-visible capability
  NO ↓

Is it a config/dependency/version update?
  YES → build: for dependencies/build/Docker, ci: for CI, chore: for general maintenance
  NO ↓

Is it trivial (typo, comment, formatting)?
  YES → docs: for documentation typo, style: for formatting-only code changes
  NO → pick the closest type
```

---

## Examples from This Repository

These are real commits — use them as reference for tone and length:

```
fix loading dataloader (#121)
missing _extra_state (#117)
Refactor model consistency checks and enhance encoder loading (#120)
add OV2 SP (#112)
update 30ba3b (#97)
feat: add MoE merge support for Qwen3-30B-A3B (#95)
refactor: move patch position block layout into task encoder (#89)
dev assert (#81)
```

Prefer the formal Conventional Commits shape for new local commits, even though older history contains mixed styles.

Better current-style examples:

```
feat: add packed SFT dataset assembly workflow
fix: prevent cross-sample attention leakage in packed runs
docs: explain cu_lengths attention boundaries
test: add HF/Megatron consistency checks for PP=2
chore: remove internal-only skill references
refactor: simplify Megatron checkpoint layout detection
build: update flash attention to v2.7.0
```

---

## Quick Template

For most changes, just fill in:

```
<type>: <imperative verb> <what> [in/for/to <where>]
```

Examples:
- `feat: add custom pipeline layer splitting for PP>2`
- `fix: correct rotary_base override for 8B config`
- `docs: document distributed offline packing workflow`
- `test: add OneVision2 consistency fixture for PP=2`
- `chore: remove internal-only skill references`
- `refactor: extract ViT encoder into standalone module`
- `build: update flash attention to v2.7.0`

