Conventions and format for AriaType commit messages.
All commits MUST follow Conventional Commits format:
type(scope): subject
[optional body]
[optional footer]
- Type: One of the predefined types (Section 2)
- Scope:
desktop,website, or omitted for repo-wide changes (Section 3) - Subject: Concise description in imperative mood, no period, ≤72 characters
- Language: English only
- No trailing period: Subject line ends without punctuation
feat(desktop): retry failed transcriptions from history
feat(desktop): cancel recording with ESC key
fix(desktop): prevent long recordings from being truncated
refactor(desktop): faster model loading on startup
chore: bump version to 0.3.0
docs: add v0.3 release notes
ci: add macOS binary pre-signing for smoother install
simple-git-hooks runs commitlint and then
scripts/check-commit-msg.mjs as the commit-msg hook.
commitlint.config.cjs validates the standard Conventional Commit
shape, allowed types and scopes, header length, body spacing, and body
wrapping. scripts/check-commit-msg.mjs enforces AriaType-specific
rules that commitlint does not cover, including English-only ASCII text,
staged-file scope checks, and contiguous Git trailer blocks.
For local checks, pipe a message into commitlint:
printf 'chore: add commitlint checks\n' | pnpm lint:commitHistorical one-line commits remain valid:
chore: release v0.5.2
fix(desktop): context aware visual terms
chore(website): update CNAME files and rebuild static assets
| Type | When | Examples |
|---|---|---|
feat |
User-facing feature | Add retry functionality, new hotkey support |
fix |
Bug fix, error correction | Fix audio truncation, correct API response handling |
refactor |
Code change without behavior change | Unify engine trait, reorganize modules |
chore |
Internal tooling, dev experience, release | Update version, dev log format, debug helpers |
docs |
Documentation only | Update README, fix typo in guide |
build |
Build system, dependencies | Add build script, update Cargo.toml |
ci |
CI/CD configuration | Update GitHub Actions, add lint step |
test |
Adding or modifying tests | Add integration test for pipeline |
perf |
Performance improvement | Optimize audio chunking, reduce memory usage |
style |
Code style (formatting, whitespace) | Fix indentation, normalize quotes |
Primary rule: Who benefits from the change determines the type.
| Audience | Type | Examples |
|---|---|---|
| End users | feat, fix, refactor, perf |
Retry button, recording fix, faster startup |
| Developers only | chore |
Dev log prefix, debug logging, internal helpers |
Changes visible to end users (in app behavior, release notes) use feat/fix/refactor/perf. Changes only visible to developers (terminal output, internal tooling, debug aids) use chore.
✅ feat(desktop): retry failed transcriptions from history
→ User sees retry button in history panel
✅ chore(desktop): show dev/prod tag in terminal logs
→ Developer sees [DEV]/[PROD] prefix when debugging
❌ feat(desktop): show dev/prod tag in terminal logs
→ Not user-facing, no release note needed
Scope identifies the affected package. Only three scopes are allowed:
| Scope | Package | Notes |
|---|---|---|
desktop |
apps/desktop/* |
Desktop application (Tauri + frontend, including assets, icons, config) |
website |
apps/website/* |
Website and marketing site |
| (none) | Repository-wide | Documentation, CI, release, monorepo-wide changes |
- Use
desktopfor any change touchingapps/desktop/*(Rust backend, frontend, assets, config) - Use
websitefor any change touchingapps/website/* - Omit scope for repository-wide changes: documentation (
README.md,context/*), CI/CD, release, tooling, dependencies that span packages - Never use invented scopes (
stt,audio,ui, etc.) — these are domains, not packages - If change touches both desktop and website — commit separately, one commit per package
Subject should describe what users experience, not technical implementation:
✅ feat(desktop): retry failed transcriptions from history
❌ feat(desktop): add transcription retry functionality with saved audio lookup
✅ fix(desktop): prevent long recordings from being truncated
❌ fix(desktop): fix audio chunk boundary handling in recorder thread
✅ refactor(desktop): faster model loading on startup
❌ refactor(desktop): unify engine trait and lazy-load on background thread
Users read commit messages in release notes. They care about:
- "What can I do now that I couldn't before?" (feat)
- "What problem is fixed?" (fix)
- "What behavior changed?" (refactor)
Technical details belong in the body, not the subject.
Use imperative mood ("add" not "added", "fix" not "fixes"):
✅ feat(desktop): retry failed transcriptions
❌ feat(desktop): retried failed transcriptions
✅ fix(desktop): prevent recording truncation
❌ fix(desktop): prevented recording truncation
Subject starts with lowercase:
✅ feat(desktop): retry failed transcriptions
❌ feat(desktop): Retry failed transcriptions
Subject line ≤72 characters. If longer, move detail to body:
✅ feat(desktop): retry failed transcriptions from history
❌ feat(desktop): retry failed transcriptions from history with saved audio and timestamp preservation
Better:
feat(desktop): retry failed transcriptions from history
Failed transcriptions can now be retried from the history
panel. The retry uses saved audio and preserves the
original timestamp.
Subject ends without trailing period:
✅ feat(desktop): retry failed transcriptions
❌ feat(desktop): retry failed transcriptions.
Optional body provides technical context for developers.
- Separate from subject with blank line
- Use imperative mood consistently
- Explain implementation details (subject already covers user impact)
- Wrap at 72 characters
- One paragraph per thought
feat(desktop): retry failed transcriptions from history
Failed transcriptions can now be retried from the history
panel. The retry uses saved audio and preserves the
original timestamp.
Implementation stores audio buffer on failure and adds a
retry button to failed history entries. Retry flow
reuses the existing transcription pipeline.
Optional footer for issues, breaking changes, or attribution.
feat(desktop): retry failed transcriptions from history
Closes #123
Refs #456
refactor(desktop): faster model loading on startup
BREAKING CHANGE: Custom model paths in settings are now
resolved relative to the app directory, not the home directory.
Users with custom paths may need to update their config.
Automation and agent-authored commits may add native Git trailers for decision context. Keep trailers as one contiguous block at the end of the message, with no blank lines between trailer lines.
feat(desktop): add voice-writing polish templates
Polish templates now cover common dictation outcomes while preserving
the existing polish pipeline boundary.
Constraint: Template scope stays within the existing polish pipeline
Rejected: Mirror Typeless actions directly | selected text is separate
Confidence: high
Scope-risk: moderate
Tested: cargo test templates
Not-tested: Full desktop e2e suite
| Anti-Pattern | Fix |
|---|---|
No type (Update CNAME) |
chore(website): update CNAME |
Wrong type (fix: add new feature) |
feat(desktop): add new feature |
Dev-only change as feat (feat: add dev log prefix) |
chore(desktop): show dev/prod tag in terminal logs |
Past tense (added retry) |
add retry |
Capitalized subject (Add retry) |
add retry |
Trailing period (add retry.) |
add retry |
Vague subject (fix bug) |
fix(desktop): prevent recording truncation on long sessions |
Too technical (fix audio chunk boundary) |
fix(desktop): prevent long recordings from being truncated |
Implementation-focused (refactor engine trait) |
refactor(desktop): faster model loading on startup |
Invented scope (feat(stt): ...) |
feat(desktop): ... |
| Too long subject (>72 chars) | Move detail to body |
Non-English (添加重试功能) |
feat(desktop): retry failed transcriptions |
Scope for docs (docs(context): ...) |
docs: ... (omit scope for repo-wide) |
- Type matches change category (Section 2)
- Type matches audience:
feat/fix/refactor/perffor users,chorefor devs - Scope is
desktop,website, or omitted (Section 3) - Subject describes user-facing impact, not implementation
- Subject uses imperative mood
- Subject starts lowercase
- Subject ≤72 characters
- Subject ends without period
- English only
- Body (if present) explains technical details
- Footer (if present) references issues or breaking changes
feat(desktop): retry failed transcriptions from history
feat(desktop): cancel recording with ESC key
feat(desktop): support Fn key in custom shortcuts
fix(desktop): prevent long recordings from being truncated
fix(desktop): eliminate white flash on app startup
refactor(desktop): faster model loading on startup
chore: bump version to 0.3.0
docs: add v0.3 release notes
ci: add macOS binary pre-signing for smoother install
chore(desktop): show dev/prod tag in terminal logs
chore(desktop): add debug logging for audio buffer
chore: update rust-toolchain version
chore: clean up unused dependencies
❌ fix audio chunk boundary handling
✅ fix(desktop): prevent long recordings from being truncated
❌ feat transcription retry with saved audio lookup
✅ feat(desktop): retry failed transcriptions from history
❌ refactor unify engine trait and lazy load
✅ refactor(desktop): faster model loading on startup
❌ fix return committed transcript from finish()
✅ fix(desktop): ensure transcription result appears after recording stops
❌ feat(desktop): add dev log prefix to terminal output
✅ chore(desktop): show dev/prod tag in terminal logs