Arc OS — Архитектура
Обзор
Arc OS заменяет 11 321 строку кастомной Python/JS-инфраструктуры нативными инструментами Claude Code. AI-агент и есть бэкенд.
Системная архитектура (Phase 52.1)
graph TB
User[👤 Браузер пользователя :18888]
TG[📱 Telegram]
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"
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 доменных модулей — Phase 48"
D1[auth · projects · workers]
D2[skills · sage · chat]
D3[wiki · files · onboarding]
D4[billing · invites · analytics]
D5[+ 7 других]
end
end
subgraph "Федеративные боты"
Master[Master Bot<br/>оркестратор]
Child[Child Bots<br/>на каждый проект]
Claude[claude -p CLI]
end
subgraph "Слой интеллекта"
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/>21+ таблиц<br/>migrations 001-021)]
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
Ключевые факты:
- 70+ REST-эндпоинтов (Phase 52.1) в 19 доменных модулях внутри
shared/routes/ - Привязка к 127.0.0.1 — Bun не слушает внешние интерфейсы; nginx проксирует через loopback
- Мультитенантный гейт —
canAccessProject(registry, chatId, project)на каждом защищённом маршруте - Zero-Knowledge E2EE (Phase 45) — WebCrypto PBKDF2 + AES-256-GCM master key в
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
Сокращение кода: 11 321 строка → ~3 700 строк (67% меньше)
Компоненты
1. Claude Code Session (Мозг)
Claude Code session заменяет:
- FastAPI-бэкенд (15 сервисов)
- HybridEngine (39KB)
- bridge_processor.sh (19.6KB)
- response_watcher.py (14KB)
- event_bus.py
- supply_chain.py (13KB)
Вся оркестрация происходит нативно через Agent Teams.
2. Arc OS Bridge MCP Server (State Adapter)
TypeScript MCP-сервер (Bun), который связывает состояние Claude Code с фронтендом.
MCP Tools (со стороны Claude Code):
| Инструмент | Направление | Описание |
|---|---|---|
get_office_state |
read | Читает state/office-state.json |
update_agent_state |
write | Обновляет позицию, статус и bubble агента |
get_tasks |
read | Читает файлы задач Agent Teams |
get_knowledge |
read | Читает индекс знаний |
HTTP API (со стороны фронтенда):
| Эндпоинт | Метод | Описание |
|---|---|---|
/api/state |
GET | Полное состояние офиса |
/api/tasks |
GET | Список задач |
/api/knowledge |
GET | Индекс знаний |
/api/events |
GET | SSE-стрим |
3. Phaser Frontend (Визуальный слой)
Phaser 3.80 + Vite. Подключается к MCP-серверу через HTTP/SSE.
Ключевое отличие от v1: нет WebSocket — заменён SSE от MCP-сервера. Нет UI для ввода команд — Telegram является командным интерфейсом.
4. Telegram Command Interface (Тактический слой UI — Phase 21.0)
Telegram — основная панель управления всем Arc OS. Два уровня ботов:
Master Bot (@citadel_ceo_bot):
- Постоянная reply-клавиатура:
Мои Проекты/Новый Проект/Watchdog/Web UI - Inline-карточки проектов: Restart, Delete, View MANIFEST, Active Skills
- Кнопки CRM URL: Project, Tasks, Files, Settings (заглушки-ссылки на фронтенд)
- Роутер callback-запросов для всех inline-действий
- Флоу подтверждения удаления: inline-клавиатура → ДА/ОТМЕНА → edit message
- Регистрация
setMyCommandsпри запуске
Child Bots (@cv2_pt_bot и т.д.):
- Каждый ответ Claude получает inline-кнопки на последнем чанке:
STOP(SIGKILL) /PAUSE(SIGSTOP) /RESUME(SIGCONT) — управление subprocessBTW— ставит дополнительный контекст в очередь для следующего вызова ClaudeFix It— автогенерирует prompt исправления по последнему ответу бота
- Кнопка с лейблом скиллов, показывающая загруженные компетенции проекта
- Роутер callback-запросов для всех signal/context-действий
Интеграция с CRM (разработка):
CRM_BASE_URL = http://62.171.128.248:18888 (dev)
https://crm.citadel.v2 (будущий prod)
Все раскладки клавиатур определены в shared/ui_templates.ts — единый источник изменений UI.
Протокол callback data: action:target (макс. 64 байта)
- Master:
restart:pt,delete:pt,confirm_del:pt,cancel_del:pt,manifest:pt,skills:pt - Child:
stop,pause,resume,btw,fixit,skills_info
Поток данных
1. Пользователь отправляет "/status" через Telegram
2. Claude Code session получает через Telegram Channel
3. Rick читает state/office-state.json + TaskList()
4. Rick отвечает через Telegram (edit_message для обновлений в реальном времени)
5. Rick вызывает update_agent_state() через MCP
6. MCP-сервер пишет в state/office-state.json
7. Файловый вотчер обнаруживает изменение → пушит SSE-событие
8. Фронтенд получает SSE → обновляет спрайты агентов
Управление состоянием
Всё состояние хранится в JSON-файлах в state/:
| Файл | Схема | Обновляется | Читается |
|---|---|---|---|
office-state.json |
Позиции агентов, статус, bubble | Claude (через MCP) | Фронтенд (через HTTP) |
knowledge.json |
Индексированные метаданные файлов | Агент Squanchy | Фронтенд, Beth |
reports/*.json |
Результаты анализа | Beth, Summer | Фронтенд |
Задачи Agent Teams управляются Claude Code нативно в ~/.claude/tasks/citadel-v2/.
Агенты (6)
| Агент | Роль | Модель | Активация |
|---|---|---|---|
| Rick | CEO/Оркестратор | opus-4.6 | Всегда активен (тимлид) |
| Morty | SRE/Мониторинг | haiku-4.5 | Health checks, cron |
| Summer | Память/Ревью | sonnet-4.5 | Code review, безопасность |
| Jerry | Обслуживание | haiku-4.5 | Очистка, доки |
| Squanchy | Архивариус | haiku-4.5 | Индексация файлов |
| Beth | Аналитик | sonnet-4.5 | Исследования, анализ |
Supply Chain
CEO → Rick (декомпозиция) → Agent Team (выполнение)
→ Cross-Review (Summer валидирует)
→ Rick (синтез)
→ CEO (финальный результат)
Обеспечивается через:
- Blueprints: конфиги отделов с ролями агентов
- Skills: динамически загружаемые экспертизы
- HANDOFF Protocol: структурированная передача контекста между агентами
Технологический стек
| Слой | v1 | v2 |
|---|---|---|
| Бэкенд | FastAPI + Python 3.12 | Claude Code session |
| База данных | SQLite (8 таблиц) | JSON-файлы + Agent Teams |
| Сообщения | WebSocket + EventBus | Agent Teams SendMessage |
| Состояние | SQLite + JSON bridge | JSON-файлы (state/) |
| Фронтенд | Phaser 3.86 + WebSocket | Phaser 3.80 + SSE |
| Telegram | Кастомный бот (111KB) | Official Channel plugin |
| Bridge | bash + jq (19.6KB) | Устранён |
| MCP | Нет | Arc OS Bridge (TypeScript) |
| Деплой | Docker Compose | Docker Compose |
Lifecycle Hooks
Claude Code hooks (~/.claude/settings.json) автосинхронизируют состояние агентов:
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
Скрипты: scripts/citadel-hooks/subagent-stop.sh, scripts/citadel-hooks/session-end.sh
Ключевые поля: subagentName (SubagentStop), stopReason (Stop), cwd (оба).
NotebookLM Bridge (Phase 36.3)
Настоящий семантический поиск через Google NotebookLM, заменивший ручную загрузку файлов:
Cloud PM Chat → Bun Master Bot (:19210)
│
executeAskNotebooklm()
│
HTTP → FastAPI Bridge (:19213, только localhost)
│
notebooklm-py async client
│
Google NotebookLM (бесплатный семантический поиск)
Fallback: локальный поиск по ключевым словам (существующий код)
- Один ноутбук на проект — маппинг хранится в
notebook_mapping.json - Автосинхронизация — закрытие/открытие задачи + обновление вики → fire-and-forget POST на
/sync - SyncWorker —
asyncio.Queue(200), задержка 2с, экспоненциальный бэкофф (3 попытки) - Query cache — LRU, TTL 5 мин, макс. 100 записей
- systemd —
citadel-notebooklm-bridge.service, автоперезапуск, только localhost - Auth — куки Google в
/root/.notebooklm/storage_state.json
Экспорт на основе файлов (legacy: /citadel-wrapup, /citadel-recall) по-прежнему доступен как fallback.
Политика маршрутизации данных и задач
Трёхуровневая система. У каждого уровня строгое назначение. Смешивать уровни — значит создавать хаос.
┌─────────────────────────────────────────────────────────────────┐
│ УРОВЕНЬ 1: Рабочая память (горячий) │
│ office-state.json + state/tasks/ │
│ CLI: /citadel-task, /citadel-status │
│ │
│ Ежедневные задачи агентов. Живёт во время сессии. Исчезает. │
│ Завершённая задача → /citadel-wrapup → Уровень 3. │
├─────────────────────────────────────────────────────────────────┤
│ УРОВЕНЬ 2: Стратегический бэклог (тёплый) │
│ GitHub Issues (репозитории Claude-CEO + citadel-v2) │
│ │
│ Только эпики: Phase 20, Phase 21, глобальные баги. │
│ Никаких ежедневных задач. Никаких "fix typo" задач. │
│ Один Issue = одна многонедельная инициатива или критический дефект. │
├─────────────────────────────────────────────────────────────────┤
│ УРОВЕНЬ 3: Долгосрочная память (холодный) │
│ docs/library-export/ → Google Drive → NotebookLM │
│ CLI: /citadel-wrapup, /citadel-recall │
│ │
│ Энциклопедия. Результаты сессий, архитектурные решения, RAG. │
│ Архив только для чтения. Без активных задач. Без трекинга. │
└─────────────────────────────────────────────────────────────────┘
Правила маршрутизации
| Тип данных | Уровень | Пример |
|---|---|---|
| "Исправить скрипт деплоя" | 1 — Рабочая память | /citadel-task "Fix deploy script" |
| "Phase 20: Multi-Tenant SaaS" | 2 — GitHub Issues | gh issue create --title "Phase 20: ..." |
| "Итог сессии: хуки внедрены" | 3 — Библиотека | /citadel-wrapup → NotebookLM |
| "Архитектурное решение: выбрали SSE вместо WS" | 3 — Библиотека | Архивируется в wrapup после сессии |
| "Баг: SSE обрывается на VPS" | 2 — GitHub Issues | Только если межсессионный / блокирующий |
| "Rick работает над хуками" | 1 — Рабочая память | office-state.json статус агента |
Жизненный цикл
CEO ставит задачу → Уровень 1 (агент работает над ней)
↓ выполнено
/citadel-wrapup → Уровень 3 (архивируется)
↓ если стратегическое
gh issue create → Уровень 2 (отслеживается долгосрочно)
Антипаттерны (НЕ ДЕЛАТЬ)
- НЕ создавай GitHub Issues для ежедневных задач ("fix typo", "update config")
- НЕ храни статус активной задачи в файлах library-export/
- НЕ используй office-state.json для долгосрочных решений или архитектурных заметок
- НЕ дублируй: одна задача живёт ровно на одном уровне в один момент времени
Инфраструктура (Phase 20.5)
Структурированное логирование (shared/logger.ts)
Формат JSONL, двойной вывод (файл + консоль), ежедневное разбиение файлов по категориям.
/var/log/citadel/
├── master/
│ ├── system-2026-04-02.log ← lifecycle, конфиг, health
│ ├── dialog-2026-04-02.log ← (master не использует)
│ └── error-2026-04-02.log ← ошибки (также в system)
├── citadel-v2/
│ ├── system-2026-04-02.log
│ ├── dialog-2026-04-02.log ← сообщения user ↔ Claude
│ └── error-2026-04-02.log
└── <project-name>/ ← на каждый онбордированный проект
Ротация логов: config/logrotate-citadel.conf → /etc/logrotate.d/citadel (ежедневно, хранение 7 дней).
Secrets Vault (shared/vault.ts)
Зашифрованное AES-256-GCM хранилище для токенов ботов.
Источник ключа: SECRET_ENCRYPTION_KEY env → файл config/vault-key → автогенерация
Хранение: config/vault.json (атомарные записи: tmp + mv)
Кэш: В памяти после initVault() — нет I/O диска при getSecret()
Fallback: getSecret("FOO") → vault cache → process.env.FOO
Именование: child:<project-name>:token
Собственный токен Master-бота остаётся в .env (vault загружается внутри процесса master).
Self-Healing Watchdog (master-bot/watchdog.ts)
Фоновый монитор для дочерних ботов. Запускается внутри процесса master-бота.
Каждые 30с: HTTP health check → /api/child/health (таймаут 5с)
Здоров → сбрасывает счётчик ошибок
Нездоров → увеличивает счётчик ошибок
3+ ошибки + бэкофф истёк → автоперезапуск (kill tmux → новый старт с vault-токеном)
Бэкофф: 30с → 1м → 5м → 15м → 60м (предел)
10 последовательных ошибок → постоянное отключение + уведомление CEO
Состояние сохраняется в config/watchdog-state.json (переживает перезапуск master).
Уведомления CEO через Telegram: первый перезапуск, ошибка перезапуска, постоянное отключение.
Команда /watchdog: статус всех дочерних ботов в реальном времени.
Протокол удаления проекта (Phase 20.4 + 21.0)
/remove_project <name> → тройное подтверждение → полная очистка:
1. Убить tmux-сессию: child-<name>
2. Массовое уничтожение призраков: ps aux | grep child-<name> → kill -9 all PIDs
3. Проверка порта: ss -tlnp | grep :<port> → принудительное освобождение при занятости
4. Удалить из bot_registry.json + перезагрузить в памяти
5. Удалить /opt/repos/<name>/ (безопасность: путь должен быть под /opt/repos/, мин. 3 сегмента)
6. Удалить /var/log/citadel/<name>/
Защищённые имена: citadel-v2, citadel, claude-ceo, claude-CEO — удаление заблокировано.
Проблема призрачных процессов (урок): после kill tmux сиротские процессы bun могут занимать порты. Массовый kill + проверка порта предотвращают "фантомных ботов", которые отвечают на health check, но игнорируют Telegram.
Управление скиллами (Phase 21.0)
Дочерние боты загружают скиллы из двух источников при запуске, дедуплицируя через Set:
Источник 1: MANIFEST.md (JSON)
→ manifest.skills[] (сопоставлено при онбординге)
→ manifest.library_skills[] (сопоставлены .md-файлы библиотеки)
Источник 2: директория skills/
→ *.md файлы → имя файла без расширения
Merge: Set<string>(manifest.skills + manifest.library_skills + skills/*.md)
Пример (проект PT): 5 из manifest + 7 из skills/ = 12 уникальных скиллов.
Скиллы отображаются как:
- Лейбл на inline-кнопке ответов дочернего бота:
🏷️ odoo-expert, docker-ops, ... - Callback
skills_info: всплывашка с полным списком - Команда
/skillsв master: список содержимого директории skills
Безопасность (Phase 42 — аудит Sentinel 2026-04-23, 4 прохода, 13 патчей)
Полный обзор: SECURITY.md. Отчёт об аудите: security/audit-2026-04-23.md.
Секреты и хранение:
- Никаких учётных данных в репозитории; файлы состояния не содержат секретов
- Токены ботов в зашифрованном vault (
config/vault.json, AES-256-GCM).getSecret()с fallback наprocess.env - Ключ шифрования автогенерируется в
config/vault-key(chmod 600).vault.json,vault-key,watchdog-state.json,data/citadel.db*в gitignore
Auth:
- JWT HMAC-SHA256, TTL 24ч,
crypto.timingSafeEqualдля сравнения подписи - OAuth Google + GitHub с CSRF state (10 мин, одноразовый)
- Email/password с обязательной верификацией перед входом (TTL 24ч), сброс пароля (TTL 30 мин), доставка через Resend
- Извлечение токена —
extractChatId()читает Bearer-заголовок ИЛИ query-параметр?token=(для браузерного EventSource), точно соответствуетcrmAuthMiddleware
Мультитенантность (Phase 42):
- Гейт
canAccessProject(registry, chatId, project)на каждом защищённом маршруте - CEO (
ceo_chat_id) и DBuser.role === 'admin'видят всё; остальные ограничены по совпадениюowner_id(DB SSOT) - SSE-маршруты, WebSocket-терминал,
/api/cli/*,/api/mcp/*,/api/crm/projects/:name/*— все под гейтом /ws/terminal/:name?mode=interactiveтребует CEO или admin
Сетевой периметр:
- Bun привязан только к
127.0.0.1:19210— nginx проксирует через loopback /api/internal/*отклоняет запросы с proxy-заголовками (X-Forwarded-For,X-Real-IP,Forwarded) как канарейка для ошибки nginx-конфига- SSRF allowlist в
handleScoutAnalyze— HTTPS + точное совпадение hostname +redirect:"manual"(блокирует обход через redirect-цепочки) - UFW блокирует
:19210,:19213,:19200снаружи
Безопасность ввода и путей:
- Regex
isValidProjectName()на каждой точке входа (включая внутренние эндпоинты) safePath()на всех пользовательских путях к файлам —handleSaveSkillнайден и пропатчен в Phase 42.6- Deny-list nginx:
/.*,/(state|scripts|config|data|knowledge-base|issues|skills|blueprints|mcp-server)/ - CORS whitelist (
CRM_ALLOWED_ORIGINS), заголовки в том числе на ошибках - Атомарные записи для мутаций реестра (
tmp.${pid}+mv) - Расшифровка vault-токена при запуске дочернего бота: использовать
bun -eс node:crypto (НЕ Python)
Регрессионное покрытие: scripts/vps-sync.sh запускает 7+ post-deploy smoke-тестов после каждого деплоя (loopback bind, path traversal, валидация chat/save, proxy canary, SSE ?token=, fail-closed валидация, SSRF-блок при наличии CEO_TOKEN).
Модули Master Bot (Phase 25 — решение DEBT-1)
Master-бот организован в специализированные модули:
master-bot/
├── bot.ts ← Bootstrap: vault, реестр, контекст, всё связывает (106 строк)
├── context.ts ← Тип MasterContext + доменные интерфейсы
├── api-server.ts ← Bun.serve() — HTTP, WebSocket, SSE, CRM-маршруты
├── tg-api.ts ← Обёртка Telegram Bot API (sendMessage, getUpdates и т.д.)
├── child-state.ts ← Читает состояние дочернего бота, health, heartbeat, tmux, bridge
├── telegram-commands.ts ← Все обработчики /команд, роутер callback-запросов, маршрутизатор сообщений
├── telegram.ts ← Минималистичный polling loop + реэкспорты для обратной совместимости
├── watchdog.ts ← Self-healing монитор дочерних ботов
└── onboarding.ts ← Интерактивный мастер создания проектов
bot.ts импортирует только из telegram.ts и api-server.ts. Все остальные модули — детали внутренней реализации.
Bridge CLI (Phase 25 — Local Gateway)
bridge/
├── bin/citadel-bridge.ts ← CLI entry (commander.js): connect, pull, push, status, disconnect
├── src/
│ ├── auth.ts ← Валидация JWT через CRM
│ ├── config.ts ← Персистентность ~/.citadel/bridge.json
│ ├── inject.ts ← Маркеры CLAUDE.md <!-- CITADEL:START/END -->
│ ├── sync.ts ← Pull skills-bundle + learnings, push local learnings
│ └── heartbeat.ts ← Репортёр активности сессии
├── package.json
└── tsconfig.json
CRM API Endpoints (50+ всего)
Core CRM (Phase 22)
| Эндпоинт | Метод | Назначение |
|---|---|---|
/api/master/health |
GET | Health master-бота (публичный) |
/api/crm/projects |
GET | Список всех проектов + live health |
/api/crm/projects/:name |
GET | Детали проекта |
/api/crm/projects/:name/logs |
GET | Tail JSONL-логов |
/api/crm/projects/:name/files |
GET | Безопасный листинг директории |
/api/crm/projects/:name/files/upload |
POST | Загрузка файлов |
/api/crm/projects/:name/files/mkdir |
POST | Создание папки |
/api/crm/projects/:name/files/create |
POST | Создание файла |
/api/crm/projects/:name/files/delete |
DELETE | Удаление файла/папки |
/api/crm/projects/:name/files/clone |
POST | Клонирование git-репозитория |
/api/crm/projects/:name/files/read |
GET | Чтение содержимого файла |
/api/crm/projects/:name/wiki/tree |
GET | Список .md-файлов вики |
/api/crm/projects/:name/wiki/file |
GET | Чтение файла вики |
/api/crm/projects/:name/skills |
GET | Установленные скиллы |
/api/crm/projects/:name/metrics |
GET | Временной ряд качества |
/api/crm/projects/:name/restart |
POST | Перезапуск дочернего бота |
/api/crm/projects/:name/specs |
GET | Список спеков |
/api/crm/projects/:name/specs/:id/approve |
POST | Одобрить спек |
/api/crm/projects/:name/specs/:id/reject |
POST | Отклонить спек |
/api/crm/projects/:name/active-role |
GET/POST | Роль агента |
/api/crm/projects/:name/message |
POST | Поставить сообщение в очередь воркера |
/api/crm/projects/:name/workers |
GET/POST | CRUD реестра воркеров |
/api/crm/projects/:name/workers/:id |
PUT/DELETE | Обновить/удалить воркер |
/api/crm/projects/:name/workers/generate-prompt |
POST | AI-генерация system prompt |
/api/crm/projects/:name/skills-bundle |
GET | Скиллы + evals для bridge |
/api/crm/projects/:name/learnings |
GET/POST | Синхронизация learnings |
/api/sse/logs/:name |
GET | SSE-стрим логов (?category=) |
Дашборд и вики (Phase 32)
| Эндпоинт | Метод | Назначение |
|---|---|---|
/api/crm/projects/:name/wiki/save |
PUT | Сохранить/создать страницу вики |
/api/crm/projects/:name/skills/save |
PUT | Сохранить файл скилла |
/api/crm/projects/:name/skills/delete |
DELETE | Удалить файл скилла |
Мультитенантность (Phase 33)
| Эндпоинт | Метод | Назначение |
|---|---|---|
/api/crm/account/settings |
GET/PUT | API-ключи на уровне аккаунта |
/api/crm/projects/create |
POST | Облегчённое создание проекта |
/api/crm/onboarding/setup |
POST | Полный мастер онбординга |
MCP и CLI (Phase 34)
| Эндпоинт | Метод | Назначение |
|---|---|---|
/api/mcp/issues/:project |
POST/GET | CRUD задач |
/api/mcp/issues/:project/:id |
PUT | Обновить задачу |
/api/mcp/wiki/:project |
PUT | Синхронизация вики через MCP |
/api/mcp/roadmap/:project |
GET/PUT | Чтение/синхронизация roadmap |
/api/cli/init/:project/:mode |
GET | Облачный контекст для CLI |
/api/mcp/skills/:project/:skill |
GET | Получить скилл для MCP |
/api/mcp/report/:project |
POST | Mission report |
/api/mcp/learnings/:project |
GET | Получить learnings для MCP |
Живой терминал (Phase 35)
| Эндпоинт | Метод | Назначение |
|---|---|---|
/api/crm/projects/:name/terminal/log |
POST | Получение терминального JSONL от ARC CLI |
Cloud PM и знания (Phase 36)
| Эндпоинт | Метод | Назначение |
|---|---|---|
/api/crm/projects/:name/chat |
POST | SSE chat proxy к Anthropic API |
/api/crm/projects/:name/skills/generate |
POST | Neural Skill Generator (NotebookLM) |
/api/crm/projects/:name/notebooks |
GET | Связанные ноутбуки NotebookLM |
Auth и OAuth (Phase 37)
| Эндпоинт | Метод | Назначение |
|---|---|---|
/api/auth/register |
POST | Регистрация email/password |
/api/auth/login |
POST | Вход email/password |
/api/auth/google |
GET | Редирект OAuth Google |
/api/auth/callback/google |
GET | Callback OAuth Google |
/api/auth/github |
GET | Редирект OAuth GitHub |
/api/auth/callback/github |
GET | Callback OAuth GitHub |
/api/auth/providers |
GET | Доступные OAuth-провайдеры |
Закреплённые заметки (Phase 41.8)
| Эндпоинт | Метод | Назначение |
|---|---|---|
/api/crm/projects/:name/pins |
GET | Список закреплённых заметок (сначала новые) |
/api/crm/projects/:name/pins |
POST | Закрепить сообщение воркера в Context Rail (body: worker_id, body, опц. title, author) |
/api/crm/projects/:name/pins/:id |
DELETE | Удалить закреплённую заметку |
Бэкенд: migration 009 (таблица pinned_notes), pinnedNoteQueries в shared/db.ts. Фронтенд: ContextRail.jsx получает данные при монтировании, слушает CustomEvent crm-pin-created, оптимистичный DELETE.
Слой защиты данных (Phase 45)
Гибридное шифрование at-rest — клиентский крипто-фундамент + серверное vault-шифрование.
Клиентская сторона (браузер)
frontend/src/crm/crypto/e2ee.ts— WebCrypto обёртка (214 строк)- PBKDF2 (100k итераций, SHA-256) → AES-256-GCM master key
- Жизненный цикл ключа:
initMasterKey(password)при входе →sessionStorage→clearMasterKey()при выходе/401 - Восстановление:
generateRecoveryKey()→ формат 1Password (XXXX-XXXX-XXXX-XXXX-XXXX)
Серверная сторона (Bun + SQLite)
shared/vault.ts—encryptField()/decryptField()через AES-256-GCM vault key (формат с префиксомv1:)- API-ключи: шифрование при сохранении, расшифровка при загрузке (прозрачно для фронтенда) —
routes/system.ts - Сообщения чата: авто-шифрование при INSERT, авто-расшифровка при SELECT —
db.ts+ migration 015 - Ключи восстановления: таблица
recovery_keys(migration 016), 4 API-эндпоинта
Заголовки безопасности
- CSP:
default-src 'self'; script-src 'self'на всех CRM-ответах X-Frame-Options: DENY,X-Content-Type-Options: nosniff,Referrer-Policy: strict-origin-when-cross-origin
PII-санитизация
shared/pii-sanitizer.ts— редактирует email'ы, API-ключи (sk-ant-*,sk-*), JWT, номера карт- Применяется к терминальному JSONL-логированию (
routes/chat.ts)
Эндпоинты ключа восстановления
| Эндпоинт | Метод | Назначение |
|---|---|---|
/api/crm/account/recovery |
POST | Создать ключ восстановления (сохраняет зашифрованный master key) |
/api/crm/account/recovery |
GET | Список активных ключей восстановления |
/api/crm/account/recovery |
DELETE | Отозвать ключ(и) восстановления |
/api/crm/account/recovery/restore |
GET | Получить зашифрованный master key для восстановления |
Полные детали безопасности: docs/SECURITY.md, docs/architecture/PHASE_45_E2EE.md.