Arc OS — Architektur
Überblick
Arc OS ersetzt 11.321 Zeilen individuelle Python/JS-Infrastruktur durch native Claude Code-Werkzeuge. Der KI-Agent IST das Backend.
Systemarchitektur (Phase 52.1)
graph TB
User[👤 User Browser :18888]
TG[📱 Telegram]
Local[💻 Local IDE]
subgraph "Edge"
Nginx[Nginx :18888<br/>basic-auth + deny-list]
FE[React CRM + Phaser<br/>frontend container]
end
subgraph "Master Bot Bun :19210 — 127.0.0.1 only"
ApiSrv[api-server.ts<br/>196 LOC]
Routes[master-bot/routes/<br/>auth · internal · cli · websocket]
Router[shared/routes/router.ts<br/>373 LOC dispatcher]
subgraph "19 Domain Modules — Phase 48"
D1[auth · projects · workers]
D2[skills · sage · chat]
D3[wiki · files · onboarding]
D4[billing · invites · analytics]
D5[+ 7 more]
end
end
subgraph "Federated Bots"
Master[Master Bot<br/>orchestrator]
Child[Child Bots<br/>per-project]
Claude[claude -p CLI]
end
subgraph "Intelligence Layer"
Eval[Binary Evals]
Ctx[Context Router top-5]
Learn[Learnings inject]
Karp[Karpathy nightly loop]
end
NB[NotebookLM Bridge<br/>FastAPI :19213 localhost]
Google[(Google NotebookLM)]
DB[(SQLite WAL<br/>30+ tables<br/>migrations 001-035)]
Vault[(AES-256-GCM Vault<br/>config/vault.json)]
Bridge[Local Bridge CLI<br/>WebSocket relay]
User -->|HTTPS| Nginx
Nginx --> FE
Nginx -->|/api/crm/*| ApiSrv
Nginx -->|/api/sse/*| ApiSrv
Nginx -->|/ws/terminal| ApiSrv
ApiSrv --> Routes
Routes --> Router
Router --> D1 & D2 & D3 & D4 & D5
TG --> Master
TG --> Child
Master -.spawns via tmux.-> Child
Child --> Claude
Claude --> Eval & Ctx & Learn
Router -.queries.-> NB
Child -.auto-sync.-> NB
NB --> Google
Router --> DB
Router --> Vault
Child --> Vault
Local --> Bridge
Bridge -.ws relay.-> ApiSrv
Karp -.nightly.-> DB
Wichtige Fakten:
- 70+ REST-Endpunkte (Phase 52.1) auf 19 Domain-Module in
shared/routes/ - 127.0.0.1-Bind — Bun ist nie nach außen exponiert; nginx proxiert über den Loopback
- Multi-Tenancy-Gate —
canAccessProject(registry, chatId, project)auf jeder geschützten Route - Zero-Knowledge E2EE (Phase 45) — WebCrypto PBKDF2 + AES-256-GCM Master-Key in
sessionStorage
LEGACY (v1):
User → Telegram Bot (Python 111KB) → HybridEngine → command_queue.json
→ bridge_processor.sh → Claude → command_responses.json
→ FastAPI EventBus → WebSocket → Phaser UI
V2 (NATIVE-FIRST):
User → Official Telegram Channel → Claude Code Session
↓ ↓
reply/edit_message Agent Teams (TaskCreate/SendMessage)
↓
Write state → JSON files
↓
Arc OS Bridge MCP → HTTP/SSE → Phaser UI
Reduzierung: 11.321 Zeilen → ~3.700 Zeilen (67 % weniger Code)
Komponenten
1. Claude Code Session (Das Gehirn)
Die Claude Code Session ersetzt:
- FastAPI-Backend (15 Services)
- HybridEngine (39 KB)
- bridge_processor.sh (19,6 KB)
- response_watcher.py (14 KB)
- event_bus.py
- supply_chain.py (13 KB)
Die gesamte Orchestrierung läuft nativ über Agent Teams.
2. Arc OS Bridge MCP Server (State Adapter)
TypeScript MCP-Server (Bun), der den Claude Code-Zustand mit dem Frontend verbindet.
MCP-Tools (Claude Code-Seite):
| Tool | Richtung | Beschreibung |
|---|---|---|
get_office_state |
read | Liest state/office-state.json |
update_agent_state |
write | Aktualisiert Agent-Position, Status, Bubble |
get_tasks |
read | Liest Agent Teams Task-Dateien |
get_knowledge |
read | Liest Knowledge-Index |
HTTP-API (Frontend-Seite):
| Endpunkt | Methode | Beschreibung |
|---|---|---|
/api/state |
GET | Vollständiger Office-State |
/api/tasks |
GET | Task-Liste |
/api/knowledge |
GET | Knowledge-Index |
/api/events |
GET | SSE-Stream |
3. Phaser Frontend (Visuelle Ebene)
Phaser 3.80 + Vite. Verbindet sich mit dem MCP-Server via HTTP/SSE.
Wesentlicher Unterschied zu v1: kein WebSocket — ersetzt durch SSE vom MCP-Server. Keine Befehlseingabe-UI — Telegram ist die Befehlsschnittstelle.
4. Telegram Command Interface (Taktische UI-Ebene — Phase 21.0)
Telegram ist das primäre Steuerungspanel für das gesamte Arc OS. Zwei Bot-Ebenen:
Master Bot (@citadel_ceo_bot):
- Persistente Reply-Tastatur:
Мої Проєкти/Новий Проєкт/Watchdog/Web UI - Inline-Projektkarten pro Child: Restart, Delete, View MANIFEST, Active Skills
- CRM-URL-Buttons: Project, Tasks, Files, Einstellungen (Stub-Links zum Frontend)
- Callback-Query-Router für alle Inline-Aktionen
- Lösch-Bestätigungs-Flow: Inline-Tastatur → YES/CANCEL → Nachricht editieren
setMyCommands-Registrierung beim Start
Child Bots (@cv2_pt_bot etc.):
- Jede Claude-Antwort erhält Inline-Buttons am letzten Chunk:
STOP(SIGKILL) /PAUSE(SIGSTOP) /RESUME(SIGCONT) — Subprocess-SteuerungBTW— Stellt zusätzlichen Kontext für den nächsten Claude-Aufruf in die WarteschlangeFix It— Generiert automatisch einen Fix-Prompt aus der letzten Bot-Antwort
- Skills-Label-Button mit den geladenen Projekt-Kompetenzen
- Callback-Query-Router für alle Signal-/Kontext-Aktionen
CRM-Integration (Entwicklung):
CRM_BASE_URL = http://62.171.128.248:18888 (dev)
https://crm.citadel.v2 (future prod)
Alle Tastatur-Layouts sind in shared/ui_templates.ts definiert — Single Source für UI-Änderungen.
Callback-Daten-Protokoll: action:target (max. 64 Bytes)
- Master:
restart:pt,delete:pt,confirm_del:pt,cancel_del:pt,manifest:pt,skills:pt - Child:
stop,pause,resume,btw,fixit,skills_info
Datenfluss
1. User sendet "/status" via Telegram
2. Claude Code Session empfängt über Telegram Channel
3. Rick liest state/office-state.json + TaskList()
4. Rick antwortet via Telegram (edit_message für Live-Updates)
5. Rick ruft update_agent_state() via MCP auf
6. MCP-Server schreibt in state/office-state.json
7. File Watcher erkennt Änderung → sendet SSE-Event
8. Frontend empfängt SSE → aktualisiert Agent-Sprites
State-Verwaltung
Aller State lebt in JSON-Dateien unter state/:
| Datei | Schema | Aktualisiert von | Gelesen von |
|---|---|---|---|
office-state.json |
Agent-Positionen, Status, Bubbles | Claude (via MCP) | Frontend (via HTTP) |
knowledge.json |
Indexierte Datei-Metadaten | Squanchy-Agent | Frontend, Beth |
reports/*.json |
Analyseausgabe | Beth, Summer | Frontend |
Agent Teams Tasks werden von Claude Code nativ unter ~/.claude/tasks/citadel-v2/ verwaltet.
Agents (6)
| Agent | Rolle | Modell | Aktivierung |
|---|---|---|---|
| Rick | CEO/Orchestrator | opus-4.6 | Immer aktiv (Teamleiter) |
| Morty | SRE/Monitoring | haiku-4.5 | Health Checks, Cron |
| Summer | Memory/Review | sonnet-4.5 | Code-Review, Security |
| Jerry | Maintenance | haiku-4.5 | Aufräumen, Docs |
| Squanchy | Archivist | haiku-4.5 | Datei-Indexierung |
| Beth | Analyst | sonnet-4.5 | Recherche, Analyse |
Supply Chain
CEO → Rick (aufteilen) → Agent Team (ausführen)
→ Cross-Review (Summer validiert)
→ Rick (zusammenführen)
→ CEO (Endergebnis)
Durchgesetzt durch:
- Blueprints: Abteilungskonfigurationen mit Agent-Rollen
- Skills: Dynamisch geladene Expertise
- HANDOFF-Protokoll: Strukturierter Kontexttransfer zwischen Agents
Technologie-Stack
| Ebene | v1 | v2 |
|---|---|---|
| Backend | FastAPI + Python 3.12 | Claude Code Session |
| Datenbank | SQLite (8 Tabellen) | JSON-Dateien + Agent Teams |
| Messaging | WebSocket + EventBus | Agent Teams SendMessage |
| State | SQLite + JSON Bridge | JSON-Dateien (state/) |
| Frontend | Phaser 3.86 + WebSocket | Phaser 3.80 + SSE |
| Telegram | Custom Bot (111 KB) | Official Channel Plugin |
| Bridge | bash + jq (19,6 KB) | Entfernt |
| MCP | Keiner | Arc OS Bridge (TypeScript) |
| Deploy | Docker Compose | Docker Compose |
Lifecycle-Hooks
Claude Code-Hooks (~/.claude/settings.json) synchronisieren Agent-State automatisch:
SubagentStop event → subagent-stop.sh → office-state.json (agent=idle)
↓
StateManager (fs.watch) → SSE → Phaser UI
Stop event → session-end.sh → latest_wrapup.txt + all agents=idle
Skripte: scripts/citadel-hooks/subagent-stop.sh, scripts/citadel-hooks/session-end.sh
Wichtige Felder: subagentName (SubagentStop), stopReason (Stop), cwd (beide).
NotebookLM Bridge (Phase 36.3)
Echte semantische Suche via Google NotebookLM — ersetzt manuelle Datei-Uploads:
Cloud PM Chat → Bun Master Bot (:19210)
│
executeAskNotebooklm()
│
HTTP → FastAPI Bridge (:19213, localhost only)
│
notebooklm-py async client
│
Google NotebookLM (kostenlose semantische Suche)
Fallback: lokale Keyword-Suche (bestehender Code)
- Ein Notebook pro Projekt — Mapping in
notebook_mapping.json - Auto-Sync — Issue schließen/öffnen + Wiki-Update → Fire-and-forget POST an
/sync - SyncWorker —
asyncio.Queue(200), 2s Verzögerung, exponentieller Backoff (3 Versuche) - Query-Cache — LRU, TTL 5 min, max. 100 Einträge
- systemd —
citadel-notebooklm-bridge.service, Auto-Restart, nur localhost - Auth — Google-Cookies unter
/root/.notebooklm/storage_state.json
Dateibasierter Export als Fallback (/citadel-wrapup, /citadel-recall) bleibt weiterhin verfügbar.
Daten- und Task-Routing-Richtlinie
Drei-Ebenen-System. Jede Ebene hat einen strikten Zweck. Ebenen zu mischen = Chaos.
┌─────────────────────────────────────────────────────────────────┐
│ TIER 1: Working Memory (Hot) │
│ office-state.json + state/tasks/ │
│ CLI: /citadel-task, /citadel-status │
│ │
│ Tägliche Agent-Tasks. Lebt in der Sitzung. Stirbt danach. │
│ Abgeschlossener Task → /citadel-wrapup → Tier 3. │
├─────────────────────────────────────────────────────────────────┤
│ TIER 2: Strategic Backlog (Warm) │
│ GitHub Issues (Claude-CEO + citadel-v2 repos) │
│ │
│ Nur Epics: Phase 20, Phase 21, globale Bugs. │
│ Keine Tages-Tasks. Kein "Tippfehler korrigieren". │
│ Ein Issue = eine mehrwöchige Initiative oder ein kritischer Defekt. │
├─────────────────────────────────────────────────────────────────┤
│ TIER 3: Long-term Memory (Cold) │
│ docs/library-export/ → Google Drive → NotebookLM │
│ CLI: /citadel-wrapup, /citadel-recall │
│ │
│ Enzyklopädie. Sitzungsergebnisse, Architekturentscheidungen, RAG. │
│ Nur-lese-Archiv. Keine aktiven Tasks. Kein Status-Tracking. │
└─────────────────────────────────────────────────────────────────┘
Routing-Regeln
| Datentyp | Tier | Beispiel |
|---|---|---|
| "Deploy-Skript reparieren" | 1 — Working Memory | /citadel-task "Fix deploy script" |
| "Phase 20: Multi-Tenant SaaS" | 2 — GitHub Issues | gh issue create --title "Phase 20: ..." |
| "Sitzungszusammenfassung: Hooks implementiert" | 3 — Library | /citadel-wrapup → NotebookLM |
| "Architekturentscheidung: SSE statt WS gewählt" | 3 — Library | Nach der Sitzung im Wrapup archiviert |
| "Bug: SSE bricht auf VPS ab" | 2 — GitHub Issues | Nur wenn sitzungsübergreifend / blockierend |
| "Rick arbeitet an Hooks" | 1 — Working Memory | office-state.json Agent-Status |
Lebenszyklus
CEO gibt Task → Tier 1 (Agent arbeitet daran)
↓ abgeschlossen
/citadel-wrapup → Tier 3 (archiviert)
↓ wenn strategisch
gh issue create → Tier 2 (langfristig verfolgt)
Anti-Patterns (NICHT TUN)
- KEINE GitHub Issues für tägliche Tasks erstellen ("Tippfehler korrigieren", "Config updaten")
- KEINEN aktiven Task-Status in library-export/-Dateien speichern
- office-state.json NICHT für langfristige Entscheidungen oder Architekturnotizen verwenden
- NICHT duplizieren: ein Task lebt genau in einem Tier gleichzeitig
Infrastruktur (Phase 20.5)
Strukturiertes Logging (shared/logger.ts)
JSONL-Format, doppelte Ausgabe (Datei + Konsole), tägliche Dateiaufteilung nach Kategorie.
/var/log/citadel/
├── master/
│ ├── system-2026-04-02.log ← Lifecycle, Config, Health
│ ├── dialog-2026-04-02.log ← (von Master nicht genutzt)
│ └── error-2026-04-02.log ← Fehler (auch in system)
├── citadel-v2/
│ ├── system-2026-04-02.log
│ ├── dialog-2026-04-02.log ← User ↔ Claude Nachrichten
│ └── error-2026-04-02.log
└── <project-name>/ ← pro ongeboardetem Projekt
Log-Rotation: config/logrotate-citadel.conf → /etc/logrotate.d/citadel (täglich, 7-Tage-Aufbewahrung).
Secrets Vault (shared/vault.ts)
AES-256-GCM-verschlüsselter Speicher für Bot-Token.
Key-Quelle: SECRET_ENCRYPTION_KEY env → config/vault-key Datei → auto-generiert
Speicher: config/vault.json (atomare Schreibvorgänge: tmp + mv)
Cache: Im Arbeitsspeicher nach initVault() — kein Disk-I/O pro getSecret()
Fallback: getSecret("FOO") → vault cache → process.env.FOO
Namensgebung: child:<project-name>:token
Der eigene Token des Masters bleibt in .env (Vault lädt innerhalb des Master-Prozesses).
Self-Healing Watchdog (master-bot/watchdog.ts)
Hintergrundmonitor für Child Bots. Läuft im Master-Bot-Prozess.
Alle 30s: HTTP-Health-Check → /api/child/health (5s Timeout)
Gesund → Fehler zurücksetzen
Ungesund → Fehler hochzählen
3+ Fehler + Backoff abgelaufen → Auto-Restart (tmux beenden → neu starten mit Vault-Token)
Backoff: 30s → 1 min → 5 min → 15 min → 60 min (Cap)
10 aufeinanderfolgende Fehler → dauerhaft deaktivieren + CEO benachrichtigen
State wird in config/watchdog-state.json persistiert (überlebt Master-Restart).
CEO-Benachrichtigungen via Telegram: erster Restart, Restart-Fehler, dauerhafte Deaktivierung.
/watchdog-Befehl: Echtzeit-Status aller Children.
Projekt-Entfernungs-Protokoll (Phase 20.4 + 21.0)
/remove_project <name> → dreifache Bestätigung → vollständige Bereinigung:
1. tmux-Sitzung beenden: child-<name>
2. Ghost-Prozesse beenden: ps aux | grep child-<name> → kill -9 alle PIDs
3. Port-Prüfung: ss -tlnp | grep :<port> → erzwingen freigeben, falls belegt
4. Aus bot_registry.json entfernen + In-Memory-Reload
5. /opt/repos/<name>/ löschen (Sicherheit: Pfad muss unter /opt/repos/, min. 3 Segmente)
6. /var/log/citadel/<name>/ löschen
Geschützte Namen: citadel-v2, citadel, claude-ceo, claude-CEO — Entfernung blockiert.
Ghost-Prozess-Problem (gelernte Lektion): Nach tmux kill können verwaiste bun-Prozesse Ports belegen. Massen-Kill + Port-Prüfung verhindert "Phantom-Bots", die auf Health Checks reagieren, aber Telegram ignorieren.
Skill-Verwaltung (Phase 21.0)
Child Bots laden Skills beim Start aus zwei Quellen, dedupliziert via Set:
Quelle 1: MANIFEST.md (JSON)
→ manifest.skills[] (beim Onboarding abgeglichen)
→ manifest.library_skills[] (Library .md-Dateien abgeglichen)
Quelle 2: skills/-Verzeichnis
→ *.md Dateien → Dateiname ohne Erweiterung
Zusammenführung: Set<string>(manifest.skills + manifest.library_skills + skills/*.md)
Beispiel (PT-Projekt): 5 aus Manifest + 7 aus skills/ = 12 eindeutige Skills.
Skills erscheinen als:
- Inline-Button-Label bei Child-Antworten:
🏷️ odoo-expert, docker-ops, ... skills_infoCallback: Toast mit vollständiger Liste/skills-Befehl im Master: listet Skills-Verzeichnisinhalt auf
Sicherheit (Phase 42 — Sentinel-Audit 2026-04-23, 4 Durchläufe, 13 Patches)
Vollständiger Überblick: SECURITY.md. Audit-Bericht: security/audit-2026-04-23.md.
Secrets & Speicherung:
- Keine Zugangsdaten im Repo; State-Dateien enthalten keine Secrets
- Bot-Token im verschlüsselten Vault (
config/vault.json, AES-256-GCM).getSecret()fällt aufprocess.envzurück - Verschlüsselungsschlüssel auto-generiert in
config/vault-key(chmod 600).vault.json,vault-key,watchdog-state.json,data/citadel.db*im gitignore
Auth:
- JWT HMAC-SHA256, 24h TTL,
crypto.timingSafeEqualSignatur-Vergleich - OAuth Google + GitHub mit CSRF-State (10 min, einmalig)
- E-Mail/Passwort mit erforderlicher Verifizierung vor dem Login (24h TTL), Passwort-Reset (30 min TTL), zugestellt via Resend
- Token-Extraktion —
extractChatId()liest Bearer-Header ODER?token=-Query (für Browser-EventSource), entspricht exaktcrmAuthMiddleware
Multi-Tenancy (Phase 42):
canAccessProject(registry, chatId, project)Gate auf jeder geschützten Route- CEO (
ceo_chat_id) und DBuser.role === 'admin'sehen alles; andere sind durchowner_id-Abgleich (DB SSOT) eingeschränkt - SSE-Routen, WebSocket-Terminal,
/api/cli/*,/api/mcp/*,/api/crm/projects/:name/*alle gesichert /ws/terminal/:name?mode=interactiveerfordert CEO oder Admin
Netzwerkperimeter:
- Bun bindet nur
127.0.0.1:19210— nginx proxiert über Loopback /api/internal/*lehnt alle Anfragen mit Proxy-Headern ab (X-Forwarded-For,X-Real-IP,Forwarded) als nginx-Fehlkonfigurations-Canary- SSRF-Allowlist bei
handleScoutAnalyze— HTTPS + exakter Hostname-Abgleich +redirect:"manual"(blockiert Redirect-Chain-Bypass) - UFW blockiert
:19210,:19213,:19200extern
Eingabe-/Pfadsicherheit:
isValidProjectName()Regex an jedem Einstiegspunkt (inkl. interne Endpunkte)safePath()auf allen nutzergesteuerten Dateipfaden —handleSaveSkillgefunden + gepatcht Phase 42.6- Nginx-Deny-List:
/.*,/(state|scripts|config|data|knowledge-base|issues|skills|blueprints|mcp-server)/ - CORS-Whitelist (
CRM_ALLOWED_ORIGINS), Header auch bei Fehlern - Atomare Schreibvorgänge für Registry-Mutationen (
tmp.${pid}+mv) - Vault-Token-Entschlüsselung für Child-Start:
bun -emit node:crypto verwenden (NICHT Python)
Regressions-Coverage: scripts/vps-sync.sh führt nach jedem Deploy 7+ Post-Deploy-Smoke-Tests durch (Loopback-Bind, Path-Traversal, chat/save-Validierung, Proxy-Canary, SSE ?token=, Fail-Closed-Validierung, SSRF-Block wenn CEO_TOKEN gesetzt).
Master-Bot-Module (Phase 25 — DEBT-1-Auflösung)
Der Master Bot ist in fokussierte Module aufgeteilt:
master-bot/
├── bot.ts ← Bootstrap: Vault, Registry, Kontext, alles verdrahten (106 Zeilen)
├── context.ts ← MasterContext-Typ + Domain-Interfaces
├── api-server.ts ← Bun.serve() — HTTP, WebSocket, SSE, CRM-Routen
├── tg-api.ts ← Telegram Bot API-Wrapper (sendMessage, getUpdates usw.)
├── child-state.ts ← Child-Bot-State, Health, Heartbeat, tmux, Bridge lesen
├── telegram-commands.ts ← Alle /command-Handler, Callback-Query-Handler, Nachrichten-Router
├── telegram.ts ← Schlanke Polling-Schleife + Re-Exporte für Rückwärtskompatibilität
├── watchdog.ts ← Self-Healing Child-Bot-Monitor
└── onboarding.ts ← Interaktiver Projekt-Erstellungs-Wizard
bot.ts importiert nur aus telegram.ts und api-server.ts. Alle anderen Module sind interne Implementierungsdetails.
Bridge CLI (Phase 25 — Local Gateway)
bridge/
├── bin/citadel-bridge.ts ← CLI-Einstieg (commander.js): connect, pull, push, status, disconnect
├── src/
│ ├── auth.ts ← JWT-Validierung gegen CRM
│ ├── config.ts ← ~/.citadel/bridge.json Persistenz
│ ├── inject.ts ← CLAUDE.md <!-- CITADEL:START/END --> Marker
│ ├── sync.ts ← Skills-Bundle + Learnings pullen, lokale Learnings pushen
│ └── heartbeat.ts ← Sitzungs-Aktivitäts-Reporter
├── package.json
└── tsconfig.json
CRM API-Endpunkte (50+ gesamt)
Core CRM (Phase 22)
| Endpunkt | Methode | Zweck |
|---|---|---|
/api/master/health |
GET | Master-Bot-Health (öffentlich) |
/api/crm/projects |
GET | Alle Projekte + Live-Health auflisten |
/api/crm/projects/:name |
GET | Projektdetails |
/api/crm/projects/:name/logs |
GET | JSONL-Logs tailing |
/api/crm/projects/:name/files |
GET | Sicheres Verzeichnis-Listing |
/api/crm/projects/:name/files/upload |
POST | Dateien hochladen |
/api/crm/projects/:name/files/mkdir |
POST | Ordner erstellen |
/api/crm/projects/:name/files/create |
POST | Datei erstellen |
/api/crm/projects/:name/files/delete |
DELETE | Datei/Ordner löschen |
/api/crm/projects/:name/files/clone |
POST | Git-Repo klonen |
/api/crm/projects/:name/files/read |
GET | Dateiinhalt lesen |
/api/crm/projects/:name/wiki/tree |
GET | Wiki .md-Dateien auflisten |
/api/crm/projects/:name/wiki/file |
GET | Wiki-Dateiinhalt lesen |
/api/crm/projects/:name/skills |
GET | Installierte Skills |
/api/crm/projects/:name/metrics |
GET | Qualitäts-Zeitreihen |
/api/crm/projects/:name/restart |
POST | Child Bot neustarten |
/api/crm/projects/:name/specs |
GET | Specs auflisten |
/api/crm/projects/:name/specs/:id/approve |
POST | Spec genehmigen |
/api/crm/projects/:name/specs/:id/reject |
POST | Spec ablehnen |
/api/crm/projects/:name/active-role |
GET/POST | Agent-Rolle |
/api/crm/projects/:name/message |
POST | Nachricht an Worker in Warteschlange stellen |
/api/crm/projects/:name/workers |
GET/POST | Worker-Registry CRUD |
/api/crm/projects/:name/workers/:id |
PUT/DELETE | Worker aktualisieren/löschen |
/api/crm/projects/:name/workers/generate-prompt |
POST | System-Prompt per KI generieren |
/api/crm/projects/:name/skills-bundle |
GET | Skills + Evals für Bridge |
/api/crm/projects/:name/learnings |
GET/POST | Learnings-Sync |
/api/sse/logs/:name |
GET | SSE-Log-Stream (?category=) |
Dashboard & Wiki (Phase 32)
| Endpunkt | Methode | Zweck |
|---|---|---|
/api/crm/projects/:name/wiki/save |
PUT | Wiki-Seite speichern/erstellen |
/api/crm/projects/:name/skills/save |
PUT | Skill-Datei speichern |
/api/crm/projects/:name/skills/delete |
DELETE | Skill-Datei löschen |
Multi-Tenant (Phase 33)
| Endpunkt | Methode | Zweck |
|---|---|---|
/api/crm/account/settings |
GET/PUT | Account-weite API-Keys |
/api/crm/projects/create |
POST | Schlanke Projekterstellung |
/api/crm/onboarding/setup |
POST | Vollständiger Onboarding-Wizard |
MCP & CLI (Phase 34)
| Endpunkt | Methode | Zweck |
|---|---|---|
/api/mcp/issues/:project |
POST/GET | Issue-CRUD |
/api/mcp/issues/:project/:id |
PUT | Issue aktualisieren |
/api/mcp/wiki/:project |
PUT | Wiki-Sync via MCP |
/api/mcp/roadmap/:project |
GET/PUT | Roadmap lesen/synchronisieren |
/api/cli/init/:project/:mode |
GET | Cloud-Kontext für CLI |
/api/mcp/skills/:project/:skill |
GET | Skill für MCP abrufen |
/api/mcp/report/:project |
POST | Missions-Report |
/api/mcp/learnings/:project |
GET | Learnings für MCP abrufen |
Live Terminal (Phase 35)
| Endpunkt | Methode | Zweck |
|---|---|---|
/api/crm/projects/:name/terminal/log |
POST | Terminal-JSONL von ARC CLI empfangen |
Cloud PM & Knowledge (Phase 36)
| Endpunkt | Methode | Zweck |
|---|---|---|
/api/crm/projects/:name/chat |
POST | SSE-Chat-Proxy zur Anthropic API |
/api/crm/projects/:name/skills/generate |
POST | Neural Skill Generator (NotebookLM) |
/api/crm/projects/:name/notebooks |
GET | Verknüpfte NotebookLM-Notebooks |
Auth & OAuth (Phase 37)
| Endpunkt | Methode | Zweck |
|---|---|---|
/api/auth/register |
POST | E-Mail/Passwort-Registrierung |
/api/auth/login |
POST | E-Mail/Passwort-Login |
/api/auth/google |
GET | OAuth Google-Redirect |
/api/auth/callback/google |
GET | OAuth Google-Callback |
/api/auth/github |
GET | OAuth GitHub-Redirect |
/api/auth/callback/github |
GET | OAuth GitHub-Callback |
/api/auth/providers |
GET | Verfügbare OAuth-Provider |
Angeheftete Notizen (Phase 41.8)
| Endpunkt | Methode | Zweck |
|---|---|---|
/api/crm/projects/:name/pins |
GET | Angeheftete Notizen auflisten (neueste zuerst) |
/api/crm/projects/:name/pins |
POST | Worker-Nachricht an Context Rail anheften (Body: worker_id, body, optional title, author) |
/api/crm/projects/:name/pins/:id |
DELETE | Pin entfernen |
Backend: Migration 009 (pinned_notes-Tabelle), pinnedNoteQueries in shared/db.ts. Frontend: ContextRail.jsx lädt beim Mount, hört auf crm-pin-created CustomEvent, optimistisches DELETE.
Datenschutz-Ebene (Phase 45)
Hybride At-Rest-Verschlüsselung — clientseitige Krypto-Grundlage + serverseitige Vault-Verschlüsselung.
Clientseitig (Browser)
frontend/src/crm/crypto/e2ee.ts— WebCrypto-Wrapper (214 Zeilen)- PBKDF2 (100.000 Iterationen, SHA-256) → AES-256-GCM Master-Key
- Key-Lebenszyklus:
initMasterKey(password)beim Login →sessionStorage→clearMasterKey()bei Logout/401 - Recovery:
generateRecoveryKey()→ 1Password-Format (XXXX-XXXX-XXXX-XXXX-XXXX)
Serverseitig (Bun + SQLite)
shared/vault.ts—encryptField()/decryptField()mit AES-256-GCM Vault-Key (v1:-Präfix-Format)- API-Keys: beim Speichern verschlüsseln, beim Laden entschlüsseln (für Frontend transparent) —
routes/system.ts - Chat-Nachrichten: Auto-Verschlüsselung INSERT, Auto-Entschlüsselung SELECT —
db.ts+ Migration 015 - Recovery-Keys:
recovery_keys-Tabelle (Migration 016), 4 API-Endpunkte
Sicherheits-Header
- CSP:
default-src 'self'; script-src 'self'auf allen CRM-Antworten X-Frame-Options: DENY,X-Content-Type-Options: nosniff,Referrer-Policy: strict-origin-when-cross-origin
PII-Bereinigung
shared/pii-sanitizer.ts— bereinigt E-Mails, API-Keys (sk-ant-*,sk-*), JWTs, Kartennummern- Angewendet auf Terminal-JSONL-Log-Ingest (
routes/chat.ts)
Recovery-Key-Endpunkte
| Endpunkt | Methode | Zweck |
|---|---|---|
/api/crm/account/recovery |
POST | Recovery-Key erstellen (verschlüsselten Master-Key speichern) |
/api/crm/account/recovery |
GET | Aktive Recovery-Keys auflisten |
/api/crm/account/recovery |
DELETE | Recovery-Key(s) widerrufen |
/api/crm/account/recovery/restore |
GET | Verschlüsselten Master-Key für Recovery abrufen |
Vollständige Sicherheitsdetails: docs/SECURITY.md, docs/architecture/PHASE_45_E2EE.md.