Skip to content

Commit 86e4e9b

Browse files
feat: Add coding standards to Claude project memory
- Created .claude/rules/empathy/coding-standards-index.md - Quick reference for critical security and quality rules - References full docs/CODING_STANDARDS.md for complete details - Updated .claude/CLAUDE.md to include coding standards reference - Ensures consistent adherence across Claude sessions and agents Critical rules now in project memory: - NEVER use eval() or exec() - ALWAYS validate file paths with _validate_file_path() - NEVER use bare except: - catch specific exceptions - ALWAYS log exceptions - Type hints and docstrings required - 80% test coverage minimum - Security tests for file operations
1 parent 8638b49 commit 86e4e9b

2 files changed

Lines changed: 330 additions & 2 deletions

File tree

.claude/CLAUDE.md

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,26 @@
11
# Project Memory
22

33
## Framework
4-
This is the Empathy Framework v1.8.0-alpha
4+
This is the Empathy Framework v3.9.1
55

66
@./python-standards.md
77

8+
## Coding Standards
9+
@./rules/empathy/coding-standards-index.md
10+
11+
Critical rules enforced across all code:
12+
13+
- NEVER use eval() or exec()
14+
- ALWAYS validate file paths with _validate_file_path()
15+
- NEVER use bare except: - catch specific exceptions
16+
- ALWAYS log exceptions before handling
17+
- Type hints and docstrings required on all public APIs
18+
- Minimum 80% test coverage
19+
- Security tests required for file operations
20+
821
## Additional Notes
922
Memory integration test
1023

1124

1225
## New Section
13-
Added after initialization for reload test
26+
Added after initialization for reload test
Lines changed: 315 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,315 @@
1+
# Coding Standards Quick Reference
2+
3+
**Full Documentation:** [docs/CODING_STANDARDS.md](../../../docs/CODING_STANDARDS.md)
4+
**Version:** 3.9.1
5+
**Last Updated:** January 7, 2026
6+
7+
---
8+
9+
## Critical Security Rules (MUST FOLLOW)
10+
11+
### 1. NEVER Use eval() or exec()
12+
13+
```python
14+
# ❌ PROHIBITED - Code injection vulnerability
15+
result = eval(user_input)
16+
17+
# ✅ REQUIRED - Use ast.literal_eval or json.loads
18+
import ast
19+
data = ast.literal_eval(user_input)
20+
```
21+
22+
**Exception:** None. Always a security vulnerability (CWE-95).
23+
24+
---
25+
26+
### 2. ALWAYS Validate File Paths
27+
28+
```python
29+
# ❌ PROHIBITED - Path traversal vulnerability
30+
with open(user_path, 'w') as f:
31+
f.write(data)
32+
33+
# ✅ REQUIRED - Validate before writing
34+
from empathy_os.config import _validate_file_path
35+
36+
validated_path = _validate_file_path(user_path)
37+
with validated_path.open('w') as f:
38+
f.write(data)
39+
```
40+
41+
**Applies to:** All user-controlled file paths
42+
**Blocks:** Path traversal (CWE-22), null byte injection, system directory writes
43+
44+
---
45+
46+
## Exception Handling Rules
47+
48+
### 3. NEVER Use Bare except:
49+
50+
```python
51+
# ❌ PROHIBITED - Masks all errors including KeyboardInterrupt
52+
try:
53+
risky_operation()
54+
except: # Never do this
55+
pass
56+
57+
# ❌ ALSO PROHIBITED - Too broad in most cases
58+
try:
59+
risky_operation()
60+
except Exception:
61+
return None
62+
63+
# ✅ REQUIRED - Catch specific exceptions
64+
try:
65+
risky_operation()
66+
except ValueError as e:
67+
logger.error(f"Invalid value: {e}")
68+
raise
69+
except FileNotFoundError as e:
70+
logger.warning(f"File not found: {e}")
71+
return default_value
72+
```
73+
74+
**Acceptable broad catches:** Only when documented with `# INTENTIONAL:` comment and `# noqa: BLE001`
75+
76+
**Scenarios allowing Exception:**
77+
- Version detection with fallback
78+
- Optional feature detection
79+
- Cleanup/teardown code (`__del__`, `__exit__`)
80+
- Graceful degradation (must log and document)
81+
82+
---
83+
84+
### 4. ALWAYS Log Exceptions
85+
86+
```python
87+
# ❌ PROHIBITED - Silent failure
88+
try:
89+
dangerous_operation()
90+
except IOError:
91+
pass
92+
93+
# ✅ REQUIRED - Log and re-raise
94+
try:
95+
dangerous_operation()
96+
except IOError as e:
97+
logger.error(f"Failed operation: {e}")
98+
raise
99+
```
100+
101+
---
102+
103+
## Code Quality Requirements
104+
105+
### 5. Type Hints Required
106+
107+
```python
108+
# ✅ All functions must have type hints
109+
def calculate_total(prices: list[float], tax_rate: float) -> float:
110+
return sum(prices) * (1 + tax_rate)
111+
```
112+
113+
### 6. Docstrings Required
114+
115+
```python
116+
def validate_email(email: str) -> bool:
117+
"""Validate email format using regex.
118+
119+
Args:
120+
email: Email address to validate
121+
122+
Returns:
123+
True if email is valid format, False otherwise
124+
125+
Example:
126+
>>> validate_email("user@example.com")
127+
True
128+
"""
129+
pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
130+
return bool(re.match(pattern, email))
131+
```
132+
133+
**Format:** Google-style docstrings
134+
135+
---
136+
137+
## Testing Requirements
138+
139+
### 7. Test Coverage: Minimum 80%
140+
141+
- ✅ Unit tests (80%+ coverage)
142+
- ✅ Edge case tests
143+
- ✅ Error handling tests
144+
145+
### 8. Security Tests for File Operations
146+
147+
```python
148+
def test_save_prevents_path_traversal():
149+
"""Test that save blocks path traversal attacks."""
150+
config = EmpathyConfig(user_id="test")
151+
152+
with pytest.raises(ValueError, match="Cannot write to system directory"):
153+
config.to_yaml("/etc/passwd")
154+
155+
def test_save_prevents_null_bytes():
156+
"""Test that save blocks null byte injection."""
157+
config = EmpathyConfig(user_id="test")
158+
159+
with pytest.raises(ValueError, match="contains null bytes"):
160+
config.to_yaml("config\x00.yml")
161+
```
162+
163+
---
164+
165+
## File Operations
166+
167+
### 9. Use Context Managers
168+
169+
```python
170+
# ✅ REQUIRED - Automatic cleanup
171+
with open(filename) as f:
172+
data = f.read()
173+
174+
# ❌ PROHIBITED - File may not close
175+
f = open(filename)
176+
data = f.read()
177+
f.close()
178+
```
179+
180+
---
181+
182+
## Enforcement
183+
184+
### Pre-commit Hooks
185+
186+
```bash
187+
# Install hooks
188+
pre-commit install
189+
```
190+
191+
**Enforces:**
192+
- Black formatting (line length 100)
193+
- Ruff linting (BLE001: no bare except)
194+
- Bandit security scanning
195+
- detect-secrets credential scanning
196+
197+
### Manual Checks
198+
199+
```bash
200+
# Find security issues
201+
ruff check src/ --select S307 # eval/exec usage
202+
grep -r "open(" src/ | grep -v "_validate_file_path"
203+
204+
# Find exception issues
205+
ruff check src/ --select BLE # bare except
206+
207+
# Check type hints
208+
mypy src/ --disallow-untyped-defs
209+
210+
# Check coverage
211+
pytest --cov=src --cov-report=term-missing
212+
```
213+
214+
---
215+
216+
## Code Review Checklist
217+
218+
Before merging, verify:
219+
220+
- [ ] No `eval()` or `exec()` usage
221+
- [ ] No bare `except:` or broad `except Exception:` (without justification)
222+
- [ ] All file paths validated with `_validate_file_path()`
223+
- [ ] Type hints on all functions
224+
- [ ] Docstrings on public APIs
225+
- [ ] Test coverage ≥80%
226+
- [ ] Security tests for file operations
227+
- [ ] CHANGELOG.md updated
228+
- [ ] Pre-commit hooks passing
229+
- [ ] All tests passing
230+
231+
---
232+
233+
## Violation Severity
234+
235+
**CRITICAL** (Must fix immediately):
236+
- `eval()` or `exec()` usage
237+
- Path traversal vulnerabilities
238+
- Hardcoded secrets
239+
240+
**HIGH** (Must fix before merge):
241+
- Bare `except:` clauses
242+
- Missing type hints on public APIs
243+
- Test coverage <80%
244+
245+
**MEDIUM** (Should fix):
246+
- Missing docstrings
247+
- Magic numbers
248+
249+
---
250+
251+
## Quick Examples
252+
253+
### Good Code Pattern
254+
255+
```python
256+
from pathlib import Path
257+
from empathy_os.config import _validate_file_path
258+
import logging
259+
260+
logger = logging.getLogger(__name__)
261+
262+
263+
def save_configuration(filepath: str, config: dict) -> Path:
264+
"""Save configuration to file with security validation.
265+
266+
Args:
267+
filepath: Path where config should be saved (user-controlled)
268+
config: Configuration dictionary to save
269+
270+
Returns:
271+
Validated Path where file was saved
272+
273+
Raises:
274+
ValueError: If filepath is invalid or targets system directory
275+
PermissionError: If insufficient permissions to write file
276+
"""
277+
# Validate path to prevent attacks
278+
validated_path = _validate_file_path(filepath)
279+
280+
try:
281+
# Use context manager for safe file handling
282+
with validated_path.open('w') as f:
283+
json.dump(config, f, indent=2)
284+
except PermissionError as e:
285+
logger.error(f"Permission denied writing to {validated_path}: {e}")
286+
raise
287+
except OSError as e:
288+
logger.error(f"OS error writing to {validated_path}: {e}")
289+
raise ValueError(f"Cannot write config: {e}") from e
290+
291+
logger.info(f"Configuration saved to {validated_path}")
292+
return validated_path
293+
```
294+
295+
**What makes this good:**
296+
- ✅ Type hints on parameters and return
297+
- ✅ Comprehensive docstring
298+
- ✅ Path validation before use
299+
- ✅ Specific exception handling
300+
- ✅ Logging at appropriate levels
301+
- ✅ Context manager for file handling
302+
- ✅ Preserves exception context with `from e`
303+
304+
---
305+
306+
## Related Documentation
307+
308+
- [Exception Handling Guide](../../../docs/EXCEPTION_HANDLING_GUIDE.md) - Detailed exception patterns
309+
- [Security Policy](../../../SECURITY.md) - Security reporting and best practices
310+
- [Contributing Guide](../../../CONTRIBUTING.md) - How to contribute
311+
- [Full Coding Standards](../../../docs/CODING_STANDARDS.md) - Complete documentation
312+
313+
---
314+
315+
**Questions?** See full documentation in [docs/CODING_STANDARDS.md](../../../docs/CODING_STANDARDS.md)

0 commit comments

Comments
 (0)