# Commit Convention

This project uses [Conventional Commits v1.0.0](https://www.conventionalcommits.org) with
project-specific rules that make every commit traceable to its tracking issue.

## Format

```text
type(scope): summary

body (optional)

footer
```

## Provider-aware scope and footer

The scope and footer format depends on the repository's issue provider
(`platform.issue_adapter` in `.github/agdt-config.json`). The **title never uses a
markdown link** for any provider — only the Jira footer keeps a full link, because
GitHub auto-links bare `#NNN` references while it does not auto-link Jira keys.

| Provider | Scope | Footer |
|----------|-------|--------|
| `github` | `(#NNN)` — bare issue number (GitHub auto-links it) | `#NNN` — bare |
| `jira` | `(KEY)` — bare key (e.g. `PROJECT-1234`) | `[KEY](https://<jira>/browse/KEY)` — full markdown link |
| `markdown` | `(KEY)` — bare key | `KEY` — plain text |

This repository is GitHub-managed, so the examples below use the GitHub `#NNN` form.

## Rules

### 1. Scope is mandatory — it identifies the tracking issue

The scope is **never** optional. On GitHub it is the plain `#NNN` issue number
(GitHub auto-links it in commit and PR views):

```text
feat(#123): add webhook support
```

### 2. Footer must repeat the issue reference

The last line of the commit message must repeat the same issue reference(s) from the
scope. On GitHub this is the bare `#NNN`:

```text
feat(#123): add webhook support

- Implemented webhook handler
- Added tests

#123
```

### 3. Breaking changes use both `!` after scope and `BREAKING CHANGE:` footer

Use `!` immediately after the closing `)` of the scope, and start the footer with `BREAKING CHANGE:` followed by the issue reference(s).

```text
feat(#123)!: remove deprecated API endpoints

- Detail part 1
- Detail part 2

BREAKING CHANGE: #123
```

### 4. Parent/child issue ordering

When a parent issue exists, it comes **first**, separated by `/`:

- In the scope: `parent/child` (no spaces around `/`)
- In the footer: `parent / child` (spaces around `/`)

```text
feat(#123/#234): implement sub-feature

- Detail part 1
- Detail part 2

#123 / #234
```

### 5. Multiple issues (no parent-child relationship)

Comma-separated, sorted in **ascending** order by issue number:

```text
feat(#123, #234): implement related features

- Detail part 1
- Detail part 2

#123, #234
```

### 6. Ordering rules summary

- Parent issues always come **before** child issues
- Within the same level, lowest issue number comes **first** (ascending order)
- These rules apply to both the scope and the footer

### 7. Supported types

| Type | Purpose |
|------|---------|
| `feat` | A new feature |
| `fix` | A bug fix |
| `docs` | Documentation only changes |
| `style` | Changes that do not affect the meaning of the code |
| `refactor` | A code change that neither fixes a bug nor adds a feature |
| `perf` | A code change that improves performance |
| `test` | Adding missing tests or correcting existing tests |
| `build` | Changes that affect the build system or external dependencies |
| `ci` | Changes to CI configuration files and scripts |
| `chore` | Other changes that don't modify src or test files |
| `revert` | Reverts a previous commit |

## Examples

### Single issue

```text
fix(#42): handle null values in PR thread API

- Added null guard in thread parser
- Updated unit tests

#42
```

### Parent + child issue

```text
feat(#10/#42): implement webhook handler

- Added endpoint
- Wired up notification

#10 / #42
```

### Multiple unrelated issues

```text
docs(#5, #12): update CONTRIBUTING and README

#5, #12
```

### Jira-managed repository

When `platform.issue_adapter` is `jira`, use the bare key in the scope and a full
markdown link to the Jira browse URL in the footer:

```text
fix(PROJECT-1234): handle null values in PR thread API

- Added null guard in thread parser

[PROJECT-1234](https://jira.example.com/browse/PROJECT-1234)
```
