Skip to content

Git Commit Guard Hook

The git-commit-guard hook prevents commits containing ontology files unless the full encoding workflow has completed with all checkpoints approved.

Overview

Attribute Value
Hook Name git-commit-guard
Script hooks/scripts/git-commit-guard.py
Event PreToolUse
Matcher Bash
Blocking Yes (when review not approved)
Timeout 5000ms

Purpose

The git commit guard ensures:

  1. Full Workflow Completion: All checkpoints must be approved before commit
  2. Review Requirement: Human review is mandatory for ontology changes
  3. Quality Assurance: Prevents premature commits of unvalidated encodings
  4. Audit Trail: Commits only after complete approval chain

Configuration

In hooks/hooks.json:

{
  "PreToolUse": [
    {
      "matcher": "Bash",
      "hooks": [
        {
          "type": "command",
          "command": "python ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/git-commit-guard.py \"$TOOL_INPUT\"",
          "timeout": 5000
        }
      ]
    }
  ]
}

Behavior

Commit Allowed

When review checkpoint is approved:

{
  "continue": true,
  "message": "Git commit guard: Review approved\n   Committing 3 ontology file(s)"
}

Non-Ontology Commit Allowed

When no ontology files are staged:

{
  "continue": true,
  "message": ""
}

Non-Commit Command Allowed

When command is not a git commit:

{
  "continue": true,
  "message": ""
}

Blocked: No Active Session

When ontology files staged but no session exists:

{
  "continue": false,
  "message": "BLOCKED: No Active Encoding Session\n\nCannot commit ontology files without approved encoding session.\n\nStaged ontology files:\n  • mistaber/ontology/corpus/yd_87/base.lp\n  • mistaber/ontology/corpus/yd_87/seif_3.lp\n\nThe encoding workflow requires:\n1. Corpus preparation → approval\n2. HLL encoding → approval\n3. Validation → approval\n4. Review → approval\n5. Then commit\n\nStart with: \"Prepare corpus for YD {siman}:{seif}\""
}

Blocked: Review Not Approved

When review checkpoint is not approved:

{
  "continue": false,
  "message": "BLOCKED: Review Not Approved\n\nCannot commit ontology files without approved review.\n\nStaged ontology files:\n  • mistaber/ontology/corpus/yd_87/base.lp\n\nCurrent checkpoint status:\n  • corpus-prep: approved\n  • hll-encode: approved\n  • validate: approved\n  • review: pending_review\n\nComplete the remaining checkpoints before committing."
}

Command Detection

Git Commit Patterns

def is_git_commit_command(command: str) -> bool:
    """Check if command is a git commit."""
    patterns = [
        r'^git\s+commit\b',       # Direct commit
        r'&&\s*git\s+commit\b',   # Chained after success
        r';\s*git\s+commit\b',    # Chained unconditionally
    ]
    return any(re.search(pattern, command) for pattern in patterns)

Matched Commands:

Command Matched
git commit -m "msg" Yes
git add . && git commit -m "msg" Yes
git status; git commit -m "msg" Yes
git status No
git push No
echo "git commit" No

Bash Input Parsing

def parse_bash_command(tool_input: str) -> str:
    """Extract bash command from tool input."""
    try:
        data = json.loads(tool_input)
        return data.get("command", "")
    except json.JSONDecodeError:
        return tool_input

Ontology File Detection

Staged Files Check

def has_ontology_files_staged() -> bool:
    """Check if any ontology .lp files are staged for commit."""
    result = subprocess.run(
        ["git", "diff", "--cached", "--name-only"],
        capture_output=True,
        text=True,
        timeout=5
    )

    if result.returncode != 0:
        return False

    staged_files = result.stdout.strip().split('\n')

    for file in staged_files:
        if file.endswith('.lp') and 'ontology' in file:
            return True

    return False

Detection Criteria:

File Path Detected
mistaber/ontology/corpus/yd_87/base.lp Yes
mistaber/ontology/worlds/mechaber.lp Yes
tests/test_data/example.lp No (not in ontology)
mistaber/ontology/manifest.yaml No (not .lp)

Get Staged Ontology Files

def get_staged_ontology_files() -> list[str]:
    """Get list of staged ontology files."""
    result = subprocess.run(
        ["git", "diff", "--cached", "--name-only"],
        capture_output=True,
        text=True,
        timeout=5
    )

    if result.returncode != 0:
        return []

    staged_files = result.stdout.strip().split('\n')
    return [f for f in staged_files if f.endswith('.lp') and 'ontology' in f]

Checkpoint Validation

Required Checkpoints

The hook verifies:

  1. Session Exists: Active encoding session with .mistaber-session.yaml
  2. Review Approved: The review checkpoint has status: approved
  3. Validate Approved: The validate checkpoint has status: approved
# Check checkpoint status
checkpoints = session.get("checkpoints", {})
review_status = checkpoints.get("review", {}).get("status", "not_started")
validate_status = checkpoints.get("validate", {}).get("status", "not_started")

if review_status != "approved":
    # Block the commit

Checkpoint Status Matrix

review validate Result
approved approved Commit allowed
approved not approved Blocked (validation and review)
not approved approved Blocked (review)
not approved not approved Blocked (validation and review)

Implementation Flow

graph TD
    A[Bash Command] --> B{Is Git Commit?}
    B -->|No| C[Allow - Return]
    B -->|Yes| D{Ontology Files Staged?}
    D -->|No| E[Allow - Non-Ontology]
    D -->|Yes| F{Session Exists?}
    F -->|No| G[Block - No Session]
    F -->|Yes| H{Review Approved?}
    H -->|No| I{Validate Approved?}
    I -->|Yes| J[Block - Review Missing]
    I -->|No| K[Block - Both Missing]
    H -->|Yes| L[Allow - Commit]

Error Messages

No Active Session

BLOCKED: No Active Encoding Session

Cannot commit ontology files without approved encoding session.

Staged ontology files:
  • mistaber/ontology/corpus/yd_87/base.lp
  • mistaber/ontology/corpus/yd_87/seif_3.lp

The encoding workflow requires:
1. Corpus preparation → approval
2. HLL encoding → approval
3. Validation → approval
4. Review → approval
5. Then commit

Start with: "Prepare corpus for YD {siman}:{seif}"

Review Not Approved

BLOCKED: Review Not Approved

Cannot commit ontology files without approved review.

Staged ontology files:
  • mistaber/ontology/corpus/yd_87/base.lp

Current checkpoint status:
  • corpus-prep: approved
  • hll-encode: approved
  • validate: approved
  • review: pending_review

Complete the remaining checkpoints before committing.

Validation and Review Missing

BLOCKED: Validation And Review Not Approved

Cannot commit ontology files without approved validation and review.

Staged ontology files:
  • mistaber/ontology/corpus/yd_87/base.lp

Current checkpoint status:
  • corpus-prep: approved
  • hll-encode: approved
  • validate: not_started
  • review: not_started

Complete the remaining checkpoints before committing.

Example Scenarios

Scenario 1: Complete Workflow

Session State:

current_phase: complete
target_seif: "YD:87:3"
checkpoints:
  corpus-prep:
    status: approved
  hll-encode:
    status: approved
  validate:
    status: approved
  review:
    status: approved

Command:

git add mistaber/ontology/corpus/yd_87/ && git commit -m "feat(ontology): encode YD 87:3"

Result:

Git commit guard: Review approved
   Committing 2 ontology file(s)

Scenario 2: Incomplete Workflow

Session State:

current_phase: validate
target_seif: "YD:87:3"
checkpoints:
  corpus-prep:
    status: approved
  hll-encode:
    status: approved
  validate:
    status: tests_passed
  review:
    status: not_started

Command:

git commit -m "feat(ontology): encode YD 87:3"

Result: Blocked with review checkpoint message.

Scenario 3: Non-Ontology Commit

Staged Files:

src/utils.py
tests/test_utils.py

Command:

git commit -m "refactor: update utils"

Result: Allowed (no ontology files).

Scenario 4: Mixed Commit

Staged Files:

src/utils.py
mistaber/ontology/corpus/yd_87/base.lp

Session State: Review not approved.

Command:

git commit -m "feat: update utils and ontology"

Result: Blocked (contains ontology files, review not approved).

Debugging

Manual Testing

# Test non-commit command
echo '{"command": "git status"}' | \
  python mistaber-skills/hooks/scripts/git-commit-guard.py | jq .

# Test commit without ontology files staged
git reset HEAD  # Unstage all
echo '{"command": "git commit -m test"}' | \
  python mistaber-skills/hooks/scripts/git-commit-guard.py | jq .

# Test with ontology files staged
git add mistaber/ontology/corpus/yd_87/base.lp
echo '{"command": "git commit -m test"}' | \
  python mistaber-skills/hooks/scripts/git-commit-guard.py | jq .

Check Staged Files

# List all staged files
git diff --cached --name-only

# List staged ontology files
git diff --cached --name-only | grep -E '\.lp$' | grep ontology

Check Session State

# View checkpoint status
cat .mistaber-session.yaml | grep -A1 "status:"

# Check specific checkpoints
python -c "
import yaml
with open('.mistaber-session.yaml') as f:
    s = yaml.safe_load(f)
for cp, data in s.get('checkpoints', {}).items():
    print(f'{cp}: {data.get(\"status\", \"not_started\")}')
"

Common Issues

False Positive Block

Symptom: Commit blocked but workflow is complete.

Causes: - Session file not updated - Review status not set to "approved" - Wrong session file loaded

Solutions:

# Verify session state
cat .mistaber-session.yaml

# Check review status specifically
grep -A2 "review:" .mistaber-session.yaml

Ontology Files Not Detected

Symptom: Commit allowed when it should be blocked.

Causes: - Files not properly staged - Path doesn't contain "ontology" - File extension not ".lp"

Solutions:

# Verify staging
git status --short

# Check file paths
git diff --cached --name-only | grep -E '\.lp$'

Git Command Fails

Symptom: Hook returns error about git.

Causes: - Not in a git repository - Git not in PATH - Subprocess timeout

Solutions:

# Verify git works
git status

# Check git is available
which git

Bypass Options

Bypass Not Recommended

The commit guard exists to ensure encoding quality. Bypassing is strongly discouraged.

Emergency Manual Override

If absolutely necessary:

  1. Temporarily approve review:

    # .mistaber-session.yaml
    checkpoints:
      review:
        status: approved  # Manually set
    

  2. Disable hook temporarily: Comment out in hooks.json.

  3. Use --no-verify flag:

    git commit --no-verify -m "emergency commit"
    

Risk

Bypassing the commit guard means ontology changes have not been properly reviewed. This can introduce errors into the knowledge base.

Integration with Workflow

Commit Skill Integration

The commit skill calls git commit after verifying the workflow:

# Commit skill verifies internally, then calls
git add mistaber/ontology/corpus/yd_87/
git commit -m "feat(ontology): encode YD 87:3"

The hook provides a safety net even if the skill is bypassed.

Post-Commit Actions

After successful commit, the commit skill:

  1. Clears session state
  2. Archives artifacts
  3. Generates session report