# Capordia — ejercicio de conmutación y reanudación, versión 1.0.0

Este ejercicio de CPU compara un procesamiento continuo con un procesamiento interrumpido,
copiado en otra carpeta y reanudado en un nuevo proceso. Permite
comprobar qué lotes están terminados, en curso y por reanudar. No mide
ningún GPU y no demuestra una migración sin interrupción.

## Preparar el ejercicio

Usar Python 3.10 o más reciente con los módulos estándar `sqlite3` y
`hashlib`, en un disco local con permisos de escritura. No se necesita ningún paquete, acceso de red,
cuenta, secreto ni administrador. Extraer todos los archivos
de la carpeta y abrir un terminal en esa carpeta. Si el sistema usa
`python3` o `py -3`, reemplazar `python` en los comandos. El script y el
conjunto de entradas permanecen separados de las carpetas de trabajo que crea.

No ejecutar este ejercicio en una carpeta de producción o en un recurso compartido
de red. Elegir un nombre de carpeta de trabajo que no exista: el programa
se niega a reutilizar o sobrescribir una carpeta existente.

```text
python ejercicio.py demonstration --dossier essai-capordia
```

Este comando crea `essai-capordia/rapport-verification.json` y las carpetas
de cada escenario. Termina con el código 0 solo si todos los
controles se superan. Volver a ejecutar con un nuevo nombre para un nuevo ensayo.
El comando no borra ningún ensayo anterior.

## Nuestro ejemplo: ocho lotes de cupones ficticios

Los ocho CSV contienen cada uno seis medidas dimensionales originales y
ficticias. Cada línea contiene `coupon`, `cible_um` y `mesure_um`. Las unidades
son micrómetros enteros. Ninguna cifra proviene de una máquina de
producción o de un cliente. Para cada lote, el procesamiento calcula el número
de cupones, la suma y el máximo de las desviaciones absolutas, y el número de desviaciones
menores o iguales a 15 µm. Este umbral es una regla de ejercicio, no una
tolerancia industrial recomendada.

El resultado contiene el número de lote, la versión de la receta y la huella
SHA-256 de la entrada. El uso de enteros permite aquí una comparación exacta.
Una carga de GPU con cálculos de coma flotante requeriría su propia regla de
comparación y tolerancias justificadas.

## Leer los estados

| Estado en el registro | Significado en este ejercicio | Procesamiento al reanudar |
|---|---|---|
| `termine` | Resultado aceptado y estado registrado en una misma transacción | Verificar; no recalcular |
| `en_cours` | Intento declarado, ningún resultado aceptado | Examinar la antigua autoridad y luego autorizar la reanudación |
| `a_reprendre` | Lote no iniciado o intento devuelto explícitamente a la cola | Ejecutar un intento |

Tras el corte inyectado en LOT-004: LOT-001 a LOT-003 están terminados,
LOT-004 está en curso, LOT-005 a LOT-008 están por reanudar. Ningún resultado de
LOT-004 se acepta. Tras `preparer-reprise`, quedan tres terminados y
cinco por reanudar. Al final, los ocho resultados deben ser iguales a los
de la referencia. Solo LOT-004 tiene dos intentos.

## Rehacer la conmutación paso a paso

Las rutas siguientes son relativas a la carpeta que contiene `exercice.py`.
El corte es una excepción inyectada después del cálculo y antes de la aceptación;
el código 75 en esta etapa es esperado. El proceso se detiene y libera su
bloqueo. No es ni un apagado brusco del ordenador ni un fallo eléctrico.

```text
python ejercicio.py initialiser --dossier manuel/reference --proprietaire reference
python ejercicio.py executer --dossier manuel/reference
python ejercicio.py initialiser --dossier manuel/source --proprietaire atelier-source
python ejercicio.py executer --dossier manuel/source --interrompre-sur LOT-004
python ejercicio.py etat --dossier manuel/source
python ejercicio.py basculer --source manuel/source --destination manuel/cible --proprietaire atelier-cible
python ejercicio.py preparer-reprise --dossier manuel/cible
python ejercicio.py executer --dossier manuel/cible
python ejercicio.py comparer --reference manuel/reference --candidat manuel/cible
```

`basculer` toma el bloqueo local, controla el conjunto, cierra la fuente, cierra
las conexiones SQLite y copia la carpeta. La copia permanece cerrada hasta
el final de su verificación; solo la cible (destino) queda después autorizada a producir.
Un comando de ejecución lanzado sobre la fuente cerrada devuelve el código 2
con `SOURCE_CLOTUREE`.

La orden de comparación exige ocho resultados aceptados de cada lado,
verifica sus entradas y sus salidas, y luego compara una serialización JSON
canónica de los resultados. Las exportaciones de texto pueden reconstruirse desde
SQLite: no son la autoridad que decide si un resultado es aceptado.

## Los archivos producidos

| Archivo | Función |
|---|---|
| `registre.sqlite` | Estado de referencia, intentos, propietario, cierre y resultados aceptados |
| `manifeste.json` y `donnees/` | Conjunto de entradas fijado con las huellas esperadas |
| `etat.json` | Estado legible y recuento de los tres estados |
| `registre-lots.csv` | Exportación: id, etat, tentativas, entree_sha256, sortie_sha256 |
| `resultats.json` | Exportación de los resultados aceptados, en el orden de los identificadores |
| `rapport-verification.json` | En la carpeta global de demostración: controles, entorno y salidas de los comandos |
| `worker.lock` | Bloqueo temporal de nuestro programa, retirado durante su salida normal o la interrupción inyectada |

El archivo `registre-lots-vierge.csv` proporcionado en el recurso es una plantilla
más amplia para tu equipo. Añade responsable, máquina autorizada,
criterio de aceptación y motivo de reanudación. No sustituye la base
del ejercicio y no es importado por el programa.

## Los errores verificados

La demostración también prueba el relanzamiento de un trabajo terminado, el rechazo de una
segunda aceptación del mismo lote, una entrada modificada, un identificador duplicado
en el manifiesto, una salida alterada, un bloqueo ya presente y una excepción
dentro de la transacción de aceptación. Este último caso deja tres
salidas aceptadas, no cuatro, y luego recupera los ocho resultados tras la reanudación.
El retorno se prueba copiando el estado reciente del destino en una tercera
carpeta, cerrando el destino. No se reactiva la instantánea anterior.

Los códigos de salida son: 0 éxito; 2 rechazo de negocio esperado; 75 interrupción
inyectada esperada; 1 error de lectura o de base de datos. El escenario global espera
explícitamente los rechazos que provoca. Cualquier otro error hace fallar la prueba.

## Límites que deben acompañar a los resultados

Un solo worker participa en este ejercicio. El bloqueo y el campo de cierre
funcionan en las carpetas locales manipuladas por este programa. No
impiden que una persona copie la base de datos o que otro programa
ignore el bloqueo. Esto no es fencing distribuido. Antes de una verdadera
conmutación, la máquina antigua debe perder su derecho a publicar mediante un mecanismo
independiente y probado. Si su parada no está confirmada, no se inicia una
segunda autoridad.

Una transacción agrupa aquí resultado y estado en **la misma base de datos local**.
No cubre un envío a un sistema externo, una notificación o un
archivo ya consumido en otro lugar. La ausencia de doble aceptación verificada se
limita a esta base de datos y a este ejercicio. SHA-256 detecta aquí una discrepancia entre
bytes y huella esperada; un manifiesto modificable junto con los datos
no autentica su origen.

Si un proceso se mata abruptamente, el bloqueo puede permanecer presente. Verifica
su parada real antes de cualquier intervención manual; el ejercicio nunca elimina
automáticamente un bloqueo considerado antiguo. Una interrupción de la copia
deja la fuente cerrada: conserva las carpetas y examina el incidente,
sin volver a poner en actividad dos copias. La pérdida de alimentación, los sistemas
de archivos de red, la concurrencia entre máquinas, los controladores GPU, los
checkpoints de frameworks y el rendimiento no se cualifican aquí.

## Resultado de nuestro control

El 24 de septiembre de 2026, en Windows AMD64, Python 3.14.6 y SQLite 3.50.4:
16 controles superados, 37 comandos ejecutados, 8 resultados aceptados idénticos
tras la conmutación. La prueba consultable es `preuve-execution-cpu.json`.
La huella de los resultados canónicos es
`bde1bc833092cc8ca481cda5f44cfef36f14f0a94dff3f856624e169f5456660`.
Estas cifras describen este conjunto de 48 líneas y no son un benchmark GPU.

Consulta [PROCEDURE.md](PROCEDURE.md) para las responsabilidades y el retorno,
[SOURCES.md](SOURCES.md) para las fuentes primarias, y [LICENSE.txt](LICENSE.txt)
para las condiciones de reutilización.
