GC-301i · Module 1

Style Guides & Convention Enforcement

3 min read

Linters enforce syntax rules. Gemini enforces semantic conventions. A linter can check that you used camelCase for variable names. It cannot check that you named your API error handler "handleApiError" instead of "processError" or "catchStuff." Semantic conventions — naming patterns, code organization, API design consistency, error handling patterns — are encoded in GEMINI.md and enforced by Gemini during interactive sessions and CI review. The GEMINI.md becomes a machine-readable style guide that Gemini applies automatically.

The hooks system provides automated enforcement. A post-write hook runs after every file Gemini creates or modifies, checking the output against conventions. Hooks can run formatters (prettier), linters (eslint --fix), and custom validators (a script that checks naming conventions, file structure, or import ordering). The key principle: hooks enforce conventions silently. Gemini writes the code, hooks clean it up, and the developer sees only the final, convention-compliant result.

{
  "hooks": {
    "post-write": {
      "command": "bash .gemini/hooks/enforce.sh {{file}}",
      "description": "Enforce team conventions on every file write"
    }
  }
}

// .gemini/hooks/enforce.sh
// #!/bin/bash
// FILE="$1"
// EXT="${FILE##*.}"
// 
// # Format
// npx prettier --write "$FILE" 2>/dev/null
// 
// # Lint and auto-fix
// if [[ "$EXT" == "ts" || "$EXT" == "tsx" ]]; then
//   npx eslint --fix "$FILE" 2>/dev/null
// fi
// 
// # Custom naming convention check
// if [[ "$FILE" == src/components/* && "$EXT" == "tsx" ]]; then
//   BASENAME=$(basename "$FILE" .tsx)
//   if [[ ! "$BASENAME" =~ ^[A-Z] ]]; then
//     echo "WARNING: Component file $BASENAME should be PascalCase" >&2
//   fi
// fi