Files
vm-cloudflare/AGENT_GUARDRAILS.md
Vault Sovereign 37a867c485 Initial commit: Cloudflare infrastructure with WAF Intelligence
- Complete Cloudflare Terraform configuration (DNS, WAF, tunnels, access)
- WAF Intelligence MCP server with threat analysis and ML classification
- GitOps automation with PR workflows and drift detection
- Observatory monitoring stack with Prometheus/Grafana
- IDE operator rules for governed development
- Security playbooks and compliance frameworks
- Autonomous remediation and state reconciliation
2025-12-16 18:31:53 +00:00

308 lines
7.5 KiB
Markdown

# AGENT GUARDRAILS for CLOUDFLARE Project
**Purpose:** Prevent common coding mistakes when using autonomous agents (Cline, Claude, etc.)
**Governed by:** [RED-BOOK.md](RED-BOOK.md) — See Appendix A for agent constraints
**Copy this into your agent prompt before asking for code changes.**
---
## 🛡️ CRITICAL RULES
### 1. NO BLIND PATCHING
**When you need to modify a Python file:**
1.**FIRST:** Use the Read tool to read the ENTIRE file (all lines)
2.**THEN:** Check if your change already exists
3.**THEN:** Check for duplicates
4.**THEN:** Rewrite the WHOLE function/block (not line-by-line insertion)
5.**NEVER:** Append code without reading the full file
### 2. ARGPARSE IS SPECIAL
**When modifying `argparse` code:**
- ❌ DO NOT add arguments in multiple places
- ❌ DO NOT call `parser.add_argument()` twice for the same option
- ✅ DO rewrite the entire `build_parser()` function
- ✅ DO check the file for existing argument definitions FIRST
- ✅ DO verify no conflicting option strings (like `--question`)
**Example of WRONG approach:**
```python
# ❌ BAD: Adding same arg in two places
parser.add_argument("--question", required=True) # Line 50
parser.add_argument("--question", required=False) # Line 100
# ^ This will throw: argparse.ArgumentError: argument --question: conflicting option string
```
**Example of RIGHT approach:**
```python
# ✅ GOOD: Single source of truth
def build_parser():
parser = argparse.ArgumentParser()
parser.add_argument("--question", required=False)
parser.add_argument("--frameworks", nargs="+")
parser.add_argument("--verbose", action="store_true")
return parser
```
### 3. NO DUPLICATES
**Before writing any function:**
1. Search the file for function with the same name
2. If it exists, rewrite it (don't add another one)
3. Check for similar function names (typos, variations)
4. Delete the old one if rewriting
### 4. IMPORTS AT TOP
**Never import mid-function:**
```python
# ✅ CORRECT: Imports at top
import sys
from pathlib import Path
def main():
result = sys.exit(0) # OK to use here
# ❌ WRONG: Import inside function
def main():
import sys # No! Import at top
import random_library # No!
```
### 5. TYPE HINTS REQUIRED
**Every function must have type hints:**
```python
# ✅ CORRECT
def answer(self, question: str, frameworks: Optional[List[str]] = None) -> ToolResponse:
...
# ❌ WRONG (missing types)
def answer(self, question, frameworks=None):
...
```
---
## 📋 CHECKLIST BEFORE WRITING CODE
Before you generate or modify any code file:
- [ ] Have I read the ENTIRE file first?
- [ ] Does this function already exist?
- [ ] Are there duplicates I should remove?
- [ ] Does this follow SRP (single responsibility)?
- [ ] Are all functions type-hinted?
- [ ] Are imports at the top?
- [ ] Is there a docstring?
- [ ] Will this create new test failures?
---
## 🔍 FILE-SPECIFIC RULES
### For oracle_answer_mcp.py
**CRITICAL:** This file had duplicate argparse definitions. If you modify it:
1. Read the ENTIRE build_parser() function
2. Look for ANY parser.add_argument() calls
3. If --question is defined MORE than once, DELETE all but one
4. Check for conflicting flags (argparse won't allow duplicates)
---
### For oracle_runner.py
**This is stable.** Only modify if:
- Bug fix required
- New compliance framework needed
- Performance issue
When modifying:
1. Keep the `run()` method signature the same
2. Keep `OracleAnswer` dataclass schema consistent
3. Update COMPLIANCE_LEDGER.jsonl format in docstring
---
### For Terraform files
**Cloudflare provider is v4.52.5.** If updating:
1. Check `.terraform.lock.hcl` first
2. Run `terraform validate` after changes
3. Run `terraform plan` before commit
4. Don't modify resource names (breaks state)
---
## ⚠️ COMMON MISTAKES (Don't Make These)
| Mistake | Symptom | Fix |
|---------|---------|-----|
| Duplicate argparse args | `ArgumentError: conflicting option string` | Delete duplicate definition |
| Missing type hints | Type checker errors | Add `: Type` to all params |
| Append instead of rewrite | Multiple similar functions | Read file, rewrite once |
| Import mid-function | Code style error | Move imports to top |
| Subscript None | `TypeError: 'NoneType' not subscriptable` | Check for None first |
| Missing docstrings | Code review failure | Add docstrings to all functions |
---
## 🧪 TESTING AFTER CHANGES
After modifying code, run:
```bash
# 1. Quick sanity check
bash TEST_WORKFLOW.sh quick
# 2. Test the specific script you changed
python3 oracle_runner.py "test question?"
# 3. Run any affected tests
python3 oracle_answer_mcp.py --tool-info
# 4. Look for errors
python3 -m py_compile oracle_runner.py # Syntax check
```
---
## 🚫 FORBIDDEN PATTERNS
### ❌ Pattern 1: Blind Appending
```python
# NO! Never do this:
# Read part of file, then append without seeing rest
parser.add_argument("--json") # Line 200
# ... 100 lines away somewhere:
parser.add_argument("--json") # DUPLICATE! Conflict!
```
### ❌ Pattern 2: Nested Imports
```python
# NO! Never do this:
def process_data():
import csv # Should be at top
import json # Should be at top
# ... code
```
### ❌ Pattern 3: Type-Free Parameters
```python
# NO! Never do this:
def answer(self, question, frameworks, verbose): # No types!
pass
# YES! Do this:
def answer(self, question: str, frameworks: Optional[List[str]], verbose: bool) -> ToolResponse:
pass
```
### ❌ Pattern 4: Patch Editing
```python
# NO! Don't patch one line:
oldString: "def main():\n ..."
newString: "def main():\n print('new line')" # This breaks the function
# YES! Rewrite whole function:
# Read the full main()
# Rewrite it completely
# Replace the entire function
```
---
## ✅ CORRECT WORKFLOW
When asked to modify code:
**Step 1: Understand**
- What is broken?
- What file needs changing?
- What is the whole context?
**Step 2: Read**
```
Use the Read tool:
read /path/to/file.py # Read ENTIRE file
```
**Step 3: Analyze**
- Where is the problem?
- Is it already fixed?
- Are there duplicates?
- What is the function signature?
**Step 4: Rewrite**
```
Use the Edit tool:
- oldString: [ENTIRE function]
- newString: [Fixed ENTIRE function]
```
**Step 5: Test**
```bash
python3 file.py --test
bash TEST_WORKFLOW.sh quick
```
**Step 6: Verify**
- No new errors?
- No duplicates?
- Tests passing?
---
## 📞 SUMMARY
| Rule | Critical? | Check Before |
|------|-----------|------------|
| Read entire file | ✅ Yes | Edit anything |
| No duplicate defs | ✅ Yes | Add any function |
| Argparse centralized | ✅ Yes | Modify argparse |
| Type hints required | ✅ Yes | Write any function |
| Docstrings needed | ✅ Yes | Finish any function |
| Imports at top | 🟡 High | Write imports |
| Tests passing | 🟡 High | Commit code |
---
## 🆘 If Something Goes Wrong
**You see: `argparse.ArgumentError: argument --question: conflicting option string`**
1. Read `oracle_answer_mcp.py` line-by-line
2. Find ALL instances of `parser.add_argument("--question"...)`
3. Keep ONE, delete the others
4. Test: `python3 oracle_answer_mcp.py --tool-info`
**You see: `TypeError: 'NoneType' object is not subscriptable`**
1. Find the line with `[...]` or `.get(...)`
2. Add null check: `if result: result['key']`
3. Test the fix
**You see: `Import "x" could not be resolved`**
1. Check if module exists: `ls mcp/oracle_answer/*.py`
2. Check imports are correct: `from .tool import X`
3. Check __init__.py exists
---
**Last Updated:** December 8, 2025
**Status:** 🟢 Active
**Apply To:** All code modifications by agents