# Gitea Syntax Guard - Pre-receive Hook

This document describes how to install and configure the Python Syntax Guard pre-receive hook in Gitea to prevent merging code with syntax errors.

## Overview

The Syntax Guard is a pre-receive hook that validates Python files for syntax errors before allowing pushes to the repository. It uses Python's built-in `py_compile` module to check files.

### Features

- **Automatic Syntax Checking**: Checks all Python files (.py) in each push
- **Critical File Protection**: Special attention to essential files:
  - `run_agent.py` - Main agent runner
  - `model_tools.py` - Tool orchestration layer
  - `hermes-agent/tools/nexus_architect.py` - Nexus architect tool
  - `cli.py` - Command-line interface
  - `batch_runner.py` - Batch processing
  - `hermes_state.py` - State management
- **Clear Error Messages**: Shows exact file and line number of syntax errors
- **Push Rejection**: Blocks pushes containing syntax errors

## Installation Methods

### Method 1: Gitea Web Interface (Recommended)

1. Navigate to your repository in Gitea
2. Go to **Settings** → **Git Hooks**
3. Find the **pre-receive** hook and click **Edit**
4. Copy the contents of `.githooks/pre-receive` (Bash version) or `.githooks/pre-receive.py` (Python version)
5. Paste into the Gitea hook editor
6. Click **Update Hook**

### Method 2: Server-Side Installation

If you have server access to the Gitea installation:

```bash
# Locate the repository on the Gitea server
# Usually in: /var/lib/gitea/repositories/<owner>/<repo>.git/hooks/

# Copy the hook
cp /path/to/hermes-agent/.githooks/pre-receive \
   /var/lib/gitea/repositories/Timmy_Foundation/hermes-agent.git/hooks/pre-receive

# Make it executable
chmod +x /var/lib/gitea/repositories/Timmy_Foundation/hermes-agent.git/hooks/pre-receive
```

### Method 3: Repository-Level Git Hook (for local testing)

```bash
# From the repository root
cp .githooks/pre-receive .git/hooks/pre-receive
chmod +x .git/hooks/pre-receive

# Or use the Python version
cp .githooks/pre-receive.py .git/hooks/pre-receive
chmod +x .git/hooks/pre-receive
```

## Configuration

### Customizing Critical Files

Edit the `CRITICAL_FILES` array in the hook to add or remove files:

**Bash version:**
```bash
CRITICAL_FILES=(
    "run_agent.py"
    "model_tools.py"
    "hermes-agent/tools/nexus_architect.py"
    # Add your files here
)
```

**Python version:**
```python
CRITICAL_FILES = [
    "run_agent.py",
    "model_tools.py",
    "hermes-agent/tools/nexus_architect.py",
    # Add your files here
]
```

### Environment Variables

The hook respects the following environment variables:

- `PYTHON_CMD`: Path to Python executable (default: `python3`)
- `SYNTAX_GUARD_STRICT`: Set to `1` to fail on warnings (default: `0`)

## Testing the Hook

### Local Testing

1. Create a test branch:
   ```bash
   git checkout -b test/syntax-guard
   ```

2. Create a file with intentional syntax error:
   ```bash
   echo 'def broken_function(' > broken_test.py
   git add broken_test.py
   git commit -m "Test syntax error"
   ```

3. Try to push (should be rejected):
   ```bash
   git push origin test/syntax-guard
   ```

4. You should see output like:
   ```
   [ERROR] Syntax error in: broken_test.py
     File "broken_test.py", line 1
       def broken_function(
                          ^
   SyntaxError: unexpected EOF while parsing
   ```

### Clean Up Test

```bash
git checkout main
git branch -D test/syntax-guard
git push origin --delete test/syntax-guard  # if it somehow got through
```

## Troubleshooting

### Hook Not Running

1. Check hook permissions:
   ```bash
   ls -la .git/hooks/pre-receive
   # Should show executable permission (-rwxr-xr-x)
   ```

2. Verify Git hook path:
   ```bash
   git config core.hooksPath
   # Should be .git/hooks or empty
   ```

### Python Not Found

If Gitea reports "python3: command not found":

1. Check Python path on Gitea server:
   ```bash
   which python3
   which python
   ```

2. Update the hook to use the correct path:
   ```bash
   # In the hook, change:
   python3 -m py_compile ...
   # To:
   /usr/bin/python3 -m py_compile ...
   ```

### Bypassing the Hook (Emergency Only)

**⚠️ WARNING: Only use in emergencies with team approval!**

Administrators can bypass hooks by pushing with `--no-verify`, but this won't work for pre-receive hooks on the server. To temporarily disable:

1. Go to Gitea repository settings
2. Disable the pre-receive hook
3. Push your changes
4. Re-enable the hook immediately

## How It Works

1. **Hook Invocation**: Git calls the pre-receive hook before accepting a push
2. **File Discovery**: Hook reads changed files from stdin (Git provides refs)
3. **Python Detection**: Filters for .py files only
4. **Syntax Check**: Extracts each file and runs `python -m py_compile`
5. **Error Reporting**: Collects all errors and displays them
6. **Decision**: Exits with code 1 to reject or 0 to accept

## Performance Considerations

- The hook only checks changed files, not the entire repository
- Syntax checking is fast (typically <100ms per file)
- Large pushes (100+ files) may take a few seconds

## Security Notes

- The hook runs on the Gitea server with the server's Python
- No code is executed, only syntax-checked
- Temporary files are created in a secure temp directory and cleaned up

## Support

For issues or questions:
1. Check Gitea logs: `/var/log/gitea/gitea.log`
2. Test the hook locally first
3. Review the hook script for your specific environment

## Related Files

- `.githooks/pre-receive` - Bash implementation
- `.githooks/pre-receive.py` - Python implementation
- `.githooks/pre-commit` - Client-side secret detection hook
