feat(platform): add new services, tools, tests and crews modules

New router intelligence modules (26 files): alert_ingest/store, audit_store,
architecture_pressure, backlog_generator/store, cost_analyzer, data_governance,
dependency_scanner, drift_analyzer, incident_* (5 files), llm_enrichment,
platform_priority_digest, provider_budget, release_check_runner, risk_* (6 files),
signature_state_store, sofiia_auto_router, tool_governance

New services:
- sofiia-console: Dockerfile, adapters/, monitor/nodes/ops/voice modules, launchd, react static
- memory-service: integration_endpoints, integrations, voice_endpoints, static UI
- aurora-service: full app suite (analysis, job_store, orchestrator, reporting, schemas, subagents)
- sofiia-supervisor: new supervisor service
- aistalk-bridge-lite: Telegram bridge lite
- calendar-service: CalDAV calendar service with reminders
- mlx-stt-service / mlx-tts-service: Apple Silicon speech services
- binance-bot-monitor: market monitor service
- node-worker: STT/TTS memory providers

New tools (9): agent_email, browser_tool, contract_tool, observability_tool,
oncall_tool, pr_reviewer_tool, repo_tool, safe_code_executor, secure_vault

New crews: agromatrix_crew (10 modules: depth_classifier, doc_facts, doc_focus,
farm_state, light_reply, llm_factory, memory_manager, proactivity, reflection_engine,
session_context, style_adapter, telemetry)

Tests: 85+ test files for all new modules
Made-with: Cursor
This commit is contained in:
Apple
2026-03-03 07:14:14 -08:00
parent e9dedffa48
commit 129e4ea1fc
241 changed files with 69349 additions and 0 deletions

View File

@@ -0,0 +1,117 @@
"""
Telemetry helpers для Humanized Stepan v2.7.2.
Забезпечує єдиний тег AGX_STEPAN_METRIC на всіх ключових лог-рядках
і PII-safe анонімізацію ідентифікаторів.
Grep у проді:
grep "AGX_STEPAN_METRIC" /logs/gateway.log
Формат рядка:
AGX_STEPAN_METRIC <event> key=value key2=value2
PII-safe:
- Ключі з pii_keys (default: {"user_id","chat_id"}) автоматично анонімізуються:
user_id=h:3f9a12b4c7 (sha256 перших 10 hex-символів)
- Дає можливість корелювати події одного користувача без прямого витоку.
- Не є криптографічним захистом проти таргетованого знання.
Правила серіалізації:
- bool → "true" / "false"
- int/float → str
- list → елементи через кому
- dict → компактний JSON
- None → "null"
- Нічого з секретів/токенів не передавати у kv.
"""
from __future__ import annotations
import hashlib
import json
import logging
from typing import Any
TELEMETRY_TAG = "AGX_STEPAN_METRIC"
# Ключі, які автоматично анонімізуються у tlog()
_DEFAULT_PII_KEYS: frozenset[str] = frozenset({"user_id", "chat_id"})
def anonymize_id(value: str | None) -> str | None:
"""
Повертає PII-safe псевдонім для ідентифікатора.
Правила:
- None → None
- Пусте рядок → повернути як є (нема що хешувати)
- Інакше: "h:" + sha256(value)[:10]
Формат стабільний: завжди 12 символів ("h:" + 10 hex).
Колізії теоретично можливі, але практично нереальні для user_id-просторів.
Приклади:
anonymize_id("123456789") → "h:3f9a12b4c7"
anonymize_id(None) → None
anonymize_id("") → ""
"""
if value is None:
return None
if not value:
return value
try:
digest = hashlib.sha256(value.encode()).hexdigest()
return f"h:{digest[:10]}"
except Exception:
return "h:error"
def _fmt_value(v: Any) -> str:
if isinstance(v, bool):
return str(v).lower()
if isinstance(v, (int, float)):
return str(v)
if v is None:
return "null"
if isinstance(v, list):
return ",".join(str(i) for i in v)
if isinstance(v, dict):
return json.dumps(v, ensure_ascii=False, separators=(",", ":"))
return str(v)
def tlog(
logger: logging.Logger,
msg: str,
level: int = logging.INFO,
pii_keys: frozenset[str] | set[str] = _DEFAULT_PII_KEYS,
**kv: Any,
) -> None:
"""
Логує рядок з уніфікованим тегом AGX_STEPAN_METRIC і PII-safe анонімізацією.
Приклади:
tlog(logger, "depth", depth="light", reason="greeting")
"AGX_STEPAN_METRIC depth depth=light reason=greeting"
tlog(logger, "memory_save", user_id="123456789", ok=True)
"AGX_STEPAN_METRIC memory_save user_id=h:3f9a12b4c7 ok=true"
Ключі в pii_keys автоматично анонімізуються через anonymize_id().
Безпечний: всі помилки форматування ігноруються — fallback без kv.
"""
try:
parts: list[str] = []
for k, v in kv.items():
if k in pii_keys:
anon = anonymize_id(str(v) if v is not None else None)
parts.append(f"{k}={_fmt_value(anon)}")
else:
parts.append(f"{k}={_fmt_value(v)}")
kv_str = " ".join(parts)
line = f"{TELEMETRY_TAG} {msg}"
if kv_str:
line = f"{line} {kv_str}"
except Exception:
line = f"{TELEMETRY_TAG} {msg}"
logger.log(level, line)