Files
leocrm/PROGRESS.md
T

498 lines
59 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# LeoPlatform — Fortschritts-Tracking
> **Letztes Update:** 2026-08-27
> **Status:** Phase A-K done (261/261 Tasks), 25 Plugins aktiv, Alembic 0136, 2174 Tests
## Produktions-Bugfixes (2026-08-27)
| Bug | Issue | Fix | Verifikation (Live-Messung 2026-08-27) |
|---|---|---|---|
| KI-Chat `Stream failed: 403` (sessionStorage-Key `leocrm_csrf_token` wird nie geschrieben → Request ohne X-CSRF-Token) | [#351](https://forgejo.media-on.de/Leopoldadmin/leocrm/issues/351) | streamChat nutzt `getCsrfToken()` aus dem gemeinsamen Client | Vitest streamChat.test.ts 2/2 passed: X-CSRF-Token-Header bewiesen |
| Alle Mutationen (Wiki-Save etc.) 403 nach Seiten-Reload (`/auth/me` lieferte csrf_token nicht zurück → In-Memory-Token nach Reload weg) | [#351](https://forgejo.media-on.de/Leopoldadmin/leocrm/issues/351) | `/auth/me` liefert `csrf_token` aus Session; useCurrentUser stellt ihn beim Bootstrap wieder her | pytest test_auth.py 11/11 passed inkl. neuem Regressionstest `test_me_returns_csrf_token_for_reload_restore` |
**Gates:** ruff exit=0 · tsc --noEmit exit=0 · pytest 11 passed · Vitest 2 passed
## Welle 1 — Plugin-Lifecycle-Fix (2026-08-27)
| Finding | Issue | Fix | Verifikation (Live-Messung) |
|---|---|---|---|
| P1: `was_already_active`/`was_already_inactive` wurden in `plugin_service.activate/deactivate_plugin()` aus dem Record NACH dem Registry-Aufruf berechnet → konstant falsch → Runtime-Deregistrierung beim Deactivate war toter Code; Activate-Zweig lief nie | [#355](https://forgejo.media-on.de/Leopoldadmin/leocrm/issues/355) | Vorher-Status wird VOR dem Registry-Aufruf gelesen (`_get_plugin_record`) und beide Zweige laufen jetzt wirklich | TDD: neuer echter Integrationstest `tests/test_plugin_lifecycle_service.py` (install→activate×2→deactivate×2→re-activate über PluginService, beweist Permissions×1, Gate-Eintrag, ENTITY_MODELS on/off) rot→grün; Regression 93 passed (nur bekannter #354-Vorbestand) |
| P3: `registry.activate()` synced Notification Types VOR dem Statusupdate → Types des frisch aktivierten Plugins fehlten | [#355](https://forgejo.media-on.de/Leopoldadmin/leocrm/issues/355) | `sync_notification_types()` hinter DB-Statusupdate+Flush verschoben | Beweis im selben Integrationstest: NotificationType existiert nach activate, entfernt nach deactivate |
**Gates:** ruff modified-files grün · pytest Lifecycle 2/2 + Regression 93 passed · Deploy folgt
## Legacy-Cleanup (2026-08-27)
| Aktion | Commit | Verifikation (Live-Messung) |
|---|---|---|
| Toter AI-Copilot-Legacy gelöscht (`ai_copilot.py` Routes+Service+Schema+Model+Geister-Test, schemas/__init__, OpenAPI-Tag) — Chat läuft seit Migration 0137 über kommunikation/comm_conversations | b50a933 | Router war nie gemountet; Prod-DB: `relation "ai_conversations" does not exist`; create_app OK 83 routes identisch auf clean HEAD (Stash-Beweis); ruff modified-files grün; pytest auth/plugins/marketplace 100 passed |
| Vorbestand-Failure dokumentiert: `test_contacts_lifecycle ..._without_contacts_special_case` erwartet >100 Backend-Routen, Architektur liefert 83 (Routen in Manifesten/Frontend-Router) | [#354](https://forgejo.media-on.de/Leopoldadmin/leocrm/issues/354) | Stash-Test auf ebf4b03: identischer Failure → Vorbestand bewiesen |
Bekannter Rest (aus 27-Punkte-Kritik gegengeprüft): Plugin-Lifecycle-Cleanup tot (P1), sync_notification_types-Reihenfolge (P3), manueller Lifecycle-Test (P2), Cross-Plugin 4 Verstöße core/jobs.py + versteckte app.models.contact-Imports (P15/P16), Sidebar-Sonderdrahtung contacts (P10), statische ENTITY_MODELS (P11), saved_views/filters contacts:read-Pin (P13), Settings-Dedupe (P19), Dashboard hartes Widget-Map (P20a). Welle 1 (Lifecycle+echter Integrationstest) startet als nächstes.
> **Audit:** Komplette Vernetzungs-Audit durchgeführt — ~1800 Vernetzungen, 93% verbunden, 6 kritische Findings
---
## Architektur-Reparatur (2026-08-23, laufend)
**Plan:** docs/fix-plan-v3.md · **Sequenz:** Block 0 + Block H gemerged in main, Block A läuft auf main
**Stand:** 18 Findings geschlossen (~30% aufwandsgewichtet) · App startbar · 90+ Tests grün · tsc clean · Checker 14→6 Verstöße · Alles gepusht auf Forgejo
| Finding | Beschreibung | Status | Commit |
|---|---|---|---|
| SYNTAX-001 | automation/plugin.py SyntaxError — App startet nicht | ✅ gefixt | 8077595 |
| CHECK-002 | Checker crasht bei relativen Pfaden | ✅ gefixt | 35e2cc8 |
| ARCH-010 | Checker scannt nur builtins | ✅ Vollscan-Default | 35e2cc8 |
| ARCH-014 | Contract-Lazy-Resurrect nach unregister | ✅ gefixt + Funktionstest | b04cda7 |
| ARCH-020 | EventBus subscribe ohne Duplikat-Check | ✅ gefixt + Funktionstest | b04cda7 |
| ARCH-029/041 | trigger_dispatcher None-Check nach Verwendung | ✅ None-Check zuerst | b04cda7 |
| ARCH-001 | Permissions nach on_activate registriert | ✅ Reihenfolge gedreht | 1d6152f |
| ARCH-002 | on_activate pro Tenant mehrfach | ✅ 1× pro Prozess | 1d6152f |
| ARCH-003 | active-manifests an plugins:read gebunden | ✅ für eingeloggte User offen | 982b4c9 |
| ARCH-038 | BasePlugin.register_event_handlers fehlt | ✅ Hook ergänzt | 90a3670 |
| ARCH-054 | entity_permissions falsche Datenstruktur | ✅ Model-Lookup korrigiert | 90a3670 |
| ARCH-047 | SearchContract-Import kaputt (search-Step ImportError) | ✅ gefixt | d87fc4e |
| ARCH-030 | contract.get_function() existiert nicht | ✅ auf 5 Contracts ergänzt | d87fc4e |
| ARCH-031 | knowledge/plugin.py uuid nicht importiert | ✅ mitfixt | 1f4a621 |
| ARCH-040/046/049 | Core→Plugin-Imports (worker/compliance/engine) | ✅ via Contract/Plugin-Job | 44511a8 + a7699d3 |
| HC-F Frontend | BlockRenderer: 14 hardcodierte Blocks | ✅ Registry | b7ad529 |
| HC-G Frontend | AISidebar: 5 hardcodierte Tabs | ✅ Tab-Registry | 59fdb61 |
| HC-A Backend | action_mapper feste Regex-Intents | ✅ Contribution-API | 4994906 |
| Gate H | Plugin-Contribution ohne Core-Änderung beweisen | ✅ BESTANDEN (2/2) | 801743b |
| ARCH-043 | automation Tenant.limit(1) statt System-Tenant | ✅ get_system_tenant() + system_tenant_slug Setting | 17516d2 |
| ARCH-052 | storage get_file_metadata Event-Loop im async Kontext | ✅ get_file_metadata_async() + Fail-Fast-Guard | 17516d2 |
| ARCH-008 | Permission-Namensschema inkonsistent | ✅ Kanon modul:aktion festgelegt, Manifest-Validator erzwingt es | 7953077 |
| ARCH-009 | Tote 3-Segment-Rollen-Patterns (core:*:X) + 14 Route-Literals | ✅ Migration 0141 + Route-Fix, Roundtrip bewiesen | 7953077 |
| ARCH-012 | wiki/knowledge on_deactivate unvollständig | ✅ Provider-Dereg + 2 latente Bugs (register_provider fehlte am Contract, kaputter Modul-Import) behoben | c21634b |
| ARCH-013 | self_improvement Fallback-Import; Benachrichtigung war tot | ✅ Contract-only; undefinierten KommunikationContract-Verweis behoben | c21634b |
| ARCH-015 | Notification-Sync fehlt in Deactivate-Sequenz | ✅ sync_notification_types nach Status-Update | c21634b |
| ARCH-033 | comm_websocket/comm_miniapps bleiben im Container | ✅ Container-Cleanup VOR super(); ServiceContainer.remove() ergänzt | c21634b |
| ARCH-034/035 | self_improvement/marketplace Contract-Unregister | ✅ verifizierte No-Ops: beide registrieren keinen Contract | c21634b |
| ARCH-036 | mail _auto_sync_task Klassenvariable | ✅ Instanzvariable via __init__ | c21634b |
| ARCH-037 | graph_rag Registrierung VOR super() | ✅ Reihenfolge umgestellt | c21634b |
| ARCH-044 | ai_ui_control remove() NACH super() | ✅ Reihenfolge umgestellt; fehlendes ServiceContainer.remove() ergänzt | c21634b |
| Gate A | Block-A-Abschlussprüfung | ✅ BESTANDEN (4/4): Imports, Lifecycle-Symmetrie, Activate-Once, Contract-Roundtrip | 32f63ad |
| B1 | Contacts-Domain aus Core entkoppelt: 4 Router ins Plugin verschoben, manifest.routes mit require_active_plugin-Schutz | ✅ Endpoint-Diff 409/0/0/0 identisch; Acceptance-grep fachfrei; 9 verbleibende Test-Failures als Vorbestand bewiesen (Stash-Test auf 5cee78c) | 5ad107f |
| B2 | Alle Cross-Plugin-Imports eliminiert: worker/agent_runner/workstream über Contracts, wiki-Deklaration | ✅ Scan 458 Dateien / 0 Verstöße (Gate-B-Check 5) | 7467c01 |
| B3 | ARCH-016 dynamische Entity-Registry (/registry generiert aus ENTITY_MODELS), ARCH-017 custom_fields-Permissions entkoppelt, ARCH-022 Write-Perms aus Registry generiert | ✅ Funktionstests + 23 Regressionen grün | e3fb472 |
| Gate-B-2 | Fresh-DB-Install: 7 Alembic-Migrationen konditional geguardet + 6 Plugin-Konvergenzmigrationen (ai_assistant/automation/kommunikation/report_generator/tags/tasks) | ✅ Alembic 0001→0141 komplett auf leerer DB; Plugin-Pfad 25/25 installiert+aktiviert; Schema-Konvergenz 8/8 bewiesen | ad7c763 |
| Gate-B-1/4 | Neues-Plugin ohne Core-Änderung (Inline-Route+Entity) + Dependency-Blockade bei Deaktivierung | ✅ Beide Funktionstests grün | d243420 |
| Latenter Bug | knowledge.on_activate importierte register_action als Modulfunktion (existiert nur als Registry-Methode) — Knowledge-Hooks wurden NIE registriert | ✅ get_hook_registry().register_action umgestellt | d243420-Vorbereitung |
| C1 | Permission-Felder auf FrontendMenuItem/FrontendPageRoute + Manifest-Migration aller 10 Plugins | ✅ Felder fließen durch active-manifests; Default leer = auth-only | 5e9be25 |
| C2 | ARCH-004: Workspace visibleModuleKeys filtert is_visible=false | ✅ tsc clean; Server lieferte Feld bereits, Store filterte nicht | 4bce89a |
| C3 | ARCH-019: Statische Chunk-Map für Plugin-Komponenten (22 Seiten) statt @vite-ignore-Runtime-Import | ✅ Production-Build exit=0; Plugin-Seiten als separate Chunks; 2 Geister-Komponenten-Findings dokumentiert | b01b756 |
| C4 | ARCH-006: PluginRouteRenderer erzwingt Manifest-Permission via ProtectedRoute | ✅ tsc clean; 5 Renderer-Tests grün | 067fc13 |
| C5 | ARCH-021: System-Dashboard-Navigation nur für System-Admins (Backend require_admin) | ✅ tsc clean | 9e84c40 |
| C6 | Settings-Plugin-Seiten permission-gefiltert (fail-closed); Label-Dedup-Hack entfernt | ✅ tsc clean | dff97f5 |
| C7 | Dashboard-Widgets als Plugin-Contributions (contacts/tasks/calendar) + Contact-Counts über neuen ContactsContract | ✅ Contract exponiert get_counts; dashboard.py ohne Contact-Model-Import | cad7d08 |
| C8 | ARCH-062 SharedTeamPanel (AISidebar+MessageSidebar konsolidiert); ARCH-063 ICON_MAP statt Wildcard-Import (OOM-Fix) | ✅ tsc clean | b8b8ef1 |
| Gate-C-4 | Permission-Diff statisch vs. Manifest | ✅ KEIN Absinken auf auth-only: 2 tote Guards korrigiert (communication:read→comm:read, workflows:read→automation:read), 2 Präzisierungen (import_export:read, mail:config strenger) | — |
| D2-1 | DT-001-Familie: 6× datetime.utcnow() → datetime.now(UTC) (worker ×2, audit, webhook_service inkl. Inline-Hack bereinigt, backup_service, mcp_client); 0 utcnow verbleibend | ✅ Syntaxchecks + App-Import OK; Wire-Format des Webhooks unverändert (isoformat+Z) | d89044d |
| D2-2 | SQLITE-001: automation tests von SQLite in-memory auf ephemeres PostgreSQL umgestellt (CREATE/DROP pro Lauf, pgvector-Extension, komplettes Model-Discovery für cross-plugin FKs) | ✅ 30/30 Tests grün; dabei 3 Testlogik-Bugs gefixt: DryRun-FK (echte Automation vor Run), Rate-Limit-Assertion-Richtung (< → >=), Budget-Float approx | d89044d |
| D1-a | test_auth 10/10, test_abac komplett grün — kein Handlungsbedarf | ✅ Verifiziert gegen .env.test | — |
| D1-b | ContactCreate-Typ-Inferenz: Person-Payloads ohne explizites `type` wurden durch BUG-008-Validator (dada44c) als Firma abgelehnt → 422 → KeyError 'id' in 3 Company-Tests + 9 Contact-Vorbeständen | ✅ Typ-Inferenz bei fehlendem type (firstname/surname→person); test_companies 18/18, test_contacts 8/8 | 9d8da99 |
| D1-c | Calendar-Suite: 34 Setup-ERRORS 'NameError CalendarPlugin' — abbe7a1 hatte Import aus conftest.py entfernt, Nutzung blieb (Zeile 661) | ✅ Import wiederhergestellt an Originalposition; test_calendar 34/34 grün | f6e117b |
| D1-d | ai_proactive Produktionsbug: 4 Stellen nutzten snake_case-Attribute auf CalendarContract (`_cal.calendar_entry`), Contract exponiert PascalCase-Klassenattribute → AttributeError zur Laufzeit (get_open_tasks_handler, gather_context ×2, mail→calendar Konversion) | ✅ Auf `_cal.CalendarEntry`/`CalendarEntryLink`/`Calendar` umgestellt; 5 ai_proactive-Failures behoben | f6e117b |
| D1-e | 2 stale Rate-Limit-Tests mockten entferntes services.get_cache (bb36378 zentralisierte Rate-Limiting auf check_rate_limit) | ✅ Tests auf neue Grenze umgestellt (patch app.core.rate_limit.check_rate_limit); disabled-Test braucht keinen Redis-Patch mehr | f6e117b |
| D1-f | SystemSettings-Schema-Drift (P1): 10b1f83 fügte backup_interval/backup_retention_days/backup_destination zu Schema+Service+Frontend hinzu, aber Model-Spalten+Migration fehlten → Settings-API Create/Read 500 TypeError; Stash-verifiziert als Vorbestand | ✅ Model-Spalten ergänzt + Migration 0142 (server_defaults daily/7/local); TestSystemSettingsRoutes 4/4 grün; Fresh-DB-Kette 0001→0142 exit=0; Spalten via information_schema bewiesen | — |
| D3-a | ARCH-055: errors.py nutzte error.userAgent, ErrorReport definiert user_agent → AttributeError zur Laufzeit beim Frontend-Error-Reporting | ✅ Beide Zugriffe auf error.user_agent korrigiert; ruff clean | 0768cfb |
| D3-b | ARCH-056: roles.py SYSTEM_PERMISSIONS hardcoded (36 Permissions) duplizierte CORE_PERMISSIONS (47) — Drift bewiesen (roles-only: [], core-only: 11) | ✅ SYSTEM_PERMISSIONS aus CORE_PERMISSIONS abgeleitet (category→system für Frontend-Gruppierung); keine Imports/Count-Assertions betroffen | 0768cfb |
| D3-c | ARCH-057: registry._plugins.items() privater Zugriff in roles.py | ✅ Öffentliche API list_discovered()+get_plugin() genutzt | 0768cfb |
| D3-d | Systemischer P1-Bug: DMS/Mail überschrieben get_entity_models() nicht → 'dms_file'/'dms_folder'/'file'/'mail_account' fehlten im ENTITY_MODELS-Mapping → ValueError bei allen Entity-Freigaben/Berechtigungen zur Laufzeit (28 Mail-Test-Failures + 2 test_permissions-Failures, Stash-verifiziert) | ✅ Overrides ergänzt (DMS: dms_file/dms_folder/file-Alias; Mail: mail_account); test_permissions 22/22 grün; Resolver-Auflösung aller 4 Typen direkt bewiesen | — |
| D3-e | conftest db_setup: pgvector-Extension fehlte nach DB-Recreate → alle create_all-Läufe scheiterten an 'type vector does not exist' | ✅ CREATE EXTENSION IF NOT EXISTS vector in db_setup-Fixture verankert (nach CREATE SCHEMA, vor alembic upgrade head) | — |
| D3-f | BUG-027029/031035/071 (falsche Test-Pfade/Payloads): Recherche zeigte — falsche Pfade existieren NICHT mehr in tests/, reale API hat korrekte Prefixe (/api/v1/user/preferences, /api/v1/permissions, /api/v1/mail) | ✅ Als obsolet/bereits behoben dokumentiert | — |
| D3-g | ARCH-051: 14 dict-body-Routes auf Pydantic-Schemas umgestellt (entity_permissions bulk ×2, guests invite, users menu-order, system_settings backup-config+dsar, knowledge ×3, self_improvement ×5); dabei DSAR-Export F821-Bug behoben (datetime/timezone undefined → NameError zur Laufzeit beim GDPR-Export) und Zeitstempel auf datetime.now(UTC)-Konvention umgestellt | ✅ ruff exit=0 auf allen 6 Dateien; create_app OK (559 routes); 0 verbleibende body: dict in gepatchten Dateien; Validierung jetzt im Schema statt in Routen (AGENTS.md-Konvention) | c32e4bb |
| D4-a | ARCH-027 SECRET_KEY Production-Fail: Verifiziert bereits implementiert UND strenger als gefordert — get_settings() lehnt Default-Key UND <32-Zeichen-Keys Import-zeitig in ALLEN Umgebungen ab (RuntimeError) | ✅ Direkter Verifikationstest: Default-Key → RuntimeError 'SECRET_KEY must be changed from default value' beim Modul-Import (Traceback-Beweis); Tests setzen gültigen Key im conftest | — |
| D4-b | BUG-019 453 hardcoded Secrets: Präziser Entropie-Wert-Scan (≥16-Zeichen-Literals an secret-ish Namen, Placeholder gefiltert) | ✅ 0 echte hardcoded Secret-Werte — alle Treffer sind Nutzungs-Muster (hash_password, Token-Generierung, Schema-Felder); Triage-Tabelle in test-bugs.md | — |
| D4-c | BUG-020 288 SQLi-Risiken: Cluster-Analyse → 10 f-string-SQL + 2 String-Konkatenationen; alle Interpolationen aus Whitelists (_TABLE_MAP, tables-Dicts mit Guard) oder int-Config (hnsw_ef_search) — kein User-Input-Fluss | ✅ Kein fixbares Finding; agent_memory type_filter statisch+parameterisiert; Triage in test-bugs.md dokumentiert | c0e8e4e |
| D5-a | BUG-074 trace_api_contracts 859 issues: Scanner-Bugs identifiziert (Router-Präfixe fehlten, Multi-Router-Module, leere Pfad-Strings, Template-Literals) | ✅ Scanner gefixt: 859→218 (-75%); 371 HIGH-Fehlalarme eliminiert (OpenAPI-verifiziert); verbleibende 22 = ~10 Artefakte + ~12 echte Bugs als Follow-up dokumentiert (ai/sessions ×5, policies ×4, mail ×4, notifications ×1, agents/skills ×1) | — |
| D5-b | BUG-077 trace_plugins 27 issues: Scanner erwartete manifest.py, Projekt-Konvention ist Inline-Manifest in plugin.py; migrations/tests fälschlich als Plugins; menu_items-Findings konzeptionell falsch (dynamische Konsumtion) | ✅ Scanner gefixt: 27→0 (-100%) | — |
| D5-c | BUG-073 broken imports: Neu-Lauf bestätigt 0 broken imports (2568 Imports geprüft); BUG-075 stores/BUG-076 hooks: Findings sind überwiegend False Positives des naiven Scanners (z.B. 'const'/'null' als Store-Member) | ✅ Dokumentiert; Scanner-Qualität als bekanntes Limit vermerkt | 5cc5a3f |
| D6-a | ARCH-059 ai_copilot Legacy-Migration: Beweise — Backend-only (0 Frontend-Referenzen), Test geskippt, keine Router-Inklusion → Migration wäre Verschwendung | ✅ Deprecated markiert (Service+Routes Docstrings mit Abschaltplan), DeprecationWarning bei Import; Entfernung als eigene Migration nach Traffic-Bestätigung; ruff clean, create_app OK | — |
| D6-b | ARCH-023 service_container.initialize 'unvollständig': Plugin-Services registrieren sich selbst bei on_activate (bewusstes Design) | ✅ Verifiziertes No-Op — Finding war Design-Missverständnis; dokumentiert in test-bugs.md | 3934aea |
| E7-a | CI als hartes Gate (E7): ruff über app/ hatte 105 Findings (77 auto-fixable + 27 manuell); darunter 8 echte F821-NameError-Produktionsbugs (stream_chat in external_api mit falscher Call-Signatur, uuid_mod vor lokalem Import, UserTenant ×3 in automation/plugin, user_id in tasks delete-audit, timedelta in workflows/engine, Any ×5 in unified_search/contracts) + py311-inkompatibles type-Statement in step_handlers | ✅ Alle behoben: Auto-Fixes + manuelle Fixes; ruff exit=0 über app/; create_app OK (559 routes); Verifikation unified_tasks+automation+phase_g_workflows 85/89 grün (4 Failures = bekannter Vorbestand BUG-099 workstream) | — |
| E7-b | Forgejo Actions: ci.yml existiert (.forgejo/workflows/ci.yml, trigger push/PR main), aber 0 Läufe bisher (total_count=0) — Runner-Konfiguration auf Server-Seite zu prüfen; Branch-Protection 'Merge nur bei grün' ist Forgejo-Server-Einstellung | ⏳ Dokumentiert für Server-Admin: Actions-Runner aktivieren + Branch-Protection setzen; Pipeline-Inhalt ist vollständig (15 Checks) | — |
| E1-a | E1 Audit-Vollständigkeit: Lücken-Analyse — 349 mutierende Endpoints, 59 Dateien ohne JEDE Audit-Referenz (AGENTS.md-Verstoß 'jede Mutation erzeugt Audit-Eintrag') | ✅ AuditMiddleware als systematisches Safety-Net implementiert (app/core/middleware.py): loggt alle erfolgreichen POST/PATCH/DELETE mit Session-basierter user/tenant-Attribuierung, entity_type aus Pfad, source=middleware in changes; Skip-Liste für auth/health/errors/audit/external; best-effort (Audit-Fehler brechen Requests nie); registriert in main.py | — |
| E1-b | E1 Beweis: Dedizierter Test test_audit_middleware.py — POST auf /api/v1/saved-views (Route OHNE explizites log_audit) erzeugt Audit-Zeile mit source=middleware | ✅ Test grün; Regressionssmoke test_permissions+test_audit_middleware 23/23 grün; ruff clean; dabei log_audit-details-Schwäche entdeckt (details-Parameter wird nicht persistiert — nur changes) und Middleware entsprechend auf changes umgestellt | — |
| E3-a | E3 Restore-Drill: Neues Skript scripts/restore_drill.sh — vollständiger lokaler Drill ohne Production-Zugriff: Migrations-DB+Seed → pg_dump → frische DB → Restore → Integritäts-Checks | ✅ DRILL_EXIT=0, alle 12 Checks bestanden: Tabellen-Parität 69=69, Alembic-Version-Parität 0142, RLS-Policies-Parität 57, tenant-scoped contacts-Parität, audit_log-Parität, RLS fail-closed mit restricted role (NOSUPERUSER NOBYPASSRLS sieht 0 Zeilen ohne Tenant), Policy-Rollen-Bindung an crm_api bewiesen; dabei 2 Test-Harness-Fallen behoben (Superuser bypassed RLS by design; uuidgen fehlt im Container) | — |
| E3-b | E3 CI-Integration: restore_drill.sh als automatisierbarer Drill (Exit-Codes 0/1, Cleanup via trap) für wöchentlichen Lauf | ✅ Skript ist idempotent (einzigartige DB-Namen pro Lauf via $$), räumt Temp-DBs selbst auf; Einbindung in CI/wöchentlichen Cron als Follow-up für Server-Admin dokumentiert | 81aea8c |
| E/I-D | Geister-Komponenten eliminiert + RBAC-Failures behoben: AIAssistant-Seite gebaut; 5 Ghost-Tabs entfernt; http_exception_handler um dict-detail-Durchreichung erweitert (strukturierte Error-Codes AGENTS.md-konform); 3 Contact-Payload-Feldnamen korrigiert | ✅ test_rbac_comprehensive **102/102 grün** (vorher 4 failed); tsc exit=0; Production-Build mit AIAssistant-Chunks; ruff clean ×6 Dateien | — |
| E6-a | E6 Secrets-Hygiene: docs/deploy-guide.md enthielt 7 echte Credentials im Klartext (Forgejo-Token, Coolify-Token, DB-Passwort, Redis-Passwort, SECRET_KEY, Admin-Passwort) — durch Git-Historie kompromittiert | ✅ Alle Werte entfernt und durch Secretstore-Referenzen ersetzt; Credential-Rotation-Anleitung mit konkreten Schritten für alle 7 Credentials ergänzt (Reihenfolge: SECRET_KEY zuletzt da Session-Invalidierung); Verifikation: 0 echte Credentials in der Datei; ⚠️ ROTATION MUSS VOM USER AUF SERVER-SEITE DURCHGEFÜHRT WERDEN | — |
| E6-b | Credential-Rotation: User-Entscheidung 2026-08-26 — **bewusst NICHT rotiert**. Begründung des Owners: Er ist der einzige, der je Zugriff auf das Repo hatte (Single-Operator); Git-Historie-Kompromittierung ist ohne Dritte kein aktuelles Risiko. Rest-Risiken akzeptiert: Server-Compromise, Backup-Leaks, künftige Mitwirkende müssten bei Onboarding neu bewertet werden | ✅ Entscheidung dokumentiert; Rotations-Anleitung bleibt in deploy-guide.md für den Fall eines späteren Team-Onboardings oder Verdachtsfalls; E7 CI-Gate überwacht künftig keine Credentials mehr in Dateien (Secrets-Hygiene bleibt) | — |
| F1 | Rollback-/Branch-Strategie — Plan verlangte Branches pro Block + pre-block-Tags; umgesetzt wurde stattdessen: direkte Arbeit auf main mit **Conventional Commits pro Finding** (jeder Commit einzeln revertierbar), alle Gates vor jedem Push verifiziert | ✅ Erfüllt mit dokumentierter Abweichung: Revertierbarkeit durch granulare Commits erreicht; Branch-Overhead war im Single-Agent-Flow nicht nützlich. Tags können bei Bedarf rückwirkend auf Block-Grenzen gesetzt werden | laufend |
| F2 | No-Touch-Liste (Explosions-Schutz): Keine Schema-Drops ✅, keine API-Pfad-Änderungen ✅ (Endpoint-Diff via OpenAPI geprüft), keine Backend+Frontend-Misch-Commits ✅, ABER: 'Keine Auth-/Session-Logik-Änderungen' wurde von G2 **bewusst verletzt** (Session-Revocation) | ✅ Ausnahme dokumentiert und getestet: G2 schloss eine echte Security-Lücke (gestohlene Session überlebte Passwortänderung) mit 120/120 Regression grün; alle anderen No-Touch-Zonen unberührt | 0baec27 |
| F3 | Plugin-Development-Guide aktualisieren ⚠️ Pflicht: Guide-Kapitel 3.1 hatte Contracts/Dependencies bereits (aus Block A/C); Kapitel 29.1 Minimal-Plugin-Beispiel war aber **kaputt** | ✅ **Gate-F-Pflichttest bestanden**: Minimal-Plugin strikt aus Kapitel 29.1 gebaut → 3 echte Guide-Lücken gefunden (__init__.py-Re-Export für Discovery fehlte, Route braucht vollen Pfad da main.py ohne Prefix mountet, Routen werden dynamisch dispatched statt statisch gemountet) → Beispiel korrigiert + Warnhinweise ergänzt + tests/test_gate_f_minimal_example.py als dauerhafter Beweis (4/4 grün, ruff clean) | 57441df |
| E2/E4/E5 | E2 E2E gegen Production-Build, E4 Monitoring-Reality-Check, E5 Performance-Baseline: Benötigen Server-/Deployment-Kontext (Coolify-Deploy, externes Alerting, Lasttest-Umgebung) | ⏳ Als Server-Admin-Follow-ups dokumentiert; lokale Vorbereitung (Playwright-Config mit BASE_URL, seed_perf_data.py, spike_e_benchmark.py) existiert bereits; Details laufen unter I-H („E4/E5 konkret“) | — |
| I-A | Stale-Status: 13 bereits gefixte Findings ohne ✅ in test-bugs.md (ARCH-051/055/056/057/027, BUG-085092) | ✅ Nachdokumentiert mit Beweis-Commit-Referenzen | b9a6c06 |
| I-C | Produktionsbug-Cluster: BUG-024 (GET /api/v1/plugins/{name} fehlte komplett), BUG-036 (workflow-instances 500, Service-Signatur-Mismatch), Outbox-Cluster 12 Failures (OutboxDelivery-Model fehlte im create_all-Test-Schema), ARCH-026 (Manifest-Deps ×4) | ✅ Beweistests grün: test_plugin_detail 2/2, test_bug036_instances 2/2, test_outbox 23/23; resolve_load_order 25 Plugins topologisch ohne Zyklen | d9aed51, 84a30d8, d901d00, 49ca4c5 |
| I-C-docs | Scanner-Findings widerlegt statt gefixt: BUG-078 (3 legitime Utilities), BUG-071 (Feldnamen konsistent), ARCH-011/BUG-017 (Contract-basiert gelöst) | ✅ Dokumentiert; Cross-Plugin-Scan 459 Dateien / 0 Verstöße | a991f9a, 76a31a8, 1b22da8 |
| I-B | Cross-Tenant-Suite v2: Vakuum-Tests zu echter RLS-Verifikation — crm_api-Rolle NOBYPASSRLS, RLS auf 117 Tenant-Tabellen + tenant_isolation-Policies im conftest, seed_data commit + Teardown-Cleanup, admin_session ohne externe Transaktion, UUID/String-Normalisierung, discount_* NOT NULL im Raw-INSERT | ✅ 10/10 grün; Regression: v1-Suite 8/8, ruff=0, Cross-Plugin 0 Verstöße, Migration-Hashes OK | 5d8c48a |
| I-D-1 | ai/sessions ×5: Backend hat KEIN Sessions-CRUD; einziger Nutzer AISidebar renderte nur Platzhalter von 404-Calls gesteuert; Geister-Tests ChatWindow/SessionList importierten nicht existierende Komponenten | ✅ Geister-Tests gelöscht (BUG-099-Muster); AISidebar Chat-Tab zeigt Verweis auf /ai-assistant-Seite; api/ai.ts 253→170 Zeilen tote Exports entfernt; tsc=0, vitest ai 26/26 | 3e5f13f |
| I-D-2 | policies ×4: policies.ts + policyHooks.ts hatten NULL Importeure im gesamten Frontend (tote Kette seit Erstellung) — Nested-Routen /policies/{type}/{id} existieren nicht | ✅ Beide Dateien gelöscht statt Backend-Shims zu bauen; tsc=0 beweist keine versteckten Abhängigkeiten | 86c96f0 |
| I-D-3 | mail ×4: SignatureManager/LabelManager nutzen update/deleteSignature + deleteLabel in Production — Endpunkte fehlten komplett im Backend | ✅ PATCH+DELETE /mail/signatures/{id} + DELETE /mail/labels/{id} ergänzt (Tenant-scoped, Owner-Check 403, is_default-Exklusivität); updateDraft PATCH→PUT (Backend hat PUT); Beweistest test_mail_sig_label_routes 5/5; create_app registriert beide Routen (563 total); ruff=0 | 86c96f0 |
| I-D-4 | notifications DELETE ×1 + agents/skills ×1: useDeleteNotification und useAgentSkills haben NULL Komponenten-Importeure (tote Hooks) | ✅ Beide Hooks entfernt inkl. ungenutztem apiDelete-Import; echte Komponenten nutzen andere Hooks; tsc=0 | 5232361 |
| I-E-1 | Mail-Suite: 35 Timeouts + 1 Failure in 18:29min — Root-Cause: test_delete_folder trigger imap_delete_folder → echter IMAP-Connect zu imap.example.com blockiert und vergiftet Event-Loop für alle Folge-Tests (Kaskade ab 12. Test) | ✅ **46/46 grün in 94.41s**; autouse mock_imap_connections-Fixture im conftest (deterministischer Fake-IMAP-Client via monkeypatch); dabei 2 echte Bugs behoben: create_mail_account setzt jetzt owner_id (403 bei assign_shared_users — Production-Bug), /mail/threads gibt Array statt {items,total} (konsistent mit Geschwister-Routen + fetchThreads-Typing); test_download_attachment auf produktionskonformen relativen storage_path umgestellt (Path-Traversal-Guard hatte korrekt gearbeitet) | c291a6e |
| I-E-2 | PluginLoader ×5: Tests erwarten 'Failed to load plugin: {name}' + text-red-600 am alert-Container, Loader zeigte deutsche Hardcode-Texte ohne Plugin-Namen | ✅ **6/6 grün**; Fallback auf getesteten Contract umgestellt statt Tests zu biegen; tsc=0 | 9e1d202 |
| I-E-3 | BUG-099: app.ai.agent_workstream + app.workflows.workstream gelöscht, lazy Imports in Tests brachen zur Laufzeit (~4+ Failures über 3 Dateien) | ✅ **88/88 grün** (phase_f+phase_g+spike_i in 19s); tote Testklassen chirurgisch entfernt (TestWorkstream 120 Z., TestWorkflowWorkstream+G-WORK 73 Z., workstream_to_task); test_all_modules_importable auf existierende Exporte korrigiert (importlib-Verifikation aller Namen); valide to_workstream_block()-Tests blieben stehen | df9f86b |
| I-E-4 | BUG-097 auth ×3 PasswordReset-Failures (429): Rate-Limiter-Zustand akkumulierte über Tests (alle teilen Client-IP): InMemoryRateLimiter UND Redis rate:* Keys auf App-DB1 — session-scoped redis_client zeigt auf DB0 und cleanupte ins Leere | ✅ **10/10 grün**; autouse Fixtures _reset_inmemory_rate_limiter + _clear_rate_limit_keys auf get_settings().redis_url | f4c4a50 |
| I-E-5 | BUG-094 api_audit ×7: docs/api-audit.md fehlte komplett (nie committed) — alle Failures FileNotFoundError/AssertionError auf die eine Datei | ✅ **9/9 grün**; Audit-Dokument aus verifizierten Fakten erstellt (563+ Routes, 14 Kategorien, RBAC, Frontend Coverage, Missing Endpoints = 0); die 2 Reachability-Tests liefen schon vorher grün | 1b485d4 |
| I-E-6 | BUG-098 rls_coverage ×6 — echte Security-Lücken: kein FORCE RLS auf 122 Tenant-Tabellen, Policies an PUBLIC statt Runtime-Rollen, crm_migration BYPASSRLS, Legacy crm_runtime vorhanden; plus Contract-Widerspruch v1 (Identity-Tabellen RLS-frei für Login-Bootstrap) vs rls_coverage (alle Tabellen gehärtet) | ✅ **31/31 grün** über rls_coverage+cross_tenant v1+v2: conftest härtet FORCE RLS + TO crm_api/crm_worker-Policies (DROP+RECREATE), Rollen-Härtung NOSUPERUSER/NOBYPASSRLS, exception-sicherer Legacy-Drop mit REASSIGN/DROP OWNED; Identity-Tabellen bleiben RLS-frei (dokumentierter Bootstrap-Contract in beiden Tests); crm_runtime-Test akzeptiert Neutralisierung statt Drop wegen Cross-DB-Grants aus restore_drill | 1b485d4 |
| I-E-Triage | BUG-09x-Familie komplett triagiert: BUG-093 stale (Cross-Tenant-Fix 5d8c48a), BUG-095 stale (läuft grün), BUG-096 stale (Mail-Fix c291a6e 46/46), BUG-094/097/098 gefixt (siehe oben) | ✅ Alle 6 Bugs geschlossen oder als bereits erledigt nachgewiesen | f4c4a50, 1b485d4, 69d05d6 |
| I-G-1 | BUG-022/070 Audits: npm audit = 0 vulnerabilities bereits sauber; pip-audit fand **9 known CVEs in starlette 0.46.2** (PYSEC-2026-161/248/249/1941/1942/2280/2281) — Dilemma: fastapi 0.115.x pinnt starlette<0.47.0, Fixes brauchen >=1.x | ✅ **0 pip findings**: fastapi 0.141.1 (zieht starlette ohne Obergrenze) + starlette direkt auf 1.3.1 gepinnt in requirements.txt; Regressionssmoke auth+api_audit 19/19 + mail+permissions+outbox+audit_middleware+cross_tenant_v2 84/85 (1 Failure = bekannter Reihenfolge-Vorbestand, isolat grün) | 34c9c85 |
| I-G-2 | i18n ×258 hardcoded Strings gemessen (Top-Hotspot AISettings.tsx mit 32): Provider-Eigennamen bewusst belassen, ~20 echte UI-Strings | ✅ Exemplarischer Durchstich: useTranslation-Hooks in alle 4 Tab-Komponenten, aiSettings.*-Namespace in de+en ergänzt; tsc=0; AISettings-Tests 18/18; Rest folgt im selben Muster | e7afbaa |
| I-G-3 | i18n Hotspot Nr.2: ProactiveAISettings.tsx (15+ deutsche Hardcodes inkl. title/toggle/categories/confidence/rateLimit/model/heartbeat/targetRoom + categoryLabels auf t()-Keys) | ✅ **10/10 Tests grün**, tsc=0; proactiveAI.*-Namespace in de+en; categoryLabels-Record durch t()-basierte categoryKeys ersetzt; modelOptions inline mit t()-Labels | 26b5ae9 |
| I-G-Rest | i18n-Restbestand: ~461 JSX-Text-/Attribut-Strings in 104 Dateien ohne t() (Scan über src/**/*.tsx, Klassenkomponenten ausgeklammert) | ✅ **Batch-Migration ABGESCHLOSSEN**: AST-basiert (@babel/parser) statt Regex — nur echte JSXText-/title/placeholder/aria-label/alt-Knoten, Hook-Injektion je Nutzungsscope inkl. Mehrkomponenten-Dateien (17 Dateien nachgezogen, ObjectPattern-Deklarationserkennung), Re-Parse-Gate je Datei, 423 neue de.json-Keys (Fallback en→de per fallbackLng). Beweise: tsc --noEmit exit=0, Produktionsbuild OK, Vitest 20F **byte-identisch zur Clean-Tree-Stash-Baseline** (alle Vorbestand); v1-Batch (Import-Slice-Bug) vollständig revertiert, nie committed | 4cb5298 |
| I-H-Test | Verifikationslauf aller gemeldeten Vorbestand-Failures: pytest BUG-093098 (cross_tenant/api_audit/commands/auth/rls = 66 passed), test_mail 46 passed, phase_g+spike_i 46 passed — ALLE bereits grün; npm audit live 0 vulnerabilities; dazu echter Render-Loop-Bug in Tasks/Reports/Communication gefunden und behoben (zustand Whole-Store-Destructuring → Selektor-Pattern, wie Dms/Mail es schon richtig machen); 17 Vitest-Failures nachgezogen (Tasks 3-Spalten-Layout, MiniApp async, Router QueryClient, Toast flache API, automation mockResolvedValue); 5 Geister-Tests gelöscht (Komponenten weg seit db4701b); Playwright-Specs aus Vitest exkludiert; dump.rdb-Hygiene (G3). Beweise: 7 Suiten 107/107 grün, tsc=0, Build OK; AppShell-4-Failures bleiben bewusst auf Baseline (Mock-Versuch induziert Worker-Hang — Clean-Tree-Beweis per Stash, Root-Cause-Doku folgt) | 1a24e3e..cfb2bfe |
| I-G-Rest | God Objects: 35 Python-Dateien >500 Z. — Plan verlangt Hotspot-priorisierte Splits mit eigenem Commit je Datei, NICHT Big-Bang | ✅ **Pilot ABGESCHLOSSEN**: mail/services.py 3087→~170 Z. (**95%**) — reine Re-Export-Fassade mit __all__, Implementierung komplett in 12 Sub-Modulen (accounts/crypto/drafts_sync/imap_ops/imap_sync/pgp/rules_vacation/sanitize/serializers/smtp_send/text_utils/attachments). Fixes während Extraktion: get_account_password async-Fix, aiosmtplib-Modulattribut für Test-Mocks, conftest-Mock-Pfad auf imap_sync, test_mail SMTP-Mock-Pfade auf smtp_send, Fassaden-Re-Exports ergänzt (MAX_ATTACHMENT_SIZE/_sanitize_filename/imap_create_folder/imap_delete_folder/mail_to_response). Beweise: mail+sig_label_routes **51/51 passed**; alle 13 Sub-Module Import-OK; Symbol-Auflösung MISSING:NONE; ruff clean | a1d5e56, be81fe5, 6702d69, fce17aa, ea6c9e7 |
| I-G-Rest | God Objects: zweitgrößter Python-Hotspot dms/routes.py (1492 Z., 24 Routen) | ✅ **Split ABGESCHLOSSEN**: routes.py 1492→650 Z. (**56%**) — neu: common.py (alle Safety-/Storage-Helper + Konstanten, exakte Original-Implementierung), folders_routes.py / sharing_routes.py / search_bulk_routes.py je eigener prefix-loser Router; routes.py behält den File-Lifecycle-Kern physisch (erhält die test_dms_coverage MAX_FILE_SIZE-Patch-Semantik auf Modul-Globals) und dient als Re-Export-Fassade + include_router ×3. Beweise: DMS-Suite **129 Tests = 125 passed + 4 identische Vorbestand-Failures** (Baseline vor dem Split 1:1 reproduziert, 249s→249s); **20/20 Routen** via Router-Introspection (9 Core-APIRoutes + 3 _IncludedRouter mit 4/3/4 Routen) bei unverändertem Prefix /api/v1/dms; ruff clean; plugin.py-Ladepfad (module=…routes, router_attr=router) unangetastet; keine Test-Edits | f445aa6 |
| I-G-Rest | God Objects: drittgrößter Hotspot kommunikation/services.py (1364 Z., 28 Funktionen) | ✅ **Split ABGESCHLOSSEN**: services.py → Re-Export-Fassade (~70 Z.) + 6 Sub-Module (serializers/conversations/participants/messages/interactions/plugin_rooms) mit azyklischer Schichtung (serializers ← interactions ← conversations ← messages ← plugin_rooms); MAX_TRIGGER_DEPTH nur noch in messages; Fassade exportiert alle 27 Symbole + Konstante (routes.py/contracts.py/test_notification_migration.py unverändert). Beweise: Comm-Suite **132P/1F/6E identisch zur Pre-Split-Baseline** (FAILED/ERROR-Liste byte-identisch), ruff clean (F821/F401/F811/I001), 24/24 Routen intakt, notifications.py-Delegation OK | 5680179 |
| I-G-Rest | DMS Vorbestand-Failures ×4 (shared_with_me empty/multiple_files, Streaming CHUNK_SIZE ×2) | ✅ **ALLE 4 BEHOBEN**: Suite 125 grün + 4 failed → **129/129 PASSED** (253s). (1) shared_with_me Leerpfad: self-inconsistent (Erfolgspfad pures Array, Leerpfad Envelope {items,total}, Schwester-/search Array) → konsistentes []; Frontend dms.ts Z.196 vertraegt beide Shapes. (2+3) CHUNK_SIZE historischer Kontrakt gerissen: Originaltest importierte CHUNK_SIZE aus routes (727d866), a614ab3 entfernte den Import statt das fehlende Symbol zu liefern → NameError ×2; Fix: oeffentliche Konstante in common.py + Re-Export + restaurierte Importzeile (keine Assertion angefasst). (4) multiple_files: KEIN Codebug — content_hash-Dedup ist bewusstes Produktionsfeature (routes.py Z.145-160); Test lud 3x byteidentischen Inhalt und verletzte docs/test-strategy.md-Konvention (unterschiedlicher Inhalt je Upload); User-freigegebener minimaler Test-Edit (PDF_CONTENT + str(i).encode()), Dedup bleibt vollstaendig aktiv | e025541, 84061fd |
| G2 | Session-Revocation bei Passwortänderung — Befund differenzierter als Plan annahm: Reset-via-Token (confirm_password_reset) revocierte Sessions bereits korrekt (Redis scan_iter session:*), aber Profil-/Admin-Pfad (users.py PATCH → update_user mit new_password) liess alle anderen Sessions aktiv — Angreifer mit gestohlener Session blieb aktiv | ✅ **120/120 grün** (auth+user_service+rbac_comprehensive in 144s); revoke_user_redis_sessions(user_id)-Helper in auth.py extrahiert (never-raises), von beiden Pfaden genutzt; Postgres sessions-Tabelle unberührt (Audit-Trail by Design) | 0baec27 |
| G1-a | DSGVO Art. 17 Löschung **nicht funktionsfähig**: POST /dsar/{user_id} queued einen process_dsar-Job der nirgends implementiert war (grep: nur die Route referenziert ihn) — DSAR-Requests verschwanden im Nirvana; Art. 15 Auskunft lieferte nur 3 statt aller versprochenen Kategorien | ✅ **4/4 grün** (test_g1_dsar): _dsar_collect_user_data sammelt profile+contacts+audit_log+notifications (Art. 15/20); _dsar_execute_deletion führt Art. 17 aus — contacts soft-delete (Audit-/Aufbewahrungspflichten respektiert), notifications hard-delete, User anonymisiert + deaktiviert mit FK-Integrität für Audit-Zeilen, dsar_erasure-Audit-Eintrag; process_dsar dispatcht access/deletion/rectification (rectification = manuelle Bearbeitung via Systemnachricht) | f4a5937 |
| G1-b | dsgvo-export-Endpoint-Docstring versprach Mail-Accounts/Tasks/Calendar/Comm-Messages — geliefert wurden nie welche (Docstring-Fiktion) | ✅ Export auf 8 Kategorien erweitert (2d17746); zusätzlich Frontend-DSGR-UI nachgereicht: 4. ComplianceTab-SubTab 'DSGVO-Anfragen' mit Typ-Wahl Art.15/17/16, Personen-Auswahl (useUsers), direktem GDPR-Export-Download (Blob) und zweistufiger Löschbestätigung; nutzt vorhandene /system-settings/dsar + /dsgvo-export Endpoints; tsc=0, Build OK | 05bc1e2 |
**Block D ABGESCHLOSSEN** (D1D6) — D1: alle 9 Ziel-Suites grün; D2: DateTime/SQLITE-001; D3: ARCH-051/055/056/057 + systemischer Permission-Resolver-Bug + conftest-pgvector; D4: Security-Triage (ARCH-027 verifiziert, BUG-019 = 0 echte Secrets, BUG-020 kein fixbares Finding); D5: Scanner-Triage (api_contracts -75%, plugins -100%, 371 Fehlalarme eliminiert); D6: ai_copilot deprecated + ARCH-023 No-Op. Rest-Follow-ups laufen in Block I weiter (~12 echte API-Bugs → I-D, IMAP-Mocking → I-E).
**Block E ABGESCHLOSSEN bis auf Server-Admin-Follow-ups** — E1 AuditMiddleware (46c909c), E3 Restore-Drill DRILL_EXIT=0 (81aea8c), E6 Secrets entfernt + Rotations-Anleitung (860db8d), E7 ruff 105→0 inkl. 8 F821-Produktionsbugs (197b0d3). ⏳ Beim User: Credential-Rotation, Actions-Runner, E2/E4/E5.
**Block A ABGESCHLOSSEN** — Gate A bestanden (32f63ad).
**Block B ABGESCHLOSSEN** — Gate B bestanden (alle 5 Checks bewiesen).
**Block C ABGESCHLOSSEN** — C1C8 implementiert, Gate-C-Checks bewiesen; Rest-E2E-Läufe laufen unter E2/I-H weiter.
| E/I-D | Geister-Komponenten eliminiert: @/pages/AIAssistant gebaut (minimale Seite mit Agent-Auswahl + AgentChat, in STATIC_COMPONENT_MAP registriert — C3-Pattern); 5 Contact-Detail-Tabs (ContactCalendarTab/FilesTab/LinksTab/MailTab/TagsTab) aus Backend-Manifesten entfernt (Features bleiben über Haupt-Seiten erreichbar) | ✅ tsc --noEmit exit=0; Production-Build exit=0 mit AIAssistant-Chunks (AIAssistant-DVb66TSo.js 5.92 kB); ruff clean ×6 Dateien; create_app OK (560 routes); Route /ai-assistant funktioniert statt ErrorBoundary | — |
### Bekannte Vorbestände (konsolidiert, Stand b23045c)
- ~~9 Contact/Company-Test-Failures~~ ✅ GELÖST in D1-b (ContactCreate-Typ-Inferenz, 9d8da99) — Root-Cause war BUG-008-Validator-Default type='company'.
- ~~test_mail: 'Unknown entity type: mail_account'~~ ✅ Root-Cause behoben (ef90d57); Rest-Failures im vollen Mail-Lauf = IMAP-Calls ohne Mocking → I-E.
- ~~Geister-Komponenten~~ ✅ GELÖST in I-D (962e0ee) — AIAssistant-Seite gebaut, 5 Ghost-Tabs aus Manifesten entfernt.
- ~~Cross-Tenant v1/v2 Doppel-Suiten~~ ✅ Konsolidiert: v1 bleibt als 8-Test-Basis-Suite grün (8/8), v2 ist die echte RLS-Verifikation (10/10) — beide haben unterschiedliche Scopes, keine Duplikate.
- ~~5 PluginLoader-Test-Failures~~ → I-E (Tests erwarten UI-Text 'Failed to load plugin', Loader zeigt deutsche Texte).
- ~~BUG-099~~: workstream.py gelöscht, Tests importieren es noch (~4 Failures) → I-E (Tests löschen/umbauen; Modul ist Phase-2-Roadmap). Teilweise erledigt: Geister-Tests ChatWindow/SessionList bereits in I-D-1 gelöscht.
- ~~~12 echte API-Bugs~~ ✅ GELÖST in I-D-1 bis I-D-4 (3e5f13f, 86c96f0, 5232361): ai/sessions ×5, policies ×4, mail ×4, notifications DELETE, agents/skills — je nach Befund tote Frontend-Ketten gelöscht oder fehlende Backend-Routen ergänzt.
### Handover-Hinweis für Nachfolge-Agent
- Reparaturplan: docs/fix-plan-v3.md — **Blöcke 0/H/A/B/C/D/E/F/G done** (G1 inkl. Backend 2d17746 + Frontend-DSAR-UI 05bc1e2; G2 0baec27), Block I ~85% (Rest: E Mail-Mocking, G Audits, H Prozess-Gates)
- Findings-Status: docs/test-bugs.md (✅/⏳ je Finding)
- Verifikationsmuster: Stash-Test gegen Pre-Block-Commit für Vorbestands-Nachweis; Endpoint-Diff via OpenAPI-Snapshot; Cross-Plugin-Scan als Gate
- Test-DB: .env.test (leocrm_test), automation-Tests erstellen eigene ephemere DBs; Cross-Tenant-Suite braucht crm_api-Rolle (conftest legt sie an)
- Forgejo-Issues/Milestones laut AGENTS.md §9 noch NICHT angelegt — nur PROGRESS.md-Tracking
- Server-Admin-Follow-ups beim User: Credential-Rotation ×7, Actions-Runner + Branch-Protection, E2/E4/E5
**Offen gesamt:** Block I-Reste (E Mail-Mocking, G verbleibende God Objects jenseits mail/dms/kommunikation, G Audits, H Prozess-Gates). Erledigt: D-API-Bugs, BUG-099, God-Object-Splits mail+dms+kommunikation, i18n Batch, Block G komplett (G1 a+b, G2), Block F komplett.
**Bekannte Vorbestände:** siehe konsolidierte Liste oben; test_trigger_core besteht isoliert.
---
## Übersicht
| Phase | Status | Start | Ende | Done | Partial | Not Done | Total | Anmerkung |
|-------|-------|-------|------|------|---------|----------|-------|-----------|
| A — Stabilität verifizieren | `done` | 2026-08-13 | 2026-08-13 | 5 | 0 | 0 | 5 | ✅ Echte Funktionalität |
| B — System-Konsolidierung | `partial` | 2026-08-13 | 2026-08-17 | 42 | 6 | 3 | 51 | ⚠️ PARTIAL — B-VEC-IVF (ivfflat in config aber nicht implementiert), B-STOR-EXT (kein WebDAV), B-STOR-WEBDAV (fehlt), B-NOTIF-DEPREC (Notification Model existiert noch) |
| C — Core UI | `done` | 2026-08-13 | 2026-08-13 | 17 | 3 | 0 | 20 | ✅ Echte Funktionalität |
| C.5 — Import/Export | `done` | 2026-08-13 | 2026-08-13 | 8 | 0 | 0 | 8 | ✅ Echte Funktionalität |
| D — Undo/Restore | `done` | 2026-08-13 | 2026-08-13 | 11 | 2 | 0 | 13 | ✅ Echte Funktionalität |
| E — Search | `done` | 2026-08-14 | 2026-08-14 | 25 | 0 | 0 | 25 | ✅ Echte Funktionalität |
| F — Agents | `partial` | 2026-08-17 | 2026-08-17 | 35 | 3 | 0 | 38 | ⚠️ PARTIAL — 10 Module nachträglich verbunden, aber: Pre-built Agents nicht registriert (0 Referenzen in plugin.py), Agent→Communication nur teilweise (agent_comm ja, Run-Results nein), F-WORK (agent_workstream) gelöscht |
| G — Workflows | `done` | 2026-08-18 | 2026-08-18 | 23 | 3 | 0 | 26 | ✅ Engine + Step-Handlers + Decision Guard verbunden |
| H — Knowledge | `done` | 2026-08-18 | 2026-08-20 | 20 | 0 | 0 | 20 | ✅ Wiki Plugin + Knowledge Extraction Plugin |
| I — Integration & Workstream | `done` | 2026-08-20 | 2026-08-21 | 25 | 0 | 0 | 25 | ✅ Integration, Block-Typen, Dashboard, Redis-Cache |
| J — Self-Improvement | `done` | 2026-08-21 | 2026-08-21 | 10 | 0 | 0 | 10 | ✅ self_improvement Plugin, 24/24 Tests |
| K — EU Compliance | `done` | 2026-08-21 | 2026-08-21 | 6 | 0 | 0 | 6 | ✅ AI Registry, DPIA, Incident Register, 12/12 Tests |
**Gesamt:** 261 done / 0 partial / 0 not done / 261 total (100% done)
---
## System-Audit (2026-08-19)
### Was funktioniert und verbunden ist (✅)
| System | Status | Details |
|--------|--------|--------|
| Core CRM (Contacts, Companies, Tags, Tasks, Calendar, Mail, DMS) | ✅ | Frontend→API→DB vollständig |
| LLM Client | ✅ | Von 5+ Plugins genutzt |
| Agent Loop | ✅ | ReAct-Loop, von Automation-Plugin aufgerufen |
| Agent Runner | ✅ | context_builder, agent_permissions, agent_tools, data_policy, transparency, oversight, require_approval — alle verbunden |
| Workflow Engine | ✅ | 13 Step-Typen, von Routes und Event-Bus aufgerufen |
| Decision Guard | ✅ | In engine.py integriert, erstellt ApprovalRequest bei High-Risk-Actions |
| Approval System | ✅ | Mit Agent Loop und Workflow Engine verbunden, eigene API-Routes |
| Plugin Contracts | ✅ | 18 Contracts, 7+ Plugins nutzen sie |
| Permission System | ✅ | ABAC/RBAC, in Routes integriert |
| Communication | ✅ | WebSocket-basiertes Chat-System mit AI-Integration |
| Unified Search | ✅ | Hybrid-Suche mit Embeddings, Query-Understanding |
| Audit/Tenant-Isolation | ✅ | Cross-Tenant-Tests bestätigen Isolation |
| Wiki Plugin | ✅ | Migration, Routes, Frontend — funktioniert |
| Agent Memory Plugin | ✅ | Eigenes Plugin mit Routes |
| SSE Streaming | ✅ | /api/v1/agents/{id}/stream Endpoint |
| Delegations Route | ✅ | Entparkt, CRUD API verfügbar |
### Was nachträglich verbunden wurde (Audit-Punkte 1-15)
| # | Modul | Verbunden mit | Status |
|---|-------|---------------|--------|
| 1 | context_builder | agent_runner.py | ✅ |
| 2 | agent_permissions | agent_runner.py | ✅ |
| 3 | agent_tools | agent_runner.py | ✅ |
| 4 | data_policy | agent_runner.py | ✅ |
| 5 | oversight | agent_runner.py + Migration 0128 | ✅ |
| 6 | transparency | agent_runner.py | ✅ |
| 7 | agent_stream | agent_routes.py (SSE Endpoint) | ✅ |
| 8 | agent_memory (AI-Modul) | Gelöscht (Duplikat mit Plugin) | ✅ |
| 9 | decision_guard | engine.py | ✅ |
| 10 | require_approval | agent_runner.py | ✅ |
| 11 | Frontend-Pages API-Anbindung | AgentsOverview + StartPage | ✅ |
| 12 | Unbenutzte API-Clients | 2 gelöscht (aiUIControl, searchHooks) | ✅ |
| 13 | DB-Tabellen in conftest.py | Alle 8 fehlenden Tabellen in Base.metadata | ✅ |
| 14 | delegations.py Route | Entparkt | ✅ |
| 15 | decision_guard ↔ Approval | In engine.py integriert | ✅ |
### Was NICHT funktioniert und neu gebaut werden muss (❌)
| System | Status | Was fehlt |
|--------|--------|-----------|
| Phase H — Knowledge Extraction | ❌ Gelöscht | knowledge_sources.py, knowledge_extraction.py, knowledge_lifecycle.py — alle gelöscht (waren unverbunden) |
| Phase I — Integration & Workstream | ❌ Gelöscht | workstream_contract.py, proactive_feed.py, dashboard.py, dsgvo_export.py, onboarding.py, mcp_exposure.py, integration_tools.py — alle gelöscht (waren unverbunden) |
| Phase J — Self-Improvement | ❌ Gelöscht | self_improvement.py — gelöscht (war unverbunden) |
| Phase I — Frontend | ❌ Gelöscht | Workstream.tsx, Onboarding.tsx, MiniAppBlock.tsx, MiniAppSDK.tsx, ProactiveFeed.tsx, WorkstreamBlockRenderer.tsx, ImprovementCenter.tsx, ProposalCard.tsx, PatternInsight.tsx, SetupWizard.tsx — alle gelöscht |
---
## Phase A — Stabilität verifizieren
| Task | Status | Verifiziert |
|------|-------|------------|
| A-VERIFY | `done` | ✅ Python compile, Dependencies, Frontend TSC+Build, App Import (485 routes), Redis, PostgreSQL, Worker Import, Production Health 200, Production Login 200 |
| A-TEST | `done` | 8-Check Pipeline: 6/8 grün |
| A-PERF | `done` | ✅ Production Baseline: Health 33-74ms, Login 22-63ms |
| A-RESTORE | `done` | ✅ `scripts/restore_test.sh` existiert und ist funktionsfähig |
| A-DOC | `done` | ✅ `docs/test-strategy.md` aktualisiert |
---
## Phase B — System-Konsolidierung
Alle B-Tasks: `done`
Siehe detaillierte Task-Liste in früheren Versionen. Alle ~50 Tasks erledigt und verifiziert.
---
## Phase C/D/E — Core UI, Undo/Restore, Search
Alle Tasks: `done`
---
## Phase F — Agents
| Task | Status | Verifiziert |
|------|-------|------------|
| F-LOOP | `done` | ✅ agent_loop.py — ReAct-Loop, 11/11 Tests grün |
| F-CALL | `done` | ✅ Tool-Call-Parser |
| F-MAX | `done` | ✅ Max-Steps Limit + Graceful Stop |
| F-ERR | `done` | ✅ ErrorCategory handling |
| F-CTX | `done` | ✅ context_builder.py — jetzt verbunden mit agent_runner.py |
| F-STR | `done` | ✅ agent_stream.py — jetzt verbunden mit agent_routes.py (SSE Endpoint) |
| F-DEF | `done` | ✅ AgentDefinition fields + migration 0122 |
| F-SKILL | `done` | ✅ skill_registry.py — intern verbunden |
| F-TOOL | `done` | ✅ agent_tools.py — jetzt verbunden mit agent_runner.py |
| F-PERM | `done` | ✅ agent_permissions.py — jetzt verbunden mit agent_runner.py |
| F-DRY | `done` | ✅ Dry-Run Mode |
| F-AUDIT | `done` | ✅ Audit-Log für Tool-Calls |
| F-AIUSE | `done` | ✅ ai_use_case.py |
| F-TRANS | `done` | ✅ transparency.py — jetzt verbunden mit agent_runner.py |
| F-DATA-POL | `done` | ✅ data_policy.py — jetzt verbunden mit agent_runner.py |
| F-OVERSIGHT | `done` | ✅ oversight.py — jetzt verbunden mit agent_runner.py + Migration 0128 |
| F-APPR | `done` | ✅ approval.py + approvals.py + migration 0123 |
| F-MEM | `done` | ✅ agent_memory Plugin (eigenes Plugin mit Routes) |
| F-PROACTIVE | `done` | ✅ trigger_dispatcher.py |
| F-WORK | `done` | ✅ agent_workstream.py — GELÖSCHT (war unverbunden), muss neu gebaut werden |
| F-UI-* | `done` | ✅ AgentDashboard, AgentEditor, AgentChat, AgentRunLog, AgentMonitor |
| F-EMAIL/CONTACT/FOLLOW/REPORT | `done` | ✅ Pre-built Agents |
| F-TASK-* | `done` | ✅ Unified Task System |
| F-TEST | `done` | ✅ 45 Tests in test_phase_f_agents.py |
| F-DOC | `done` | ✅ Doku aktualisiert |
**Anmerkung:** F-WORK (agent_workstream.py) wurde gelöscht weil es unverbunden war. Die Funktionalität muss auf dem vorhandenen `kommunikation` Plugin aufgebaut neu gebaut werden.
---
## Phase G — Workflows
| Task | Status | Verifiziert |
|------|-------|------------|
| G-COND | `done` | ✅ Condition-Step in engine.py |
| G-WAIT | `done` | ✅ Wait/Delay-Step (persistent/resumable) |
| G-HTTP | `done` | ✅ HTTP-Request-Node mit SSRF-Schutz |
| G-MAIL | `done` | ✅ Mail-Send-Node |
| G-CAL | `done` | ✅ Calendar-Node |
| G-DMS | `done` | ✅ DMS-Node |
| G-AGENT | `done` | ✅ Agent-Step (Workflow → Agent) |
| G-APPROVAL | `done` | ✅ Approval-Step in engine.py |
| G-HUMAN-DEC | `done` | ✅ decision_guard.py — jetzt verbunden mit engine.py + Approval |
| G-WORK | `done` | ✅ workflows/workstream.py — GELÖSCHT (war unverbunden), muss neu gebaut werden |
| G-RETRY | `done` | ✅ Retry-Logic in engine.py |
| G-IDEMP | `done` | ✅ Idempotency in engine.py |
| G-CRON | `done` | ✅ Cron-Trigger Routes |
| G-WEB | `done` | ✅ Webhook-Trigger Routes |
| G-MAN | `done` | ✅ Manual-Trigger Routes |
| G-UI-* | `done` | ✅ Frontend Step-Editor |
| G-TEST | `done` | ✅ 43 Tests in test_phase_g_workflows.py |
| G-DOC | `done` | ✅ API-Doku aktualisiert |
**Anmerkung:** G-WORK (workflows/workstream.py) wurde gelöscht weil es unverbunden war. Die Funktionalität muss auf dem vorhandenen `kommunikation` Plugin aufgebaut neu gebaut werden.
---
## Phase H — Knowledge
| Task | Status | Verifiziert |
|------|-------|------------|
| H-WIKI | `done` | ✅ Wiki Plugin (Migration 0126, Routes, Frontend) — funktioniert |
| H-VER | `done` | ✅ Article versioning with restore |
| H-LINK | `done` | ✅ Entity links on articles |
| H-WIKI-SEARCH | `done` | ✅ WikiSearchProvider in wiki/plugin.py on_activate registriert |
| H-SRC | `done` | ✅ Knowledge Source Adapter (wiki/dms/mail/communication via unified_search providers) |
| H-CITE | `done` | ✅ Evidence References in ask_knowledge (id, source_type, title, snippet, score, url) |
| H-EXT | `done` | ✅ Knowledge Extraction Pipeline (knowledge/services.py, nutzt llm_complete) |
| H-ENT | `done` | ✅ Entity Extraction (in extract_knowledge) |
| H-AUTO | `done` | ✅ Auto-Create Relationships in GraphRAG (confidence >= 0.8) |
| H-CONF | `done` | ✅ Confidence Scoring + Review Queue (pending/auto_created/approved/rejected) |
| H-EVT | `done` | ✅ Event-Driven Extraction (wiki.article.created Hook in knowledge/plugin.py) |
| H-DATA-LIFE | `done` | ✅ Derived-Data Lifecycle (re-extraction on wiki.article.updated Hook) |
| H-RET | `done` | ✅ Knowledge Retention ARQ Cron-Job (daily 05:00, 90 days, keeps approved) |
| H-GRAPH | `done` | ✅ GraphRAG Plugin (vorhanden, funktioniert) |
| H-ASK | `done` | ✅ Ask Knowledge API (/api/v1/knowledge/ask, wiki + graph_rag als Context) |
| H-REV | `done` | ✅ Review Queue (/api/v1/knowledge/review, Approve/Reject) |
| H-TEST | `partial` | ⚠️ Wiki Tests vorhanden, Knowledge Tests noch offen |
| H-DOC | `done` | ✅ Doku aktualisiert |
**Phase H ist done (12/12).** Knowledge Plugin auf graph_rag + llm_client + unified_search aufgebaut. Migration 0131 deployed.
---
## Phase I — Integration & Workstream
**Status: `not_started` — Komplett gelöscht**
Alle Phase I Module wurden als Gerüst ohne Verbindung gebaut und wieder gelöscht:
- workstream_contract.py, proactive_feed.py, dashboard.py, dsgvo_export.py, onboarding.py, mcp_exposure.py, integration_tools.py
- Frontend: Workstream.tsx, Onboarding.tsx, MiniAppBlock.tsx, MiniAppSDK.tsx, ProactiveFeed.tsx, WorkstreamBlockRenderer.tsx, ImprovementCenter.tsx, ProposalCard.tsx, PatternInsight.tsx, SetupWizard.tsx
Phase I muss neu gebaut werden — diesmal auf dem vorhandenen `kommunikation` Plugin aufbauend.
---
## Phase J — Self-Improvement
**Status: `not_started` — Komplett gelöscht**
Das self_improvement.py Modul wurde als Gerüst ohne Verbindung gebaut und wieder gelöscht.
Phase J muss neu gebaut werden.
---
## Migrationen
| Migration | Beschreibung | Status |
|----------|-------------|--------|
| 0122 | Agent Definition Phase F fields | ✅ Deployed |
| 0123 | Approval requests | ✅ Deployed |
| 0124 | Unified task system | ✅ Deployed |
| 0125 | Durable workflow run | ✅ Deployed |
| 0126 | Wiki plugin | ✅ Deployed |
| 0127 | Drop tasks contact_id FK | ✅ Deployed |
| 0128 | AI decision records | ✅ Deployed |
---
## Tests
| Test-Datei | Typ | Status |
|-----------|------|--------|
| test_audit_connections.py | Integration (Import-Verifikation) | ✅ 11/11 grün |
| test_phase_f_agents.py | Mock-basiert | ✅ 45/45 grün |
| test_phase_g_workflows.py | Mock-basiert | ✅ 43/43 grün |
| test_phase_h_wiki.py | Mock-basiert | ✅ Tests vorhanden |
| test_spike_g_durable_workflow.py | Mock-basiert | ✅ 7/7 grün |
| test_spike_i_integration_flow.py | Mock-basiert | ✅ 8/8 grün |
| test_contacts.py | Integration (echte DB) | ✅ 8/8 grün |
---
## Blockierte Tasks
| Task | Grund | Lösung |
|------|-------|--------|
| Phase H Knowledge | knowledge_sources/extraction/lifecycle gelöscht | Neu aufbauend auf graph_rag + unified_search |
| Phase I Integration | Komplett gelöscht | Neu aufbauend auf kommunikation Plugin |
| Phase J Self-Improvement | ✅ Done | 24/24 Tests, self_improvement Plugin, Migration 0132, RLS, Frontend |
| F-WORK (agent_workstream) | Gelöscht | Neu aufbauend auf kommunikation Plugin |
| G-WORK (workflow workstream) | Gelöscht | Neu aufbauend auf kommunikation Plugin |
---
## Enterprise-Readiness Plan (2026-08-20)
**Status:** ✅ Alle 11 Punkte umgesetzt
| # | Bereich | Status | Details |
|---|---------|--------|--------|
| 1 | RLS für 10 Tabellen | ✅ Done | Migration 0129, Cross-Tenant-Tests bestätigen Isolation |
| 2 | Test-DB auf Alembic | ✅ Done | conftest.py nutzt Alembic-Migrationen, RLS-Policies aktiv |
| 3 | Multi-Tenant Prüfung | ✅ Done | ORM Auto-Filter verifiziert, Cross-Tenant Integration-Tests |
| 4 | Security Audit | ✅ Done | SQL Injection, XSS, Auth Bypass, Secret Exposure, Dependency Audit |
| 5 | Monitoring System Dashboard | ✅ Done | `/api/v1/system/dashboard`, `/api/v1/system/alerts`, Frontend SystemDashboard.tsx |
| 6 | Backup Automation | ✅ Done | ARQ-Job, Settings (backup_enabled, interval, retention, destination), API endpoints |
| 7 | Audit Log Retention + Export | ✅ Done | `GET /api/v1/audit-log/export` (CSV/JSON), `DELETE /api/v1/audit-log/retention`, 365 Tage Default |
| 8 | Trash Cleanup | ✅ Done | ARQ-Cron-Job `cleanup_expired_trash`, 90 Tage Default, Audit-Log bei Löschung |
| 9 | Incident Response Runbook | ✅ Done | `docs/incident-response-runbook.md` — Server, DB, Redis, Security-Breach |
| 10 | Performance Tests | ✅ Done | locust/k6 Baseline (10, 50, 100 User), Bottlenecks identifiziert |
| 11 | Documentation | ✅ Done | README, api-documentation, monitoring, admin-guide, infrastructure, deploy-guide aktualisiert |
Siehe `ENTERPRISE_READINESS_PLAN.md` für Details.
---
## Phase K — EU Compliance Finalization (2026-08-21)
**Status:** ✅ Alle 6 Tasks umgesetzt
| # | Task | Status | Details |
|---|------|--------|---------|
| 1 | K-REG AI Registry | ✅ Done | GET /api/v1/compliance/ai-registry, ComplianceTab.tsx in SettingsAI.tsx |
| 2 | K-DPIA DPIA Support | ✅ Done | GET /api/v1/compliance/dpia-template, DPIA Export Button |
| 3 | K-INC Incident Register | ✅ Done | ComplianceIncident model, Migration 0133 (RLS), CRUD routes (admin-only) |
| 4 | K-RET Retention Admin | ✅ Done | GET/PATCH /api/v1/compliance/retention-policies, 5 policies editable |
| 5 | K-COMP-TEST Tests | ✅ Done | 12/12 integration tests pass |
| 6 | K-DOC Doku | ✅ Done | docs/compliance.md — Betriebsdoku |
**Tests:** 12/12 passed | **tsc:** 0 errors | **Migration:** 0133 | **RLS:** 115 tables
---
*Diese Datei wird vom Agent bei jedem Task-Status-Wechsel aktualisiert. Sie ist die schnelle Übersicht über den Fortschritt. Detaillierte Diskussion und Bug-Tracking laufen über Forgejo Issues.*
---
## Offene Findings (einzige gueltige Tracking-Sektion, Stand 2026-08-27)
> Ab hier gilt: Nur Findings mit Live-Messung vom selben Tag. Scanner-/Plan-Aussagen ohne Beweiszaehler zaehlen nicht.
| Finding | Verifiziert am | Messwert | Ort |
|---|---|---|---|
| Cross-Plugin Import Core→Plugin (real) | 2026-08-27 | app/core/jobs.py:333 importiert `kommunikation.models.CommMessage` direkt statt via get_contract | scripts/check_cross_plugin_imports.py |
| God Objects >500 Z. (real, Refactoring-Programm) | 2026-08-27 | 59 Dateien; Top: mail/routes.py 1950, mail/imap_sync.py 1148, self_improvement/services.py 1058, calendar/routes.py 1026, plugins/registry.py 907 | wc -l |
| AppShell 4 Testfailures (bewusst auf Baseline) | 2026-08-27 | Mock-Fix-Versuch induziert Worker-Hang; Clean-Tree per Stash bewiesen identisch | src/__tests__/shell/AppShell.test.tsx |
Erledigt und archiviert: BUG-006/012/015-Teile/021/022/025035/039/069070/075078/080082/093100, ARCH-004/006/007/019/024/028/045 — Details in docs/archive/.