.agent/validar-setup.sh

250 lines
11 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
# ==============================================================================
# Script de Governança: Validar Setup Multi-Projeto (.agent)
# Valida a conformidade de qualquer projeto hospedeiro com os 6 pilares DDD
# e audita o agnosticismo do submódulo .agent.
# ==============================================================================
set -e
# Cores para saída no terminal
VERDE="\033[0;32m"
AMARELO="\033[1;33m"
VERMELHO="\033[0;31m"
AZUL="\033[0;34m"
NEGRITO="\033[1m"
RESET="\033[0m"
# Identificar a raiz do projeto pai
if [ -d "memorias-ia" ] || [ -f "memorias-ia/modulo.yml" ] || [ -f "package.json" ]; then
ROOT_DIR="."
elif [ -d "../memorias-ia" ] || [ -f "../memorias-ia/modulo.yml" ] || [ -f "../package.json" ]; then
ROOT_DIR=".."
else
ROOT_DIR="."
fi
echo -e "${AZUL}${NEGRITO}======================================================${RESET}"
echo -e "${AZUL}${NEGRITO}🔍 Auditoria de Setup Multi-Projeto (.agent)${RESET}"
echo -e "${AZUL}${NEGRITO}======================================================${RESET}"
TOTAL_ERROS=0
TOTAL_AVISOS=0
# 0. Validar Submódulo .agent e tracking da branch master
echo -e "\n${NEGRITO}[0/6] Submódulo .agent (Sincronização, Branch Master & Agnosticismo)${RESET}"
if [ -f "$ROOT_DIR/.gitmodules" ]; then
if grep -q '\[submodule "\.agent"\]' "$ROOT_DIR/.gitmodules"; then
echo -e " ${VERDE}✓${RESET} Submódulo .agent configurado em .gitmodules."
SUBMODULE_BRANCH=$(git -C "$ROOT_DIR" config -f .gitmodules submodule..agent.branch 2>/dev/null || true)
if [ "$SUBMODULE_BRANCH" = "master" ]; then
echo -e " ${VERDE}✓${RESET} Submódulo configurado para rastrear branch: ${NEGRITO}master${RESET}"
else
echo -e " ${AMARELO}⚠${RESET} Submódulo .agent não possui 'branch = master' configurado no .gitmodules."
echo -e " Execute: git submodule set-branch --branch master .agent"
TOTAL_AVISOS=$((TOTAL_AVISOS + 1))
fi
else
echo -e " ${VERMELHO}✗${RESET} Entrada do submódulo .agent não encontrada em .gitmodules."
TOTAL_ERROS=$((TOTAL_ERROS + 1))
fi
else
echo -e " ${AMARELO}⚠${RESET} Arquivo .gitmodules não encontrado na raiz."
fi
# Verificar sincronismo interno das pastas espelhadas do .agent
if [ -d "$ROOT_DIR/.agent/rules" ] && [ -d "$ROOT_DIR/.agent/global/rules" ]; then
if diff -rq "$ROOT_DIR/.agent/rules" "$ROOT_DIR/.agent/global/rules" >/dev/null 2>&1 && \
diff -rq "$ROOT_DIR/.agent/skills" "$ROOT_DIR/.agent/global/skills" >/dev/null 2>&1; then
echo -e " ${VERDE}✓${RESET} Artefatos internos do .agent (rules/ e skills/) 100% sincronizados."
else
echo -e " ${AMARELO}⚠${RESET} Divergência detectada entre rules/skills e global/ no .agent."
TOTAL_AVISOS=$((TOTAL_AVISOS + 1))
fi
fi
# Verificar agnosticismo polimórfico do .agent em relação ao modulo-id hospedeiro
HOST_MODULO_ID=$(grep -E "^modulo-id:" "$ROOT_DIR/memorias-ia/modulo.yml" 2>/dev/null | awk '{print $2}' || true)
if [ -n "$HOST_MODULO_ID" ] && [ -d "$ROOT_DIR/.agent/rules" ]; then
if grep -rnI -i "$HOST_MODULO_ID" "$ROOT_DIR/.agent/rules" "$ROOT_DIR/.agent/skills" "$ROOT_DIR/.agent/agents" >/dev/null 2>&1; then
echo -e " ${VERMELHO}✗${RESET} Violação de agnosticismo: modulo-id '$HOST_MODULO_ID' encontrado hardcoded dentro de .agent/."
TOTAL_ERROS=$((TOTAL_ERROS + 1))
else
echo -e " ${VERDE}✓${RESET} Agnosticismo verificado: zero menções ao módulo hospedeiro (${NEGRITO}$HOST_MODULO_ID${RESET}) em .agent/."
fi
fi
# Verificar runtime Bun e atualização diária (bun upgrade --stable)
export PATH="$HOME/.bun/bin:$PATH"
if command -v bun >/dev/null 2>&1; then
BUN_STAMP_FILE="/tmp/.antigravity_bun_upgrade_date"
TODAY=$(date +%Y-%m-%d)
LAST_BUN_CHECK=$(cat "$BUN_STAMP_FILE" 2>/dev/null || true)
if [ "$LAST_BUN_CHECK" != "$TODAY" ]; then
if bun upgrade --stable >/dev/null 2>&1; then
echo "$TODAY" > "$BUN_STAMP_FILE" 2>/dev/null || true
fi
fi
BUN_VER=$(bun --version 2>/dev/null || true)
echo -e " ${VERDE}✓${RESET} Runtime Bun verificado (${NEGRITO}v${BUN_VER}${RESET} — check diário: ${NEGRITO}bun upgrade --stable${RESET})."
else
echo -e " ${AMARELO}⚠${RESET} Runtime Bun não encontrado no PATH."
TOTAL_AVISOS=$((TOTAL_AVISOS + 1))
fi
# 1. Validar memorias-ia/modulo.yml (Pilar 6 - Identidade)
MODULO_YML="$ROOT_DIR/memorias-ia/modulo.yml"
echo -e "\n${NEGRITO}[1/6] Identidade do Módulo (memorias-ia/modulo.yml)${RESET}"
if [ -f "$MODULO_YML" ]; then
echo -e " ${VERDE}✓${RESET} Arquivo memorias-ia/modulo.yml encontrado."
# Validar as 4 chaves obrigatórias
MODULO_ID=$(grep -E "^modulo-id:" "$MODULO_YML" | awk '{print $2}' || true)
MODULO_CAMINHO=$(grep -E "^modulo-caminho:" "$MODULO_YML" | awk '{print $2}' || true)
MODULO_DESCRICAO=$(grep -E "^modulo-descricao:" "$MODULO_YML" || true)
MODULO_TIPO=$(grep -E "^modulo-tipo:" "$MODULO_YML" || true)
if [ -n "$MODULO_ID" ]; then
echo -e " ${VERDE}✓${RESET} modulo-id: ${NEGRITO}$MODULO_ID${RESET}"
else
echo -e " ${VERMELHO}✗${RESET} Chave 'modulo-id' ausente ou vazia."
TOTAL_ERROS=$((TOTAL_ERROS + 1))
fi
if [ -n "$MODULO_CAMINHO" ]; then
echo -e " ${VERDE}✓${RESET} modulo-caminho: ${NEGRITO}$MODULO_CAMINHO${RESET}"
else
echo -e " ${VERMELHO}✗${RESET} Chave 'modulo-caminho' ausente ou vazia."
TOTAL_ERROS=$((TOTAL_ERROS + 1))
fi
if [ -n "$MODULO_DESCRICAO" ]; then
echo -e " ${VERDE}✓${RESET} modulo-descricao configurada."
else
echo -e " ${VERMELHO}✗${RESET} Chave 'modulo-descricao' ausente."
TOTAL_ERROS=$((TOTAL_ERROS + 1))
fi
if [ -n "$MODULO_TIPO" ]; then
echo -e " ${VERDE}✓${RESET} modulo-tipo configurado."
else
echo -e " ${VERMELHO}✗${RESET} Chave 'modulo-tipo' ausente."
TOTAL_ERROS=$((TOTAL_ERROS + 1))
fi
# Validar modulo-acesso (credenciais de teste para automação e QA)
if grep -q "modulo-acesso:" "$MODULO_YML"; then
if grep -E -q "^\s+(interno|cliente|externo|anonimo):" "$MODULO_YML"; then
echo -e " ${VERDE}✓${RESET} modulo-acesso: credenciais multi-contexto configuradas (isolamento de tokens)."
else
echo -e " ${VERDE}✓${RESET} modulo-acesso: credenciais de teste configuradas."
fi
else
echo -e " ${AMARELO}⚠${RESET} modulo-acesso: credenciais de teste não configuradas em modulo.yml."
fi
# Resolver modulo-wiki (caminho da wiki com fallback mandatório para ../wiki)
MODULO_WIKI=$(grep -E "^modulo-wiki:" "$MODULO_YML" | awk '{print $2}' || true)
if [ -z "$MODULO_WIKI" ]; then
MODULO_WIKI="../wiki"
fi
echo -e " ${VERDE}✓${RESET} modulo-wiki resolvido: ${NEGRITO}$MODULO_WIKI${RESET}"
# Exibir convenção de sessão isolada para agent-browser
if [ -n "$MODULO_ID" ]; then
echo -e " ${AZUL}ℹ${RESET} Sessão agent-browser: agent-browser --session ${NEGRITO}${MODULO_ID}_<contexto?>${RESET}"
echo -e " Exemplos: ${MODULO_ID}_interno | ${MODULO_ID}_cliente | ${MODULO_ID}_externo | ${MODULO_ID}_anonimo"
fi
# Validar memorias-ia/historico-acoes.md (Pilar 6 - Índice de Ações)
HISTORICO_MD="$ROOT_DIR/memorias-ia/historico-acoes.md"
if [ -f "$HISTORICO_MD" ]; then
echo -e " ${VERDE}✓${RESET} Índice memorias-ia/historico-acoes.md encontrado."
else
echo -e " ${AMARELO}⚠${RESET} Arquivo memorias-ia/historico-acoes.md não encontrado."
echo -e " Execute: cp .agent/DOCUMENTACAO/templates/historico-acoes.md.template memorias-ia/historico-acoes.md"
TOTAL_AVISOS=$((TOTAL_AVISOS + 1))
fi
else
echo -e " ${VERMELHO}✗ CRÍTICO: Arquivo memorias-ia/modulo.yml NÃO encontrado!${RESET}"
echo -e " Execute: cp .agent/DOCUMENTACAO/templates/modulo.yml.template memorias-ia/modulo.yml"
TOTAL_ERROS=$((TOTAL_ERROS + 1))
fi
# 2. Validar Wiki do Usuário (Pilar 3)
echo -e "\n${NEGRITO}[2/6] Wiki do Usuário (Pilar 3)${RESET}"
if [ -n "$MODULO_ID" ]; then
WIKI_USER_DIR="$ROOT_DIR/$MODULO_WIKI/$MODULO_ID"
if [ -d "$WIKI_USER_DIR" ]; then
echo -e " ${VERDE}✓${RESET} Diretório encontrado em: $MODULO_WIKI/$MODULO_ID/"
elif [ -d "$ROOT_DIR/$MODULO_WIKI" ]; then
echo -e " ${VERDE}✓${RESET} Repositório de Wiki dedicado encontrado em: $MODULO_WIKI/"
else
echo -e " ${AMARELO}⚠${RESET} Diretório $MODULO_WIKI/$MODULO_ID/ não encontrado."
TOTAL_AVISOS=$((TOTAL_AVISOS + 1))
fi
else
echo -e " ${AMARELO}⚠${RESET} Ignorado: modulo-id não definido."
fi
# 3. Validar Wiki de Desenvolvimento (Pilar 4)
echo -e "\n${NEGRITO}[3/6] Wiki de Desenvolvimento (Pilar 4)${RESET}"
if [ -n "$MODULO_ID" ]; then
WIKI_DEV_DIR="$ROOT_DIR/$MODULO_WIKI/dev/$MODULO_ID"
if [ -d "$WIKI_DEV_DIR" ]; then
echo -e " ${VERDE}✓${RESET} Diretório encontrado em: $MODULO_WIKI/dev/$MODULO_ID/"
elif [ -d "$ROOT_DIR/$MODULO_WIKI/dev" ] || [ -d "$ROOT_DIR/$MODULO_WIKI" ]; then
echo -e " ${VERDE}✓${RESET} Base de Wiki disponível em: $MODULO_WIKI/ (sugerido: $MODULO_WIKI/dev/$MODULO_ID/)"
else
echo -e " ${AMARELO}⚠${RESET} Diretório $MODULO_WIKI/dev/$MODULO_ID/ não encontrado."
TOTAL_AVISOS=$((TOTAL_AVISOS + 1))
fi
else
echo -e " ${AMARELO}⚠${RESET} Ignorado: modulo-id não definido."
fi
# 4. Validar Integração de IA (/llm.md - Pilar 5)
echo -e "\n${NEGRITO}[4/6] Integração de IA /llm.md (Pilar 5)${RESET}"
BACK_DIRS=$(find "$ROOT_DIR" -maxdepth 2 -iname "*-back" -type d 2>/dev/null || true)
if [ -n "$BACK_DIRS" ]; then
if grep -rq "llm\.md" $BACK_DIRS/src 2>/dev/null; then
echo -e " ${VERDE}✓${RESET} Rota /llm.md configurada no backend."
else
echo -e " ${AMARELO}⚠${RESET} Rota /llm.md não detectada no código do backend."
TOTAL_AVISOS=$((TOTAL_AVISOS + 1))
fi
else
echo -e " ${AZUL}ℹ${RESET} Nenhum pacote *-back identificado no nível raiz."
fi
# 5. Validar Camada de Extensão Local (.agent-local/)
echo -e "\n${NEGRITO}[5/6] Extensibilidade Local (.agent-local/)${RESET}"
if [ -d "$ROOT_DIR/.agent-local" ]; then
echo -e " ${VERDE}✓${RESET} Camada .agent-local/ presente para regras específicas deste projeto."
else
echo -e " ${AZUL}ℹ${RESET} .agent-local/ ausente (usando 100% regras e skills globais)."
fi
# 6. Validar Limite de Linhas (Governança de Código)
echo -e "\n${NEGRITO}[6/6] Governança de Código (verificar-linhas.sh)${RESET}"
if [ -f "$ROOT_DIR/.agent/verificar-linhas.sh" ]; then
sh "$ROOT_DIR/.agent/verificar-linhas.sh" > /dev/null 2>&1 && \
echo -e " ${VERDE}✓${RESET} 100% dos arquivos dentro do limite de 250 linhas." || \
echo -e " ${AMARELO}⚠${RESET} Há arquivos excedendo 250 linhas (execute sh .agent/verificar-linhas.sh)."
fi
# Resumo Final
echo -e "\n${AZUL}${NEGRITO}======================================================${RESET}"
if [ "$TOTAL_ERROS" -eq 0 ]; then
if [ "$TOTAL_AVISOS" -eq 0 ]; then
echo -e "${VERDE}${NEGRITO}🎉 SUCESSO: Projeto 100% em conformidade com o ecossistema .agent!${RESET}"
else
echo -e "${AMARELO}${NEGRITO}✨ PROJETO VÁLIDO: $TOTAL_AVISOS aviso(s) secundário(s) para revisar.${RESET}"
fi
exit 0
else
echo -e "${VERMELHO}${NEGRITO}❌ CONFORMIDADE INCOMPLETA: $TOTAL_ERROS erro(s) mandatório(s) encontrado(s).${RESET}"
exit 1
fi