Files
ss-tools/INSTALL.md
busya 65121cac6b feat(logging): self-diagnosing EXPLORE + shared/ absorption + belief analytics (ADR-0021/0022)
T0: absorb shared/ into backend — cot_logger→src/core, CotJsonFormatter→src/core/cot_formatter.py, _llm_http/_llm_health/ssl→src/core/utils; imports rewritten (26 prod + tests, patch targets); run.sh/backend.Dockerfile/requirements/.axiom source_dirs/semantic_health/AGENTS/INSTALL cleaned; ADR-0022 supersedes ADR-0015; fixed latent CI defects (ss_tools ImportError, record.message in logger tests, same-name test-module collision).

ADR-0021 wire enrichment (additive): contract_id/claim/error_code/loc fields; _contract_id ContextVar + resolve_contract_id (explicit > belief_scope > declared-src mirror, derived src never mirrors); EXPLORE auto-loc via single frame walk; facade error auto-fill; 2KB payload cap with payload_truncated/payload_bytes markers; migrated 85 error="CODE" sites to error_code= (12 files); pilot editor/load.py; superset preview payload-bomb inlined bodies removed.

Analytics SSOT src/core/log_stats.py (bond transition matrix, orphan-EXPLORE ratio, REFLECT pairing, intent families, coverage, insufficient-sample flag); pretty_cot.py --stats/--digest/--trajectory/--story over one engine; log_gap_service three-tier ground-truth triangulation (FAILED w/o EXPLORE etc.) + GET /api/reports/log-stats|task-log-gaps (polling-suppressed); scripts/cot_audit.py CLI; enriched fields persisted into task_logs.payload for tier queries.

Frontend: ReportsAnalyticsModel + AnalyticsStatsPanel (Logs tab) + TaskGapPanel and per-row T1/T2/T3 gap badges (Tasks tab); cot-logger.ts ADR-0021 opts; i18n en/ru. Scheduler console spam fixed: apscheduler logger demoted to WARNING via LoggingConfig.scheduler_log_level. .axiom belief patterns -> $OBJ.* (alias undercount). molecular-cot-logging skill updated (fields, decision rules, tie-break, CLI) and synced.

Reviewed orthogonally: F1 cot_span contract pollution, F2 cap boundary accounting, F3 digest over-dedup, F4 trace-state bound, F5 tier metadata — fixed with regression tests. Validation: backend 11287 passed + ruff + compileall; frontend 3446 passed + lint + build; CLI smoke on live app.log.
2026-09-04 20:56:41 +03:00

445 lines
21 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.

# Установка и настройка superset-tools
## Содержание
- [Требования](#требования)
- [Архитектура](#архитектура)
- [Технологический стек](#технологический-стек)
- [Docker (рекомендуется)](#docker-рекомендуется)
- [Локальная разработка](#локальная-разработка)
- [Конфигурация](#конфигурация)
- [Система сборки](#система-сборки)
- [Тестирование](#тестирование)
- [Покрытие кода](#покрытие-кода)
- [SSL/TLS конфигурация](#ssltls-конфигурация)
- [Enterprise Clean Deployment](#enterprise-clean-deployment)
- [Спецификации](#спецификации)
- [Утилиты](#утилиты)
- [Исследования](#исследования)
## Требования
- **Docker (рекомендуется):** Docker Engine 24+, Docker Compose v2, 4 GB RAM
- **Локальная разработка:** Python 3.9+, Node.js 18+, npm, 2 GB RAM, 5 GB диска
## Архитектура
Проект состоит из двух сервисов (внешние ассистенты подключаются через MCP — spec 050):
| Сервис | Технологии | Назначение |
|---|---|---|
| **backend/** | Python FastAPI, SQLAlchemy 2.0, APScheduler, PostgreSQL | REST API, бизнес-логика, плагины, MCP-сервер |
| **frontend/** | Svelte 5 (Runes), SvelteKit, Vite, Tailwind CSS | SPA-клиент |
```
superset-tools/
├── backend/ # REST API (FastAPI)
│ ├── src/
│ │ ├── api/routes/ # 30+ роутов (admin, auth, translate, git, agent...)
│ │ ├── core/
│ │ │ ├── auth/ # JWT, OAuth, API Keys, RBAC
│ │ │ ├── migration/ # Dry-run, risk assessment
│ │ │ ├── task_manager/ # Async jobs, event bus, persistence
│ │ │ ├── superset_client/
│ │ │ ├── logger/ # Structured logging, belief state
│ │ │ └── ...
│ │ ├── models/ # SQLAlchemy модели
│ │ ├── plugins/ # Реализации плагинов
│ │ ├── schemas/ # Pydantic схемы
│ │ ├── services/ # Бизнес-логика
│ │ └── scripts/ # CLI/TUI админ-скрипты
│ └── tests/
├── frontend/ # SvelteKit SPA
│ ├── src/
│ │ ├── routes/ # 20+ групп страниц
│ │ ├── lib/
│ │ │ ├── api/ # API клиент
│ │ │ ├── auth/ # Auth store, permissions
│ │ │ ├── components/ # UI компоненты
│ │ │ ├── stores/ # Svelte stores
│ │ │ ├── i18n/ # Мультиязычность
│ │ │ └── ...
│ │ └── ...
│ └── tests/
├── docker/ # Dockerfile, entrypoint, nginx
├── docs/ # Документация, ADR
├── specs/ # 40+ feature specifications
├── scripts/ # Утилиты (coverage, security, build)
├── research/ # Исследования (mcp-superset)
├── semantics/ # Семантическая карта кода
├── dist/ # Релизные бандлы
├── storage/ # Runtime данные (backups, repos)
├── certs/ # SSL-сертификаты
└── examples/ # Примеры интеграции
```
## Технологический стек
**Backend:** Python 3.9+ (FastAPI 0.126, SQLAlchemy 2.0, APScheduler 3.11), PostgreSQL 16, Authlib, JWT, OpenAI API, GitPython, Playwright, lingua-language-detector
**Frontend:** Svelte 5 (Runes), SvelteKit 2.49, Vite 7, Tailwind CSS 3, Vitest 4.1, Playwright 1.60
**DevOps:** Docker & Docker Compose (3 профиля + E2E), GitHub Actions (CI), Nginx (опциональный SSL)
## Docker (рекомендуется)
### Профили окружения
Система поддерживает несколько профилей через `.env` файлы:
| Профиль | Файл | Команда |
|---|---|---|
| **current** | `.env.current` | `docker compose --profile current up --build` |
| **master** | `.env.master` | `docker compose --profile master up --build` |
| **enterprise-clean** | `.env` | `docker compose -f docker-compose.enterprise-clean.yml up --build` |
| **e2e** | `.env.e2e` | `docker compose -f docker-compose.e2e.yml up --build` |
```bash
git clone <repository-url>
cd superset-tools
cp .env.example .env
docker compose --profile current up --build
```
После запуска:
- Frontend: http://localhost:8000
- Backend API: http://localhost:8001
- PostgreSQL: localhost:5432
### Offline-бандл
```bash
xz -dc dist/docker/superset-tools.20260517.tar.xz | docker load
export POSTGRES_PASSWORD="my-strong-password"
docker compose -f dist/docker/docker-compose.light.yml up -d
```
## Локальная разработка
### Backend
```bash
cd backend
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements-backend.txt
python3 -m uvicorn src.app:app --reload --port 8000
```
### Frontend
```bash
cd frontend
npm install
npm run dev -- --port 5173
```
### Начальная настройка
```bash
# Переменные окружения
cp .env.example backend/.env
# Инициализация БД
cd backend && source .venv/bin/activate
python src/scripts/init_auth_db.py
# Создание администратора
python src/scripts/create_admin.py --username admin --password '<temporary-secret>'
```
## Конфигурация
Полный список переменных — в каждом `.env.*.example` файле.
### Основные категории
| Категория | Переменные | Описание |
|---|---|---|
| **Security** | `AUTH_SECRET_KEY`, `ENCRYPTION_KEY`, `SERVICE_JWT` | JWT-подпись, шифрование данных, сервисный токен для сервисных принципалов |
| **Database** | `DATABASE_URL` | Единственное PostgreSQL подключение |
| **Admin bootstrap** | `INITIAL_ADMIN_CREATE`, `INITIAL_ADMIN_USERNAME`, `INITIAL_ADMIN_PASSWORD`, `INITIAL_ADMIN_EMAIL` | Автосоздание admin при первом запуске |
| **LLM** | `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, `LLM_BASE_URL`, `LLM_MODEL` | Провайдеры и модели |
| **Features** | `FEATURES__DATASET_REVIEW`, `FEATURES__HEALTH_MONITOR` | Включение фич |
| **SSO** | `ADFS_CLIENT_ID`, `ADFS_CLIENT_SECRET`, `ADFS_METADATA_URL` | Active Directory Federation Services |
| **Certificates** | `CERTS_PATH`, `SSL_KEY_PASSPHRASE`, `LLM_CA_CERT_URLS` | PKI для корпоративных сетей |
| **CORS** | `ALLOWED_ORIGINS`, `FORCE_HTTPS`, `APP_TIMEZONE` | Безопасность и регион |
| **Logging** | `ENABLE_BELIEF_STATE_LOGGING`, `TASK_LOG_LEVEL` | Структурированное логирование |
| **Ports** | `BACKEND_HOST_PORT`, `FRONTEND_HOST_PORT`, `POSTGRES_HOST_PORT` | Проброс портов Docker |
## MCP клиент (внешние ассистенты)
Единая точка подключения внешних MCP-клиентов — Streamable HTTP `/mcp` внутри backend
(spec 050). Каталог из 47 инструментов фильтруется по live-RBAC; мутирующие операции
проходят через durable approval-гейты.
```bash
# 1. Discovery (RFC 9728) — метаданные защищённого ресурса и authorization server
curl http://<host>:8001/.well-known/oauth-protected-resource/mcp
curl http://<host>:8001/.well-known/oauth-authorization-server
# 2. Dynamic Client Registration (нужен Bearer веб-сессии пользователя-владельца)
# public-клиент (browser PKCE) или confidential (machine, выдаётся client_secret одноразово)
curl -X POST http://<host>:8001/oauth/register \
-H "Authorization: Bearer <web-jwt>" -H "Content-Type: application/json" \
-d '{"client_name":"my-mcp","redirect_uris":["http://localhost:9999/cb"],"scope":"mcp:read","client_type":"confidential"}'
# 3a. Machine-клиент: client_credentials → сервисный токен (только read-поверхность каталога)
curl -X POST http://<host>:8001/oauth/token \
-d "grant_type=client_credentials&client_id=<id>&client_secret=<secret>"
# 3b. Пользовательский клиент: authorization code + PKCE (S256)
# GET /oauth/authorize?... с Bearer веб-сессии (SPA-mediated consent) → 302 code
# POST /oauth/token grant_type=authorization_code + code_verifier
# 4. MCP сессия: POST /mcp с Authorization: Bearer <mcp-token>
# initialize → notifications/initialized → tools/list → tools/call
```
Альтернатива для доверенных машинных интеграций внутри периметра — `SERVICE_JWT`
(задаётся в `.env`; композ намеренно падает без него). Gated-инструменты
(`deploy_dashboard`, `execute_migration`, `run_backup`, superset-writes,
`consume_baseline_approval`) возвращают `approval_required` и исполняются только
после `decide_approval` тем же принципалом через серверный поллер.
PRODUCTION SQL (`superset_execute_sql` на PROD-окружении) отклоняется терминально.
## Локальный периметр (LLM/VLM/MCP endpoints)
Spec 050 (MCPX-FR-020, T008b): MCP-клиенты и все LLM/VLM-провайдеры по умолчанию
расположены внутри enterprise-периметра. PII (дашборды, сэмплы датасетов, маскированные
скриншоты) допускается только к локальным провайдерам; credentials/cookies/токены/секреты
и raw-пути хранения отвергаются везде (typed secret-exposure rejection, E13).
**Deny-by-default на конфигурации провайдера** (Admin → LLM Settings): `base_url`,
не являющийся локальным, отклоняется типизированной ошибкой
`400 endpoint_not_local:<reason>` ДО сохранения. Локальными считаются:
- host-литералы `localhost`, `127.*`, `[::1]`, `0.0.0.0`, `host.docker.internal`;
- IP из private/loopback/link-local диапазонов (RFC1918 `10/8`, `172.16/12`,
`192.168/16`, ULA/loopback IPv6);
- DNS-имена с enterprise-суффиксами `.local`, `.internal`, `.lan`, `.corp`, `.intranet`
(split-horizon DNS не требует резолва);
- DNS-имена, у которых ВСЕ резолвимые адреса приватные;
- пустой `base_url` отклоняется (SDK-дефолт указывает на публичное облако).
Нерезолвимое имя = отказ (fail closed). Substring-эвристики не используются:
`https://api.openai.com/localhost` отклоняется по hostname.
Escape hatches (явные, задокументированные, по умолчанию закрыты):
```bash
# Полный opt-out периметровой проверки (только для непод perimeter-развёртываний!):
LLM_ALLOW_NONLOCAL_ENDPOINTS=true
# Точечный allowlist публичных хостов (через запятую):
LLM_NONLOCAL_ENDPOINT_ALLOWED_HOSTS=llm.partner.example
# Дополнительные enterprise-суффиксы:
LLM_LOCAL_HOST_SUFFIXES=.enterprise
```
MCP-транспорт держит свой локальный контур independently: DNS-rebinding protection с
локальными дефолтами `MCP_ALLOWED_HOSTS`/`MCP_ALLOWED_ORIGINS`, server-owned лимиты
тела запроса (4 MiB), JSON-глубины (`json_depth_limit=32`, typed `400 json_depth_exceeded`
до dispatch) и per-session rate limit (`120 req/60s`, typed `429 rate_limited` +
стандартный `Retry-After`). Исполнимые пины: `tests/test_endpoint_locality.py`,
`tests/test_mcp_transport_limits.py`.
## Система сборки
`build.sh` — унифицированная CLI-утилита:
```bash
# Сборка и запуск
./build.sh compose # docker compose up --build (current profile)
./build.sh compose:master # docker compose up (master profile)
# Индивидуальные сборки
./build.sh backend # backend image only
./build.sh frontend # frontend image only
# Offline-бандлы
./build.sh bundle v1.0.0 # полный бандл (все сервисы)
./build.sh bundle:light v1.0.0 # light (backend + frontend)
```
Артефакты: `dist/docker/superset-tools.<version>.tar.xz` + sha256sum + manifest.
## Тестирование
### Makefile (tiered test system)
```bash
make test # Tier 1: быстрые unit-тесты backend + frontend (<30с)
make test-unit # Backend unit-тесты с SQLite (без Docker)
make test-frontend # Frontend vitest-тесты
make test-related F=path # Tier 2: умный выбор тестов для изменённого файла
make test-integration # Tier 3: backend integration с testcontainers
make test-e2e # Tier 3: Playwright E2E (требуется запущенное приложение)
make test-all # Все тесты (без установки зависимостей)
make lint # Все линтеры
make lint-backend # ruff check
make lint-frontend # eslint
make coverage # coverage обоих стеков
```
### Самостоятельный запуск
```bash
# Backend тесты
cd backend && source .venv/bin/activate && pytest
# Frontend тесты
cd frontend && npm run test
# Конкретный тест
pytest backend/tests/test_auth.py::test_create_user
```
### E2E тестирование
```bash
docker compose -f docker-compose.e2e.yml up --build
cd frontend && npm run test:e2e
```
## Покрытие кода
Сводный отчёт — `scripts/coverage-summary.sh`:
```bash
./scripts/coverage-summary.sh # Полный запуск (integration + frontend)
./scripts/coverage-summary.sh --unit # Backend unit (SQLite) + frontend
./scripts/coverage-summary.sh --frontend-only # Только frontend
./scripts/coverage-summary.sh --backend-only --unit # Только backend
./scripts/coverage-summary.sh --output-dir ./reports/coverage
```
Результат: `coverage-summary/index.html`.
### Текущие показатели
| Стек | Тип тестов | Процент | Покрытие (Stmts) |
|---|---|---|---|
| Backend (unit) | 1723 | 1721/2 ✅ | 48% |
| Backend (integration) | 167 | 167/0 ✅ | 12% |
| Frontend | 2443 | 2442/1 ✅ | 99.25% |
## SSL/TLS конфигурация
### Сертификаты для HTTPS (nginx)
Поместите файлы в `./certs/`:
**Вариант A — отдельные файлы:**
```
./certs/server.crt # SSL сертификат
./certs/server.key # Приватный ключ
```
**Вариант B — зашифрованный ключ + пароль:**
```
./certs/server.crt # SSL сертификат
./certs/server.key # Приватный ключ (зашифрован, с DEK-Info)
SSL_KEY_PASSPHRASE=my-passphrase
```
**Вариант C — PKCS#12 контейнер:**
```
./certs/server.p12 # Контейнер с сертификатом + ключом
SSL_KEY_PASSPHRASE=my-passphrase
```
Entrypoint автоматически извлекает `.crt` и `.key` из `.p12`, расшифровывает ключ и передаёт nginx (ключ остаётся в tmpfs контейнера).
### Корпоративные CA-сертификаты
Положите `.crt`/`.pem` в `./certs/` — entrypoint установит их в системное хранилище Alpine и NSS (Chromium/Playwright). Поддерживаются цепочки (Root → Intermediate).
### LLM CA-сертификаты
```bash
LLM_CA_CERT_URLS="http://pki.company.com/root-ca.crt http://pki.company.com/intermediate-ca.crt"
```
Сертификаты скачиваются на старте контейнеров, конвертируются из DER в PEM при необходимости, устанавливаются в системное хранилище.
### Диагностика SSL
```bash
scripts/check_llm_certs.py # Полная проверка цепочки доверия
scripts/diag_container.py --target your-llm-provider.com:443 # Контейнерная диагностика
```
Подробнее — [ADR-0009](docs/adr/ADR-0009-ssl-certificate-management.md).
`LLM_SSL_VERIFY` удалён в 0.2.x — TLS verify всегда включён.
## Enterprise Clean Deployment
Разворот в корпоративной сети с очищенным дистрибутивом (без тестовых данных, запрет внешних источников, compliance-проверка):
```bash
cp .env.example .env
docker compose --profile enterprise-clean up --build
```
Поддерживаются CLI, API и TUI flows. Подробнее — [docs/enterprise-clean.md](docs/enterprise-clean.md).
## Авторизация
Два метода аутентификации:
1. **Локальная** (username/password) — JWT-токены, RBAC (admin/analyst/viewer)
2. **ADFS SSO** — Active Directory Federation Services
Управление: `POST /api/admin/users`, `POST /api/admin/roles`.
## Мониторинг
- **Dashboard Hub** — управление дашбордами с Git-статусом
- **Dataset Hub** — управление датасетами с прогрессом маппинга
- **Task Drawer** — мониторинг фоновых задач (WebSocket real-time)
- **Unified Reports** — `GET /api/reports?page=1&page_size=20` (фильтры по статусу, типу, дате)
- **Health Monitor** — мониторинг здоровья системы (через `FEATURES__HEALTH_MONITOR`)
- **Semantic Map** — автоматически генерируемая семантическая карта кода (`semantics/semantic_map.json`)
## Спецификации
В `specs/` ведётся 40+ feature specifications. Каждая включает: `spec.md`, `research.md`, `plan.md`, `contracts/modules.md`, `data-model.md`, `checklists/requirements.md`, `tasks.md`.
| # | Название | Описание |
|---|---|---|
| 011 | `git-integration-dashboard` | Git-интеграция дашбордов |
| 017 | `llm-analysis-plugin` | LLM-аналитика и валидация |
| 022 | `sync-id-cross-filters` | Sync ID cross-filters |
| 023 | `clean-repo-enterprise` | Чистый репозиторий для enterprise |
| 033 | `gradio-agent-chat` | Gradio/LangGraph AI-агент |
| 034 | `task-status-center` | Центр статуса задач |
| 038 | `dashboard-scenario-model` | Сценарная модель дашбордов |
| 041 | `dataset-lineage-blast-radius` | Lineage и blast radius датасетов |
## Примеры скриптов
Примеры интеграции с внешними системами (Airflow, CI/CD, cron) — в [`examples/`](./examples/):
- [Python](examples/maintenance-api-python.py)
- [Bash](examples/maintenance-api-bash.sh)
Аутентификация через API Key (`X-API-Key`), запуск и завершение maintenance-событий.
## Утилиты
| Скрипт | Назначение |
|---|---|
| `coverage-summary.sh` | Сводный отчёт покрытия |
| `scan_secrets.sh` | Сканирование секретов |
| `check_llm_certs.py` | Проверка SSL-сертификатов LLM |
| `diag_container.py` | SSL-диагностика |
| `find-related-tests.py` | Поиск тестов по изменённому файлу |
| `pretty_cot.py` | Форматирование CoT-логов |
| `gen_semantics.py` | Семантическая карта кода |
| `build_offline_docker_bundle.sh` | Сборка offline-бандлов |
## Исследования
- **mcp-superset** — MCP-сервер для Apache Superset (137 инструментов, PyPI). Streamable HTTP, SSE, stdio транспорты. Подробнее — [`research/mcp-superset/`](research/mcp-superset/).