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
This commit is contained in:
Apple
2026-03-03 07:14:53 -08:00
parent 129e4ea1fc
commit 67225a39fa
102 changed files with 20060 additions and 0 deletions

277
docs/tools/governance.md Normal file
View File

@@ -0,0 +1,277 @@
# Tool Governance
**Система керування інструментами DAARION.city**
Версія: 2.0 | Нода: NODE2 (розробка) + NODA1 (production)
---
## Огляд
Tool Governance — єдина система контролю над усіма tool-викликами агентів.
Складається з чотирьох компонентів:
| Компонент | Файл | Що робить |
|-----------|------|-----------|
| **Rollout Policy** | `config/tools_rollout.yml` | Визначає, які tools отримує кожен агент за роллю |
| **RBAC Matrix** | `config/rbac_tools_matrix.yml` | Матриця `tool → action → entitlement → role` |
| **Safety Middleware** | `services/router/tool_governance.py` | Limits, redaction, allowlist, audit |
| **Release Gate** | `ops/task_registry.yml` + `services/router/release_check_runner.py` | Єдиний release verdict |
---
## 1. Global Tools Rollout
### 1.1 Merge Policy
```
effective_tools = unique(DEFAULT_TOOLS_BY_ROLE FULL_STANDARD_STACK agent.specialized_tools)
```
Кожен агент **автоматично** отримує набір tools відповідно до ролі — без необхідності явно вказувати їх.
### 1.2 Конфіг (`config/tools_rollout.yml`)
```yaml
# Групи tools
default_tools_read:
- repo_tool
- kb_tool
- oncall_tool
- observability_tool
...
cto_tools:
- pr_reviewer_tool
- contract_tool
- config_linter_tool
- threatmodel_tool
- job_orchestrator_tool
# Ролі → групи
role_map:
agent_default:
tools: ["@default_tools_read", "@content_tools"]
agent_cto:
tools: ["@default_tools_read", "@cto_tools", "@content_tools", "@media_tools"]
agent_oncall:
tools: ["@default_tools_read", "job_orchestrator_tool"]
# Агент → роль
agent_roles:
sofiia: agent_cto
helion: agent_oncall
alateya: agent_media
```
### 1.3 Ролі
| Роль | Хто | Набір |
|------|-----|-------|
| `agent_cto` | sofiia, yaromir | Все: read + cto + content + media |
| `agent_oncall` | helion | Read + job_orchestrator |
| `agent_media` | alateya, nutra, agromatrix, greenfood... | Read + content + media |
| `agent_default` | всі інші / нові агенти | Read + content |
### 1.4 Розширення груп (`@group`)
`@group_name` у конфігу розгортається рекурсивно. Підтримуються вкладені групи:
```yaml
my_super_group:
- "@cto_tools"
- "@media_tools"
- custom_tool
```
### 1.5 Як перевірити tools агента
```python
from agent_tools_config import get_agent_tools, get_agent_role
tools = get_agent_tools("sofiia") # → список всіх tools
role = get_agent_role("sofiia") # → "agent_cto"
```
**Acceptance**: новий агент без явного `tools` отримує read-набір автоматично.
---
## 2. RBAC Matrix
### 2.1 Структура (`config/rbac_tools_matrix.yml`)
```yaml
tools:
pr_reviewer_tool:
actions:
review:
entitlements: ["tools.pr_review.use"]
gate:
entitlements: ["tools.pr_review.gate"]
role_entitlements:
agent_cto:
- tools.pr_review.use
- tools.pr_review.gate
...
agent_default:
- tools.repo.read
- tools.kb.read
...
```
### 2.2 Enforcement Flow
```
execute_tool(tool, action, agent_id)
→ get_agent_role(agent_id) → "agent_cto"
→ get_role_entitlements(role) → ["tools.pr_review.use", ...]
→ get_required_entitlements(tool, action) → ["tools.pr_review.gate"]
→ missing = required - agent_ents
→ if missing: DENY
```
### 2.3 Entitlement схема
```
tools.<tool_short>.<scope>
Приклади:
tools.repo.read
tools.oncall.incident_write
tools.pr_review.gate
tools.jobs.run.deploy
```
### 2.4 Перевірка вручну
```python
from tool_governance import check_rbac
ok, reason = check_rbac("sofiia", "pr_reviewer_tool", "gate")
# → (True, "")
ok, reason = check_rbac("helion", "pr_reviewer_tool", "gate")
# → (False, "Missing entitlements: ['tools.pr_review.gate']")
```
**Acceptance**: всі tool handlers використовують матрицю — жодного хардкоду прав у коді.
---
## 3. Tool Safety Middleware
Реалізовано у `services/router/tool_governance.py`.
Застосовується автоматично до **кожного** `execute_tool(...)` виклику.
### 3.1 Limits (`config/tool_limits.yml`)
| Параметр | Опис |
|----------|------|
| `timeout_ms` | Максимальний час виконання |
| `max_chars_in` | Максимальна довжина вхідного тексту |
| `max_bytes_out` | Максимальний розмір відповіді |
| `rate_limit_rpm` | Запитів на хвилину |
| `concurrency` | Паралельних викликів |
Приклад:
```yaml
pr_reviewer_tool:
timeout_ms: 60000 # 60s
max_chars_in: 409600 # 400KB
rate_limit_rpm: 10
```
### 3.2 Redaction
Модуль `redact(text)` у `tool_governance.py` маскує:
- API ключі (`api_key=***REDACTED***`)
- Токени (`token=***REDACTED***`)
- Паролі (`password=***REDACTED***`)
- Bearer tokens, JWT, OAuth secrets, private keys
Застосовується до:
- Evidence/snippets у результатах pr_reviewer_tool
- Evidence у config_linter_tool
- Log lines у observability_tool
**Включено за замовчуванням.** Вимкнути: `ToolGovernance(enable_redaction=False)`.
### 3.3 Network Allowlist (`config/network_allowlist.yml`)
Tools, що роблять HTTP-запити, обмежені allowlist:
```python
from tool_governance import check_url_allowed
ok, reason = check_url_allowed("oncall_tool", "http://localhost:9102/health")
# → (True, "")
ok, reason = check_url_allowed("oncall_tool", "http://evil.com/steal")
# → (False, "Host 'evil.com' not in allowlist for tool 'oncall_tool'")
```
`web_extract` та `crawl4ai_scrape` мають `allow_any_public: true` але блокують private IPs (RFC1918/loopback).
### 3.4 Audit Events
На кожен tool-виклик емітується structured event у log:
```json
{
"ts": "2026-02-23T12:00:00Z",
"req_id": "abc123def456",
"tool": "pr_reviewer_tool",
"action": "review",
"workspace_id": "default",
"user_id": "user_123",
"agent_id": "sofiia",
"status": "pass",
"duration_ms": 234.5,
"limits_applied": {"timeout_ms": 60000, "max_chars_in": 409600},
"input_hash": "a1b2c3d4e5f6",
"input_chars": 1024,
"output_size_bytes": 2048
}
```
**Payload не логується** — тільки hash та розміри.
Log prefix: `TOOL_AUDIT`.
### 3.5 Integration у `execute_tool`
```python
# В tool_manager.py, автоматично:
governance = get_governance()
pre = governance.pre_call(tool, action, agent_id, user_id, workspace_id, input_text)
if not pre.allowed:
return ToolResult(success=False, error=pre.reason)
result = await _handler(args) # actual tool execution
governance.post_call(pre.call_ctx, result.result, error=result.error)
```
---
## 4. Налаштування та Hot-Reload
```python
# Force reload конфігів (без перезапуску)
from agent_tools_config import reload_rollout_config
from tool_governance import _reload_yaml_cache
reload_rollout_config()
_reload_yaml_cache()
```
---
## 5. Acceptance Criteria
- ✅ Новий агент без явного `tools` отримує read-набір автоматично
- ✅ Sofiia/CTO має повний набір через роль `agent_cto`
- ✅ Будь-який tool call проходить через middleware (limits/redaction/audit)
- ✅ RBAC денить без entitlement, без хардкоду в коді
- ✅ Allowlist блокує довільні URL для HTTP-tools
- ✅ 31/31 тест проходить