Files
microdao-daarion/docs/tools/drift_analyzer_tool.md
Apple 67225a39fa docs(platform): add policy configs, runbooks, ops scripts and platform documentation
Config policies (16 files): alert_routing, architecture_pressure, backlog,
cost_weights, data_governance, incident_escalation, incident_intelligence,
network_allowlist, nodes_registry, observability_sources, rbac_tools_matrix,
release_gate, risk_attribution, risk_policy, slo_policy, tool_limits, tools_rollout

Ops (22 files): Caddyfile, calendar compose, grafana voice dashboard,
deployments/incidents logs, runbooks for alerts/audit/backlog/incidents/sofiia/voice,
cron jobs, scripts (alert_triage, audit_cleanup, migrate_*, governance, schedule),
task_registry, voice alerts/ha/latency/policy

Docs (30+ files): HUMANIZED_STEPAN v2.7-v3 changelogs and runbooks,
NODA1/NODA2 status and setup, audit index and traces, backlog, incident,
supervisor, tools, voice, opencode, release, risk, aistalk, spacebot

Made-with: Cursor
2026-03-03 07:14:53 -08:00

254 lines
8.5 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.
# drift_analyzer_tool
**Drift Analyzer — 6-й gate у release_check**
Знаходить розбіжності між "джерелами правди" (docs/inventory/config) та фактичним станом repo.
---
## Огляд
`drift_analyzer_tool` — детерміністичний (без LLM), read-only аналізатор drift у 4 категоріях.
| Категорія | Джерело правди | Факт | Приклад drift |
|-----------|---------------|------|---------------|
| **services** | `inventory_services.csv` / `01_SERVICE_CATALOG.md` | `docker-compose*.yml` | DEPLOYED сервіс відсутній у compose |
| **openapi** | `docs/contracts/*.openapi.yaml` | FastAPI route decorators у коді | Endpoint у spec але нема в коді |
| **nats** | `inventory_nats_topics.csv` | `nc.publish/subscribe` у коді | Subject у коді не задокументований |
| **tools** | `config/tools_rollout.yml` + `rbac_tools_matrix.yml` | Handlers у `tool_manager.py` | Tool у rollout але нема handler |
---
## Використання
### Через агента (OpenCode / Telegram)
```
"Запусти drift аналіз"
"Перевір drift для категорій tools та openapi"
"Drift check перед релізом"
```
### Через execute_tool
```json
{
"action": "analyze",
"categories": ["services", "openapi", "nats", "tools"],
"timeout_sec": 25
}
```
### Через release_check (Gate 6, optional)
```json
{
"action": "start_task",
"params": {
"task_id": "release_check",
"inputs": {
"service_name": "router",
"run_drift": true,
"drift_categories": ["openapi", "tools"],
"drift_timeout_sec": 20
}
}
}
```
---
## Параметри
| Параметр | Тип | Обов'язковий | Опис |
|----------|-----|:---:|------|
| `action` | `"analyze"` | ✅ | Єдина дія |
| `categories` | array | — | Підмножина `["services","openapi","nats","tools"]` (default: всі) |
| `timeout_sec` | number | — | Таймаут в секундах (default: 25, max: 30) |
---
## Формат відповіді
```json
{
"pass": false,
"summary": "❌ Drift analysis FAILED. 2 error(s), 1 warning(s).",
"stats": {
"errors": 2,
"warnings": 1,
"infos": 0,
"skipped": [],
"items_checked": {
"services": 42,
"openapi": 18,
"tools": 65
},
"elapsed_ms": 1234.5,
"by_category": { "...": "..." }
},
"findings": [
{
"category": "tools",
"severity": "error",
"id": "DRIFT-TOOLS-001",
"title": "Tool 'fake_tool_x' in tools_rollout.yml but no handler in tool_manager.py",
"evidence": {
"path": "config/tools_rollout.yml",
"details": "'fake_tool_x' referenced in rollout groups but missing from KNOWN_TOOL_HANDLERS"
},
"recommended_fix": "Add handler for 'fake_tool_x' in tool_manager.py execute_tool dispatch, or remove from rollout."
}
]
}
```
### Pass/Fail правило
| Умова | `pass` |
|-------|--------|
| Будь-який `severity: error` | `false` |
| Тільки `warning` / `info` | `true` |
| Категорія відсутня (skipped) | не впливає |
---
## Категорії деталі
### 1. services — Service Catalog vs docker-compose
**Джерела:**
- A: `docs/architecture_inventory/inventory_services.csv` → поле `type` (DEPLOYED/DEFINED/...)
- B: всі `docker-compose*.yml` у repo root + `infra/compose/docker-compose.yml`
**Findings:**
| ID | Severity | Умова |
|----|----------|-------|
| `DRIFT-SVC-001` | error | Сервіс `DEPLOYED` у catalog, але відсутній в compose |
| `DRIFT-SVC-002` | warning | Сервіс є в compose, але не в catalog |
**Normalization:** `my-svc``my_svc` (dash/underscore equivalence).
---
### 2. openapi — API Spec vs Code Routes
**Джерела:**
- A: `docs/contracts/*.openapi.yaml` та будь-які `openapi*.yaml/yml/json` у repo
- B: Python файли — `@app.get(...)`, `@router.post(...)`, `.add_api_route(...)`
**Findings:**
| ID | Severity | Умова |
|----|----------|-------|
| `DRIFT-OAS-001` | error | Path у OpenAPI spec але не знайдено в коді |
| `DRIFT-OAS-002` | error | Path `/v1/*` є в коді але не описаний у spec |
| `DRIFT-OAS-003` | warning | Method mismatch для тієї самої path |
**Normalization:** trailing slash, lowercase path comparison.
**Скоп коду:** тільки `/v1/` routes перевіряються для OAS-002.
---
### 3. nats — Subject Inventory vs Code Usage
**Джерела:**
- A: `docs/architecture_inventory/inventory_nats_topics.csv` (поле `subject`)
- B: regex пошук `nc.publish(...)`, `nc.subscribe(...)`, `subject=...` у `.py` файлах
**Findings:**
| ID | Severity | Умова |
|----|----------|-------|
| `DRIFT-NATS-001` | warning | Subject використовується в коді але відсутній у inventory |
| `DRIFT-NATS-002` | info | Subject у inventory але не знайдено в коді (можливо legacy) |
**Wildcard matching:** `agent.run.{agent_id}``agent.run.*``agent.run.>`.
**Skipped:** якщо `inventory_nats_topics.csv` відсутній — категорія `skipped`, gate не падає.
---
### 4. tools — Rollout/Matrix vs Handlers
**Джерела:**
- A: `config/tools_rollout.yml` (всі tool-назви у groups, з @group expand)
- B: `config/rbac_tools_matrix.yml` (секція `tools:`)
- C: `KNOWN_TOOL_HANDLERS` у `drift_analyzer.py` (compile-time список)
- D: `agent_tools_config.effective_tools` для ролей `agent_default` і `agent_cto`
**Findings:**
| ID | Severity | Умова |
|----|----------|-------|
| `DRIFT-TOOLS-001` | error | Tool у rollout але нема handler |
| `DRIFT-TOOLS-002` | warning | Handler є але tool відсутній у RBAC matrix |
| `DRIFT-TOOLS-003` | warning | Tool у matrix але ніколи не потрапляє в effective_tools |
**Maintenance:** при додаванні нового tool handler — оновіть `KNOWN_TOOL_HANDLERS` у `drift_analyzer.py`.
---
## Безпека
- **Read-only:** не записує нічого у repo
- **Path traversal:** сканує тільки всередині `REPO_ROOT`
- **Excluded dirs:** `node_modules`, `.git`, `venv*`, `__pycache__`, `dist`, `build`, `rollback_backups`
- **File size limit:** max 256KB per file
- **File count limit:** max 300 files per category scan
- **Secret redaction:** evidence маскується `_redact_evidence()` перед поверненням
- **Governance:** проходить через `ToolGovernance.pre_call/post_call` (RBAC, limits, audit)
---
## RBAC Entitlements
| Entitlement | Хто | Що дозволяє |
|-------------|-----|-------------|
| `tools.drift.read` | `agent_cto`, `agent_oncall` | Запускати drift analyze |
| `tools.drift.gate` | `agent_cto` | Запускати drift у release gate |
---
## Limits (`config/tool_limits.yml`)
| Параметр | Значення |
|----------|----------|
| `timeout_ms` | 30 000 (30s) |
| `max_chars_in` | 5 000 |
| `max_bytes_out` | 524 288 (512KB) |
| `rate_limit_rpm` | 5 |
| `concurrency` | 1 |
---
## Оновлення `KNOWN_TOOL_HANDLERS`
Коли додається новий tool handler у `tool_manager.py`:
1. Додай tool name до `KNOWN_TOOL_HANDLERS` у `drift_analyzer.py`
2. Додай tool до `config/tools_rollout.yml` (потрібна роль)
3. Додай tool до `config/rbac_tools_matrix.yml` (actions + entitlements)
4. Запусти `pytest tests/test_drift_analyzer.py::TestToolsDrift` щоб перевірити
```python
# drift_analyzer.py
KNOWN_TOOL_HANDLERS: FrozenSet[str] = frozenset({
...,
"my_new_tool", # add here
})
```
---
## Файли
| Файл | Призначення |
|------|-------------|
| `services/router/drift_analyzer.py` | Вся логіка аналізу (4 категорії) |
| `services/router/tool_manager.py` | Handler `_drift_analyzer_tool` + TOOL_DEFINITIONS |
| `services/router/release_check_runner.py` | Gate 6 `_run_drift()` |
| `config/tools_rollout.yml` | `cto_tools` включає `drift_analyzer_tool` |
| `config/rbac_tools_matrix.yml` | `drift_analyzer_tool` actions + `tools.drift.*` entitlements |
| `config/tool_limits.yml` | `drift_analyzer_tool` limits |
| `tests/test_drift_analyzer.py` | 29 тестів + fixtures |