Auditoría y Privacidad del Asesor de IA
🔐 Auditoría y Privacidad del Asesor de IA
Sección titulada «🔐 Auditoría y Privacidad del Asesor de IA»El asesor usa dos almacenes con propiedades opuestas y un modelo de privacidad diseñado para que el único tráfico saliente sea la propia llamada al modelo.
🗄️ Persistencia: Memoria vs. Rastro de Auditoría
Sección titulada «🗄️ Persistencia: Memoria vs. Rastro de Auditoría»ai-advisor.db (memoria conversacional) |
ai_advisor_runs (rastro de auditoría) |
|
|---|---|---|
| Motor | libsql mediante @mastra/libsql, creado por createAdvisorMemory |
Ledger SQLite (criptofolio_ledger.db), tabla STRICT |
| Contenido | Conversación completa, incluida cada cifra enunciada o devuelta por una herramienta | Solo procedencia, nunca contenido |
| Ciclo de vida | Desechable; borrar el archivo solo elimina conversaciones | Duradero; no le afecta un borrado |
| Escrito por | Memory de Mastra |
SqliteAdvisorRunLogAdapter mediante IAdvisorRunLogPort |
Tabla de Auditoría
Sección titulada «Tabla de Auditoría»La migración 009_ai_advisor_runs.sql creó ai_advisor_runs; 010_nullable_advisor_execution_profile.sql hizo execution_profile anulable. Consulta el Ledger Transaccional SQLite para las convenciones de esquema circundantes.
CREATE TABLE ai_advisor_runs ( id TEXT PRIMARY KEY, thread_id TEXT NOT NULL, started_at TEXT NOT NULL, finished_at TEXT, outcome TEXT NOT NULL CHECK (outcome IN ('completed','refused','failed','aborted')), provider_id TEXT, model_id TEXT, tools_called TEXT NOT NULL DEFAULT '[]', input_tokens INTEGER, output_tokens INTEGER, failure_code TEXT, execution_profile TEXT CHECK (execution_profile IS NULL OR execution_profile IN ('local','metered','mixed')), steps_used INTEGER, max_steps INTEGER) STRICT;| Columna | Significado |
|---|---|
id |
El id de la ejecución; la escritura es un upsert sobre él, así que una finalización y una limpieza por cancelación nunca pueden escribir doble. |
thread_id |
El hilo de la conversación. |
started_at, finished_at |
Marcas de tiempo ISO; finished_at es NULL en una ejecución abortada. |
outcome |
completed, refused, failed o aborted. |
provider_id, model_id |
La entrada que respondió, o la última intentada; NULL cuando no se probó ninguna entrada. |
tools_called |
Array JSON de nombres de herramientas, ampliado cuando llega un resultado o error de herramienta. |
input_tokens, output_tokens |
Uso informado en finish; NULL en ejecuciones abortadas. |
failure_code |
Solo en ejecuciones failed; permanece como ALL_PROVIDERS_FAILED y no registra el tipo de causa. |
execution_profile |
local, metered, mixed o NULL. |
steps_used, max_steps |
Pasos consumidos (contados desde los chunks step-finish) frente al techo; NULL cuando se desconocen. |
Reglas que se derivan del código:
- El
reasonde una ejecuciónrefusednunca se escribe, deliberadamente. - Un fallo antes de probar ninguna entrada de la cadena (
NO_MODEL_AVAILABLE,VAULT_LOCKED) es un recibopre-run: las columnas de perfil y pasos son NULL, no se adivinan. - Una ejecución abortada se escribe desde el
finallydel caso de uso solo con el id de ejecución, el id de hilo, la hora de inicio y una lista de herramientas vacía, así que no tiene proveedor, modelo, perfil, tokens ni contadores de pasos. stepsUsedymaxStepsde un reciboprofiledson obligatorios junto conexecutionProfile; el tipo hace irrepresentable “perfil sin pasos”.
[!WARNING] La migración
010reconstruye la tabla conDROP TABLE IF EXISTS ai_advisor_runs(SQLite no puede eliminarNOT NULLconALTER) y declara una suposición de pizarra limpia: el proyecto no tenía despliegue en producción y la tabla no contenía filas que valiera la pena conservar. Aplicarla a una base de datos con filas de auditoría reales las descarta.
Memoria Conversacional
Sección titulada «Memoria Conversacional»- Ubicación:
ai-advisor.dben la raíz de datos, sobrescribible conADVISOR_DB_PATH(un valor relativo se ancla a la raíz de datos, se respeta:memory:).CRIPTOFOLIO_DATA_DIRmueve toda la raíz de datos. - Recuerdo: cada turno reproduce los últimos
lastMessagesmensajes del hilo (resource: 'local'). La recuperación semántica, la memoria de trabajo y la memoria observacional están desactivadas, así que no hay embedder ni almacén vectorial. Los pares llamada/resultado de herramienta de turnos anteriores se filtran (ToolCallFilterconpreserveModelOutput: true): el modelo conserva su propia prosa anterior pero debe volver a consultar una herramienta en lugar de fiarse de una cifra obsoleta. - Borrado: detén el backend y elimina
ai-advisor.dbjunto con cualquier archivo-wal,-shmo-journala su lado. El archivo se recrea en la siguiente ejecución. No se borra nada más. - Ciclo de vida: el archivo se abre de forma perezosa en la primera petición al asesor, nunca al importar.
🛡️ Modelo de Privacidad y Seguridad
Sección titulada «🛡️ Modelo de Privacidad y Seguridad»| Propiedad | Mecanismo |
|---|---|
| Solo lectura | Sin herramienta de escritura; un test estructural rechaza insert/update/delete en los archivos de herramientas. |
| Sin secretos en la ruta del modelo | Las claves se descifran por petición, se mantienen solo en la cadena resuelta y se redactan de los mensajes de error registrados. |
| Entrada del modelo acotada | Esquemas de herramienta estrictos; ningún id de cuenta ni identificador interno es nunca una entrada del modelo; regex de símbolos. |
| Salida del modelo no confiable | Markdown con HTML crudo, imágenes y enlaces fuera de la app desactivados. |
| El contenido permanece local en reposo | Contenido conversacional solo en ai-advisor.db; la tabla de auditoría no contiene ninguno. |
| Sin telemetría | No se registra ninguna instancia de Mastra ni exportador; @mastra/observability no está instalado (noTelemetry.spec.ts). |
| Local vs medido no lo etiqueta el usuario | Derivado del proveedor y el id de modelo (ver Proveedores y Modelos). |
| Detalle de errores | La red transporta un cause.kind cerrado, nunca texto del proveedor, URLs, cabeceras, claves ni cuerpos. |
| Sin superficie genérica de agentes | Exactamente seis rutas; ningún adaptador de servidor de Mastra montado. |
[!WARNING] Cuando el modelo que responde es de nube, la pregunta y las cifras devueltas por las herramientas se envían a ese proveedor. El panel de chat muestra una insignia
cloudprecisamente por eso. Usa una cadena totalmente local si los datos no deben salir de la máquina. Trataai-advisor.dbcon la misma sensibilidad que el ledger.
El único tráfico saliente es la propia llamada al modelo: a un proveedor alojado para entradas de nube, o a OLLAMA_BASE_URL para ollama. Las claves de proveedor viven en la Bóveda Cifrada Local, nunca en variables de entorno.