# Git Conventions

> Apply Singleton SD git conventions — commit format, branch naming, ticket linking, and sibling worktrees

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

---


# Git Conventions

You are a senior engineer helping enforce Singleton SD's git conventions. Apply these rules when writing commit messages, naming branches, or reviewing either.

---

## Engineering host

Read consumer `.skills/profile` / [`config/tracker-profiles/`](../../config/tracker-profiles/README.md).

| Host | Preferred branch | Preferred commit ticket token |
|------|------------------|-------------------------------|
| GitHub / GitLab app repos | `<type>/<issue-number>-<kebab-title>` | `#<issue>` or bare issue number from branch |
| This skills repo (ClickUp) | `feature/AI-NN-slug` | `AI-NN` custom id |

Legacy ClickUp Delivery branches (`feature/<clickup-id>-…`) may exist on older app work — do not create new ones.

## Commit message format

```
type: TICKET Description in sentence case
```

Examples:
```
feat: #284 Add multi-agent skills install
feat: AI-47 Migrate poc skills into categories
feat: SSDOP-42 Add dark mode toggle to settings page
```

### Rules

| Rule | Requirement |
|------|-------------|
| Format | `type: TICKET Description` |
| Subject case | Sentence-case — first letter capitalized, rest lowercase |
| Subject max length | 50 characters |
| Subject ending | No period `.` at end |
| Ticket presence | Required in commit message **or** inferrable from branch name |
| Ticket format | Host issue (`#284` / `284`) **or** `[A-Z]{1,5}-[0-9]{1,5}` (e.g. `AI-47`, `SSDOP-42`) |
| Body separator | Blank line between subject and body (if body is present) |
| Body line length | Max 72 characters per line |
| Release commits | Skipped — format is `chore: Release vX.Y.Z` (auto-generated) |

### Commit body: 72-character lines

When the commit has a **body** (paragraphs or bullet list):

- **Every** body line must be **≤ 72 characters** (count spaces and punctuation).
- That includes lines that start with a bullet (`- `): the whole line must stay
  within the limit; wrap long bullets onto continuation lines if needed.
- Prefer breaking at natural phrase boundaries, not mid-word.

Example (subject obeys 50-character limit; each body line ≤ 72):

```
chore: SSDOP-42 Add parallel TS build driver

- Parallel: generate-html, manifest icons, and profile pipeline
- Profile: static assets, then animations (PNG cache reuse)
- Run build via ts-node instead of bash for portability
```

### Ticket auto-injection

The `prepare-commit-msg` hook automatically injects the ticket number from the branch name. If you are on `feature/SSDOP-42-dark-mode`, writing:
```
feat: Add dark mode toggle
```
becomes:
```
feat: SSDOP-42 Add dark mode toggle
```

You only need to include the ticket explicitly when:
- You are on a non-feature/hotfix branch (e.g., `develop`)
- The ticket in your commit differs from the branch (this will error — fix the mismatch)

### Allowed types (conventional commits)

| Type | When to use |
|------|-------------|
| `feat` | New feature or user-facing behaviour |
| `fix` | Bug fix |
| `docs` | Documentation only |
| `style` | Formatting, whitespace — no logic change |
| `refactor` | Restructure without changing behaviour |
| `perf` | Performance improvement |
| `test` | Add or update tests |
| `ci` | CI/CD pipeline changes |
| `chore` | Build scripts, tooling, dependency updates |
| `revert` | Reverting a previous commit |

---

## Branch naming

**App repos (GitHub / GitLab issues):**

```
<type>/<issue-number>-<kebab-title>
```

Examples: `feat/284-skills-multi-agent-install`, `fix/211-login-redirect`, `chore/284-skills-install`.

**Skills repo / ClickUp-custom-id workflows:**

```
feature/TICKET-NUMBER[-optional-slug]
hotfix/TICKET-NUMBER[-optional-slug]
release/vMAJOR.MINOR.PATCH
```

Also allowed (protected): `main`, `master`, `develop`, `design`.

Examples:
```
feature/AI-47-skills-consolidation
feature/SSDOP-42-dark-mode-toggle
hotfix/SSDOP-17-null-pointer-fix
release/v1.3.0
```

Prefer the target repo's `AGENTS.md` when it defines a stricter pattern. The skills-repo `post-checkout` hook validates ClickUp-style names on creation.

---

## Isolated worktrees

Implement and review on a **sibling** worktree created from the latest
`origin/<default-branch>`. Detect the default branch from `origin/HEAD` (`master`
or `main`); do not hardcode it.

- Path sits next to the default checkout, for example
  `<repo>/feature-SSDOP-42-dark-mode` beside `<repo>/main`.
- Never nest `.worktrees/` (or any worktree) inside an existing checkout.
- Never edit or push `main` / `master` for feature work.
- Parent agents create the worktree **before** launching a subagent and pass
  that path as the subagent working directory.
- Subagents already inside a feature worktree must stay there and must not
  create another worktree.

Full procedure: [`engineering/isolated-worktree`](../isolated-worktree/SKILL.md).

---

## TypeScript filename conventions

Staged `.ts` files must match one of these patterns:

| Pattern | Example |
|---------|---------|
| `kebab-case.ts` | `token-parser.ts` |
| `kebab-case.spec.ts` | `token-parser.spec.ts` |
| `kebab-case.test.ts` | `token-parser.test.ts` |
| `PascalCase.ts` | `TokenParser.ts` |
| `PascalCase.d.ts` | `TokenParser.d.ts` |

The `pre-commit` hook blocks commits containing files that don't match.

---

## Versioning

Versions follow **semver** and are bumped automatically by `release-it` based on commit types:

| Commit type | Version bump |
|-------------|-------------|
| `fix:` | Patch (`1.2.3` → `1.2.4`) |
| `feat:` | Minor (`1.2.3` → `1.3.0`) |
| `BREAKING CHANGE:` in footer | Major (`1.2.3` → `2.0.0`) |

Never manually edit the version in `package.json`. Run `yarn release` (dry-run) or `yarn release:ci` (CI/CD) instead.

---

## Validation checklist

Before pushing, verify:
- [ ] Work happens in a sibling worktree, not on `main` / `master`
- [ ] Branch name matches `feature/TICKET-NNN` or `hotfix/TICKET-NNN` or an allowed base branch
- [ ] Commit subject is ≤ 50 chars, sentence-case, no period
- [ ] Ticket number is present (in commit or auto-injected from branch)
- [ ] Body lines (if any) are ≤ 72 chars with a blank separator line
- [ ] TypeScript filenames follow kebab-case or PascalCase

