{
"event": "PreToolUse",
"tool_name": "mcp__mcp-docs__docs_update",
"tool_input": {
"id": 99,
"content": "<nav class=\"breadcrumb\">\n <a href=\"\/docs\">Dokumentation<\/a> » \n <a href=\"\/docs\/prozesse\">Prozesse<\/a> » \n Quality Gates\n<\/nav>\n\n<h1>Quality Gates<\/h1>\n<p class=\"doc-meta\"><strong>Erstellt:<\/strong> 2025-12-23 | <strong>Aktualisiert:<\/strong> 2025-12-28<\/p>\n\n<p>Automatische Code-Qualitätsprüfung via Claude Code Hooks mit Task-Integration.<\/p>\n\n<table>\n <tr><th>Status<\/th><td>Aktiv<\/td><\/tr>\n <tr><th>Implementiert<\/th><td>2025-12-23 (Phase 1+2: 2025-12-28)<\/td><\/tr>\n <tr><th>Regeln<\/th><td><strong>36 BLOCK + 38 WARN<\/strong><\/td><\/tr>\n <tr><th>Task-Integration<\/th><td>Automatisch bei Violations<\/td><\/tr>\n<\/table>\n\n<section>\n <h2>Architektur<\/h2>\n <pre><code>\/var\/www\/tools\/ki-protokoll\/claude-hook\/\n├── hook_dispatcher.py ← Stabiler Einstiegspunkt\n├── .env ← DB-Credentials\n└── quality\/\n ├── pre_rules.py ← BLOCK-Regeln Dispatcher\n ├── post_rules.py ← WARN-Regeln Dispatcher\n ├── pre_rules_guard.py ← P1.x SRP, P4.x OOP\n ├── pre_rules_mvc.py ← P2.x MVC\n ├── pre_rules_validation.py ← P3.x PSR\n ├── pre_rules_layers.py ← P6.x SOLID\n ├── pre_rules_htmx.py ← HTMX-C1-C5\n ├── pre_rules_constants.py ← P7.x Magic Numbers\n ├── pre_rules_deterministic.py ← P8.x Deterministic\n ├── pre_rules_tests.py ← P14.x Test Isolation\n ├── pre_rules_python.py ← PP1.x Python\n ├── rules_quality.py ← W1.x-W6.x Quality\n ├── rules_security.py ← Security Warnings\n ├── rules_style.py ← Style Warnings\n ├── rules_constants.py ← W7.x Magic Numbers\n ├── rules_failfast.py ← W8.x Fail Fast\n ├── rules_leastsurprise.py ← W15.x Least Surprise\n ├── rules_testisolation.py ← W14.x Test Isolation\n └── task_creator.py ← Violations → ki_dev.tasks<\/code><\/pre>\n<\/section>\n\n<section>\n <h2>Prüfungen (15 Prinzipien)<\/h2>\n <table>\n <tr><th>#<\/th><th>Prüfung<\/th><th>Pre-Hook (BLOCK)<\/th><th>Post-Hook (WARN)<\/th><\/tr>\n <tr><td>1<\/td><td>SRP + KISS<\/td><td>P1.1 Header, P1.2 Müllhalden<\/td><td>W1.1-W1.5 Metriken<\/td><\/tr>\n <tr><td>2<\/td><td>MVC + CRUD<\/td><td>P2.1-P2.4 SQL, Trans, echo<\/td><td>W2.1-W2.2 Keywords<\/td><\/tr>\n <tr><td>3<\/td><td>PSR + Types<\/td><td>P3.1-P3.4 strict, NS, Return<\/td><td>W3.1, W3.3 Params<\/td><\/tr>\n <tr><td>4<\/td><td>OOP<\/td><td>P4.1 Public Property<\/td><td>W4.1-W4.4 Anämie<\/td><\/tr>\n <tr><td>5<\/td><td>DRY<\/td><td>-<\/td><td>W5.1-W5.2 Duplikate<\/td><\/tr>\n <tr><td>6<\/td><td>SOLID + DIP<\/td><td>P6.1-P6.2 Layer-Imports<\/td><td>W6.1-W6.2 Interface<\/td><\/tr>\n <tr><td>7<\/td><td>Constants<\/td><td>P7.1-P7.3 Magic Numbers<\/td><td>W7.1-W7.5 Magic Strings<\/td><\/tr>\n <tr><td>8<\/td><td><strong>Deterministic<\/strong><\/td><td>P8.1-P8.9 time, rand, global<\/td><td>W8.1-W8.5 Fail Fast<\/td><\/tr>\n <tr><td>14<\/td><td><strong>Test Isolation<\/strong><\/td><td>P14.1-P14.6 Prod-DB, TRUNCATE<\/td><td>W14.1-W14.7 tearDown, sleep<\/td><\/tr>\n <tr><td>15<\/td><td><strong>Least Surprise<\/strong><\/td><td>-<\/td><td>W15.1-W15.6 Getter Side Effects<\/td><\/tr>\n <\/table>\n <p><em>Fett = Neu in Phase 1+2 (2025-12-28)<\/em><\/p>\n<\/section>\n\n<section>\n <h2>Neue Regeln (Phase 1+2)<\/h2>\n \n <h3>P8.x Deterministic Behavior (BLOCK)<\/h3>\n <ul>\n <li><strong>P8.1-P8.5:<\/strong> Blockiert time(), date(), rand(), mt_rand(), random_int() - nutze Clock\/Random Interface<\/li>\n <li><strong>P8.6-P8.9:<\/strong> Blockiert global $, $GLOBALS, $_SESSION, $_COOKIE<\/li>\n <li><em>Allowlist:<\/em> Infrastructure\/Clock\/, Infrastructure\/Random\/, Framework\/<\/li>\n <\/ul>\n \n <h3>W8.x Fail Fast (WARN)<\/h3>\n <ul>\n <li><strong>W8.1:<\/strong> Leere catch-Blöcke<\/li>\n <li><strong>W8.2:<\/strong> @ Error-Suppression<\/li>\n <li><strong>W8.3:<\/strong> Catch nur mit return (kein Logging)<\/li>\n <li><strong>W8.4:<\/strong> Nur generische Exception gefangen<\/li>\n <li><strong>W8.5:<\/strong> throw in __destruct<\/li>\n <\/ul>\n \n <h3>W15.x Least Surprise (WARN)<\/h3>\n <ul>\n <li><strong>W15.1:<\/strong> Getter mit Side Effects (save, update, $this->prop++)<\/li>\n <li><strong>W15.2:<\/strong> Setter mit unerwartetem Return-Typ<\/li>\n <li><strong>W15.3:<\/strong> Bool-Methode ohne is\/has\/can Prefix<\/li>\n <li><strong>W15.4:<\/strong> Constructor mit Return-Value<\/li>\n <li><strong>W15.5:<\/strong> void-Methode mit echo<\/li>\n <li><strong>W15.6:<\/strong> __toString mit throw<\/li>\n <\/ul>\n \n <h3>P14.x Test Isolation (BLOCK)<\/h3>\n <ul>\n <li><strong>P14.1-P14.3:<\/strong> Produktions-DB in Tests (ki_content, ki_dev, ki_protokoll)<\/li>\n <li><strong>P14.4:<\/strong> TRUNCATE TABLE in Tests<\/li>\n <li><strong>P14.5:<\/strong> DROP TABLE\/DATABASE in Tests<\/li>\n <li><strong>P14.6:<\/strong> Static Property ohne tearDown<\/li>\n <\/ul>\n \n <h3>W14.x Test Isolation (WARN)<\/h3>\n <ul>\n <li><strong>W14.1:<\/strong> setUp ohne tearDown<\/li>\n <li><strong>W14.2:<\/strong> Filesystem-Zugriff ohne Cleanup<\/li>\n <li><strong>W14.3:<\/strong> Global State (ini_set, putenv, define)<\/li>\n <li><strong>W14.4:<\/strong> Hardcoded absolute Pfade<\/li>\n <li><strong>W14.5:<\/strong> sleep() in Tests<\/li>\n <li><strong>W14.6:<\/strong> Viele @depends Annotations<\/li>\n <li><strong>W14.7:<\/strong> Test ohne Assertions<\/li>\n <\/ul>\n<\/section>\n\n<section>\n <h2>Workflow<\/h2>\n <pre><code>Claude schreibt PHP\/Python-Datei\n ↓\nPre-Hook prüft BLOCK-Regeln\n ↓\nViolation? → BLOCK + Task erstellen\n ↓\nCode okay? → Datei geschrieben\n ↓\nPost-Hook prüft WARN-Regeln → Tasks erstellen<\/code><\/pre>\n<\/section>\n\n<section>\n <h2>Task-Integration<\/h2>\n <p>Bei jeder Violation wird automatisch ein Task in <code>ki_dev.tasks<\/code> erstellt:<\/p>\n <ul>\n <li><strong>Violation:<\/strong> Datei, Regel, Meldung<\/li>\n <li><strong>Analyse:<\/strong> Was ist die Ursache?<\/li>\n <li><strong>Plan:<\/strong> Checkliste zur Behebung<\/li>\n <li><strong>Umsetzung:<\/strong> Dokumentation nach Abschluss<\/li>\n <\/ul>\n <p><strong>Duplikat-Schutz:<\/strong> Existiert bereits ein offener Task für dieselbe Datei+Regel, wird kein neuer erstellt.<\/p>\n<\/section>\n\n<section>\n <h2>Regeländerungen<\/h2>\n <table>\n <tr><th>Änderung<\/th><th>Claude-Neustart?<\/th><\/tr>\n <tr><td>Regeln in <code>quality\/*.py<\/code><\/td><td>Nein<\/td><\/tr>\n <tr><td><code>settings.json<\/code><\/td><td>Ja<\/td><\/tr>\n <tr><td><code>hook_dispatcher.py<\/code><\/td><td>Ja<\/td><\/tr>\n <\/table>\n<\/section>\n\n<section>\n <h2>Detaillierte Dokumentation<\/h2>\n <ul>\n <li><a href=\"\/docs\/prozesse\/claude-hooks-prozess\">Claude Pre-\/Post-Hook Prozess<\/a><\/li>\n <li><a href=\"\/docs\/prozesse\/claude-hooks-prozess\/hook-system-python-erweiterung\">Python-Erweiterung<\/a><\/li>\n <li><code>\/var\/www\/dev.campus.systemische-tools.de\/docs\/codequality\/ist-soll-analyse.md<\/code><\/li>\n <\/ul>\n<\/section>"
}
}
{
"tool_response": [
{
"type": "text",
"text": "{\n \"success\": true,\n \"doc\": {\n \"id\": 99,\n \"parent_id\": 91,\n \"slug\": \"quality-gates\",\n \"path\": \"\/prozesse\/quality-gates\",\n \"title\": \"Quality Gates\",\n \"description\": \"Automatische Code-Qualitätsprüfung via Claude Code Hooks\",\n \"content\": \"<nav class=\\\"breadcrumb\\\">\\n <a href=\\\"\/docs\\\">Dokumentation<\/a> » \\n <a href=\\\"\/docs\/prozesse\\\">Prozesse<\/a> » \\n Quality Gates\\n<\/nav>\\n\\n<h1>Quality Gates<\/h1>\\n<p class=\\\"doc-meta\\\"><strong>Erstellt:<\/strong> 2025-12-23 | <strong>Aktualisiert:<\/strong> 2025-12-28<\/p>\\n\\n<p>Automatische Code-Qualitätsprüfung via Claude Code Hooks mit Task-Integration.<\/p>\\n\\n<table>\\n <tr><th>Status<\/th><td>Aktiv<\/td><\/tr>\\n <tr><th>Implementiert<\/th><td>2025-12-23 (Phase 1+2: 2025-12-28)<\/td><\/tr>\\n <tr><th>Regeln<\/th><td><strong>36 BLOCK + 38 WARN<\/strong><\/td><\/tr>\\n <tr><th>Task-Integration<\/th><td>Automatisch bei Violations<\/td><\/tr>\\n<\/table>\\n\\n<section>\\n <h2>Architektur<\/h2>\\n <pre><code>\/var\/www\/tools\/ki-protokoll\/claude-hook\/\\n├── hook_dispatcher.py ← Stabiler Einstiegspunkt\\n├── .env ← DB-Credentials\\n└── quality\/\\n ├── pre_rules.py ← BLOCK-Regeln Dispatcher\\n ├── post_rules.py ← WARN-Regeln Dispatcher\\n ├── pre_rules_guard.py ← P1.x SRP, P4.x OOP\\n ├── pre_rules_mvc.py ← P2.x MVC\\n ├── pre_rules_validation.py ← P3.x PSR\\n ├── pre_rules_layers.py ← P6.x SOLID\\n ├── pre_rules_htmx.py ← HTMX-C1-C5\\n ├── pre_rules_constants.py ← P7.x Magic Numbers\\n ├── pre_rules_deterministic.py ← P8.x Deterministic\\n ├── pre_rules_tests.py ← P14.x Test Isolation\\n ├── pre_rules_python.py ← PP1.x Python\\n ├── rules_quality.py ← W1.x-W6.x Quality\\n ├── rules_security.py ← Security Warnings\\n ├── rules_style.py ← Style Warnings\\n ├── rules_constants.py ← W7.x Magic Numbers\\n ├── rules_failfast.py ← W8.x Fail Fast\\n ├── rules_leastsurprise.py ← W15.x Least Surprise\\n ├── rules_testisolation.py ← W14.x Test Isolation\\n └── task_creator.py ← Violations → ki_dev.tasks<\/code><\/pre>\\n<\/section>\\n\\n<section>\\n <h2>Prüfungen (15 Prinzipien)<\/h2>\\n <table>\\n <tr><th>#<\/th><th>Prüfung<\/th><th>Pre-Hook (BLOCK)<\/th><th>Post-Hook (WARN)<\/th><\/tr>\\n <tr><td>1<\/td><td>SRP + KISS<\/td><td>P1.1 Header, P1.2 Müllhalden<\/td><td>W1.1-W1.5 Metriken<\/td><\/tr>\\n <tr><td>2<\/td><td>MVC + CRUD<\/td><td>P2.1-P2.4 SQL, Trans, echo<\/td><td>W2.1-W2.2 Keywords<\/td><\/tr>\\n <tr><td>3<\/td><td>PSR + Types<\/td><td>P3.1-P3.4 strict, NS, Return<\/td><td>W3.1, W3.3 Params<\/td><\/tr>\\n <tr><td>4<\/td><td>OOP<\/td><td>P4.1 Public Property<\/td><td>W4.1-W4.4 Anämie<\/td><\/tr>\\n <tr><td>5<\/td><td>DRY<\/td><td>-<\/td><td>W5.1-W5.2 Duplikate<\/td><\/tr>\\n <tr><td>6<\/td><td>SOLID + DIP<\/td><td>P6.1-P6.2 Layer-Imports<\/td><td>W6.1-W6.2 Interface<\/td><\/tr>\\n <tr><td>7<\/td><td>Constants<\/td><td>P7.1-P7.3 Magic Numbers<\/td><td>W7.1-W7.5 Magic Strings<\/td><\/tr>\\n <tr><td>8<\/td><td><strong>Deterministic<\/strong><\/td><td>P8.1-P8.9 time, rand, global<\/td><td>W8.1-W8.5 Fail Fast<\/td><\/tr>\\n <tr><td>14<\/td><td><strong>Test Isolation<\/strong><\/td><td>P14.1-P14.6 Prod-DB, TRUNCATE<\/td><td>W14.1-W14.7 tearDown, sleep<\/td><\/tr>\\n <tr><td>15<\/td><td><strong>Least Surprise<\/strong><\/td><td>-<\/td><td>W15.1-W15.6 Getter Side Effects<\/td><\/tr>\\n <\/table>\\n <p><em>Fett = Neu in Phase 1+2 (2025-12-28)<\/em><\/p>\\n<\/section>\\n\\n<section>\\n <h2>Neue Regeln (Phase 1+2)<\/h2>\\n \\n <h3>P8.x Deterministic Behavior (BLOCK)<\/h3>\\n <ul>\\n <li><strong>P8.1-P8.5:<\/strong> Blockiert time(), date(), rand(), mt_rand(), random_int() - nutze Clock\/Random Interface<\/li>\\n <li><strong>P8.6-P8.9:<\/strong> Blockiert global $, $GLOBALS, $_SESSION, $_COOKIE<\/li>\\n <li><em>Allowlist:<\/em> Infrastructure\/Clock\/, Infrastructure\/Random\/, Framework\/<\/li>\\n <\/ul>\\n \\n <h3>W8.x Fail Fast (WARN)<\/h3>\\n <ul>\\n <li><strong>W8.1:<\/strong> Leere catch-Blöcke<\/li>\\n <li><strong>W8.2:<\/strong> @ Error-Suppression<\/li>\\n <li><strong>W8.3:<\/strong> Catch nur mit return (kein Logging)<\/li>\\n <li><strong>W8.4:<\/strong> Nur generische Exception gefangen<\/li>\\n <li><strong>W8.5:<\/strong> throw in __destruct<\/li>\\n <\/ul>\\n \\n <h3>W15.x Least Surprise (WARN)<\/h3>\\n <ul>\\n <li><strong>W15.1:<\/strong> Getter mit Side Effects (save, update, $this->prop++)<\/li>\\n <li><strong>W15.2:<\/strong> Setter mit unerwartetem Return-Typ<\/li>\\n <li><strong>W15.3:<\/strong> Bool-Methode ohne is\/has\/can Prefix<\/li>\\n <li><strong>W15.4:<\/strong> Constructor mit Return-Value<\/li>\\n <li><strong>W15.5:<\/strong> void-Methode mit echo<\/li>\\n <li><strong>W15.6:<\/strong> __toString mit throw<\/li>\\n <\/ul>\\n \\n <h3>P14.x Test Isolation (BLOCK)<\/h3>\\n <ul>\\n <li><strong>P14.1-P14.3:<\/strong> Produktions-DB in Tests (ki_content, ki_dev, ki_protokoll)<\/li>\\n <li><strong>P14.4:<\/strong> TRUNCATE TABLE in Tests<\/li>\\n <li><strong>P14.5:<\/strong> DROP TABLE\/DATABASE in Tests<\/li>\\n <li><strong>P14.6:<\/strong> Static Property ohne tearDown<\/li>\\n <\/ul>\\n \\n <h3>W14.x Test Isolation (WARN)<\/h3>\\n <ul>\\n <li><strong>W14.1:<\/strong> setUp ohne tearDown<\/li>\\n <li><strong>W14.2:<\/strong> Filesystem-Zugriff ohne Cleanup<\/li>\\n <li><strong>W14.3:<\/strong> Global State (ini_set, putenv, define)<\/li>\\n <li><strong>W14.4:<\/strong> Hardcoded absolute Pfade<\/li>\\n <li><strong>W14.5:<\/strong> sleep() in Tests<\/li>\\n <li><strong>W14.6:<\/strong> Viele @depends Annotations<\/li>\\n <li><strong>W14.7:<\/strong> Test ohne Assertions<\/li>\\n <\/ul>\\n<\/section>\\n\\n<section>\\n <h2>Workflow<\/h2>\\n <pre><code>Claude schreibt PHP\/Python-Datei\\n ↓\\nPre-Hook prüft BLOCK-Regeln\\n ↓\\nViolation? → BLOCK + Task erstellen\\n ↓\\nCode okay? → Datei geschrieben\\n ↓\\nPost-Hook prüft WARN-Regeln → Tasks erstellen<\/code><\/pre>\\n<\/section>\\n\\n<section>\\n <h2>Task-Integration<\/h2>\\n <p>Bei jeder Violation wird automatisch ein Task in <code>ki_dev.tasks<\/code> erstellt:<\/p>\\n <ul>\\n <li><strong>Violation:<\/strong> Datei, Regel, Meldung<\/li>\\n <li><strong>Analyse:<\/strong> Was ist die Ursache?<\/li>\\n <li><strong>Plan:<\/strong> Checkliste zur Behebung<\/li>\\n <li><strong>Umsetzung:<\/strong> Dokumentation nach Abschluss<\/li>\\n <\/ul>\\n <p><strong>Duplikat-Schutz:<\/strong> Existiert bereits ein offener Task für dieselbe Datei+Regel, wird kein neuer erstellt.<\/p>\\n<\/section>\\n\\n<section>\\n <h2>Regeländerungen<\/h2>\\n <table>\\n <tr><th>Änderung<\/th><th>Claude-Neustart?<\/th><\/tr>\\n <tr><td>Regeln in <code>quality\/*.py<\/code><\/td><td>Nein<\/td><\/tr>\\n <tr><td><code>settings.json<\/code><\/td><td>Ja<\/td><\/tr>\\n <tr><td><code>hook_dispatcher.py<\/code><\/td><td>Ja<\/td><\/tr>\\n <\/table>\\n<\/section>\\n\\n<section>\\n <h2>Detaillierte Dokumentation<\/h2>\\n <ul>\\n <li><a href=\\\"\/docs\/prozesse\/claude-hooks-prozess\\\">Claude Pre-\/Post-Hook Prozess<\/a><\/li>\\n <li><a href=\\\"\/docs\/prozesse\/claude-hooks-prozess\/hook-system-python-erweiterung\\\">Python-Erweiterung<\/a><\/li>\\n <li><code>\/var\/www\/dev.campus.systemische-tools.de\/docs\/codequality\/ist-soll-analyse.md<\/code><\/li>\\n <\/ul>\\n<\/section>\",\n \"status\": \"published\",\n \"sort_order\": 3,\n \"depth\": 1,\n \"created_at\": \"2025-12-23T07:47:51\",\n \"updated_at\": \"2025-12-28T13:51:22\"\n },\n \"message\": \"Document #99 updated\"\n}"
}
]
}