Inferensys

Prompt

Conventional Commit Message Generation Prompt Template

A practical prompt playbook for using Conventional Commit Message Generation Prompt Template in production AI workflows.
Operations team reviewing AI workflow automation on laptop, workflow builder visible, casual office setup.
PROMPT PLAYBOOK

When to Use This Prompt

Define the job, the user, and the boundaries for generating Conventional Commits messages from a diff.

This prompt is designed for platform teams and AI coding agents that need to enforce a consistent commit history across a repository. The primary job-to-be-done is to transform a raw code diff into a single, well-structured commit message that strictly adheres to the Conventional Commits specification. The ideal user is a developer who has just staged a change or an automated CI/CD pipeline that needs to generate a squash commit message for a pull request. The required context is a unified diff of the changes, and optionally, any linked issue tracker IDs or co-author information.

Do not use this prompt for generating release notes, changelogs, or pull request descriptions, as those require a broader synthesis of multiple commits and a different audience. This prompt is also unsuitable for repositories that do not follow the Conventional Commits standard, or for commits that represent multiple unrelated logical changes; in those cases, the changes should be split into smaller, atomic commits first. The prompt assumes the input diff is a complete and final representation of a single logical change. It will not interrogate the diff for correctness or test coverage, only describe it.

Before integrating this prompt into a production harness, you must define clear evaluation criteria. The generated message must pass a strict schema check: the type must be from the allowed list, the description must be in the imperative mood, the first line must not exceed 72 characters, and any breaking change must be declared in the footer with a BREAKING CHANGE: token. If your team uses a custom scope list or extended footer fields, add those as explicit constraints in the prompt's [CONSTRAINTS] placeholder. The next step is to build a validation harness that can parse the output and provide immediate, actionable feedback to the developer if the message fails any of these rules.

PRACTICAL GUARDRAILS

Use Case Fit

Where this prompt works and where it does not. Use these cards to decide if the Conventional Commit Message Generation Prompt Template fits your workflow before integrating it into a CI pipeline or coding agent harness.

01

Good Fit: Automated CI Enforcement

Use when: You have a pre-commit or pre-push hook that needs to generate or validate commit messages from a diff. Guardrail: Always run a post-generation lint check for imperative mood, header length, and footer format before accepting the output.

02

Bad Fit: Unconventional or Custom Formats

Avoid when: Your team uses a non-Conventional Commits format, custom changelog tooling, or freeform commit messages. Guardrail: Fork the prompt template and replace the type/scope schema with your team's actual convention before use.

03

Required Input: Diff with Sufficient Context

Risk: Generating a commit message from a truncated or file-level-only diff produces vague descriptions. Guardrail: Provide at least 3 lines of surrounding context per hunk and include file paths. Validate that the output message references specific symbols or files changed.

04

Operational Risk: Breaking Change False Negatives

Risk: The model may fail to detect a breaking change in the diff and omit the ! marker or BREAKING CHANGE footer. Guardrail: Pair this prompt with a separate breaking change detection prompt and cross-validate. Require human approval for any commit flagged as non-breaking by the model but touching public API surfaces.

05

Operational Risk: Scope Drift in Monorepos

Risk: The model may guess the wrong scope when multiple packages or services are touched. Guardrail: Provide a file-to-scope mapping or CODEOWNERS context in the prompt. Validate the generated scope against the actual changed paths before accepting.

06

Variant: Squash Commit Synthesis

Use when: You need a single commit message from multiple branch commits rather than a single diff. Guardrail: Switch to the Squash Commit Message Synthesis Prompt variant. This prompt is designed for single-diff input and will produce incoherent results when fed multiple commit messages directly.

PROMPT PLAYBOOK

Copy-Ready Prompt Template

A reusable prompt template for generating Conventional Commits messages from a code diff, ready to be copied into your AI harness.

This prompt template is the core instruction set for an AI coding agent to generate a commit message that strictly follows the Conventional Commits specification. It is designed to be dropped into a system prompt or a user message within your AI harness. The template uses square-bracket placeholders for all dynamic inputs, ensuring you can wire it directly into your CI pipeline, pre-commit hook, or IDE plugin. The prompt instructs the model to analyze a provided diff, determine the correct type and scope, and structure the output with a description, body, and footer for breaking changes.

text
You are a commit message generator that strictly follows the Conventional Commits specification.

Analyze the provided code diff and generate a single commit message.

## Input
- **Diff:** [DIFF]
- **Repository Context (Optional):** [REPO_CONTEXT]
- **Team Convention Overrides (Optional):** [CONVENTION_OVERRIDES]

## Output Schema
Generate a commit message with the following structure:
<type>[optional scope]: <description>

[optional body]

[optional footer(s)]

## Constraints
- **Type:** Must be one of `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `build`, `ci`, `chore`, or `revert`.
- **Scope:** A noun in parentheses describing the section of the codebase (e.g., `auth`, `api`, `parser`). Omit if the change is global.
- **Description:** Use the imperative, present tense (e.g., "add" not "added" or "adds"). Start with a lowercase letter. Do not end with a period. Keep it under 72 characters.
- **Body:** Optional. Use the imperative, present tense. Explain the motivation for the change and contrast it with the previous behavior. Wrap lines at 72 characters.
- **Footer:**
  - **Breaking Changes:** If the diff introduces a breaking change, the footer MUST start with `BREAKING CHANGE: ` followed by a description of what changed, why, and migration notes.
  - **Issue References:** If the diff relates to any issues, include a footer line like `Closes #123` or `Refs #456`.
- **Formatting:** Separate the header from the body and each footer with a single blank line. Do not include any text before or after the commit message.

## Examples
### Example 1: Simple fix
Diff: `- return user.name + ' ' + user.surname;` `+ return `${user.name} ${user.surname}`;`
Commit Message:

fix(user-utils): correct string concatenation in display name

code

### Example 2: Feature with breaking change
Diff: `... changes to an API function signature ...`
Commit Message:

feat(api)!: send confirmation email on user registration

The registration endpoint now accepts an email field and triggers a confirmation email. Previously, only a username was required.

BREAKING CHANGE: the registerUser function now requires an email parameter in the options object. Update all callers to include a valid email address.

Closes #421

code

## Task
Generate the commit message for the provided diff.

To adapt this template, replace the [DIFF] placeholder with the actual unified diff output from your version control system. The [REPO_CONTEXT] placeholder can be populated with relevant file paths, directory structures, or package names to help the model infer an accurate scope. The [CONVENTION_OVERRIDES] placeholder allows you to inject team-specific rules, such as allowed custom types or required co-author footers, without rewriting the core prompt. For high-risk repositories, consider adding a final instruction that forces a [HUMAN_REVIEW] flag in the output if the model's confidence in the breaking change detection is low, ensuring a developer always validates potentially destructive changes before they are pushed.

IMPLEMENTATION TABLE

Prompt Variables

Required inputs for the Conventional Commit Message Generation Prompt. Each placeholder must be populated before the prompt is sent. Validation rules help catch missing or malformed inputs before the model runs.

PlaceholderPurposeExampleValidation Notes

[DIFF]

The git diff or patch content to analyze for commit message generation

diff --git a/src/auth/login.ts b/src/auth/login.ts @@ -12,7 +12,8 @@ export function authenticate...

Must be non-empty string. Validate with git diff --staged output or equivalent unified diff format. Reject if only whitespace changes without semantic content.

[COMMIT_TYPE_HINT]

Optional hint to constrain the Conventional Commits type field

fix

Must match one of: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert. Null allowed. If provided but invalid, prompt should fall back to model inference with a warning.

[SCOPE_HINT]

Optional hint for the scope field based on affected module or component

auth

Must be a lowercase alphanumeric string with optional hyphens, max 30 characters. Null allowed. Validate against known scope list if team convention enforces a controlled vocabulary.

[BREAKING_CHANGE_INDICATOR]

Boolean flag signaling whether the diff contains breaking changes

Must be true, false, or null. When null, the model must infer from diff. When true, prompt must enforce footer with BREAKING CHANGE: prefix. When false, prompt must suppress breaking change footer.

[TEAM_CONVENTION]

Team-specific rules for commit message format beyond Conventional Commits spec

{"max_header_length": 72, "require_issue_ref": true, "imperative_mood": true, "footer_fields": ["Refs", "Reviewed-by"]}

Must be a valid JSON object. Validate schema: max_header_length as integer 50-100, require_issue_ref as boolean, imperative_mood as boolean, footer_fields as array of strings. Reject if unknown keys present.

[ISSUE_REF]

Optional linked issue or ticket reference to include in footer

PROJ-1234

Must match pattern [A-Z]+-[0-9]+ or be null. If TEAM_CONVENTION.require_issue_ref is true, this field must be non-null. Validate format before prompt assembly.

[CO_AUTHORS]

Optional list of co-authors to include in commit message trailer

Must be array of strings matching Name <email> format or null. Validate each entry against email regex. Empty array allowed and treated as null.

[OUTPUT_FORMAT]

Desired output structure for the generated commit message

full

Must be one of: header_only, header_and_body, full. header_only returns type(scope): description. header_and_body adds body. full includes footers. Validate enum membership before prompt execution.

PROMPT PLAYBOOK

Implementation Harness Notes

How to wire the Conventional Commits prompt into a CI/CD pipeline, pre-commit hook, or AI coding agent with validation, retries, and logging.

This prompt is designed to be called programmatically, not pasted into a chat window. The primary integration points are a pre-commit hook, a CI job in a merge queue, or an AI coding agent's post-edit workflow. In all cases, the harness should capture the raw diff (via git diff --staged or the PR's unified diff), inject it into the [DIFF] placeholder, and parse the model's structured output. The prompt's [OUTPUT_SCHEMA] should request a JSON object with fields for type, scope, description, body, footer, and breaking_change boolean, making it straightforward to validate before the message is written to a commit or PR.

A production implementation requires a validation layer before the generated message is accepted. Write a post-generation validator that checks: (1) the type field matches an allowed list (e.g., feat, fix, docs, style, refactor, perf, test, chore, ci); (2) the description is in imperative mood (a simple heuristic is checking the first word is not past tense, but a stronger approach is a second LLM call with a binary classifier prompt); (3) the description does not exceed 72 characters; (4) if breaking_change is true, the footer contains a BREAKING CHANGE: token or the type/scope includes a !; and (5) the body wraps at 72 characters. If validation fails, the harness should retry once by feeding the validation errors back into the [CONSTRAINTS] or [OUTPUT_SCHEMA] section of the prompt, asking the model to correct the specific violations. If the retry also fails, the harness should log the failure and fall back to a human-authored message rather than silently accepting a non-compliant commit.

For model choice, a capable but cost-effective model like claude-3-5-haiku or gpt-4o-mini is sufficient for most diffs. Reserve larger models for complex, multi-file diffs where the body and footer require nuanced synthesis. The harness should log every generation attempt—including the raw diff, the model's output, validation results, and the final accepted message—to a structured logging system (e.g., JSON lines to a file or an observability platform). This audit trail is critical for debugging prompt drift, model regressions, or false-positive validation failures over time. For high-compliance repositories (e.g., SOC 2, FedRAMP), add a human approval step for any commit message where the model's breaking_change flag is true or where the diff touches files in a sensitive directory (e.g., auth/, billing/, migrations/). The harness should post the generated message to a review channel (Slack, a PR comment, or an internal tool) and block the commit until a human approves. Finally, avoid wiring this prompt directly into a post-commit hook that rewrites history; always generate the message before the commit is finalized so the developer can edit it.

IMPLEMENTATION TABLE

Expected Output Contract

Defines the fields, types, and validation rules for the Conventional Commits message generated by the prompt. Use this contract to parse and validate the model's output before accepting it into a commit or CI pipeline.

Field or ElementType or FormatRequiredValidation Rule

type

string enum: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert

Must match one of the allowed enum values exactly. Case-sensitive. Reject unknown types.

scope

string or null

If present, must be a non-empty string matching [a-zA-Z0-9._-]+. Must be wrapped in parentheses in the final message. Null allowed.

breaking

boolean

Must be true if the description starts with 'BREAKING CHANGE:' or the type/scope prefix ends with '!'. Otherwise false. Used to enforce footer presence.

description

string

Must be non-empty. Must start with a lowercase letter. Must use imperative mood (e.g., 'add' not 'added'). Must not end with a period. Max 72 characters.

body

string or null

If present, must be separated from the description by a blank line. Each line must wrap at 72 characters. Null allowed.

footer

string or null

If breaking is true, a 'BREAKING CHANGE:' footer is required. May also contain issue references like 'Refs: #123'. Each token must be on its own line. Null allowed if no breaking change and no references.

full_message

string

The assembled commit message. Must match the pattern: type(scope)!: description

body

footer. Validate with a regex that enforces structural integrity and line-length limits.

PRACTICAL GUARDRAILS

Common Failure Modes

What breaks first when generating Conventional Commits messages from diffs, and how to guard against it in production.

01

Imperative Mood Drift

What to watch: The model slips into past tense ('Fixed bug') or gerund form ('Fixing bug') instead of the required imperative mood ('Fix bug'). This is the most common format violation. Guardrail: Add a strict schema check that validates the first word after the type and scope against a blocklist of past-tense verbs and gerunds. Include a retry prompt that explicitly requests imperative mood with a counterexample.

02

Scope Hallucination

What to watch: The model invents a scope that doesn't exist in the repository's defined scope list (e.g., feat(auth)) when the team only uses feat(api). This breaks downstream changelog grouping. Guardrail: Pass the allowed scope list as a constrained enum in the prompt. Post-process the output to reject any scope not in the approved list and request regeneration with the valid options explicitly restated.

03

Breaking Change False Positives

What to watch: The model marks a change as breaking (! after type or BREAKING CHANGE: footer) for internal refactors or non-public API changes, causing unnecessary downstream alarm. Guardrail: Instruct the model to only flag breaking changes when public API signatures, documented behavior, or schema contracts are modified. Add a secondary check that requires at least one specific public-facing symbol or endpoint to be cited in the footer.

04

Subject Line Length Violation

What to watch: The generated subject line exceeds the 50-72 character limit, causing truncation in GitHub, git log --oneline, and notification tools. Guardrail: Enforce a hard character-count validator on the first line of the output. If exceeded, trigger a retry with an explicit constraint: 'Subject line must be under 60 characters. Shorten the description while preserving meaning.'

05

Body-Only Changes Without Subject

What to watch: For large diffs, the model sometimes generates a detailed body but a vague or empty subject line, making git log --oneline useless. Guardrail: Require a non-empty, specific subject line as a hard output constraint. Validate that the subject contains at least one concrete verb and object before accepting the output.

06

Footer Format Inconsistency

What to watch: The model uses non-standard footer formats like Breaking: instead of BREAKING CHANGE:, or Closes #123 without the required Refs: prefix for non-closing references. Guardrail: Define the exact footer token format in the prompt schema. Use a regex validator to reject any footer that doesn't match the approved patterns (BREAKING CHANGE:, Closes, Fixes, Refs).

IMPLEMENTATION TABLE

Evaluation Rubric

Use this rubric to test the quality of generated Conventional Commit messages before integrating the prompt into a CI pipeline or pre-commit hook. Each criterion targets a specific requirement of the specification.

CriterionPass StandardFailure SignalTest Method

Structure: Type and Scope

Message starts with a valid type (e.g., feat, fix) followed by parentheses containing a lowercase scope, then a colon and a space.

Missing type prefix, uppercase scope, or malformed separator (e.g., 'feat scope:')

Regex validation against ^(build|chore|ci|docs|feat|fix|perf|refactor|style|test)(\([a-z0-9-]+\))?!?: .+

Subject: Imperative Mood

The subject line begins with a verb in the imperative mood (e.g., 'add', 'fix', 'remove') and does not end with a period.

Subject starts with past tense ('added'), third person ('adds'), or ends with a period.

LLM-as-judge check: 'Does the subject use the imperative mood?' with a binary pass/fail.

Subject: Length Limit

The entire subject line (type, scope, and description) is 72 characters or fewer.

Subject line exceeds 72 characters.

String length check: len(subject) <= 72.

Body: Wrapping and Spacing

The body is separated from the subject by a single blank line and each line in the body is wrapped at 100 characters.

Missing blank line between subject and body, or body lines exceed 100 characters.

Parse check: verify one empty string between subject and body array. Iterate body lines and check len(line) <= 100.

Footer: Breaking Change Notation

If the diff contains a breaking change, the footer MUST include 'BREAKING CHANGE:' followed by a description or the type/scope MUST include a '!' marker.

Breaking change detected in the diff but the generated message lacks both the '!' marker and the 'BREAKING CHANGE' footer.

LLM-as-judge check: 'Does the diff contain a breaking change?' If yes, validate footer or marker presence with regex.

Footer: Issue Reference Format

If the diff references an issue, the footer contains 'Refs: #[ISSUE_NUMBER]' or 'Closes: #[ISSUE_NUMBER]'.

Issue number is mentioned in the body but missing from the structured footer, or uses an invalid format like '#123' without a token.

Regex validation against ^(Refs|Closes|Fixes): #\d+$ for each footer line.

Content: Diff Grounding

The message describes the 'what' and 'why' of the diff. It does not hallucinate features or files not present in the [DIFF].

The message mentions a file, function, or feature that does not appear in the provided [DIFF] context.

Manual spot-check or LLM-as-judge: 'Does the commit message reference any entity not found in the provided diff?'

ADAPTATION OPTIONS

Adapt This Prompt

How to adapt

Use the base prompt with a lightweight wrapper. Skip strict schema validation in the harness. Accept the model's raw output and log it for review.

code
Generate a Conventional Commits message for this diff:

[DIFT]

Return only the commit message.

Watch for

  • Missing ! on breaking changes
  • Scope guessing when no scope is obvious
  • Body/footer omitted entirely on complex diffs
Prasad Kumkar

About the author

Prasad Kumkar

CEO & MD, Inference Systems

Prasad Kumkar is the CEO & MD of Inference Systems and writes about AI systems architecture, LLM infrastructure, model serving, evaluation, and production deployment. Over 5+ years, he has worked across computer vision models, L5 autonomous vehicle systems, and LLM research, with a focus on taking complex AI ideas into real-world engineering systems.

His work and writing cover AI systems, large language models, AI agents, multimodal systems, autonomous systems, inference optimization, RAG, evaluation, and production AI engineering.