{
"event": "PreToolUse",
"tool_name": "mcp__mcp-docs__docs_update",
"tool_input": {
"id": 155,
"content": "<h1>Hook-System Python-Erweiterung<\/h1>\n\n<p><strong>Status<\/strong>: ✅ IMPLEMENTIERT (2025-12-28)<br>\n<strong>Task<\/strong>: #506<\/p>\n\n<h2>Problem<\/h2>\n\n<p>Das Claude Code Hook-System (<code>\/var\/www\/tools\/ki-protokoll\/claude-hook\/<\/code>) prüfte nur PHP-Dateien. Python-Dateien in der Pipeline (<code>\/var\/www\/scripts\/pipeline\/<\/code>) wurden nicht validiert.<\/p>\n\n<h3>Root Cause<\/h3>\n\n<pre><code class=\"language-python\"># hook_dispatcher.py Zeile 78-80 (vorher)\nif not file_path.endswith(\".php\"):\n sys.exit(0)<\/code><\/pre>\n\n<h2>Implementierung<\/h2>\n\n<h3>Phase 1: Dispatcher (hook_dispatcher.py)<\/h3>\n\n<pre><code class=\"language-python\">ALLOWED_EXTENSIONS = {\".php\", \".py\"}\nPYTHON_CHECK_PATHS = [\"\/var\/www\/scripts\/pipeline\/\"]\nSKIP_PATHS = [\"\/venv\/\", \"\/__pycache__\/\", \"\/tests\/\", \"\/vendor\/\"]\n\ndef should_check(file_path: str) -> bool:\n if any(skip in file_path for skip in SKIP_PATHS):\n return False\n ext = Path(file_path).suffix\n if ext not in ALLOWED_EXTENSIONS:\n return False\n if ext == \".php\":\n return True\n if ext == \".py\":\n return any(file_path.startswith(p) for p in PYTHON_CHECK_PATHS)\n return False<\/code><\/pre>\n\n<h3>Phase 2: Python-Regeln (pre_rules_python.py)<\/h3>\n\n<p><strong>PP1.1<\/strong>: Hardcoded Model-Namen blockieren<\/p>\n<ul>\n<li>BLOCKIERT: <code>default=\"mistral\"<\/code>, <code>model=\"gemma\"<\/code><\/li>\n<li>ERLAUBT: <code>get_pipeline_model()<\/code>, <code>DEFAULT_MODEL = \"mistral\"<\/code><\/li>\n<\/ul>\n\n<p><strong>PP1.2<\/strong>: Hardcoded Pipeline-IDs blockieren<\/p>\n<ul>\n<li>BLOCKIERT: <code>pipeline_id = 5<\/code><\/li>\n<li>ERLAUBT: <code>DEFAULT_PIPELINE_ID = 5<\/code>, <code>args.pipeline_id<\/code><\/li>\n<\/ul>\n\n<h3>Phase 3: Integration (pre_rules.py)<\/h3>\n\n<pre><code class=\"language-python\"># Regelfilterung nach Dateityp\nif file_path.endswith(\".php\"):\n rules = PHP_RULES\nelif file_path.endswith(\".py\"):\n rules = PYTHON_RULES\nelse:\n return allow()<\/code><\/pre>\n\n<h2>Testmatrix (7\/7 bestanden)<\/h2>\n\n<table>\n<tr><th>Test<\/th><th>Szenario<\/th><th>Erwartet<\/th><th>Ergebnis<\/th><\/tr>\n<tr><td>1<\/td><td>PP1.1 <code>default=\"mistral\"<\/code><\/td><td>DENY<\/td><td>✅<\/td><\/tr>\n<tr><td>2<\/td><td>PP1.1 <code>get_pipeline_model()<\/code><\/td><td>ALLOW<\/td><td>✅<\/td><\/tr>\n<tr><td>3<\/td><td>PP1.1 <code>DEFAULT_MODEL = \"mistral\"<\/code><\/td><td>ALLOW<\/td><td>✅<\/td><\/tr>\n<tr><td>4<\/td><td>PP1.2 <code>pipeline_id = 5<\/code><\/td><td>DENY<\/td><td>✅<\/td><\/tr>\n<tr><td>5<\/td><td>PP1.2 <code>DEFAULT_PIPELINE_ID = 5<\/code><\/td><td>ALLOW<\/td><td>✅<\/td><\/tr>\n<tr><td>6<\/td><td>Skip <code>\/venv\/<\/code> Pfade<\/td><td>ALLOW<\/td><td>✅<\/td><\/tr>\n<tr><td>7<\/td><td>PHP P1.1 @responsibility<\/td><td>DENY<\/td><td>✅<\/td><\/tr>\n<\/table>\n\n<h2>Dateien<\/h2>\n\n<table>\n<tr><th>Datei<\/th><th>Aktion<\/th><\/tr>\n<tr><td><code>hook_dispatcher.py<\/code><\/td><td>MODIFIZIERT<\/td><\/tr>\n<tr><td><code>quality\/pre_rules_python.py<\/code><\/td><td>NEU<\/td><\/tr>\n<tr><td><code>quality\/pre_rules.py<\/code><\/td><td>MODIFIZIERT<\/td><\/tr>\n<\/table>"
}
}
{
"tool_response": [
{
"type": "text",
"text": "{\n \"success\": true,\n \"doc\": {\n \"id\": 155,\n \"parent_id\": 92,\n \"slug\": \"hook-system-python-erweiterung\",\n \"path\": \"\/prozesse\/claude-hooks-prozess\/hook-system-python-erweiterung\",\n \"title\": \"Hook-System Python-Erweiterung\",\n \"description\": \"Analyse und Implementierungsplan für Python-Datei-Unterstützung im Claude Code Hook-System\",\n \"content\": \"<h1>Hook-System Python-Erweiterung<\/h1>\\n\\n<p><strong>Status<\/strong>: ✅ IMPLEMENTIERT (2025-12-28)<br>\\n<strong>Task<\/strong>: #506<\/p>\\n\\n<h2>Problem<\/h2>\\n\\n<p>Das Claude Code Hook-System (<code>\/var\/www\/tools\/ki-protokoll\/claude-hook\/<\/code>) prüfte nur PHP-Dateien. Python-Dateien in der Pipeline (<code>\/var\/www\/scripts\/pipeline\/<\/code>) wurden nicht validiert.<\/p>\\n\\n<h3>Root Cause<\/h3>\\n\\n<pre><code class=\\\"language-python\\\"># hook_dispatcher.py Zeile 78-80 (vorher)\\nif not file_path.endswith(\\\".php\\\"):\\n sys.exit(0)<\/code><\/pre>\\n\\n<h2>Implementierung<\/h2>\\n\\n<h3>Phase 1: Dispatcher (hook_dispatcher.py)<\/h3>\\n\\n<pre><code class=\\\"language-python\\\">ALLOWED_EXTENSIONS = {\\\".php\\\", \\\".py\\\"}\\nPYTHON_CHECK_PATHS = [\\\"\/var\/www\/scripts\/pipeline\/\\\"]\\nSKIP_PATHS = [\\\"\/venv\/\\\", \\\"\/__pycache__\/\\\", \\\"\/tests\/\\\", \\\"\/vendor\/\\\"]\\n\\ndef should_check(file_path: str) -> bool:\\n if any(skip in file_path for skip in SKIP_PATHS):\\n return False\\n ext = Path(file_path).suffix\\n if ext not in ALLOWED_EXTENSIONS:\\n return False\\n if ext == \\\".php\\\":\\n return True\\n if ext == \\\".py\\\":\\n return any(file_path.startswith(p) for p in PYTHON_CHECK_PATHS)\\n return False<\/code><\/pre>\\n\\n<h3>Phase 2: Python-Regeln (pre_rules_python.py)<\/h3>\\n\\n<p><strong>PP1.1<\/strong>: Hardcoded Model-Namen blockieren<\/p>\\n<ul>\\n<li>BLOCKIERT: <code>default=\\\"mistral\\\"<\/code>, <code>model=\\\"gemma\\\"<\/code><\/li>\\n<li>ERLAUBT: <code>get_pipeline_model()<\/code>, <code>DEFAULT_MODEL = \\\"mistral\\\"<\/code><\/li>\\n<\/ul>\\n\\n<p><strong>PP1.2<\/strong>: Hardcoded Pipeline-IDs blockieren<\/p>\\n<ul>\\n<li>BLOCKIERT: <code>pipeline_id = 5<\/code><\/li>\\n<li>ERLAUBT: <code>DEFAULT_PIPELINE_ID = 5<\/code>, <code>args.pipeline_id<\/code><\/li>\\n<\/ul>\\n\\n<h3>Phase 3: Integration (pre_rules.py)<\/h3>\\n\\n<pre><code class=\\\"language-python\\\"># Regelfilterung nach Dateityp\\nif file_path.endswith(\\\".php\\\"):\\n rules = PHP_RULES\\nelif file_path.endswith(\\\".py\\\"):\\n rules = PYTHON_RULES\\nelse:\\n return allow()<\/code><\/pre>\\n\\n<h2>Testmatrix (7\/7 bestanden)<\/h2>\\n\\n<table>\\n<tr><th>Test<\/th><th>Szenario<\/th><th>Erwartet<\/th><th>Ergebnis<\/th><\/tr>\\n<tr><td>1<\/td><td>PP1.1 <code>default=\\\"mistral\\\"<\/code><\/td><td>DENY<\/td><td>✅<\/td><\/tr>\\n<tr><td>2<\/td><td>PP1.1 <code>get_pipeline_model()<\/code><\/td><td>ALLOW<\/td><td>✅<\/td><\/tr>\\n<tr><td>3<\/td><td>PP1.1 <code>DEFAULT_MODEL = \\\"mistral\\\"<\/code><\/td><td>ALLOW<\/td><td>✅<\/td><\/tr>\\n<tr><td>4<\/td><td>PP1.2 <code>pipeline_id = 5<\/code><\/td><td>DENY<\/td><td>✅<\/td><\/tr>\\n<tr><td>5<\/td><td>PP1.2 <code>DEFAULT_PIPELINE_ID = 5<\/code><\/td><td>ALLOW<\/td><td>✅<\/td><\/tr>\\n<tr><td>6<\/td><td>Skip <code>\/venv\/<\/code> Pfade<\/td><td>ALLOW<\/td><td>✅<\/td><\/tr>\\n<tr><td>7<\/td><td>PHP P1.1 @responsibility<\/td><td>DENY<\/td><td>✅<\/td><\/tr>\\n<\/table>\\n\\n<h2>Dateien<\/h2>\\n\\n<table>\\n<tr><th>Datei<\/th><th>Aktion<\/th><\/tr>\\n<tr><td><code>hook_dispatcher.py<\/code><\/td><td>MODIFIZIERT<\/td><\/tr>\\n<tr><td><code>quality\/pre_rules_python.py<\/code><\/td><td>NEU<\/td><\/tr>\\n<tr><td><code>quality\/pre_rules.py<\/code><\/td><td>MODIFIZIERT<\/td><\/tr>\\n<\/table>\",\n \"status\": \"published\",\n \"sort_order\": 7,\n \"depth\": 2,\n \"created_at\": \"2025-12-28T09:42:14\",\n \"updated_at\": \"2025-12-29T14:48:01\"\n },\n \"message\": \"Document #155 updated\"\n}"
}
]
}