Masalah: Polusi AI Boilerplate pada Git History

Penggunaan asisten koding berbasis Large Language Model (LLM) sering kali menghasilkan artefak dokumentasi yang berlebihan. Alih-alih menjelaskan alasan teknis suatu perubahan (why), commit message yang di-generate otomatis cenderung memuat frasa klise, ringkasan mekanis baris per baris, dan basa-basi sintaksis seperti "In this commit, we ensure that..." atau "This change refactors the codebase to enhance readability and maintainability."

Kondisi ini menurunkan kualitas riwayat Git (`git log`), menyulitkan proses debugging via `git bisect`, serta memperlambat code review. Untuk menjaga standar dokumentasi teknis yang autentik dan ringkas, tim engineering perlu menerapkan automated linting di pipeline Continuous Integration (CI) dan client-side hook.

1. Membangun Ruleset Pola Frasa AI

Langkah awal adalah mendefinisikan pola ekspresi reguler (regex) yang menangkap struktur kalimat umum dari generator AI. Pola ini harus case-insensitive dan menyasar pembuka kalimat redundan atau filler generik.

# ai-patterns.txt
(?i)^(in this commit|this commit (introduces|adds|modifies|refactors|fixes)|this pull request addresses)
(?i)(enhance(s)? readability and maintainability|robust and scalable solution)
(?i)(as per (the)? requirements|adhering to best practices)
(?i)^(summary of changes|key changes included|overview:)
(?i)(vital|crucial|seamless) integration

Pola di atas memetakan tiga kategori masalah:

  • Redundant Opening: Membuang informasi subjek yang sudah implisit dalam commit git.
  • Subjective Filler: Frasa evaluatif tanpa konteks teknis terukur (misal: "scalable solution").
  • Structural Markdown Boilerplate: Tag ringkasan yang dihasilkan otomatis oleh prompt bawaan CLI AI.

2. Validasi Lokal: Git Pre-Commit Hook

Pencegahan paling efisien dilakukan sebelum kode terdorong ke remote repository. Buat validator bash pada `.git/hooks/commit-msg` atau kelola via generic runner.

#!/usr/bin/env bash
set -euo pipefail

COMMIT_MSG_FILE="$1"
COMMIT_MSG=$(cat "$COMMIT_MSG_FILE")

# Regex blacklist frasa AI
AI_REGEX="(in this commit|this commit introduces|enhance readability and maintainability|adhering to best practices)"

if echo "$COMMIT_MSG" | grep -Ei "$AI_REGEX" > /dev/null; then
    echo "[ERROR] Commit message ditolak: Terdeteksi frasa boilerplate AI."
    echo "------------------------------------------------------------------"
    echo "Hindari teks generik. Jelaskan masalah dan solusi teknis langsung."
    echo "Pelanggaran:"
    echo "$COMMIT_MSG" | grep -Ein "$AI_REGEX"
    echo "------------------------------------------------------------------"
    exit 1
fi

exit 0

Pastikan script memiliki izin eksekusi menggunakan chmod +x .git/hooks/commit-msg.

3. Implementasi Custom Plugin pada Commitlint

Jika repository sudah menggunakan ekosistem Node.js dan standard Conventional Commits, validasi dapat dipusatkan menggunakan @commitlint/cli dengan aturan kustom.

// commitlint.config.js
const aiPhrases = [
  /in this commit/i,
  /this commit (introduces|modifies|fixes)/i,
  /enhance(s)? readability/i,
  /best practices/i,
  /seamless integration/i,
];

module.exports = {
  extends: ['@commitlint/config-conventional'],
  plugins: [
    {
      rules: {
        'no-ai-boilerplate': ({ raw }) => {
          const match = aiPhrases.find((regex) => regex.test(raw));
          return [
            !match,
            match
              ? `Commit message terdeteksi menggunakan template AI: "${raw.match(match)[0]}". Gunakan deskripsi imperatif dan langsung.`
              : '',
          ];
        },
      },
    },
  ],
  rules: {
    'no-ai-boilerplate': [2, 'always'],
  },
};

4. Enforcing di CI Pipeline (GitHub Actions)

Client hook dapat dilewati menggunakan flag --no-verify. Oleh karena itu, pipeline CI harus memverifikasi commit message seluruh range PR serta Pull Request description.

# .github/workflows/lint-commits.yml
name: Lint Commit Messages and PR Body

on:
  pull_request:
    types: [opened, edited, synchronize]

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Repository
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20

      - name: Install Commitlint
        run: npm install @commitlint/cli @commitlint/config-conventional

      - name: Validate Commits with Commitlint
        run: |
          npx commitlint --from ${{ github.event.pull_request.base.sha }} --to ${{ github.event.pull_request.head.sha }} --verbose

      - name: Validate PR Body
        env:
          PR_BODY: ${{ github.event.pull_request.body }}
        run: |
          if [ -z "$PR_BODY" ]; then
            echo "PR body kosong. Harap isi penjelasan teknis perubahan."
            exit 1
          fi

          # Cek pola boilerplate
          AI_PATTERN="(as an ai language model|in this pull request, we|summary of changes:)"
          if echo "$PR_BODY" | grep -Ei "$AI_PATTERN" > /dev/null; then
            echo "[ERROR] PR description memuat template/filler AI."
            exit 1
          fi

5. Menangani False Positives dan Trade-Offs

Validasi berbasis pola memiliki batasan presisi. Beberapa skenario memerlukan penanganan khusus:

  • Dokumentasi RFC atau Tooling AI: Jika pull request memang bertujuan menambahkan fungsionalitas AI ke dalam sistem, regex dapat salah menandai kata sah seperti "best practices" dalam body dokumentasi.
  • Mekanisme Bypass Terkontrol: Sediakan bypass eksplisit via commit footer, misalnya tag Acked-AI: <reason> yang hanya diizinkan untuk maintainer repo melalui skrip validasi.
  • Prinsip Penulisan yang Diizinkan: Terapkan format imperatif (Imperative Mood). Contoh benar: fix(auth): handle null refresh tokens in redis adapter. Hindari: fix(auth): this commit fixes an issue where tokens were null to improve code quality.