Sherlock: Método de Investigación, Lentes y Cruces Forenses

La Filosofía de Sherlock: Inventariar sin Opinar

Cuando se le pide a un modelo de inteligencia artificial que analice un expediente judicial completo en un solo paso, tiende a resumir, alucinar y pasar por alto detalles críticos. Las maniobras de encubrimiento, los anacronismos o las contradicciones testimoniales en una causa penal no se encuentran en una oración aislada: se revelan cuando se cruzan afirmaciones distanciadas por meses, fojas o expedientes distintos.
Sherlock resuelve este problema mediante una división estricta de tareas:
  1. Extracción atómica (con IA): La inteligencia artificial lee documento por documento bajo preguntas muy estrechas y objetivas, extrayendo hechos con citas textuales literales y sin emitir opiniones ni conclusiones jurídicas.
  2. Validación formal: Cada cita extraída se contrasta automáticamente contra el texto del documento original; si no coincide de forma exacta, el hecho se rechaza.
  3. Cruces deterministas (con SQL, sin IA): Las contradicciones, desfases temporales, plagios y líneas de tiempo se computan mediante consultas a una base de datos relacional (hechos.db), garantizando un resultado objetivo, verificable y reproducible.
  4. Razonamiento sobre el inventario: Los modelos de lenguaje o los investigadores solo intervienen al final para evaluar los hallazgos producidos por los cruces sobre un corpus estructurado y de tamaño acotado.

El Procedimiento y el Sistema de "Lentes"

Para no saturar la atención del modelo ni mezclar conceptos, el análisis se realiza aplicando lentes temáticas de manera secuencial e independiente sobre cada pieza del expediente:
Cada hecho extraído califica el nivel de certidumbre probatoria de la fecha:
Además, las lentes están estrictamente versionadas (v1, v2, v3). Si las instrucciones de una lente se perfeccionan, solo se re-encolan en el pipeline de pendientes aquellos documentos alcanzados por la modificación, sin necesidad de reprocesar el resto.

Cruces Relacionales y Motores Especializados

Una vez poblado el inventario de hechos, el motor ejecuta comandos de cruce analítico sin intervención de modelos de lenguaje:
El sistema cuenta además con motores forenses complementarios integrados:

Capas de Evidencia y Roles Argumentativos

Para evitar sesgos y mantener el rigor metodológico, Sherlock divide el análisis en dos capas conceptuales:
Para evaluar los hallazgos generados, el sistema implementa tres roles en tensión dialéctica:

Estructura Relacional de la Base de Datos (hechos.db)

Toda la evidencia estructurada, el estado de cobertura de las lentes, los hallazgos detectados y las intervenciones del investigador se almacenan en una base de datos relacional SQLite (var/hechos.db).
Las anotaciones sobre un hallazgo cuentan con un sistema de registro en capas:
-- Catálogo unificado de entidades (personas, instituciones, documentos, delitos)
CREATE TABLE entidades (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    nombre TEXT UNIQUE NOT NULL,
    tipo TEXT,                          -- persona, institucion, documento, norma, etc.
    alias_de INTEGER REFERENCES entidades(id)
);

-- Inventario atómico de hechos extraídos por documento y lente
CREATE TABLE hechos (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    ruta TEXT NOT NULL,                 -- ruta relativa del documento dentro del corpus
    lente TEXT NOT NULL,                -- lente utilizada (hechos, tiempos, ausencias, etc.)
    lente_version INTEGER NOT NULL,     -- versión de la lente con la que se procesó
    ubicacion TEXT,                     -- foja, página o marca horaria
    cita TEXT NOT NULL,                 -- cita literal extraída del documento
    sujeto_id INTEGER REFERENCES entidades(id),
    accion TEXT,                        -- descripción estandarizada de la acción
    objeto_id INTEGER REFERENCES entidades(id),
    fecha TEXT,                         -- formato ISO AAAA-MM-DD
    hora TEXT,                          -- formato HH:MM o HH:MM:SS
    precision TEXT,                     -- exacta, aprox
    rol_fecha TEXT,                     -- evento, impresion, firma, recepcion, etc.
    prueba_fecha TEXT,                  -- verificable, tercero, indicio, declarada
    afirma_id INTEGER REFERENCES entidades(id),
    modalidad TEXT,                     -- constata, relata, infiere, niega, omite
    nota TEXT,                          -- nota técnica objetiva sin opinión
    modelo TEXT NOT NULL,               -- modelo de IA que extrajo el hecho
    autor TEXT NOT NULL,                -- operador o agente responsable
    peso REAL DEFAULT 1.0               -- ponderación de certeza probatoria
);

-- Control de cobertura por documento y lente para evitar lecturas duplicadas
CREATE TABLE cobertura (
    ruta TEXT NOT NULL,
    lente TEXT NOT NULL,
    modelo TEXT NOT NULL,
    version_lente INTEGER NOT NULL,
    md5_texto TEXT NOT NULL,            -- hash del texto leído para detectar modificaciones
    fecha TEXT NOT NULL,
    agente TEXT,
    duda TEXT,                          -- duda pendiente de aclaración por el investigador
    PRIMARY KEY (ruta, lente, modelo)
);

-- Hallazgos e hipótesis propuestas por los cruces o modelos
CREATE TABLE hallazgos (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    tipo TEXT NOT NULL,                 -- contradiccion, anacronismo, copia, omision, etc.
    descripcion TEXT NOT NULL,
    hechos TEXT NOT NULL,               -- array JSON con IDs de hechos vinculados
    documentos TEXT,                    -- array JSON con rutas de documentos involucrados
    a_favor_de TEXT,                    -- postura o hipótesis respaldada
    prueba TEXT,                        -- nivel de prueba resultante
    rol TEXT,                           -- fiscal, defensa, juez
    estado TEXT DEFAULT 'propuesto',    -- propuesto, confirmado, descartado, autoverificado
    nota TEXT,                          -- notas y anotaciones acumuladas sobre el hallazgo
    linea TEXT,                         -- línea de investigación asociada
    elemento TEXT,                      -- elemento concreto a probar (E1, E2...)
    capa TEXT DEFAULT 'completa',       -- expediente o completa
    fecha TEXT NOT NULL,
    modelo TEXT NOT NULL,
    autor TEXT NOT NULL,
    peso REAL DEFAULT 1.0
);

-- Historial inmutable de anotaciones, notas y cambios de estado sobre cada hallazgo
CREATE TABLE hallazgos_historial (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    hallazgo_id INTEGER NOT NULL REFERENCES hallazgos(id),
    accion TEXT NOT NULL,               -- anotar, confirmar, descartar, autoverificar, etc.
    estado_antes TEXT,
    estado_despues TEXT,
    nota TEXT,                          -- texto de la anotación o motivo del cambio
    autor TEXT NOT NULL,                -- quién realizó la anotación o decisión
    fecha TEXT NOT NULL                 -- timestamp de la anotación
);

-- Análisis estructurados sobre un hallazgo (aclaraciones, hipótesis y preguntas)
CREATE TABLE hallazgos_analisis (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    hallazgo_id INTEGER NOT NULL REFERENCES hallazgos(id),
    tipo TEXT NOT NULL,                 -- aclaracion, hipotesis, pregunta
    estado TEXT DEFAULT 'abierta',      -- abierta, sostenida, descartada, respondida
    texto TEXT,                         -- desarrollo argumental o pregunta analítica
    referencias TEXT,                   -- array JSON con documentos vinculados y comentarios
    autor TEXT NOT NULL,
    fecha TEXT NOT NULL
);

-- Comentarios y anotaciones del usuario sobre documentos o hechos particulares
CREATE TABLE comentarios (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    ruta TEXT NOT NULL,                 -- documento comentado
    hecho_id INTEGER REFERENCES hechos(id), -- hecho específico si aplica
    tipo TEXT NOT NULL,                 -- omision, error, duda, nota, oro
    texto TEXT NOT NULL,
    cita TEXT,                          -- fragmento textual aludido
    nivel TEXT,                         -- vista, lectura, cruce, forense (si tipo es oro)
    respuesta TEXT,                     -- respuesta o resolución técnica del agente
    estado TEXT DEFAULT 'abierto',      -- abierto, resuelto
    autor TEXT NOT NULL,
    fecha TEXT NOT NULL
);

-- Aportes documentales y testimoniales incorporados por el usuario
CREATE TABLE aportes (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    texto TEXT NOT NULL,
    documentos TEXT,                    -- array JSON de documentos relacionados
    hallazgos TEXT,                     -- array JSON de IDs de hallazgos vinculados
    tipo TEXT NOT NULL,                 -- prueba, testimonio, observacion
    uso TEXT,                           -- contexto, refutacion, corroboracion
    autor TEXT NOT NULL,
    fecha TEXT NOT NULL,
    modelo TEXT
);

-- Aclaraciones manuales sobre el documento sin modificar el texto original
CREATE TABLE aclaraciones (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    documento TEXT NOT NULL,
    texto TEXT NOT NULL,
    autor TEXT NOT NULL,
    fecha TEXT NOT NULL
);

-- Vínculos explícitos entre documentos
CREATE TABLE vinculos (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    doc_a TEXT NOT NULL,
    doc_b TEXT NOT NULL,
    tipo TEXT NOT NULL,                 -- misma-pieza, respuesta, cita, corrobora, etc.
    descripcion TEXT,
    prueba TEXT,                        -- verificable, tercero, indicio, declarada
    origen TEXT DEFAULT 'usuario',
    confirmado INTEGER DEFAULT 0,
    autor TEXT NOT NULL,
    fecha TEXT NOT NULL
);

-- Registro de posturas del denunciante o investigador sobre cada hallazgo
CREATE TABLE posturas (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    hallazgo_id INTEGER REFERENCES hallazgos(id),
    postura TEXT NOT NULL,              -- acuerdo, desacuerdo, matiza
    texto TEXT NOT NULL,
    autor TEXT NOT NULL,
    fecha TEXT NOT NULL
);

-- Diligencias y pruebas faltantes asociadas a un hallazgo
CREATE TABLE pruebas_pendientes (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    hallazgo_id INTEGER REFERENCES hallazgos(id),
    texto TEXT NOT NULL,
    estado TEXT DEFAULT 'pendiente',    -- pendiente, obtenida, no-existe
    ruta TEXT,
    fecha TEXT NOT NULL
);

-- Registro de ejecuciones de cruces y barridos analíticos
CREATE TABLE corridas (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    fecha TEXT NOT NULL,
    corte_hecho_id INTEGER,             -- ID del último hecho procesado
    estado TEXT NOT NULL,
    nota TEXT
);