Nivel 2 · El arco, por traspasos
This content is not available in your language yet.
El arco, por traspasos
Sección titulada «El arco, por traspasos»El taller avanza en cinco traspasos (hitos). En cada uno, un rol actúa y el otro espera. El icono y la columna te indican de quién es el turno: 🧭 Nerea arriba (portal · producto), 🛡️ Diego en medio (portal · calidad), 🧑💻 Marta a la derecha (CLI + git). Los tres están presentes desde el primer hito. La diferencia respecto al Nivel 1 es el tema del riesgo: no la exactitud de un modelo, sino si un dato de un alumno que puede ser menor de edad conserva demasiado detalle re-identificador — y, en el quinto hito, la revisión periódica que reabre el cierre verde para re-confirmarlo.
Los datos duros de cada hito —los comandos, el mensaje de commit, el diff y el color de la barrera— no están escritos a mano: cada bloque GuionStep los lee del guion steps/ del repositorio publicado. Si un paso no existiera, el build fallaría; lo que lees aquí es exactamente lo que el repositorio hace.
Nerea es la responsable de producto de la institución que quiere clasificar las admisiones con un modelo. Abre el portal y ejecuta las tres misiones de autoría que generan el manifiesto de gobernanza froga.yaml. Cuatro cosas importan en él:
- El nivel es
high, declarado por un humano, con la base legal nombrada. La misiónclassify-systemrellena el bloqueclassificationcon la justificación en palabras llanas: «Ley de IA de la UE, Anexo III §3 (educación y formación profesional) — el sistema decide la admisión/asignación.» El motor no lo infiere; Nerea lo declara y lo asume. - Las normas son la columna vertebral, y solo la columna vertebral. La misión
declare-standardsescribecontext.applicable_standardscon exactamente tres entradas:eu/ai-act@2024,eu/pren-18228@2026,iso/23894@2023. Ni DORA ni MDR — no hay capa sectorial aquí.frogaproyecta un sistema solo contra las normas que declaras. - El riesgo de equidad también está declarado — pero ya no es la barrera bloqueante. La misión
identify-risksañaderisk.unfair-selection— «el modelo selecciona estudiantes de forma injusta por sexo» — con su controlfairness-parity(paridad demográfica sobregender). Cuando Marta mida sobre la muestra real (mat + portugués, 1044 filas, no un curso solo), la disparidad resulta pequeña y el control queda comoauditcertificado en verde: real, medido, en el registro — pero no el que decide el color del arco. - Los sujetos pueden ser menores, y ESE es el arco de este nivel. La misma misión añade
risk.minors-vulnerable-processing: los estudiantes pueden ser menores de edad (sujetos vulnerables), y el RGPD exige una protección reforzada — condiciones del consentimiento del niño (Art. 8), DPIA obligatoria (Art. 35), no elaboración de perfiles de menores (Art. 22 + considerando 71) y minimización de los datos personales tratados (Art. 5(1)(c)). El consentimiento/DPIA/Art. 22 el motor aún no los proyecta (no hay catálogo RGPD) y se llevan como una medida atestada — un hueco honesto. Pero la minimización SÍ se mide:minors-data-minimizationcalcula el k-anonimato del trío edad/dirección/tamaño de familia de cada alumno — cuántos alumnos comparten exactamente esa combinación. Es el control bloqueante del escenario.
Las cuatro entradas del programa abren un PR en el repositorio del sistema. El turno pasa a Diego, que lo revisa e integra. En el guion, la identidad, el encuadre y el programa de riesgos quedan como tres commits del manifiesto froga.yaml —el diff del último muestra los dos riesgos, con la minimización de datos como el que trae el gate numérico:
Diego recibe el PR que abrieron las misiones de Nerea, revisa que el manifiesto sea correcto — nivel high por Anexo III §3, normas eu/ai-act@2024 + eu/pren-18228@2026 + iso/23894@2023, el riesgo de menores con su gate de minimización de datos — e integra el PR. El froga.yaml declarado queda en el repositorio.
Todavía no hay nada que medir, pero Marta deja el reproductor listo en git: el proyecto uv + DVC, las DOS cohortes reales UCI Student Performance (matemáticas + portugués — 382 de los 1044 alumnos están en las dos) con su manifiesto Croissant, y el paso de rasgos que las combina, ya son commits del guion:
15
git init -q -b maingit config user.email marta@demo.seigarrena.devgit config user.name "Marta Demo"uv init --bare --name vldemo-student-selection --python 3.12patch: pyproject-index.patchuv add "dvc>=3" pyyaml froga "venturalitica==0.6.11" "mlcroissant>=1.0" pyarrow "scikit-learn==1.8.0" "fairlearn==0.13.0" pandas joblibpatch: gitignore.patchpatch: gitattributes.patchpatch: readme.patchuv syncuv run dvc init --no-scm -quv run dvc config core.analytics falsefroga pubkey --out .froga/PUBKEY.txtgit add -Agit commit -m "init: repo, proyecto uv (deps reales) y README del reproductor"
Con el manifiesto declarado y el andamiaje en git, el turno pasa a medir: Marta ejecuta la barrera e informa del primer color (hito 2).
Esperando. Nerea ha declarado el sistema y los dos riesgos y Diego lo ha aprobado; ahora Diego espera la primera medición de Marta. Él no toca la CLI: cuando Marta informe del color de la barrera, verá si el riesgo es real y cuánto supera el apetito.
Marta toma el manifiesto y mide el sistema tal como está hoy — el riesgo inherente, sin tratar. Primero compila el contrato de la barrera desde froga.yaml —qué controles se van a medir y con qué umbral—:
froga compilegit add -Agit commit -m "compile: assessment plan OSCAL (contrato del gate, antes del modelo)"
Ahora añade el modelo base V1 —una regresión logística entrenada con validación cruzada de 5 folds (train.py) que usa la edad, la dirección y el tamaño de familia de cada alumno tal cual llegan del dataset, sin generalizar— y corre la evidencia. froga run reproduce el pipeline, mide los controles y aplica la barrera:
patch: params.patchpatch: dvc-evaluate.patchpatch: train.patchpatch: evaluate.patchpatch: compliance-eval.patchfroga runmay failgit add -Agit commit -m "modelo: logreg V1 (train/evaluate + dvc.yaml) — run: V1 evidencia base (gate RED esperado; seed=42)"
froga run señala el control minors-data-minimization como ROJO: sobre los 1044 alumnos (matemáticas + portugués), agrupar por edad exacta + dirección + tamaño de familia da un mínimo de grupo de 1 — 216 de los 1044 alumnos son la única persona con esa combinación exacta —, muy por debajo del umbral declarado k ≥ 5. El comando sale con código de error —de ahí el aviso «puede fallar» sobre froga run— pero el paquete está firmado y anclado: un resultado ROJO sigue siendo evidencia, registrada honestamente. El chip «reproducir» de arriba clona la etiqueta student-v1.0.0-red y reproduce este mismo color.
El riesgo es real y supera el apetito; necesita tratamiento.
Esperando. Diego ha visto el ROJO. Espera la evidencia tratada — él no toca git. Cuando Marta publique el paquete vuelto a medir, verá no solo un color sino por qué es ese color: el motor informa el intervalo de confianza, no solo el valor puntual.
Este es el tratamiento (ISO 23894 §6.5), y trae DOS cambios de código reales en train.py. El que cierra el gate: la edad exacta de cada alumno se generaliza a un tercil (b0/b1/b2, la misma columna age, un valor más grueso — la técnica clásica de k-anonimato de Sweeney) antes de entrenar; dirección y tamaño de familia ya eran coarse y no se tocan. El que mejora la equidad en paralelo: el estimador pasa de regresión logística plana al ExponentiatedGradient de fairlearn bajo una restricción de DemographicParity sobre gender. Ninguno es un flag: el git diff de train.py muestra ambos cambios de verdad. El diff es el tratamiento — y, en el mismo paso, con ambos tratamientos aplicados, el motor vuelve a correr la barrera:
git checkout -b tratamiento/minimizacion-rgpdpatch: train-treatment.patchfroga rungit add -Agit commit -m "treatment: fairlearn DemographicParity (sexo) + minimización RGPD (edad→tercil, k-anonimato) — ISO 23894 §6.5"
El k-anonimato del mismo trío (edad/dirección/tamaño de familia) sube de 1 a 27 — generalizar la edad basta para que 216 alumnos “únicos” pasen a compartir grupo con al menos otros 26. El motor hace un bootstrap del IC 95% sobre ese mínimo y obtiene [18, 37] — la banda entera queda por encima del umbral k ≥ 5, sin cruzarlo. A diferencia de una diferencia de proporciones medida sobre un hold-out pequeño, el mínimo de un grupo de 27 (sobre clases de ~130 alumnos de media) no es frágil bajo remuestreo con este margen: el gate cierra VERDE limpio, sin infrapotenciar.
La evidencia VERDE firmada ya vive en git —bajo la etiqueta student-v2.0.0-green, reproducible desde el chip de arriba—; Marta la publica y el turno vuelve a Diego. La conformidad se emite en el hito de gobernanza.
La evidencia VERDE firmada de Marta está en el repositorio, con la conformidad ya emitida (columna de Marta) y la Declaración de Aplicabilidad (SoA, ISO 42001 6.1.3) ejecutada. Diego cierra el bucle desde el portal — pero «verde» no significa «sin nada que decidir».
4.1 — Revisar la evidencia y lo que queda fuera del gate. El portal lee el paquete .froga/, verifica la firma de Marta y muestra el sistema declarado, tratado y VERDE: el gate bloqueante (minors-data-minimization) pasa con margen amplio, y la paridad demográfica (fairness-parity) queda certificada en paralelo. Pero risk.opacity — decisiones automatizadas sin explicabilidad suficiente — mantiene un residual por encima del apetito del programa (nivel Critical vs criterio Medium): su único control, accuracy-floor, es de auditoría, sin una reducción de probabilidad declarada. El motor lo dice sin ambigüedad: «RIESGO RESIDUAL AGREGADO POR ENCIMA DEL APETITO … la aprobación exigirá aceptación consciente con motivo» — aunque no bloquea el gate.
4.2 — Aprobar con el residual reconocido. Diego, como el rol responsable del sistema (owner), aprueba el verde — y, junto con eso, acepta conscientemente el residual de explicabilidad, con revisión periódica anual programada. Marta había solicitado la aprobación; Diego la concede, y el motivo queda exigido y registrado en el acta de la aprobación, no en una nota aparte: el acto firmado .froga/acts/NNNN-approve.json (un sobre DSSE ECDSA-P256, verificado contra signers:) registra quién aprobó por su firma, el acta del portal guarda por qué, y junto a ambos está el paquete VERDE firmado.
Reason: «Aprobación en VERDE: el gate de minimización de datos RGPD (minors-data-minimization, k-anonimato del trío edad/dirección/tamaño de familia) certifica con margen amplio (k=27 sobre el umbral 5, IC95≈[18,37]) y la paridad demográfica por sexo es un control audit certificado verde en paralelo (0.014, muy por debajo de 0.08). El riesgo risk.opacity (decisiones automatizadas sin explicabilidad) mantiene un residual agregado por encima del apetito del programa (nivel Critical vs criterio Medium, prEN 18228 cl.10 / Art.9(5)): su único control (accuracy-floor) es audit, sin una reducción de likelihood declarada. Dirección acepta conscientemente ese residual, con revisión periódica anual (P1Y) programada — el motor no certifica lo que el programa no ha reducido; lo certificado es el gate de minimización de datos y la equidad.»
Quien lea el repositorio más adelante ve las tres cosas a la vez: el gate cerró en verde, y queda un residual reconocido y aceptado, y por qué. Eso es lo opuesto al teatro del cumplimiento: un verde no es «nada que vigilar», y aquí queda documentado qué sigue en observación.
Marta cierra su parte del ciclo desde la CLI. Con la V2 en VERDE firmada, emite la conformidad y el reconstruct sobre las normas aplicables, ejecuta la Declaración de Aplicabilidad (SoA) y solicita la aprobación:
patch: entitlement.patchfroga conformance --standard eu/pren-18228@2026 --outmay failfroga conformance --standard iso/23894@2023 --outmay failfroga conformance --standard eu/ai-act@2024 --outmay failfroga reconstruct --outmay failgit add -Agit commit -m ".froga: conformance + reconstruct firmados"
froga soa
solicitud de aprobación (el acto lo commitea froga request)La aprobación es de Diego y solo de Diego (arriba): Marta la solicitó con el acto anterior, no puede concederla ella misma. Cuando el acto firmado .froga/acts/NNNN-approve.json de Diego aterriza —con el residual de opacidad aceptado conscientemente—, Marta re-emite la conformidad para que froga derive el ciclo de la historia git, ahora con la aprobación real (la cláusula 11 de prEN 18228 —revisión de gestión de riesgo— pasa de Gap a Cubierta):
froga conformance --standard eu/pren-18228@2026 --outmay failfroga conformance --standard iso/23894@2023 --outmay failfroga conformance --standard eu/ai-act@2024 --outmay failfroga reconstruct --outmay failgit add -Agit commit -m ".froga: re-emisión de conformance + reconstruct tras aprobar (cl.11 = Approved)"
El sistema queda declarado, tratado, firmado y aprobado en verde con el residual restante en acta: el final del arco, con la aprobación de Diego anclada en la etiqueta student-v2.0.0-approved de arriba.
Aprobar en verde, con el residual de explicabilidad en acta
La minimización de datos cierra en verde con margen amplio (k=27 sobre el umbral 5). El riesgo de opacidad (Art. 13) queda sin control bloqueante y su residual excede el apetito del programa. Diego acepta ese residual con motivo.El cierre del hito 4 no es el final del ciclo, es el principio de su mantenimiento. El froga.yaml declaró review_interval: P1Y: el sistema se comprometió a revisar el gate y el residual con cadencia anual (ISO 23894 §6.6, la supervisión continua del Art. 14) — incluso estando verde. Diego ejecuta esa revisión desde el portal — y la revisión no es un sello más, reabre el ciclo:
El acto firmado .froga/acts/NNNN-review.json posterior a la aprobación suspende el sello anterior: el motor deriva el estado «en revisión periódica» (froga status lo dice sin ambages: «Sistema en revisión periódica (ISO 23894 §6.6). Compliance debe re-aprobar el sistema.»). La aprobación de arriba deja de bastar: hay que re-validar y volver a aprobar. El turno pasa a Marta: revisar un gate verde significa volver a medirlo, no darlo por sentado.
Cuando Marta publica la evidencia re-medida (columna de la derecha) y la re-solicita, Diego cierra el bucle otra vez — pero con una condición que es el corazón del hito:
Reason: «Re-aprobación tras la revisión periódica (P1Y): la re-medición V2.0.1 confirma el mismo gate verde de minimización RGPD (k-anonimato del trío edad/dirección/tamaño de familia, k=27 sobre el umbral 5) y la misma paridad demográfica certificada (0.014 << 0.08). El residual de risk.opacity (nivel Critical vs criterio Medium, prEN 18228 cl.10 / Art.9(5)) se acepta de nuevo conscientemente: no se maquilla, se re-valida en acta sobre evidencia fresca.»
Diego re-aprueba sobre la evidencia fresca, y el motivo lo vuelve a exigir el acta: la re-medición confirmó el mismo gate verde (k=27 sobre el umbral 5) y el mismo residual de opacidad, así que ambos no se dan por sentados, se re-validan conscientemente. El sistema vuelve a «aprobado», ahora anclado a la V2.0.1 (froga status: «Aprobación de dirección … Diego Demo», apuntando a la re-aprobación). Como entre la revisión y la re-aprobación hubo evidencia nueva, el aprobador vigente es sencillamente esta re-aprobación sobre el bundle fresco — la cadena de aprobaciones arranca de cero con la evidencia nueva (el caso de la cadena sobre el mismo bundle, con aprobador efectivo, lo verás en el Nivel 4).
La revisión de Diego devuelve la pelota a Marta: §6.6 → §6.7, la revisión del riesgo puede exigir volver a tratar o, como aquí, volver a medir. Marta re-corre la barrera con los mismos parámetros —no toca el modelo ni la semilla— para producir evidencia fresca:
froga rungit add -Agit commit -m "run: re-medición V2.0.1 ante la revisión periódica (mismo params; gate verde confirmado; seed=42)"
La re-medición V2.0.1 vuelve a anclar la terna al estado git actual (el triple.code del bundle se actualiza) y el bundle deja de arrastrar el treatment_event heredado —es una medición nueva, no la del tratamiento—, pero el veredicto no cambia: sigue VERDE. El k-anonimato sigue en 27, sobre el mismo umbral 5: re-medir no degrada lo que no ha cambiado. Eso es exactamente lo que la revisión debe comprobar — que el gate sigue donde estaba, con evidencia al día —, no darlo por sentado. Marta re-solicita la aprobación sobre esta evidencia fresca:
re-solicitud de aprobación sobre la evidencia fresca V2.0.1 (el acto lo commitea froga request)El turno vuelve a Diego, que re-aprueba (columna del medio). La lección del hito: una aprobación en verde no es un cierre para siempre — la revisión periódica la reabre, te devuelve a medir, y el gate se re-confirma con evidencia fresca en acta, nunca se asume.