# Decisión de auditoría SQL del split

Política: `support-split-policy-v1`.
Versión de split: `support-split-v1`.
Decisión: `review`.

## Qué se ha comprobado

| Check | Resultado | Lectura |
|---|---:|---|
| Asignaciones duplicadas | 0 | Debe ser 0: cada caso pertenece a un único split. |
| Casos sin asignación | 0 | Debe ser 0: todo el snapshot queda cubierto. |
| Estudiantes en train y test | 0 | Debe ser 0 si medimos entidades no vistas. |
| Fuentes en train y test | 0 | Debe ser 0 si medimos fuentes no vistas. |
| Features futuras candidatas | 7 | Riesgo de leakage si se hace un join ingenuo. |
| Casos sin feature as-of | 0 | Debe ser 0 si la feature es obligatoria. |

## Lectura técnica

El historial contiene features posteriores a algunos casos. Eso es normal en una tabla histórica viva, pero obliga a usar un as-of join: para cada caso, selecciona el último valor con `feature_available_at <= created_at`.

Si alguien hiciera un join por `student_id` y eligiera el valor más reciente de toda la tabla, la evaluación miraría futuro. Por eso este reporte queda en `review`: no bloquea el split, pero obliga a revisar el código de feature engineering.

## Archivos que sostienen esta decisión

- `output/dataset_split_assignments.csv`: tabla materializada de split.
- `data/feature_history.csv`: historial de features con fecha de disponibilidad.
- `sql/split_audit_duckdb.sql`: versión SQL que puedes portar a DuckDB o a tu almacén.
- `output/sql_split_audit_report.json`: reporte estructurado de checks.
