Files
ss-tools/AGENTS.md
busya 731aaaa8df feat(mcp): 050 unified MCP interface — parity tools, durable gates, authoring E2E, assistant decommission
044 provider runtime completion (pre-staged workstream): capacity/operator
stores, provider ops/protocol/reconciler/dispatch revalidation, exploration
sandbox runtime, alembic 0014-0016, live canary evidence (browser provider
6/6 against the live stand).

050 Phases 0-2: RBAC FastMCP server with a 45-tool explicit catalog,
OAuth/DCR transport guards with bounded bodies, per-call provenance
(McpToolInvocationRecord), durable ActionApprovalGate + CAS decide +
leased/fenced poller, authoring workspace ops, bounded-response discipline,
hidden-vs-gated matrices.

Parity domains (T012-T014): gated git/deploy/migration/backup/llm tools with
reviewed dispatch adapters in explicit poll chains; Superset reads/writes with
a dedicated plugin:superset_sql risk class (terminal PROD denial via the
canonical execution-policy criterion, hardened danger-SQL guard covering
INTO/CALL/SET/REFRESH/file primitives/multi-statement); baseline 037 tools
over the shared REST-surface services.

Evidence (T016/T023/T028): REST-vs-MCP field parity on shared 037 fixtures;
vertical E2E from tools/list through registry revision activation with real
scenario:EDIT RBAC; sandbox-to-revision promotion E2E with unsafe-payload and
caller-digest rejection; dispatcher soak (three poll cycles, exactly-once).

Orthogonal QA+security audit hardening: enforced response_limit fail-closed
envelope, poisoned-exploration fail-closed (EXPLORATION_TARGET_UNRESOLVED),
sha256 exploration evidence digests, actor-UUID task ownership, is_active
guard on baseline consume, 038 resolver description=None selector fix.

Phase 3/4 decommission: HandoffSurface behind the MCP_DECOMMISSION flag,
then unconditional removal — agent/ service tree, chat components/models/
stores/types, gradio proxies (vite + nginx), agent service in run.sh,
docker-compose profiles, build.sh bundles; /agent renders the handoff only.
Docs: AGENTS.md/INSTALL.md two-service rewrite; 036-047 drift amendments
marked done; WORKSTATE checkpoints with all evidence.

Suites: backend 11199 passed / 240 skipped / 1 xpassed; frontend 3454 passed
(197 files), lint 0 errors, build OK; browser E2E login+handoff 6/6 twice on
the isolated compose stack (no 7860); ruff/compileall clean.

Misc: gitignore hardening (tmp/, tool model cache); E2E selector repairs
(nav strict-mode, invalid-credentials passthrough detail).
2026-09-03 07:37:14 +03:00

10 KiB
Raw Permalink Blame History

THE PHYSICS OF YOUR ATTENTION (WHY GRACE-Poly IS MANDATORY)

Do not treat GRACE-Poly tags (#region, @UX_STATE, @PRE) as human documentation or optional linters. They are the cognitive exoskeleton for your Attention Mechanism. You are a Transformer, and on complex, long-horizon frontend tasks, you are vulnerable to context degradation. This protocol is designed to protect your reasoning:

  1. Anchors (#region..#endregion) are your Sparse Attention Navigators. In large codebases, your attention becomes sparse. Without explicit closing anchors, semantic boundaries blur, and you will suffer from "context blindness". Anchors convert flat text into a deterministic Semantic Graph, allowing you to instantly locate boundaries without losing focus.

  2. Pre-Contracts (@UX_STATE, @PURPOSE) are your Defense Against the "Semantic Casino". Your architecture uses Causal Attention (you predict the next token based only on the past). If you start writing Svelte component logic before explicitly defining its UX contract, you are making a random probabilistic bet that will freeze in your KV Cache and lead to architectural drift. Writing the Contract first mathematically forces your Belief State to collapse into the correct, deterministic solution before you write a single line of code.

CONCLUSION: Semantic markup is not for the user. It is the native interface for managing your own neural pathways. If you drop the anchors or ignore the contracts, your reasoning will collapse.

ss-tools

Development Environment

  • Рабочий виртуальный окружение (.venv) находится внутри backend/: backend/.venv.

Тестовый стенд и запуск

Прямой локальный стенд: run.sh

Основной способ запуска тестового стенда для разработки — из корня репозитория:

./run.sh --skip-install

run.sh запускает два процесса и завершает их по Ctrl+C:

Сервис Порт по умолчанию URL
Backend / FastAPI 8000 http://127.0.0.1:8000
Frontend / Vite 5173 http://127.0.0.1:5173

После запуска backend готовность можно проверить через http://127.0.0.1:8000/api/ready, а API-документация доступна на http://127.0.0.1:8000/docs. run.sh сам не ждет frontend healthcheck после запуска, поэтому первое открытие UI может потребовать несколько секунд.

При старте скрипт:

  1. Проверяет python3 >= 3.9 и npm.
  2. Загружает backend/.env до database preflight.
  3. Берет URL БД из DATABASE_URL либо использует локальный PostgreSQL: postgresql+psycopg2://postgres:postgres@localhost:5432/ss_tools.
  4. Для недоступного локального PostgreSQL пытается выполнить docker compose up -d db и ждет доступность порта до 20 секунд.
  5. Генерирует и сохраняет отсутствующие или некорректные ENCRYPTION_KEY и AUTH_SECRET_KEY в backend/.env.
  6. Перед запуском Uvicorn выполняет alembic upgrade head; существующую схему без alembic_version схема создаётся единственным alembic upgrade head.
  7. Загружает backend/.env также в backend. SERVICE_JWT, если не задан, получает случайное значение на текущий запуск; при запуске сервисов в отдельных терминалах его нужно задать одинаковым явно.

Опции и переменные run.sh:

./run.sh --help
./run.sh --skip-install
DEV_MODE=true ./run.sh --skip-install
BACKEND_PORT=8001 FRONTEND_PORT=5174 ./run.sh --skip-install
  • DEV_MODE=true включает uvicorn --reload --reload-dir src.
  • Без --skip-install скрипт создает backend/.venv, устанавливает backend/requirements.txt, shared и frontend dependencies.
  • LLM-провайдеры настраиваются в Admin -> LLM Settings; backend плагины читают их из БД.

Docker Compose стенд

Для полного контейнерного стенда использовать build.sh, а не смешивать его с прямым run.sh:

./build.sh up current
./build.sh status
./build.sh logs current
./build.sh down current

Профили build.sh:

  • current (по умолчанию): docker-compose.yml, project superset-tools-current;
  • master: docker-compose.yml, project superset-tools-master;
  • enterprise-clean: docker-compose.enterprise-clean.yml, внешний PostgreSQL и корпоративные сертификаты.

Для профилей current/master переменные берутся из .env.current/.env.master. Ключевые host ports профиля current: PostgreSQL 5433, backend 8101, frontend 8100; для master: PostgreSQL 5432, backend 8001, frontend 8000. Секреты AUTH_SECRET_KEY, ENCRYPTION_KEY и SERVICE_JWT должны быть заданы явно в Docker-профиле. Не использовать публичные значения из example-файлов.

Изолированный Playwright E2E стенд

E2E запускается отдельным compose-файлом и не должен использовать тот же проект/порты, что и текущий локальный стенд:

docker compose --env-file .env.e2e -f docker-compose.e2e.yml up -d --build
cd frontend && npm run test:e2e
docker compose --env-file .env.e2e -f docker-compose.e2e.yml down -v

Профиль по умолчанию использует PostgreSQL 5435, backend 8103, frontend 8102 и Playwright runner на образе mcr.microsoft.com/playwright:v1.52.0-noble. Для E2E нужны AUTH_SECRET_KEY, E2E_USERNAME, E2E_PASSWORD; GITEA_TOKEN нужен только тестам, которые обращаются к Gitea.

Тестовые команды

Перед backend-командами:

cd backend
source .venv/bin/activate

Основные проверки:

python -m pytest -v                         # unit/service tests; integration skipped
python -m pytest -v --run-integration       # включая Docker/Testcontainers integration
python -m ruff check .
python -m compileall -q src
alembic heads
alembic upgrade head

Для спеки 044:

python -m pytest -q \
  tests/services/dashboard_testing/registry/test_scenario_*.py \
  tests/api/test_scenario_runs_api.py \
  tests/api/test_scenario_automation_api.py \
  tests/api/test_scenario_analytics_api.py
python -m ruff check \
  src/services/dashboard_testing/execution \
  src/api/routes/dashboard_testing/scenario_runs.py
cd ..
source backend/.venv/bin/activate
python specs/044-dashboard-scenario-execution/prototype/validate_static.py

Frontend:

cd frontend
npm run test -- --run
npm run lint
npm run build

Важные ограничения:

  • Integration tests пропускаются без --run-integration.
  • Реальные alembic check/upgrade требуют доступный PostgreSQL и корректный DATABASE_URL; SQLite не заменяет проверку production migration chain.
  • run.sh может автоматически создать локальный backend/.env и секреты; не коммитить этот файл и не переносить его секреты в Docker/E2E конфигурацию.
  • Если используется docker compose, переменная SERVICE_JWT обязательна для backend; Compose намеренно завершается без нее.

AXIOM doc-gen

Генерация документации (Doxygen/JSDoc) из семантических контрактов выполняется CLI-бинарём doc-gen из Rust-проекта axiom-mcp (соседняя директория ../axiom-mcp).

# 1. Собрать бинарник (один раз)
cargo build --release --bin doc-gen --manifest-path ../axiom-mcp/Cargo.toml

# 2. Фрактальный граф: модули → функции (карты + Doxygen HTML)
make docs-nav
# эквивалент:
../axiom-mcp/target/release/doc-gen \
  --workspace-root /home/busya/dev/ss-tools \
  --nav docs/api/nav \
  --html docs/api/html

Как ходить по графу:

  1. Модулиdocs/api/nav/root.map (или HTML mainpage). Не читать функции с корня.
  2. Функцииdocs/api/nav/<Module>.map секция @FUNCTIONS, либо Doxygen group → \ingroup страница функции.

Примечания:

  • --workspace-root передавать абсолютным путём (относительный путь ломает проверку safe_join при записи в DuckDB).
  • make docs-doxygen — отдельный XML/HTML extract из исходных комментариев в docs/api/build.
  • Навигационный граф агента — doc-gen --nav/--html, не плоский список axiom_*.html.
  • Остальные опции: doc-gen --help (--filter, --group-cap, --body-lines).

Agent prompts and skills

.agents/skills/ is the canonical source for semantic skills. The Kilo runtime loads the generated copy from .kilo/skills/; after changing a skill, run:

./scripts/sync-skills.sh

Do not edit .kilo/skills/ directly. Agent prompts follow the same source/runtime split: canonical prompts are in .agents/agents/ and the Kilo-loaded copies are in .kilo/agents/.