Protokoll #27997

ID27997
Zeitstempel2025-12-28 12:40:10.708859
Clientroot
IP145.224.72.140
Modellclaude-sonnet-4-20250514
Statuscompleted
Tokens2,243 (Input: 1,119, Output: 1,124)
Dauer85 ms
Request-Zeit2025-12-28 12:40:10.708859
Response-Zeit2025-12-28 12:40:10.793694

Request

{
    "event": "PreToolUse",
    "tool_name": "Write",
    "tool_input": {
        "file_path": "\/var\/www\/tools\/ki-protokoll\/claude-hook\/quality\/pre_rules_deterministic.py",
        "content": "#!\/usr\/bin\/env python3\n\"\"\"\nPre-Hook Deterministic Regeln (BLOCK) - Deterministic Behavior.\n\nP8.x Regeln: Verbietet nicht-deterministische Funktionen und globalen Zustand.\nErzwingt Dependency Injection statt globaler Abhängigkeiten.\n\nPrinzip: \"Gleicher Input erzeugt gleichen Output. Kein versteckter globaler Zustand.\"\n\"\"\"\n\nimport re\nfrom typing import Optional\nfrom .rule_base import GLOBAL_ALLOWLIST, is_in_allowlist, block\n\n\n# =============================================================================\n# KONFIGURATION\n# =============================================================================\n\n# Verbotene nicht-deterministische Funktionen\nFORBIDDEN_FUNCTIONS = {\n    \"P8.1\": {\n        \"pattern\": r\"\\btime\\s*\\(\",\n        \"message\": \"Use Clock interface instead of time(). Inject ClockInterface for testability.\",\n        \"allowlist\": [\"\/Infrastructure\/Clock\/\"],\n    },\n    \"P8.2\": {\n        \"pattern\": r\"\\bdate\\s*\\(\",\n        \"message\": \"Use Clock interface instead of date(). Inject ClockInterface for testability.\",\n        \"allowlist\": [\"\/Infrastructure\/Clock\/\"],\n    },\n    \"P8.3\": {\n        \"pattern\": r\"\\brand\\s*\\(\",\n        \"message\": \"Use RandomGenerator interface instead of rand(). Inject for testability.\",\n        \"allowlist\": [\"\/Infrastructure\/Random\/\"],\n    },\n    \"P8.4\": {\n        \"pattern\": r\"\\bmt_rand\\s*\\(\",\n        \"message\": \"Use RandomGenerator interface instead of mt_rand(). Inject for testability.\",\n        \"allowlist\": [\"\/Infrastructure\/Random\/\"],\n    },\n    \"P8.5\": {\n        \"pattern\": r\"\\brandom_int\\s*\\(\",\n        \"message\": \"Use RandomGenerator interface instead of random_int(). Inject for testability.\",\n        \"allowlist\": [\"\/Infrastructure\/Random\/\"],\n    },\n}\n\n# Verbotener globaler Zustand\nFORBIDDEN_GLOBAL_STATE = {\n    \"P8.6\": {\n        \"pattern\": r\"\\bglobal\\s+\\$\",\n        \"message\": \"Use dependency injection instead of 'global' keyword.\",\n    },\n    \"P8.7\": {\n        \"pattern\": r\"\\$GLOBALS\\b\",\n        \"message\": \"Use dependency injection instead of $GLOBALS.\",\n    },\n    \"P8.8\": {\n        \"pattern\": r\"\\$_SESSION\\b\",\n        \"message\": \"Use SessionInterface instead of $_SESSION. Inject for testability.\",\n        \"allowlist\": [\"\/Infrastructure\/Session\/\", \"\/Framework\/\"],\n    },\n    \"P8.9\": {\n        \"pattern\": r\"\\$_COOKIE\\b\",\n        \"message\": \"Use CookieInterface instead of $_COOKIE. Inject for testability.\",\n        \"allowlist\": [\"\/Infrastructure\/Http\/\", \"\/Framework\/\"],\n    },\n}\n\n\n# =============================================================================\n# REGELN\n# =============================================================================\n\ndef p8_forbidden_functions(file_path: str, content: str) -> Optional[dict]:\n    \"\"\"P8.1-P8.5: Nicht-deterministische Funktionen blockieren.\"\"\"\n    if is_in_allowlist(file_path, GLOBAL_ALLOWLIST):\n        return None\n\n    for rule_id, config in FORBIDDEN_FUNCTIONS.items():\n        # Spezifische Allowlist für diese Regel\n        specific_allowlist = config.get(\"allowlist\", [])\n        if is_in_allowlist(file_path, specific_allowlist):\n            continue\n\n        if re.search(config[\"pattern\"], content):\n            return block(rule_id, config[\"message\"])\n\n    return None\n\n\ndef p8_forbidden_global_state(file_path: str, content: str) -> Optional[dict]:\n    \"\"\"P8.6-P8.9: Globaler Zustand blockieren.\"\"\"\n    if is_in_allowlist(file_path, GLOBAL_ALLOWLIST):\n        return None\n\n    for rule_id, config in FORBIDDEN_GLOBAL_STATE.items():\n        # Spezifische Allowlist für diese Regel\n        specific_allowlist = config.get(\"allowlist\", [])\n        if is_in_allowlist(file_path, specific_allowlist):\n            continue\n\n        if re.search(config[\"pattern\"], content):\n            return block(rule_id, config[\"message\"])\n\n    return None\n\n\n# =============================================================================\n# RULE COLLECTION\n# =============================================================================\n\nRULES = [\n    p8_forbidden_functions,\n    p8_forbidden_global_state,\n]\n"
    }
}

Response

{
    "tool_response": {
        "type": "create",
        "filePath": "\/var\/www\/tools\/ki-protokoll\/claude-hook\/quality\/pre_rules_deterministic.py",
        "content": "#!\/usr\/bin\/env python3\n\"\"\"\nPre-Hook Deterministic Regeln (BLOCK) - Deterministic Behavior.\n\nP8.x Regeln: Verbietet nicht-deterministische Funktionen und globalen Zustand.\nErzwingt Dependency Injection statt globaler Abhängigkeiten.\n\nPrinzip: \"Gleicher Input erzeugt gleichen Output. Kein versteckter globaler Zustand.\"\n\"\"\"\n\nimport re\nfrom typing import Optional\nfrom .rule_base import GLOBAL_ALLOWLIST, is_in_allowlist, block\n\n\n# =============================================================================\n# KONFIGURATION\n# =============================================================================\n\n# Verbotene nicht-deterministische Funktionen\nFORBIDDEN_FUNCTIONS = {\n    \"P8.1\": {\n        \"pattern\": r\"\\btime\\s*\\(\",\n        \"message\": \"Use Clock interface instead of time(). Inject ClockInterface for testability.\",\n        \"allowlist\": [\"\/Infrastructure\/Clock\/\"],\n    },\n    \"P8.2\": {\n        \"pattern\": r\"\\bdate\\s*\\(\",\n        \"message\": \"Use Clock interface instead of date(). Inject ClockInterface for testability.\",\n        \"allowlist\": [\"\/Infrastructure\/Clock\/\"],\n    },\n    \"P8.3\": {\n        \"pattern\": r\"\\brand\\s*\\(\",\n        \"message\": \"Use RandomGenerator interface instead of rand(). Inject for testability.\",\n        \"allowlist\": [\"\/Infrastructure\/Random\/\"],\n    },\n    \"P8.4\": {\n        \"pattern\": r\"\\bmt_rand\\s*\\(\",\n        \"message\": \"Use RandomGenerator interface instead of mt_rand(). Inject for testability.\",\n        \"allowlist\": [\"\/Infrastructure\/Random\/\"],\n    },\n    \"P8.5\": {\n        \"pattern\": r\"\\brandom_int\\s*\\(\",\n        \"message\": \"Use RandomGenerator interface instead of random_int(). Inject for testability.\",\n        \"allowlist\": [\"\/Infrastructure\/Random\/\"],\n    },\n}\n\n# Verbotener globaler Zustand\nFORBIDDEN_GLOBAL_STATE = {\n    \"P8.6\": {\n        \"pattern\": r\"\\bglobal\\s+\\$\",\n        \"message\": \"Use dependency injection instead of 'global' keyword.\",\n    },\n    \"P8.7\": {\n        \"pattern\": r\"\\$GLOBALS\\b\",\n        \"message\": \"Use dependency injection instead of $GLOBALS.\",\n    },\n    \"P8.8\": {\n        \"pattern\": r\"\\$_SESSION\\b\",\n        \"message\": \"Use SessionInterface instead of $_SESSION. Inject for testability.\",\n        \"allowlist\": [\"\/Infrastructure\/Session\/\", \"\/Framework\/\"],\n    },\n    \"P8.9\": {\n        \"pattern\": r\"\\$_COOKIE\\b\",\n        \"message\": \"Use CookieInterface instead of $_COOKIE. Inject for testability.\",\n        \"allowlist\": [\"\/Infrastructure\/Http\/\", \"\/Framework\/\"],\n    },\n}\n\n\n# =============================================================================\n# REGELN\n# =============================================================================\n\ndef p8_forbidden_functions(file_path: str, content: str) -> Optional[dict]:\n    \"\"\"P8.1-P8.5: Nicht-deterministische Funktionen blockieren.\"\"\"\n    if is_in_allowlist(file_path, GLOBAL_ALLOWLIST):\n        return None\n\n    for rule_id, config in FORBIDDEN_FUNCTIONS.items():\n        # Spezifische Allowlist für diese Regel\n        specific_allowlist = config.get(\"allowlist\", [])\n        if is_in_allowlist(file_path, specific_allowlist):\n            continue\n\n        if re.search(config[\"pattern\"], content):\n            return block(rule_id, config[\"message\"])\n\n    return None\n\n\ndef p8_forbidden_global_state(file_path: str, content: str) -> Optional[dict]:\n    \"\"\"P8.6-P8.9: Globaler Zustand blockieren.\"\"\"\n    if is_in_allowlist(file_path, GLOBAL_ALLOWLIST):\n        return None\n\n    for rule_id, config in FORBIDDEN_GLOBAL_STATE.items():\n        # Spezifische Allowlist für diese Regel\n        specific_allowlist = config.get(\"allowlist\", [])\n        if is_in_allowlist(file_path, specific_allowlist):\n            continue\n\n        if re.search(config[\"pattern\"], content):\n            return block(rule_id, config[\"message\"])\n\n    return None\n\n\n# =============================================================================\n# RULE COLLECTION\n# =============================================================================\n\nRULES = [\n    p8_forbidden_functions,\n    p8_forbidden_global_state,\n]\n",
        "structuredPatch": [],
        "originalFile": null
    }
}
← Vorheriger Zur Liste Nächster →