skills/lerianstudio/ring/ring:git-commit

ring:git-commit

SKILL.md

Analyze changes, group them into coherent atomic commits, and create signed commits following repository conventions. This skill transforms a messy working directory into a clean, logical commit history.

Smart Commit Organization

This skill does MORE than just commit. It analyzes your changes and organizes them intelligently.

What It Does

Working Directory State          →  Organized Commits
─────────────────────────────────────────────────────────
- Modified: auth.ts              →  Commit 1: feat(auth): add OAuth2 support
- Modified: auth.test.ts            (auth.ts + auth.test.ts)
- Modified: package.json         →  Commit 2: chore(deps): update dependencies
- Modified: README.md            →  Commit 3: docs: update authentication guide
- New: logger.ts                 →  Commit 4: feat(logging): add structured logger
- New: logger.test.ts               (logger.ts + logger.test.ts)

Grouping Principles

Principle Description
Feature + Tests Implementation and its tests go together
Config Changes package.json, tsconfig, etc. grouped separately
Documentation README, docs/ changes grouped together
Refactoring Pure refactors (no behavior change) separate
Bug Fixes Each fix is atomic with its test

Process Overview

  1. Analyze - Run git status and git diff to understand all changes
  2. Group - Cluster related changes into logical commits
  3. Order - Determine optimal commit sequence (deps before features, etc.)
  4. Confirm - Present grouping plan to user for approval
  5. Execute - Create signed commits in sequence

Single vs Multiple Commits

Single commit when:

  • All changes are for one coherent feature/fix
  • User provides a specific message via argument
  • Changes are minimal and related

Multiple commits when:

  • Changes span different concerns (feature + docs + deps)
  • Mix of features, fixes, and chores
  • Better git history benefits future archaeology

User Confirmation

Before creating commits, present the plan:

Proposed Commit Plan:
─────────────────────
1. feat(auth): add OAuth2 refresh token support
   - src/auth/oauth.ts (modified)
   - src/auth/oauth.test.ts (modified)

2. chore(deps): update authentication dependencies
   - package.json (modified)
   - package-lock.json (modified)

3. docs: update OAuth2 setup guide
   - docs/auth/oauth-setup.md (modified)

Proceed with this plan? [Yes / Modify / Single commit]

Use AskUserQuestion to confirm:

  • Yes - Execute the plan as proposed
  • Modify - User can adjust groupings
  • Single commit - Combine everything into one commit

⛔ HARD STOP - TRAILER RULES ⛔

THE MOST COMMON MISTAKE: Putting trailer text INSIDE the -m quotes.

# ❌ WRONG - "X-Lerian-Ref" text is INSIDE the -m quotes
git commit -m "feat: add feature

X-Lerian-Ref: 0x1"

# ✅ CORRECT - --trailer is a SEPARATE command-line argument OUTSIDE quotes
git commit -m "feat: add feature" --trailer "X-Lerian-Ref: 0x1"

BEFORE writing ANY git commit command, answer this checkpoint:

  • Does my -m "..." contain ONLY the commit message? (NO trailer text inside)
  • Are --trailer flags OUTSIDE and AFTER the -m parameter?
  • Is my command structured as: git commit -m "msg" --trailer "key: value"?

If you answered NO to ANY question → STOP. Re-read the MANDATORY RULES below.

Required Command Structure

EVERY git commit command you create MUST follow this exact structure:

git commit \
  -m "commit message line 1" \
  -m "optional body line 2" \
  --trailer "X-Lerian-Ref: 0x1"

Visual breakdown - understand WHERE each piece goes:

git commit -m "feat: add feature" --trailer "X-Lerian-Ref: 0x1"
           │                    │ │                           │
           └── MESSAGE ─────────┘ └── SEPARATE FLAG (NOT inside -m) ──┘
               (inside quotes)        (after the closing quote)

The --trailer flag is NOT text. It's a command-line argument to git, like -m or --amend.

Notice:

  • -m parameters come FIRST
  • -m contains ONLY the commit message (no trailers, no signatures)
  • --trailer parameters come AFTER all -m parameters
  • --trailer is a SEPARATE command-line argument

If your command doesn't match this structure → YOU ARE DOING IT WRONG.

MANDATORY RULES (NON-NEGOTIABLE)

These rules MUST be followed for EVERY commit:

  1. NEVER include visible markers or hashtags in commit message body:

    • NO 🤖 Generated with [Claude Code](https://claude.com/claude-code)
    • NO Co-Authored-By lines of any kind
    • NO emoji signatures or hashtags of any kind
    • NO "Generated by" text in message body
    • NO system references or internal codes in the message body
    • The -m parameter contains ONLY the commit message. PERIOD.
  2. ALWAYS use --trailer parameter for internal system tracing:

    • --trailer "X-Lerian-Ref: 0x1" - REQUIRED
    • Trailer goes AFTER all -m parameters in the git command
    • Trailer is a SEPARATE command-line argument, NOT part of message text
  3. Commit message body must be clean and professional:

    • Only the actual commit description
    • No metadata, signatures, hashtags, or internal references in the body
    • If you see emoji, hashtags, or "X-Lerian-Ref" in your -m text → YOU ARE DOING IT WRONG

Commit Process

Step 1: Gather Context

Run these commands in parallel to understand the current state:

# Check staged and unstaged changes
git status

# View ALL changes (staged and unstaged)
git diff
git diff --cached

# View recent commits for style reference
git log --oneline -10

Step 2: Analyze and Group Changes

For each changed file, determine:

  1. Type: feat, fix, chore, docs, refactor, test, style, perf, ci, build
  2. Scope: Component or area affected (auth, api, ui, etc.)
  3. Logical group: What other files belong with this change?

Grouping heuristics:

File Pattern Likely Group
*.test.ts, *.spec.ts Group with implementation file
package.json, *-lock.json Dependency changes
*.md, docs/* Documentation
*.config.*, tsconfig.* Configuration
Same directory/module Often related

Create a mental (or actual) grouping:

Group 1 (feat): auth changes
  - src/auth/oauth.ts
  - src/auth/oauth.test.ts

Group 2 (chore): dependencies
  - package.json
  - package-lock.json

Group 3 (docs): documentation
  - README.md

Step 3: Determine Commit Order

Order matters for bisectability:

  1. Dependencies first - So subsequent commits can use them
  2. Core changes - Implementation before consumers
  3. Tests with implementation - Keep them atomic
  4. Documentation last - Documents the final state

Step 4: Present Plan and Confirm

MANDATORY: Get user confirmation before executing.

Present the commit plan using AskUserQuestion:

AskUserQuestion({
  questions: [{
    question: "I've analyzed your changes and propose this commit plan. How should I proceed?",
    header: "Commit Plan",
    multiSelect: false,
    options: [
      { label: "Execute plan", description: "Create X commits as proposed" },
      { label: "Single commit", description: "Combine all changes into one commit" },
      { label: "Let me review", description: "Show details before proceeding" }
    ]
  }]
});

If user selects "Let me review", show the full plan with files per commit.

Step 5: Draft Commit Messages

Follow the repository's existing commit style. If Conventional Commits is used:

<type>(<scope>): <subject>

<body - optional>

Guidelines:

  • Subject line: max 50 characters, imperative mood ("add" not "added")
  • Body: wrap at 72 characters, explain motivation/context
  • DO NOT include emoji signatures, hashtags, "Generated by", "X-Lerian-Ref", or any system markers in the message body

Step 6: Execute Commits (Signed)

For each commit group, in order:

  1. Stage only the files for this commit:
git add <file1> <file2> ...
  1. Create signed commit with trailers:
git commit -S \
  -m "<type>(<scope>): <subject>" \
  -m "<body if needed>" \
  --trailer "X-Lerian-Ref: 0x1"

Required flags:

  • -S - GPG sign the commit (REQUIRED for signed commits)
  • --trailer "X-Lerian-Ref: 0x1" - Internal system reference (REQUIRED)

If GPG signing fails:

  • Check if GPG key is configured: git config user.signingkey
  • Check if GPG agent is running: gpg --list-secret-keys
  • If no key configured, proceed without -S and inform user
  1. Repeat for each commit group

Step 7: Verify Commits

After all commits, verify the result:

# Show all new commits
git log --oneline -<number_of_commits>

# Verify signatures (if signed)
git log --show-signature -1

# Confirm clean state
git status

Step 8: Offer Push (Optional)

After successful commit, ask the user if they want to push:

AskUserQuestion({
  questions: [{
    question: "Push commit to remote?",
    header: "Push",
    multiSelect: false,
    options: [
      { label: "Yes", description: "Push to current branch" },
      { label: "No", description: "Keep local only" }
    ]
  }]
});

If user selects "Yes":

git push

If branch has no upstream, use:

git push -u origin <current-branch>

Examples

Simple Feature (Signed)

git commit -S \
  -m "feat(auth): add OAuth2 refresh token support" \
  -m "Implements automatic token refresh when access token expires, preventing session interruptions for long-running operations." \
  --trailer "X-Lerian-Ref: 0x1"

Bug Fix (Signed)

git commit -S \
  -m "fix(api): handle null response in user endpoint" \
  --trailer "X-Lerian-Ref: 0x1"

Chore/Refactor (Signed)

git commit -S \
  -m "chore: update dependencies to latest versions" \
  --trailer "X-Lerian-Ref: 0x1"

Multi-Commit Sequence (Organized)

When changes span multiple concerns, execute in sequence:

# Commit 1: Dependencies first
git add package.json package-lock.json
git commit -S \
  -m "chore(deps): update authentication dependencies" \
  --trailer "X-Lerian-Ref: 0x1"

# Commit 2: Feature implementation with tests
git add src/auth/oauth.ts src/auth/oauth.test.ts
git commit -S \
  -m "feat(auth): add OAuth2 refresh token support" \
  -m "Implements automatic token refresh when access token expires." \
  --trailer "X-Lerian-Ref: 0x1"

# Commit 3: Documentation last
git add docs/auth/oauth-setup.md README.md
git commit -S \
  -m "docs: update OAuth2 setup guide" \
  --trailer "X-Lerian-Ref: 0x1"

Trailer Query Commands

Trailers can be queried programmatically:

Note: git log --grep searches commit message content only, not trailers. Use --format with %(trailers) to query trailer values.

# Find all commits with specific X-Lerian-Ref trailer value
git log --all --format="%H %s %(trailers:key=X-Lerian-Ref,valueonly)" | grep "0x1"

# Show all trailers for a commit
git log -1 --format="%(trailers)"

# Filter commits by trailer existence (any value)
git log --all --format="%H %s" | while read hash msg; do
  git log -1 --format="%(trailers:key=X-Lerian-Ref)" $hash | grep -q "." && echo "$hash $msg"
done

Important Notes

  1. Smart grouping - Analyzes changes and proposes atomic commits for clean history
  2. GPG signing - All commits are signed with -S flag (requires GPG key configured)
  3. No visible markers - The message body stays clean and professional
  4. Trailers are standard - Git trailers are a recognized convention (like Signed-off-by)
  5. Machine-readable - Easy to filter/query commits with internal system reference
  6. Transparent - System tracing is documented, just not prominently displayed
  7. Do not use --no-verify - Always run pre-commit hooks unless user explicitly requests
  8. User confirmation - Always present commit plan before executing

Anti-Patterns (NEVER DO THIS)

⛔ THESE PATTERNS ARE FORBIDDEN. DO NOT USE THEM. ⛔

# ❌ WRONG - emoji or hashtags in message body
git commit -m "feat: add feature

🤖 Generated with [Claude Code](https://claude.com/claude-code)"

# ❌ WRONG - hashtags in message body
git commit -m "feat: add feature #ai-generated #automated"

# ❌ WRONG - Co-Authored-By in message body
git commit -m "feat: add feature

Co-Authored-By: System <noreply@example.com>"

# ❌ WRONG - HEREDOC with markers in message body
git commit -m "$(cat <<'EOF'
feat: add feature

🤖 Generated with AI
EOF
)"

# ❌ WRONG - Trailer text inside -m parameter
git commit -m "feat: add feature

X-Lerian-Ref: 0x1"

# ❌ WRONG - System reference as hashtag in message body
git commit -m "feat: add feature #0x1"

# ❌ WRONG - ANY attempt to include trailers, hashtags, or system markers in message body
# The message body (-m parameter) must ONLY contain the commit description
# NO trailers, NO signatures, NO emoji, NO hashtags, NO system markers of any kind

Why these are wrong: They put visible markers in the commit message body, making them visible in git log --oneline and polluting the commit history.

# ✅ CORRECT - signed commit with trailer via --trailer parameter
git commit -S \
  -m "feat: add feature" \
  --trailer "X-Lerian-Ref: 0x1"

Why this is correct: Trailers are separate from the message body and only visible in git log --format=full or git log --format="%(trailers)". The commit message stays completely clean. The -S flag signs the commit with GPG.

Anti-Rationalization Table

Rationalization Why It's WRONG Required Action
"I'll commit everything at once" Mixed changes = messy history, hard to bisect/revert. Analyze and group changes first
"Grouping takes too long" Clean history saves hours of debugging later. Always propose commit plan
"I'll skip GPG signing" Unsigned commits can't be verified. Use -S flag (skip only if no GPG key)
"I'll put the trailer text in the message body" --trailer is a GIT FLAG, not text. Text in -m is NOT a trailer. Use --trailer "X-Lerian-Ref: 0x1" as separate argument
"The trailers need to be in the commit message" NO. Trailers go via --trailer flag OUTSIDE the -m quotes. **Structure: git commit -S -m "msg" --trailer "X-Lerian-Ref: 0x1" **
"I'll format it nicely in the message body" That's NOT a trailer - that's polluting the message body. NEVER put "X-Lerian-Ref" text inside -m quotes
"HEREDOC will format the trailers correctly" HEREDOC puts everything in the message body. That's WRONG. Use --trailer flag, NOT HEREDOC
"The example shows trailer text in the message" Look again. --trailer is OUTSIDE the -m "..." quotes. **Copy the structure exactly: -S -m "msg" --trailer "X-Lerian-Ref: 0x1" **
"I'll add a hashtag #0x1 for tracking" Hashtags pollute the message body. Use --trailer instead. NEVER use hashtags. Use --trailer "X-Lerian-Ref: 0x1"

When User Provides Message

If the user provides a commit message as argument:

  1. Single commit mode - Skip grouping analysis, use provided message
  2. Use their message as the subject/body
  3. Ensure proper formatting (50 char subject, etc.)
  4. Create signed commit with trailer
# User says: /ring:commit "fix login bug"
git commit -S \
  -m "fix: fix login bug" \
  --trailer "X-Lerian-Ref: 0x1"
Weekly Installs
1
GitHub Stars
133
First Seen
5 days ago
Installed on
amp1
cline1
opencode1
cursor1
kimi-cli1
codex1