# 0003 — Release workflow Date: 2026-06-01 Status: accepted ## Context The project needed a consistent, enforced standard for commit messages, changelog generation, versioning, and GitHub releases — especially important since both humans and AI agents (Claude Code, Codex) commit to the repo. ## Decision - **commitlint** (`@commitlint/config-conventional`) enforces conventional commit format at the `commit-msg` git hook - **husky** v9 wires the hooks; `prepare` installs them on `pnpm install` - **lint-staged** runs prettier + eslint on staged files at the `pre-commit` hook - **release-it** + `@release-it/conventional-changelog` manages the full release cycle: - bumps `package.json` version (semver) - generates/prepends to `CHANGELOG.md` - creates a signed git tag (`v{version}`) - creates a GitHub Release with the generated notes - pushes the tag and commit Release commands: - `pnpm release` — interactive (prompts for increment type) - `pnpm release:patch` / `:minor` / `:major` — non-interactive - `pnpm release:dry` — preview without writing anything - Requires `GITHUB_TOKEN` in env for GitHub Release creation Conventional commit types: `feat`, `fix`, `refactor`, `docs`, `test`, `chore`, `perf`, `ci`, `revert` ## Consequences - Every commit is validated; bad format is rejected immediately - CHANGELOG.md is auto-generated from commit history — no manual upkeep - Releases are reproducible: one command, idempotent output - `chore`, `ci`, `test` commits are hidden in the changelog; `feat`, `fix`, `perf`, `refactor`, `docs` are surfaced