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

8.5 KiB
Raw Permalink Blame History

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

{
  "action": "analyze",
  "categories": ["services", "openapi", "nats", "tools"],
  "timeout_sec": 25
}

Через release_check (Gate 6, optional)

{
  "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)

Формат відповіді

{
  "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-svcmy_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 щоб перевірити
# 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