Skip to content

feat(hermes): ADR-018 Hermes Agent (Nous Research) integration Phase 1 - #63

Open
UNIFY-MC wants to merge 4 commits into
mainfrom
feat/adr-018-hermes-integration
Open

feat(hermes): ADR-018 Hermes Agent (Nous Research) integration Phase 1#63
UNIFY-MC wants to merge 4 commits into
mainfrom
feat/adr-018-hermes-integration

Conversation

@UNIFY-MC

Copy link
Copy Markdown
Owner

Resumo

  • ADR-018 DRAFT — Decisão arquitectural sobre integração do Hermes Agent (Nous Research) como executor externo de recipes CookAI (5002c41).
  • Migration Phase 1Asystem.api_keys + iam.permission_groups (hermes_executor) + 8 permission_sections + 8 permission_grants whitelist + RPC iam.api_key_can(api_key_id, section, action) (dd100b5).
  • Mirror fix migration202605240101 sincroniza DB → git (search_path da RPC inclui extensions para evitar regressão futura) (02aa424).
  • Edge Function hermes-invoke-recipe — entry point HTTP que valida X-API-Key, resolve api_key_id, chama iam.api_key_can() e despacha para a recipe pedida (a8aa8ab).

Estado actual em produção

Tudo aplicado em V1 Core Hub (hkmvszkpxjbxmnixzqbl) em modo seguro:

Componente Estado Notas
system.api_keys (Hermes row) active = false Placeholder, sem hash real — bloqueia execução
iam.permission_groups (hermes_executor) Activo Whitelist de 8 sections (read-only sobre recipes/skills/missions + execute recipe)
RPC iam.api_key_can() Security definer search_path = iam, system, public, extensions
Edge Function hermes-invoke-recipe v1 ACTIVE (cedcf76e-eb49-4330-a01a-9508617b4c80) verify_jwt = false (auth via X-API-Key)

Como active = false e não há hash real, qualquer chamada actual à EF devolve 401/403 — não há risco de execução não autorizada.

Pendente para @mario

  1. Gerar API key real localmente:
    openssl rand -hex 32
  2. Calcular hash (sha256) e fazer UPDATE em system.api_keys:
    UPDATE system.api_keys
    SET key_hash = '<sha256-da-key>',
        active = true,
        activated_at = now()
    WHERE name = 'hermes-agent-primary';
  3. Setup do Hermes host (Nous Research) com a key plaintext em variável de ambiente segura (nunca commitar).
  4. Smoke test end-to-end (ver checklist abaixo).

Test plan

Validation queries (SQL Editor V1 Core Hub)

  • Confirmar row placeholder existe e está inactiva:
    SELECT id, name, active, key_hash IS NULL AS sem_hash
    FROM system.api_keys
    WHERE name = 'hermes-agent-primary';
  • Confirmar grupo + 8 grants:
    SELECT pg.name, COUNT(*) AS grants
    FROM iam.permission_groups pg
    JOIN iam.permission_grants g ON g.group_id = pg.id
    WHERE pg.name = 'hermes_executor'
    GROUP BY pg.name;
    -- esperado: hermes_executor | 8
  • Confirmar RPC tem search_path correcto:
    SELECT proname, proconfig
    FROM pg_proc
    WHERE proname = 'api_key_can'
      AND pronamespace = 'iam'::regnamespace;
    -- esperado: proconfig contém search_path=iam, system, public, extensions

Edge Function smoke test (após gerar key real)

  • Chamar EF sem X-API-Key401.
  • Chamar EF com X-API-Key inválido → 401.
  • Chamar EF com key válido mas section/action fora da whitelist → 403.
  • Chamar EF com key válido + section/action permitido (ex: cookai.recipes / read) → 200.
  • Verificar audit trail em iam.activity_logs (ou equivalente) após chamada bem-sucedida.

Gate de merge

  • Vercel Preview build OK (sem impacto esperado — apenas docs/EF/migrations, sem apps/).
  • Validation queries acima retornam o esperado.
  • Mário valida ADR-018 (DRAFT → ACCEPTED) ou pede alterações.

Refs

  • ADR-018 — .claude/strategy/adrs/ADR-018-hermes-agent-integration.md (DRAFT)
  • ADR-013 — IAM cross-vertical pattern reutilizado para hermes_executor
  • Memory — project-hermes-agent-nous (contexto Nous Research)
  • Migrations — supabase/migrations/202605240100_*.sql + 202605240101_*.sql (mirror fix)
  • Edge Function — supabase/functions/hermes-invoke-recipe/

🤖 Generated with Claude Code

UNIFY-MC and others added 4 commits May 24, 2026 02:45
Documenta integração formal do Hermes Agent (self-hosted Nous Research v0.14.0)
como executivo externo do Mário, complementar aos CookAI agents internos.

Status: Draft (aguarda 4 decisões finais Mário)
  - D2 ✅ Confirmado: VPS Ubuntu Hetzner CAX11 (~€3.79/mês) + Anthropic API direct
  - D3 confirma via Discord Developer Portal (bot Hermes separado de property007)
  - D4 [PENDING]: memory model interno (built-in v0.14.0 / Letta / Mem0 / pgvector / a descobrir)
  - D6 [PENDING]: split detalhado 20 tarefas Hermes vs CookAI agents tabulado

Decisões CONFIRMADAS:
  D1 — Hermes externo ao monorepo (não copiar para apps/)
  D2 — Hetzner CAX11 ARM EU recomendado (~€10-25/mês total Hermes operacional)
  D5 — Hermes invoca CookAI via Edge Function 'hermes-invoke-recipe' com:
       * system.api_keys row 'hermes_executor' + iam.permission_grants whitelist
       * 7 RPCs whitelisted (get_record_summary, list_records, search_records,
         get_activity_timeline, create_task, queue_approval, ask_property007_intent)
  D7 — 5 padrões canónicos agente↔Hermes:
       1) Hermes orquestra → CookAI executa
       2) CookAI escala → Hermes notifica Mário (Discord)
       3) Hermes detecta padrão → propõe nova skill CookAI
       4) Hermes faz Truth Engine query → consume swarm_discoveries
       5) Hermes acede activity_unified para context cross-vertical
  D8 — Bia deprecada (ARCH-002 brownfield); Mia mantém papel especializado V5

Custos totais estimados Hermes operacional: ~€10-25/mês
(vs €500-2000/mês de managed agents enterprise — savings dramáticos via self-host).

Implementação Phase 1 (próximo commit):
  - migration: system.api_keys + iam.permission_grants seed Hermes
  - Edge Function: hermes-invoke-recipe (wrapper REST whitelist 7 RPCs)
  - smoke test E2E

Refs: ADR-010, ADR-011, ADR-013, ADR-V11-004, ADR-V11-005, ADR-017,
      ARCH-002 brownfield, project-hermes-agent-nous memory

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
… Phase 1A]

Phase 1 Step A do ADR-018 — infraestrutura para Hermes Agent (Nous Research)
invocar CookAI recipes via Supabase REST API.

ADR-018 update — D5 CORRIGIDO:
  Proposta original tinha api_key_id em iam.permission_grants — INCORRECTA.
  iam.permission_grants tem PK (group_code, section_code) — não suporta api_key_id.
  Solução adoptada (coerente com iam.staff_login_aliases pattern):
    system.api_keys.permission_group_code → iam.permission_groups.code
  Bridge: RPC iam.api_key_can(p_api_key, p_section, p_action) → boolean

Migration 202605240100_hermes_api_key.sql (486 linhas):
  PARTE A — CREATE TABLE system.api_keys (14 colunas, 3 RLS policies staff_only,
           3 indexes, trigger updated_at, service_role bypass)
  PARTE B — INSERT iam.permission_groups: 'hermes_executor'
  PARTE C — INSERT iam.permission_sections (8 rows, idempotente via ON CONFLICT):
           system.recipes_exec, system.tasks_create, core.{pessoas,empresas,
           imoveis,condominios,activity_unified}_read, system.swarm_discoveries_read
  PARTE D — INSERT iam.permission_grants (8 rows whitelist hermes_executor):
           recipes_exec + tasks_create can_create=true,
           restantes 6 só can_view=true (least-privilege)
  PARTE E — CREATE FUNCTION iam.api_key_can(text,text,text):
           SECURITY DEFINER, GRANT EXECUTE TO service_role only
           Hash bcrypt via pgcrypto crypt() match
  PARTE F — INSERT system.api_keys row placeholder:
           name='hermes_executor', api_key_hash='\$PENDING\$', active=false
           (Mário gera key real via bash script + UPDATE manual após apply)

Idempotente: todos CREATE IF NOT EXISTS + ON CONFLICT DO NOTHING.
Reversível: DROP TABLE + DELETE rows.
RGPD: api_key_hash bcrypt 10 rounds, plaintext nunca persistido.
0 GRANT anon (Regra X).

Phase 1 Step B (próximo commit): Edge Function hermes-invoke-recipe.

Refs: ADR-018, ADR-013 IAM pattern, ARCH-002 Bia→Mia rename relacionado

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…18 Phase 1A]

Fix migration foi aplicada em V1 (hkmvszkpxjbxmnixzqbl) durante apply Phase 1A
porque pgcrypto.crypt() está em schema 'extensions' (não 'public'). RPC iam.api_key_can
falhava silenciosamente sem este fix.

Este commit cria o ficheiro mirror local para evitar DB-003 (215 migrations remotas
sem ficheiro git) brownfield Critical. Source SQL recuperado via
execute_sql FROM supabase_migrations.schema_migrations WHERE name LIKE 'hermes_api_key%'.

Conteúdo:
  - CREATE OR REPLACE FUNCTION iam.api_key_can com SET search_path = iam, system, extensions, public
  - Qualifica extensions.crypt() explicitamente (defesa em profundidade)
  - REVOKE ALL FROM public/anon/authenticated + GRANT EXECUTE TO service_role

Forward-only. Idempotente (CREATE OR REPLACE). Validado em DB:
  SELECT iam.api_key_can('any', 'system.recipes_exec', 'create') → false (placeholder).

Refs: ADR-018, DB-003 brownfield, supabase-designer session
Wrapper REST para Hermes Agent (Nous Research) invocar CookAI recipes via API.

Fluxo:
  1. POST com x-api-key header + body { recipe_slug | recipe_id, payload, idempotency_key? }
  2. Valida via RPC iam.api_key_can('system.recipes_exec', 'create') → 403 se inválida
  3. Resolve recipe (slug→id) + valida status='active' → 404/409 se não
  4. Idempotência: tasks últimas 24h com tag 'idempotency:<key>' → devolve existing se duplicate
  5. Cria system.tasks via RPC system.task_create (kind='task' + tag 'recipe_invoke')
  6. Devolve 202 Accepted com { task_id, recipe_slug, status: 'queued', idempotency_key }

Auth: verify_jwt=false (custom via x-api-key).
Pattern D7-1 do ADR-018: Hermes orquestra → CookAI executa.
Audit: cada invocação loga via trigger de system.task_create → core.agent_audit_log.

Constraints respeitadas:
  - kind='task' (existing constraint) + tag 'recipe_invoke' para distinção
  - TODO Phase 1B+1: expandir tasks_kind_check para incluir 'recipe_invoke'
  - 0 GRANT anon (Regra X) — todos os RPCs invocados são SECURITY DEFINER service_role
  - CORS configurado mas restritivo
  - 5 error codes claros (401/400/403/404/409/500)

Phase 1 Step C (próximo): smoke test E2E.

Refs: ADR-018 D5 + D7-1, ARCH-002 brownfield

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@vercel

vercel Bot commented May 24, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
proptech-agentic-ops Error Error May 24, 2026 2:06am
proptech-v5-alpha Error Error May 24, 2026 2:06am

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant