This release has been yanked by its maintainers, and will be ignored by installers, except when explicitly specified.
Consider using release 1.0.4 instead.
Reason given by maintainers: Critical API flaw (SEC-01), fixed in 1.0.0. Upgrade to 1.0.0 or later.
Vigía
Control de calidad continuo para los datos de modelos de ciberseguridad.
Vigía revisa los datasets con los que se entrenan los detectores de intrusiones y responde una pregunta incómoda: ¿este 0.99 de F1 es real, o es un artefacto de los datos?
La investigación sobre los datasets más usados del área (CIC-IDS2017, CSE-CIC-IDS2018, UGR'16) documenta duplicados masivos, etiquetas incorrectas, fugas entre entrenamiento y prueba, y columnas que le delatan la respuesta al modelo. El resultado es siempre el mismo: el modelo parece excelente en el laboratorio y falla en una red real.
Estado: v0.2.0 — los tres módulos implementados y validados contra datos reales. El auditor cubre los diez requisitos P0, más los lectores de Zeek, Suricata EVE y PCAP (R13 y R14). El monitor de deriva está medido sobre los cinco días de CIC-IDS2017, y los detectores de envenenamiento sobre ataques inyectados en ese mismo tráfico y sobre el ruido de etiqueta que documentaron Engelen et al. Los números están en
benchmarks/RESULTADOS.md, incluidos los casos donde el rendimiento es pobre.
Los tres módulos
| Módulo | Comando | Qué responde |
|---|---|---|
| 1. Auditor | vigia audit |
¿Este dataset tiene defectos que inflen las métricas? |
| 2. Envenenamiento | vigia poison |
¿Alguien insertó registros para manipular el modelo? |
| 3. Deriva | vigia drift |
¿El tráfico de hoy sigue pareciéndose al de entrenamiento? |
24 checks, 8 correcciones automáticas y la comparación de rendimiento antes/después.
Instalación
pip install -e ".[dev]" # desde el repositorio
vigia --help
Requiere Python 3.11 o superior.
Uso
# Auditar un dataset (las columnas se detectan solas por nombre)
vigia audit data/flows.csv --report out/
# Indicar las columnas explícitamente
vigia audit data/flows.parquet \
--label-col Label --split-col split --time-col Timestamp \
--report out/
# Correr solo una categoría de checks
vigia audit data/flows.csv --checks leak,dup
# En CI: salir con código 1 si hay hallazgos críticos
vigia audit data/train.csv --fail-on critical
# Listar los checks disponibles
vigia checks
Desde Python:
import vigia
ctx = vigia.load("data/flows.parquet", label_col="Label", split_col="split")
report = vigia.audit(ctx)
print(report.traffic_light()) # 'rojo' | 'amarillo' | 'verde' | 'gris'
print(report.counts()) # {'critical': 2, 'high': 1, ...}
from vigia.report import write_report
write_report(report, "out/") # report.html + report.json
Qué revisa hoy
| Check | Qué encuentra |
|---|---|
dup.exact |
Filas idénticas: el modelo se evalúa con ejemplos que ya vio |
dup.class_ratio |
Clases formadas mayoritariamente por duplicados |
dup.cross_split |
Crítico. La misma fila en entrenamiento y en prueba |
leak.temporal |
El conjunto de prueba se solapa con el de entrenamiento en el tiempo |
leak.host |
El mismo host atacante en ambos splits: el modelo memoriza la IP |
shortcut.single_feature |
Una sola columna predice la etiqueta demasiado bien |
shortcut.identifier |
IPs, IDs de flujo o timestamps usados como características |
validity.nan_inf |
NaN e infinitos (CIC-IDS2017 los tiene en las columnas de tasas) |
validity.constant |
Columnas con un solo valor |
validity.impossible |
Puertos > 65535, duraciones negativas, bytes negativos |
validity.column_names |
Nombres con espacios (" Destination Port") o ambiguos |
leak.session |
Flujos de la misma conexión repartidos entre splits |
labels.conflict |
Filas idénticas con etiquetas distintas |
labels.noise |
Etiquetas que contradicen al resto del dataset (cleanlab) |
labels.taxonomy |
La misma clase escrita de varias formas |
labels.imbalance |
Clases con tan pocos ejemplos que su métrica no dice nada |
Cada hallazgo trae severidad, métrica, filas afectadas, ejemplos concretos y una recomendación. Un check que no puede correr (falta la columna de split, por ejemplo) no falla en silencio: aparece en la sección "checks no ejecutados" del reporte.
El semáforo
| Color | Significa |
|---|---|
| rojo | Hay hallazgos críticos o altos |
| amarillo | Hay hallazgos medios o bajos |
| verde | Sin hallazgos y todos los checks se ejecutaron |
| gris | Sin hallazgos, pero algunos checks no se ejecutaron |
El gris existe porque "no encontré nada" y "está limpio" no son lo mismo. Si la
columna de etiqueta o la de split no se detectan, los checks que se saltan son
justamente los que buscan fuga y duplicados entre conjuntos: dar verde ahí sería
confirmar que el dataset está bien cuando en realidad casi no se lo revisó. Si el
semáforo da gris, especificá las columnas a mano con --label-col y --split-col.
Corregir
Los hallazgos nombran su corrección. vigia fix las aplica:
# Ver las disponibles
vigia fixes
# Aplicarlas en cadena; el archivo original nunca se toca
vigia fix data/flows.csv \
--apply drop_duplicates,drop_constant,drop_identifiers \
--out data/flows_corregido.parquet
Las filas con etiqueta dudosa nunca se borran: quarantine_noise las deja
en un archivo aparte para que una persona las revise.
Medir cuánto del rendimiento era real
from vigia.benchmark import compare
c = compare(ctx, ["drop_identifiers"])
print(c.summary())
print(c.after.per_class_recall)
Entrena el mismo modelo antes y después de corregir. Una caída no significa
que las correcciones empeoraron el modelo: significa que el número original
estaba inflado. Sobre CIC-IDS2017, cambiar un split aleatorio por uno temporal
lleva el recall de DoS Hulk, PortScan y DDoS de ~0,95 a 0,00 — ver
benchmarks/RESULTADOS.md.
Formatos de entrada
| Formato | Extensión | Notas |
|---|---|---|
| CSV | .csv, .txt |
Reintenta en cp1252 si no es UTF-8 |
| Parquet | .parquet, .pq |
Conserva los tipos |
| Zeek | .log |
TSV con cabecera o JSON Lines |
| Suricata EVE | .json, .eve |
--event-type elige flujos o alertas |
| PCAP | .pcap, .pcapng, .cap |
Con pip install 'vigia-nids[pcap]' |
Archivo suelto o carpeta completa: los datasets CIC vienen partidos en un
archivo por día, Vigía los concatena y conserva la procedencia en
__source_file. Los PCAP se leen de a uno, porque extraer flujos tarda minutos.
Detalles de cada formato en docs/USO.md.
Desarrollo
pip install -e ".[dev,ml]"
pytest # pruebas
ruff check src tests # lint
ruff format src tests # formato
mypy src # tipos
Agregar un check nuevo es una clase con cuatro atributos y un método. El
registro es automático al importarse el módulo desde vigia/checks/__init__.py.
Los detalles están en docs/ARQUITECTURA.md.
Documentación
| Documento | Para qué |
|---|---|
docs/CHECKS.md |
Qué significa cada hallazgo del auditor y qué hacer |
docs/ENVENENAMIENTO.md |
Módulo 2: los detectores, el simulador y qué tan bien funcionan |
docs/DERIVA.md |
Módulo 3: los checks, las métricas y cómo leerlos |
docs/USO.md |
Referencia de la CLI, del SDK y del formato JSON |
docs/ARQUITECTURA.md |
Cómo está armado por dentro; cómo agregar un check |
benchmarks/RESULTADOS.md |
Resultados verificados sobre NSL-KDD y CIC-IDS2017 |
docs/PLAN.md |
Qué falta hasta la 1.0, en qué orden y cómo |
Documento de diseño
El diseño completo — los tres módulos (auditor, envenenamiento, deriva), la
arquitectura, el plan por fases y las referencias académicas — está en
vigia.md.
Licencia
Apache 2.0.
Metadata
Release files for vigia-nids 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| vigia_nids-0.2.0.tar.gz | 211.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| vigia_nids-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 326.2 kB
Release files / vigia_nids-0.2.0.tar.gz
| Download URL | vigia_nids-0.2.0.tar.gz |
|---|---|
| Size | 211.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8f903b2b7ff728dc7c01818e946bfcdd7aa79d9da5f0aff6c17cad5597c0637c
|
|
BLAKE2b-256 checksum How to use checksums |
d5a72022febdad15eddef380bf8607fcde4568f5a2834786c0b8588ddb638bab
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 30, 2026.
Transparency logRelease files / vigia_nids-0.2.0-py3-none-any.whl
| Download URL | vigia_nids-0.2.0-py3-none-any.whl |
|---|---|
| Size | 114.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c9e31e6c19fb1a223ccf22543bfa298c3ee59379d51b0a2790e96346e928c38f
|
|
BLAKE2b-256 checksum How to use checksums |
29cc0322d9b7e0a01d6262e7959efb9cbe1844f556ac713ccbcfabf94c01deeb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 30, 2026.
Transparency log