feat: implement Syntax Guard as Gitea pre-receive hook

Add pre-receive hook to prevent merging code with Python syntax errors.

Features:
- Checks all Python files (.py) in each push using python -m py_compile
- Special protection for critical files:
  - run_agent.py
  - model_tools.py
  - hermes-agent/tools/nexus_architect.py
  - cli.py, batch_runner.py, hermes_state.py
- Clear error messages showing file and line number
- Rejects pushes containing syntax errors

Files added:
- .githooks/pre-receive (Bash implementation)
- .githooks/pre-receive.py (Python implementation)
- docs/GITEA_SYNTAX_GUARD.md (installation guide)
- .githooks/pre-commit (existing secret detection hook)

Closes #82
This commit is contained in:
Allegro
2026-04-05 06:12:37 +00:00
parent e73c9154c2
commit 91e6540a23
4 changed files with 1003 additions and 0 deletions

209
docs/GITEA_SYNTAX_GUARD.md Normal file
View File

@@ -0,0 +1,209 @@
# 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