# Capordia — 전환 및 재개 실습, 버전 1.0.0

이 CPU 실습은 연속 처리와 중단된 처리를 비교합니다. 중단된 처리는 다른
폴더로 복사된 뒤 새 프로세스에서 재개됩니다. 이를 통해 어떤 배치가
완료되었는지, 진행 중인지, 재개해야 하는지 확인할 수 있습니다. 이 실습은
어떤 GPU도 측정하지 않으며 무중단 마이그레이션을 입증하지도 않습니다.

## 실습 준비

Python 3.10 이상과 표준 모듈 `sqlite3` 및 `hashlib`를 사용하며, 쓰기
가능한 로컬 디스크에서 실행합니다. 패키지, 네트워크 접근, 계정, 비밀
정보, 관리자 권한은 필요하지 않습니다. 폴더의 모든 파일을 추출한 뒤,
해당 폴더에서 터미널을 엽니다. 시스템이 `python3` 또는 `py -3`를
사용한다면 명령에서 `python`을 바꿔 사용합니다. 스크립트와 입력
집합은 스크립트가 생성하는 작업 폴더와 별도로 유지됩니다.

이 실습을 운영 폴더나 네트워크 공유에서 실행하지 마십시오. 존재하지
않는 작업 폴더 이름을 선택하십시오. 프로그램은 기존 폴더를 재사용하거나
덮어쓰는 것을 거부합니다.

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

이 명령은 `essai-capordia/rapport-verification.json`과 각 시나리오의
폴더를 생성합니다. 모든 검사가 성공한 경우에만 코드 0으로 종료됩니다.
새로운 시도를 하려면 새 이름으로 다시 실행하십시오. 이 명령은 이전
시도를 삭제하지 않습니다.

## 예시: 가상 쿠폰 여덟 배치

여덟 개의 CSV 파일은 각각 여섯 개의 원본이며 가상인 치수 측정값을
포함합니다. 각 행은 `coupon`, `cible_um`, `mesure_um`을 포함합니다.
단위는 정수 마이크로미터입니다. 어떤 수치도 운영 장비나 고객으로부터
온 것이 아닙니다. 각 배치에 대해 처리는 쿠폰 수, 절대 편차의 합계와
최댓값, 그리고 15 µm 이하인 편차의 개수를 계산합니다. 이 임계값은
실습 규칙이며 권장되는 산업 공차가 아닙니다.

결과는 배치 번호, 레시피 버전, 입력의 SHA-256 해시를 포함합니다.
여기서 정수를 사용하면 정확한 비교가 가능합니다. 부동소수점 연산을
사용하는 GPU 워크로드는 자체적인 비교 규칙과 정당화된 공차가
필요합니다.

## 상태 읽기

| 레지스트리 내 상태 | 이 실습에서의 의미 | 재개 시 처리 |
|---|---|---|
| `termine` | 결과가 승인되고 상태가 동일 트랜잭션에 기록됨 | 확인하고, 재계산하지 않음 |
| `en_cours` | 시도가 선언되었으나 승인된 결과가 없음 | 이전 권한을 검토한 뒤 재개를 허용 |
| `a_reprendre` | 시작되지 않았거나 명시적으로 재대기된 배치 | 시도를 실행 |

LOT-004에 주입된 중단 이후: LOT-001부터 LOT-003은 완료되었고,
LOT-004는 진행 중이며, LOT-005부터 LOT-008은 재개 대상입니다.
LOT-004의 어떤 결과도 승인되지 않습니다. `preparer-reprise` 이후에는
완료된 배치 세 개와 재개할 배치 다섯 개가 남습니다. 마지막에는 여덟
결과가 모두 참조 결과와 같아야 합니다. LOT-004만 시도가 두 번입니다.

## 전환을 단계별로 재현하기

다음 경로는 `exercice.py`가 있는 폴더를 기준으로 한 상대 경로입니다.
중단은 계산 후 승인 전에 주입된 예외입니다. 이 단계에서 코드 75는
예상된 결과입니다. 프로세스는 중지되고 잠금을 해제합니다. 이는
컴퓨터의 갑작스러운 종료나 정전이 아닙니다.

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

`basculer`는 로컬 잠금을 획득하고, 데이터 집합을 검사하고, 소스를
종료하고, SQLite 연결을 닫고, 폴더를 복사합니다. 복사본은 검증이
끝날 때까지 종료된 상태로 유지됩니다. 이후에는 대상만이 결과를
생성하도록 허용됩니다. 종료된 소스에서 실행 명령을 시작하면
`SOURCE_CLOTUREE`와 함께 코드 2를 반환합니다.

La commande de comparaison exige huit résultats acceptés de chaque côté,
vérifie leurs entrées et leurs sorties, puis compare une sérialisation JSON
canonique des résultats. Les exports texte peuvent être reconstruits depuis
SQLite : ils ne sont pas l'autorité qui décide si un résultat est accepté.

## Les fichiers produits

| Fichier | Rôle |
|---|---|
| `registre.sqlite` | État de référence, tentatives, propriétaire, clôture et résultats acceptés |
| `manifeste.json` et `donnees/` | Jeu d'entrées figé avec les empreintes attendues |
| `etat.json` | État lisible et décompte des trois statuts |
| `registre-lots.csv` | Export : id, etat, tentatives, entree_sha256, sortie_sha256 |
| `resultats.json` | Export des résultats acceptés, dans l'ordre des identifiants |
| `rapport-verification.json` | Dans le dossier global de démonstration : contrôles, environnement et sorties des commandes |
| `worker.lock` | Verrou temporaire de notre programme, retiré lors de sa sortie normale ou de la coupure injectée |

Le fichier `registre-lots-vierge.csv` fourni dans la ressource est un modèle
plus large pour votre équipe. Il ajoute responsable, machine autorisée,
critère d'acceptation et raison de reprise. Il ne remplace pas la base de
l'exercice et n'est pas importé par le programme.

## Les erreurs vérifiées

La démonstration teste aussi la relance d'un travail terminé, le rejet d'une
seconde acceptation du même lot, une entrée modifiée, un identifiant dupliqué
dans le manifeste, une sortie altérée, un verrou déjà présent et une exception
à l'intérieur de la transaction d'acceptation. Ce dernier cas laisse trois
sorties acceptées, pas quatre, puis retrouve les huit résultats après reprise.
Le retour est testé en copiant l'état récent de la cible dans un troisième
dossier, en clôturant la cible. On ne réactive pas l'ancien instantané.

Les codes de sortie sont : 0 réussite ; 2 refus métier attendu ; 75 coupure
injectée attendue ; 1 erreur de lecture ou de base. Le scénario global attend
explicitement les refus qu'il provoque. Une autre erreur fait échouer l'essai.

## Limites à garder avec les résultats

Un seul worker participe à cet exercice. Le verrou et le champ de clôture
fonctionnent dans les dossiers locaux manipulés par ce programme. Ils
n'empêchent pas une personne de recopier la base ou un autre programme
d'ignorer le verrou. Ce n'est pas du fencing distribué. Avant une véritable
bascule, l'ancienne machine doit perdre son droit de publier par un mécanisme
indépendant et testé. Si son arrêt n'est pas confirmé, on ne démarre pas une
seconde autorité.

Une transaction regroupe ici résultat et statut dans **la même base locale**.
Elle ne couvre pas un envoi vers un système externe, une notification ou un
fichier déjà consommé ailleurs. L'absence de double acceptation vérifiée se
limite à cette base et à cet exercice. SHA-256 détecte ici un écart entre
octets et empreinte attendue ; un manifeste modifiable avec les données
n'authentifie pas leur origine.

Si un processus est tué brutalement, le verrou peut rester présent. Vérifier
son arrêt réel avant toute intervention manuelle ; l'exercice ne supprime
jamais automatiquement un verrou jugé ancien. Une interruption de copie
laisse la source clôturée : conserver les dossiers et examiner l'incident,
sans remettre deux copies en activité. La perte d'alimentation, les systèmes
de fichiers réseau, la concurrence entre machines, les pilotes GPU, les
checkpoints de frameworks et les performances ne sont pas qualifiés ici.

## Résultat de notre contrôle

Le 24 septembre 2026, sous Windows AMD64, Python 3.14.6 et SQLite 3.50.4 :
16 contrôles réussis, 37 commandes exécutées, 8 résultats acceptés identiques
après bascule. La preuve consultable est `preuve-execution-cpu.json`.
L'empreinte des résultats canoniques est
`bde1bc833092cc8ca481cda5f44cfef36f14f0a94dff3f856624e169f5456660`.
Ces chiffres décrivent ce jeu de 48 lignes et ne sont pas un benchmark GPU.

Voir [PROCEDURE.md](PROCEDURE.md) pour les responsabilités et le retour,
[SOURCES.md](SOURCES.md) pour les sources primaires, et [LICENSE.txt](LICENSE.txt)
pour les conditions de réutilisation.
