Skip to content

Latest commit

 

History

History
121 lines (106 loc) · 8.59 KB

ARCHITECTURE.md

File metadata and controls

121 lines (106 loc) · 8.59 KB

ARCHITECTURE

Zweck

CareCenter for Codex trennt den sicheren Wartungskern von UI und CLI. Dadurch kann die Logik getestet werden, ohne die Tray-App zu starten (der interne Python-Paketname codex_logdatenbank_wartung ist historisch und bleibt unveraendert).

Module

Modul Aufgabe
config.py lokale Konfiguration, Standardpfade (aus %LOCALAPPDATA%/%APPDATA%/~/.codex), Schwellwerte
i18n.py leichtgewichtige DE-/EN-Lokalisierung und persistierte Sprachauswahl
processes.py Codex-Prozessprüfung über PowerShell/CIM; Klassifikation (--type), exaktes Exe-Matching, Prozessbaum, tote-Parent-/Altersprüfung für allowlist-basierte MCP-/Language-Server-Waisen und fail-closed Erkennung wiederholter Runtime-MCP-Launcher
maintenance.py Backup + Retention, Integritätscheck, WAL-Checkpoint, PRAGMA optimize, VACUUM, Protokolle
health.py Startup-Diagnose (diagnose) und gezielte Reparatur (repair_start) — getrennt vom Wartungsblocker
orchestrator.py Autonome Wartung (auto_maintain): Aktivitätsmessung (CPU+DB des ganzen Baums), zwei Modi (safe/fast)
automation_control.py aktive Codex-Automatisierungen pausieren, CareCenter-eigene Pausen nachhalten und gezielt reaktivieren
watchdog.py Hintergrund-Wächter: reapt idle Ghosts und alte, CPU-inaktive MCP-/Language-Server-Waisen nur mit totem Parent; Live-Cohorts werden nicht gekillt, erfolgreiche Waisen-Kills landen mit Kind-/Parent-Identität und Kriterium im App-Log
start_repair.py Klassifikation der Start-Lage für die zusammengefasste „Codex reparieren"-Eskalation
repair_workflow.py Hang-sichere S1–S7-Eskalationsengine (rein, injizierbare Bausteine)
repair_live.py Echte Windows-/AppX-Implementierungen der Reparatur-Bausteine (P11 absent-Erkennung, Reinstall-Prävention)
store_repair.py Microsoft-Store-Reparatur (wsreset/register/reset) + Store-Produktseite öffnen
store_release.py Store-Materialien, öffentliche URLs, Pages-Artefakt und EXE-Pfad validieren
store_screenshot.py reproduzierbaren README-/Store-Screenshot aus dem echten Statusfenster rendern
scheduler.py Optionaler Windows-Task-Scheduler-Helfer für periodische Aufrufe von maintain --execute
thread_hygiene.py Altersbasierte Thread-Pflege: Ungelesen-State, transactionales Archivieren und Backups bei geschlossenem Codex
startup_receipt.py Read-only First-Turn-Herkunftsbeleg: getrennte Größen/Hashes für Base-, Developer-, Skill-, AGENTS-, Hook- und User-Quellen ohne Promptausgabe
mark_runs_read.py Codex-Ungelesen-State für Automations-/Thread-Ergebnisse gesichert als gelesen markieren
config_audit.py Audit plus getrennte off/notify/auto-Fixes für MCP-Konfigurationsduplikate, Plattform-Plugins und leere Threads; manueller Audit startet zusätzlich den Runtime-MCP-Reaper
safe_start_integration.py Safe-Start-Status, Installation, Start-Gate, Wiederherstellung und Aufschublogik anbinden
single_instance.py Windows-Mutex für die Tray-App
tray.py PySide6-Systemtray-App mit Statusfenster, QThread-Workern, Wächter, Reparatur, Wartung und Store-Aktionen
tray_app.py direkter EXE-/PyInstaller-Einstieg für die Systemtray-App
runtime/app_logging.py rotierendes Datei-Logging und Crash-Hooks für fensterlose pythonw-/EXE-Starts
cli.py maschinenlesbare Bedienung für LLMs und Shell
main.py kompatibler Moduleinstieg, der an die CLI weiterleitet

Zwei getrennte Pfade

  • Wartung (maintenance.py) ist bewusst „dumm & sicher": Sobald irgendein Codex-Prozess läuft, wird die DB-Wartung blockiert (keine VACUUM/Schreiboperation auf möglicherweise aktiver DB).
  • Startup-Reparatur (health.py) adressiert das Startproblem getrennt davon: Sie erkennt Zombie-Hauptprozesse (kein Renderer im Baum) und verwaiste Lockfiles und beendet/entfernt nur diese. Reihenfolge im Problemfall: repair-start → keine Codex-Prozesse mehr → maintain läuft unblockiert.
  • Auto-Trigger (scheduler.py) bleibt separat: Er ruft lediglich den bestehenden sicheren Wartungspfad periodisch auf, ohne den konservativen Blocker aufzuweichen.

Wartungsablauf

flowchart TD
    A["Start"] --> B["Konfiguration laden"]
    B --> C["Datenbank und Sidecars prüfen"]
    C --> D{"Codex läuft?"}
    D -- ja --> E["Blockieren und protokollieren"]
    D -- nein --> F{"Dry-Run?"}
    F -- ja --> G["Geplante Schritte ausgeben"]
    F -- nein --> H["Wartungs-Lock setzen"]
    H --> I["Backup DB/WAL/SHM"]
    I --> J["Integritätscheck auf Backup"]
    J --> K{"ok?"}
    K -- nein --> L["Abbruch"]
    K -- ja --> M["Optimize/Vacuum"]
    M --> N["Protokoll schreiben"]
Loading

Startup-Reparaturablauf

flowchart TD
    A["doctor/repair-start"] --> B["Codex-Prozesse über EXAKTEN Exe-Pfad finden"]
    B --> C["Prozessbaum bilden, Typen klassifizieren (--type)"]
    C --> D{"Hauptprozess ohne Renderer & alt genug?"}
    D -- ja --> E["Zombie -> Prozessbaum beenden (nur bei --execute + Flag)"]
    D -- nein --> F["Aktive Sitzung -> nicht anfassen"]
    C --> G{"Lockfile vorhanden & kein Hauptprozess?"}
    G -- ja --> H["verwaistes Lockfile entfernen (nur bei --execute + Flag)"]
Loading

Autonome Wartung (auto-maintain, zwei Modi)

flowchart TD
    A["auto-maintain (safe|fast)"] --> B["Aktivität messen: CPU des GANZEN Codex-Baums + DB-Ruhe"]
    B --> C{"Codex vorhanden?"}
    C -- nein --> M["Wartung ausführen"]
    C -- ja --> D{"Modus?"}
    D -- safe --> E{"aktiv? (CPU>Schwelle o. DB frisch)"}
    E -- ja --> W["warten + Tray informiert (eingereiht) → erneut messen"]
    W --> E
    E -- "User-Abbruch" --> CXL["abgebrochen: Codex nicht geschlossen, Wartung nicht gestartet"]
    E -- "Timeout" --> X["blockiert: Lauf NICHT abgebrochen, Wartung verschoben"]
    E -- nein --> F["Codex kontrolliert schließen (sanft, dann Rest beenden)"]
    D -- fast --> F
    F --> G{"wirklich beendet?"}
    G -- nein --> X
    G -- ja --> M
    M --> R{"haben WIR Codex geschlossen?"}
    R -- ja --> S["Codex neu starten"]
Loading

Empirie (2026-05-29): Aktive Automatisierung erzeugt 25–500 % CPU eines Kerns (auch in Worker-Kindern wie python run.py), Leerlauf-Rest <2 %. Das Schließen von Codex bricht laufende Läufe ab — deshalb handelt der Safe-Modus erst bei echtem Leerlauf und unterbricht nie einen Lauf. Der manuelle Safe-Abbruch beendet nur die Wartephase; er schließt Codex nicht und greift nicht in bereits laufende Datenbankoperationen ein.

Sicherheitsmodell

  • Codex-Prozesse blockieren die DB-Wartung (maintain).
  • Backups entstehen vor jeder echten SQLite-Operation; Backup-Anzahl ist begrenzt (backup_keep).
  • Die Integrität wird auf dem Backup geprüft, nicht nur behauptet.
  • Ohne explizite Archivkonfiguration werden keine Logdaten gelöscht.
  • Thread-Archivierung ist separat konfiguriert (auto_archive_threads_days=0 bedeutet aus), wartet beim Empty-Thread-Autofix mindestens 300 Sekunden und sichert state_5.sqlite vor Änderungen. Ein breiter Prozess-Snapshot blockiert bei Desktop oder npm-Codex-CLI und wird unmittelbar vor Backup sowie Move erneut erhoben.
  • Startup-Reparatur beendet ausschließlich Zombie-Hauptprozesse (kein Renderer); aktive Sitzungen nie.
  • Runtime-MCP-Erkennung gilt nur für direkte Launcher unter dem Store-Desktop-App-Server: der neueste Start-Cohort bleibt immer bestehen, mindestens zwei verschiedene Signaturen müssen exakt wiederholt sein, die Karenzzeit muss abgelaufen sein und der vollständige Kandidatenbaum darf im CPU-Sample nicht arbeiten. Für den mutierenden Reap muss zusätzlich der Parent tot sein; eine lebende Parent-Beziehung sperrt den Kill.
  • Runtime-Waisen müssen einen toten oder nach dem Kind neu belegten Parent haben, mindestens 30 Minuten alt sein und in zwei Messpunkten CPU-inaktiv bleiben. Bei codex exec blockieren zusätzlich ein Session-Rollout jünger als 120 Sekunden, ein noch fehlendes --output-last-message-Ziel oder das vollständige Fehlen dieser Output-Option den Kill. Der systemweite externe Task-Schutz pausiert außerdem die Runtime-MCP-Bereinigung bei codex-companion.mjs oder laufendem codex exec.
  • npm-/CLI-app-server, der Desktop-App-Server selbst, fremde Kindprozesse und Kandidaten mit unvollständigen Zeitdaten werden fail-closed ausgeschlossen.
  • Ghost-Targeting nutzt den exakten konfigurierten Exe-Pfad plus Prozessbaum. Runtime-Waisen nutzen allowlist-basierte Typ-Signaturen: Companion-app-server, gängige Language-Server, MCP-Nodes oder der exakte Prozessname codex.exe mit exec-Subcommand. Die letzte bekannte Parent-Identität wird nur protokolliert und niemals als Kill-Grundlage erfunden.