feat: Node Self-Healing, DAGI Audit, Agent Prompts, Infra Invariants

### Backend (city-service)
- Node Registry + Self-Healing API (migration 039)
- Improved get_all_nodes() with robust fallback for node_registry/node_cache
- Agent Prompts Runtime API for DAGI Router integration
- DAGI Router Audit endpoints (phantom/stale detection)
- Node Agents API (Guardian/Steward)
- Node metrics extended (CPU/GPU/RAM/Disk)

### Frontend (apps/web)
- Node Directory with improved error handling
- Node Cabinet with metrics cards
- DAGI Router Card component
- Node Metrics Card component
- useDAGIAudit hook

### Scripts
- check-invariants.py - deploy verification
- node-bootstrap.sh - node self-registration
- node-guardian-loop.py - continuous self-healing
- dagi_agent_audit.py - DAGI audit utility

### Migrations
- 034: Agent prompts seed
- 035: Agent DAGI audit
- 036: Node metrics extended
- 037: Node agents complete
- 038: Agent prompts full coverage
- 039: Node registry self-healing

### Tests
- test_infra_smoke.py
- test_agent_prompts_runtime.py
- test_dagi_router_api.py

### Documentation
- DEPLOY_CHECKLIST_2024_11_30.md
- Multiple TASK_PHASE docs
This commit is contained in:
Apple
2025-11-30 13:52:01 -08:00
parent 0c7836af5a
commit bca81dc719
36 changed files with 10630 additions and 55 deletions

View File

@@ -0,0 +1,66 @@
-- Migration 035: Agent DAGI Audit Fields
-- Поля для відстеження активності агентів в DAGI Router
-- ============================================================================
-- Додати поля для аудиту
-- ============================================================================
-- last_seen_at — останній раз коли агента бачив DAGI Router
ALTER TABLE agents ADD COLUMN IF NOT EXISTS last_seen_at timestamptz;
-- dagi_status — статус в контексті DAGI Router
-- active: агент активний в Router і БД
-- stale: агент є в БД, але не відповідає в Router
-- phantom: агент є в Router, але немає в БД (не зберігається в БД)
-- error: помилка при перевірці
ALTER TABLE agents ADD COLUMN IF NOT EXISTS dagi_status text
CHECK (dagi_status IS NULL OR dagi_status IN ('active', 'stale', 'error'));
-- Індекс для швидкого пошуку по dagi_status
CREATE INDEX IF NOT EXISTS idx_agents_dagi_status ON agents(dagi_status) WHERE dagi_status IS NOT NULL;
-- Індекс для пошуку агентів що давно не відповідали
CREATE INDEX IF NOT EXISTS idx_agents_last_seen ON agents(last_seen_at) WHERE last_seen_at IS NOT NULL;
-- ============================================================================
-- Таблиця для зберігання історії аудитів
-- ============================================================================
CREATE TABLE IF NOT EXISTS dagi_audit_reports (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
node_id text NOT NULL,
timestamp timestamptz NOT NULL DEFAULT now(),
-- Summary
router_total integer NOT NULL DEFAULT 0,
db_total integer NOT NULL DEFAULT 0,
active_count integer NOT NULL DEFAULT 0,
phantom_count integer NOT NULL DEFAULT 0,
stale_count integer NOT NULL DEFAULT 0,
-- Детальний звіт (JSON)
report_data jsonb,
-- Метадані
triggered_by text, -- 'cron', 'manual', 'api'
created_at timestamptz NOT NULL DEFAULT now()
);
-- Індекс по ноді та часу
CREATE INDEX IF NOT EXISTS idx_dagi_audit_node_time
ON dagi_audit_reports(node_id, timestamp DESC);
-- ============================================================================
-- Коментарі
-- ============================================================================
COMMENT ON COLUMN agents.last_seen_at IS 'Last time this agent was seen active in DAGI Router';
COMMENT ON COLUMN agents.dagi_status IS 'Current status in DAGI ecosystem: active, stale, error';
COMMENT ON TABLE dagi_audit_reports IS 'History of DAGI agent audit reports per node';
-- ============================================================================
-- Результат
-- ============================================================================
SELECT 'Migration 035 completed: DAGI audit fields added' AS result;