# Reglas de violacion del agente (issue 0085g). # # Estas reglas las aplica `.claude/scripts/hook_call_monitor.sh` (PostToolUse Bash). # Cuando una regla matchea -> INSERT INTO violations (operations.db call_monitor). # # Schema rules: # id: ID estable de la regla (rule_id en violations table) # when: Pattern shell-like (texto descriptivo del matcher en el hook) # tool_used: Filtro de tool_used (bash_other|heredoc_py|sqlite_direct|...) # severity: critical | warning | info # message: Lo que vera el humano al revisar # suggestion: Alternativa canonica a usar # active: true|false (off por defecto si rotura sospechosa) # # Para anadir/cambiar una regla: # 1. Editar este archivo (declarativo, source of truth). # 2. Replicar el matcher en `.claude/scripts/hook_call_monitor.sh` (manualmente # por ahora; runtime YAML reader TBD — requiere jq/yq y refactor del hook). # 3. Smoke: ejecutar un comando que dispare la regla y verificar # `sqlite3 projects/fn_monitoring/apps/call_monitor/operations.db # "SELECT rule_id, severity FROM violations ORDER BY ts DESC LIMIT 5"`. rules: - id: sqlite3_registry_select when: "sqlite3 registry.db \"SELECT ... FROM functions|types|apps|proposals\"" tool_used: sqlite_direct severity: warning active: true message: "Lectura directa a registry.db sin MCP. Pierde trazabilidad + sin escape FTS5." suggestion: "mcp__registry__fn_search / fn_show / fn_code / fn_uses / fn_list_domains. sqlite3 directo SOLO para .schema, PRAGMA, COUNT/GROUP BY, JOINs custom." - id: python_dir_inspect when: "python -c 'import X; print(dir(X))' o 'help(X)'" tool_used: bash_other severity: info active: true message: "Inspeccion via stdlib en lugar del registry como fuente de verdad." suggestion: "mcp__registry__fn_search '' + mcp__registry__fn_show ." - id: import_star_in_heredoc when: "from import *" tool_used: heredoc_py severity: warning active: true message: "Imposible identificar que funciones del registry uso el heredoc." suggestion: "Imports explicitos: from import , ." - id: client_http_request_direct when: "._http.request(...) saltando wrapper" tool_used: heredoc_py severity: warning active: true message: "Salta wrapper del registry + telemetria + validacion del wrapper." suggestion: "Usar wrapper; si la firma no cubre el caso, fn proposal add --kind improve_function." # --- Reglas propuestas (no implementadas en hook todavia) --- - id: mcp_ratio_low when: "Por sesion: count(mcp_*) / count(*) < 0.4 al cerrar sesion" tool_used: "(rollup por sesion)" severity: warning active: false # requiere assertion en cierre de sesion, no PreToolUse message: "Sesion uso mcp_* < 40% del tiempo. Heredocs/sqlite directo dominan." suggestion: "Revisar patrones por session_id en call_monitor; refactorizar a MCP/fn run." - id: heredoc_repetition when: "Mismo cluster patron > 5x en window=30d" tool_used: heredoc_py|heredoc_bash severity: info active: false # detectado offline por call_monitor cluster-patterns message: "Patron inline repetido sin promocion a funcion." suggestion: "Promocionar a python/functions/pipelines/ o bash/functions/pipelines/ via fn-constructor." - id: edit_registry_without_fn_index when: "Edit/Write en functions/ o types/ sin run ./fn index despues" tool_used: edit_registry severity: warning active: false # requiere correlacion temporal entre Edit y siguiente Bash message: "Codigo modificado pero registry.db no regenerado. fn doctor reportara drift." suggestion: "Ejecutar ./fn index tras editar y antes de cerrar turno." - id: protected_path_modified when: "Edit/Write en path declarado en dev/autonomous_protected_paths.json" tool_used: edit_registry severity: critical active: false # solo aplica dentro de fn-orquestador, no a Claude main message: "Path protegido modificado fuera del scope autorizado." suggestion: "Revertir cambio o documentar autorizacion explicita del humano."