pre_rules_deterministic.py
- Pfad:
/var/www/tools/ki-protokoll/claude-hook/quality/pre_rules_deterministic.py - Namespace: claude-hook.quality
- Zeilen: 118 | Größe: 4,020 Bytes
- Geändert: 2025-12-28 12:40:10 | Gescannt: 2025-12-31 10:22:15
Code Hygiene Score: 100
- Dependencies: 100 (25%)
- LOC: 100 (20%)
- Methods: 100 (20%)
- Secrets: 100 (15%)
- Classes: 100 (10%)
- Magic Numbers: 100 (10%)
Keine Issues gefunden.
Dependencies 5
- use re
- use typing.Optional
- use rule_base.GLOBAL_ALLOWLIST
- use rule_base.is_in_allowlist
- use rule_base.block
Funktionen 2
-
p8_forbidden_functions()Zeile 76 -
p8_forbidden_global_state()Zeile 93
Code
#!/usr/bin/env python3
"""
Pre-Hook Deterministic Regeln (BLOCK) - Deterministic Behavior.
P8.x Regeln: Verbietet nicht-deterministische Funktionen und globalen Zustand.
Erzwingt Dependency Injection statt globaler Abhängigkeiten.
Prinzip: "Gleicher Input erzeugt gleichen Output. Kein versteckter globaler Zustand."
"""
import re
from typing import Optional
from .rule_base import GLOBAL_ALLOWLIST, is_in_allowlist, block
# =============================================================================
# KONFIGURATION
# =============================================================================
# Verbotene nicht-deterministische Funktionen
FORBIDDEN_FUNCTIONS = {
"P8.1": {
"pattern": r"\btime\s*\(",
"message": "Use Clock interface instead of time(). Inject ClockInterface for testability.",
"allowlist": ["/Infrastructure/Clock/"],
},
"P8.2": {
"pattern": r"\bdate\s*\(",
"message": "Use Clock interface instead of date(). Inject ClockInterface for testability.",
"allowlist": ["/Infrastructure/Clock/"],
},
"P8.3": {
"pattern": r"\brand\s*\(",
"message": "Use RandomGenerator interface instead of rand(). Inject for testability.",
"allowlist": ["/Infrastructure/Random/"],
},
"P8.4": {
"pattern": r"\bmt_rand\s*\(",
"message": "Use RandomGenerator interface instead of mt_rand(). Inject for testability.",
"allowlist": ["/Infrastructure/Random/"],
},
"P8.5": {
"pattern": r"\brandom_int\s*\(",
"message": "Use RandomGenerator interface instead of random_int(). Inject for testability.",
"allowlist": ["/Infrastructure/Random/"],
},
}
# Verbotener globaler Zustand
FORBIDDEN_GLOBAL_STATE = {
"P8.6": {
"pattern": r"\bglobal\s+\$",
"message": "Use dependency injection instead of 'global' keyword.",
},
"P8.7": {
"pattern": r"\$GLOBALS\b",
"message": "Use dependency injection instead of $GLOBALS.",
},
"P8.8": {
"pattern": r"\$_SESSION\b",
"message": "Use SessionInterface instead of $_SESSION. Inject for testability.",
"allowlist": ["/Infrastructure/Session/", "/Framework/"],
},
"P8.9": {
"pattern": r"\$_COOKIE\b",
"message": "Use CookieInterface instead of $_COOKIE. Inject for testability.",
"allowlist": ["/Infrastructure/Http/", "/Framework/"],
},
}
# =============================================================================
# REGELN
# =============================================================================
def p8_forbidden_functions(file_path: str, content: str) -> Optional[dict]:
"""P8.1-P8.5: Nicht-deterministische Funktionen blockieren."""
if is_in_allowlist(file_path, GLOBAL_ALLOWLIST):
return None
for rule_id, config in FORBIDDEN_FUNCTIONS.items():
# Spezifische Allowlist für diese Regel
specific_allowlist = config.get("allowlist", [])
if is_in_allowlist(file_path, specific_allowlist):
continue
if re.search(config["pattern"], content):
return block(rule_id, config["message"])
return None
def p8_forbidden_global_state(file_path: str, content: str) -> Optional[dict]:
"""P8.6-P8.9: Globaler Zustand blockieren."""
if is_in_allowlist(file_path, GLOBAL_ALLOWLIST):
return None
for rule_id, config in FORBIDDEN_GLOBAL_STATE.items():
# Spezifische Allowlist für diese Regel
specific_allowlist = config.get("allowlist", [])
if is_in_allowlist(file_path, specific_allowlist):
continue
if re.search(config["pattern"], content):
return block(rule_id, config["message"])
return None
# =============================================================================
# RULE COLLECTION
# =============================================================================
RULES = [
p8_forbidden_functions,
p8_forbidden_global_state,
]