159 lines
12 KiB
Markdown
159 lines
12 KiB
Markdown
Fiche VERR1-SPEC — Niveau N2 — Modèle prévu opus | utilisé claude-opus-5-5 — Agent orchestrateur (session « Piège du verrou ») — Skills lp-lot, boss.md (lus)
|
||
# VERR1-SPEC : piège du verrou (`New-Item` non atomique) dans `sk-repo` § 2 et `lp-repo` (2026-10-11)
|
||
|
||
Lot DOC de report VERR1, projet AG (organisation des agents), copie `D:\Game\LifePlay-master 5.8` (branche `ue5.8`).
|
||
Origine : écart E1 du lot OUTC (`etat\OUTC\OUTC-T2-IMPL.md` § 2), signalé à ORGA1 après ses commits ; ORGA1 excluait
|
||
`sk-repo` et `lp-repo` de son périmètre, OUTC aussi (`OUTC-SPEC.md` § 5 : « lot DOC séparé, décision E5 »).
|
||
Aucun usage de la copie UE, aucun MCP.
|
||
|
||
## 1. Fait à porter (sources)
|
||
|
||
- **Mesure OUTC** (`OUTC-T2-IMPL.md` § 2 E1) : pwsh 7.6.6, 100 tours de 8 threads sur une `Threading.Barrier`, tous
|
||
`New-Item -ItemType Directory -Path <même chemin> -ErrorAction Stop` : 1 seul succès dans 12 tours, **plusieurs
|
||
succès dans 88 tours**. `CreateDirectoryW` (kernel32) : 1 succès dans 100 tours sur 100 ; second appel : erreur 183.
|
||
Retenu dans `Tools\Verrou.ps1` (`New-DossierAtomique`, l. 75-84), commité `f4ac257` (CHG-329).
|
||
- **Contre-essai VERR1** (`VERR1-essai-mkdir.ps1`, sortie `VERR1-essai-mkdir.txt`, même montage, base créée, 100
|
||
tours) : `mkdir` de pwsh (fonction qui appelle `New-Item`, vérifié par `(Get-Command mkdir).Definition`) : 8 tours à
|
||
un succès, **92 à plusieurs** ; `/usr/bin/mkdir` de Git Bash (`C:\Program Files\Git\usr\bin\mkdir.exe`) : **1 succès
|
||
dans 100 tours sur 100**. Une première passe à base absente (Git Bash 0 succès, faute de parent) est écartée.
|
||
- Conséquence : deux gardiens peuvent se croire titulaires du même `k+1` si le dossier est créé par `New-Item` ou par
|
||
le `mkdir` de pwsh, alors que `sk-repo` § 2 dit « `mkdir` … (opération atomique) » sans préciser le shell.
|
||
- Écart de chiffres à signaler (non corrigé ici) : CHG-329 écrit « 10 tours sur 60 à un seul succès », l'IMPL
|
||
« 12 sur 100 ». VERR1 cite l'IMPL.
|
||
|
||
## 2. Fichiers touchés, ordre
|
||
|
||
| # | Fichier | Dépôt | Opération |
|
||
|---|---|---|---|
|
||
| 1 | `~\.claude\skills\sk-repo\SKILL.md` | hors git | A.1 : ligne 22 complétée + paragraphe « Piège » après l. 29 |
|
||
| 2 | `D:\Game\LifePlay-Sandbox-5.8\Tools\claude\skills\sk-repo\SKILL.md` | addon, **non suivi** | recopie de 1 (MD5 identique), pas de commit (précédent ORGA1 Q3) |
|
||
| 3 | `D:\Game\LifePlay-Sandbox-5.8\Tools\claude\skills\lp-repo\SKILL.md` | addon `ue5.8` (HEAD `22dd7c3`) | A.2 : § 4 puce `VERROU\` complétée + puce au § 10 |
|
||
| 4 | `D:\Game\LifePlay-Sandbox\Tools\claude\skills\lp-repo\SKILL.md` | addon `lot/DC3-atelier` (HEAD `083a3a0`) | recopie octet pour octet de 3 (copie chargée par les deux jeux : jonction `.claude\skills`) |
|
||
| 5 | journal (CHG), index (plage), `NUMEROS.md`, livrables `etat\AG\VERR1\` | jeu | DOC de clôture sous jeton, après les commits addon |
|
||
|
||
MD5 de départ : `sk-repo` `ab3ac013…` ×2 ; `lp-repo` `a575c783…` ×2 ; LF, 0 CR. Ordre : R0 (instantanés
|
||
`VERR1-home`, `VERR1-addon58`, `VERR1-addon`, `VERR1` ; DÉCLARATION) → T1 (lp-writer, 1 à 4) → T1v (lp-validator) →
|
||
R1 / R2 (commits addon 5.8 puis 5.5, lp-gardien) → T2 (JOURNAL-DEMANDE, CHG, index, NUMEROS) → R3 (commit jeu) →
|
||
FIN-LOT. Pin du doc 21 l. 136 : ~~non touché (appartient à ARCH427)~~ **posé par VERR1 dans son commit du jeu** (R3), avec les HEAD des deux addons relevés à l'entrée du ticket (règle révisée par Big Boss pour tous les lots, 2026-10-12).
|
||
|
||
## 3. Repli
|
||
Avant commit : `Restore.ps1 -Lot VERR1-home|VERR1-addon58|VERR1-addon` (proposé, jamais lancé sans accord) ; après
|
||
commit : ticket `RESTORE` / `git revert` sur accord.
|
||
|
||
## 4. Questions
|
||
- **Q1** — Emplacement : `sk-repo` § 2 (règle générique : dossier créé par appel système direct) et `lp-repo` § 4 +
|
||
§ 10 (outil du projet : `Tools\Verrou.ps1`) — recommandé ; sinon tout dans `lp-repo`.
|
||
- **Q2** — `sk-repo` de l'addon 5.8 reste non suivi, gardé identique par MD5 sans commit (recommandé, comme ORGA1 Q3).
|
||
- Hors périmètre (suite proposée, non faite) : `lp-repo` § 7 pourrait nommer `Tools\Numero.ps1` pour les réservations ;
|
||
écart de chiffres de CHG-329 (§ 1).
|
||
|
||
## 5. Interdits
|
||
Aucun autre fichier que ceux du § 2 ; aucune règle sans source ; pas de pin ; rien sur le journal hors jeton ; aucune
|
||
commande git qui écrit hors du gardien ; rien poussé.
|
||
|
||
## 6. Critères de VAL (commande → attendu)
|
||
1. `md5sum` des deux `sk-repo` égaux ; `cmp` des deux `lp-repo` → 0 différence.
|
||
2. `diff` contre l'instantané : `sk-repo` 1 ligne modifiée (l. 22) + ajouts ; `lp-repo` 1 ligne modifiée (§ 4) + ajouts
|
||
; rien d'autre.
|
||
3. Textes = annexe A ; chiffres (88 / 100, 92 / 100, 100 / 100, l. 75-84, `f4ac257`, CHG-329) = sources (`sed -n` sur
|
||
`OUTC-T2-IMPL.md` l. 21, `VERR1-essai-mkdir.txt`, `Tools/Verrou.ps1`, `git log`).
|
||
4. `grep -c "New-Item"` ≥ 1 dans chaque fichier ; `grep -c "OUTC-T2-IMPL"` ≥ 1 dans chaque fichier.
|
||
5. Fins de ligne : 0 CR (`tr -cd '\r' | wc -c`) sur les 4 fichiers ; `git ls-files --eol` `i/lf w/lf` pour `lp-repo`.
|
||
6. `git status --short` des deux addons = état d'entrée + `lp-repo/SKILL.md` modifié.
|
||
|
||
## Annexe A — textes exacts
|
||
|
||
### A.1 `sk-repo/SKILL.md`
|
||
Ligne 22 remplacée par :
|
||
```markdown
|
||
Verrou sans suppression de fichier, fondé sur `mkdir`, qui échoue si le dossier existe (opération atomique **par un
|
||
appel système direct seulement** : piège ci-dessous) :
|
||
```
|
||
Inséré après la ligne 29 (« Les dossiers s'accumulent … (§ 6). ») :
|
||
```markdown
|
||
**Piège (mesuré)** : sous pwsh 7, `New-Item -ItemType Directory` sans `-Force`, et le `mkdir` de pwsh (fonction qui
|
||
l'appelle), **ne sont pas atomiques** : 8 threads créant le même dossier, plusieurs succès dans 88 tours sur 100 (lot
|
||
OUTC de LifePlay, `etat\OUTC\OUTC-T2-IMPL.md` § 2 E1) et 92 sur 100 (contre-essai, `etat\AG\VERR1\VERR1-SPEC.md` § 1).
|
||
Les `mkdir` des étapes 3 et 4 se font donc par le script de verrou du projet (`CreateDirectoryW`, 1 succès dans 100
|
||
tours sur 100) ou par `/usr/bin/mkdir` de Git Bash (1 succès dans 100 tours sur 100), jamais par `New-Item` ni par le
|
||
`mkdir` de pwsh.
|
||
```
|
||
|
||
### A.2 `lp-repo/SKILL.md`
|
||
§ 4, ligne 44 remplacée par :
|
||
```markdown
|
||
- `VERROU\` (verrou du gardien et des réservations, `sk-repo` § 2) : `Tools\Verrou.ps1 -Prendre <ticket> -Session
|
||
<s>`, `-Rendre -Ticket <ticket>`, `-Etat` (codes 0 pris, rendu ou libre ; 1 occupé, refusé ou déjà libre ; 2 erreur),
|
||
ou `mkdir` de Git Bash ; jamais `New-Item` (§ 10).
|
||
```
|
||
§ 10, puce ajoutée en fin de liste :
|
||
```markdown
|
||
- Verrou : `New-Item -ItemType Directory` sans `-Force` et le `mkdir` de pwsh ne sont pas atomiques (8 threads, plusieurs
|
||
succès dans 88 tours sur 100) ; `Tools\Verrou.ps1` crée le dossier par `CreateDirectoryW` (`New-DossierAtomique`,
|
||
l. 75-84 ; 1 succès sur 100 / 100), commité `f4ac257` (CHG-329). Source : lot OUTC, `etat\OUTC\OUTC-T2-IMPL.md` § 2
|
||
E1 ; contre-essai `etat\AG\VERR1\VERR1-SPEC.md` § 1 (Git Bash `mkdir` : 1 succès sur 100 / 100).
|
||
```
|
||
|
||
---
|
||
|
||
## Avenant 1 (2026-10-12) — trois règles de gardien, demande de Big Boss
|
||
|
||
Big Boss (`[9f1d99]`, réservation VERR1 accordée le 2026-10-12) demande de proposer à l'utilisateur, **en avenant**,
|
||
trois règles relevées depuis la reprise et qui touchent `sk-repo` / `lp-repo` (P7 n'y touche pas). Sans accord de
|
||
l'utilisateur : non écrites. **Approuvé par l'utilisateur le 2026-10-12 : B1, B2 et B3** (réponse dans la session VERR1). Sources (`etat\BOSS\BOSS-JOURNAL.md`, « BOSS l. N ») :
|
||
- **B1 reprise de son propre verrou** : verrou 105 pris par OUTC-R1 le 2026-10-11 à 07:32, gardien coupé (limite
|
||
hebdomadaire), repris le 2026-10-12 par un gardien neuf sur consigne de Big Boss (BOSS l. 326, 327 ;
|
||
`etat\REPO\VERROU\105\qui.txt` porte la ligne de reprise) ; `sk-repo` § 2 ne prévoit que « signalé, jamais forcé ».
|
||
- **B2 ordre « fait » et commit** : `lp-repo` § 4 R-REPO1 écrit « fait » et la ligne de `REPO-JOURNAL.md` **avant** le
|
||
commit ; `sk-repo` § 4 étape 7 met `fait (<hash>)` **après**. La coupure a laissé OUTC-R1 « fait » sans commit
|
||
(BOSS l. 326, 328 ; `OUTC-TACHES.md` ligne OUTC-R1).
|
||
- **B3 nom cherché** : la cellule de contrôle de la ligne OUTC-R1 de `REPO-JOURNAL.md` portait le nom d'utilisateur
|
||
Windows cherché, corrigée par OUTC-R2 (`d1f7ce5`, toujours présent dans `f4ac257`, historique local) ; ORGA1-R3
|
||
refusé une première fois pour la même raison (BOSS l. 322).
|
||
- Effet sur le § 6 (VAL) : comptes de lignes recalculés par la fiche T1 ; `Verrou.ps1 -Rendre -Ticket` accepte un
|
||
`qui.txt` à plusieurs lignes (motif `^<ticket>` sur le texte joint, `Get-Qui` l. 99-120, lu le 2026-10-12).
|
||
|
||
### B.1 `sk-repo/SKILL.md`
|
||
§ 2, inséré après le paragraphe « **Piège (mesuré)** » de A.1 :
|
||
```markdown
|
||
**Reprise après interruption** : un gardien coupé (limite d'API, arrêt de session) laisse `<k>` sans `<k>-libre`. Un
|
||
gardien neuf ne reprend ce verrou que pour **le même ticket** et sur consigne écrite de l'orchestrateur, si
|
||
`<k>/qui.txt` commence par ce ticket, qu'aucun commit ne le porte (`git log --grep <ticket>`), sans `index.lock` ni
|
||
opération en cours ; il ajoute à `qui.txt` la ligne `repris le <date> par <session>, même ticket <ticket>`, reprend le
|
||
ticket à l'étape 2 du § 4 et crée `<k>-libre` à la fin. Autre ticket, `qui.txt` illisible ou doute : rien d'écrit,
|
||
`BLOCKED-VERROU`. Source : LifePlay, OUTC-R1 (verrou 105, pris le 2026-10-11, repris le 2026-10-12 ; BOSS l. 327).
|
||
```
|
||
§ 4, ligne de l'étape 7 remplacée par :
|
||
```markdown
|
||
7. **Suite** : tag, puis pin (§ 5) ; ligne au journal (§ 7) ; statut `fait (<hash>)` ; verrou rendu. Si le projet
|
||
emporte le ticket et sa ligne de journal dans le commit (LifePlay : R-REPO1, `lp-repo` § 4), statut `fait` et ligne
|
||
s'écrivent juste avant l'étape 5, sans hash ; commit en échec : statut `refusé`, ligne de journal corrigée.
|
||
```
|
||
§ 4, inséré après la ligne « Échec à une étape : … verrou rendu. » :
|
||
```markdown
|
||
**Statut `fait` sans commit** (`git log --grep <ticket>` vide) = passage interrompu, jamais un ticket fait : le gardien
|
||
suivant le signale, l'orchestrateur remet le statut à `demandé` et relance (reprise du verrou : § 2). Source :
|
||
LifePlay, OUTC-R1 marqué `fait` sans commit après la coupure du 2026-10-11 (BOSS l. 326, 328).
|
||
```
|
||
§ 9, ajouté en fin de section :
|
||
```markdown
|
||
Contrôle de donnée personnelle (nom d'utilisateur, adresse, dossier personnel) : la valeur cherchée se lit dans une
|
||
variable (`$env:USERNAME`) et ne s'écrit jamais, ni dans une commande citée, ni dans un ticket, un journal ou un
|
||
livrable ; la trace dit « nom d'utilisateur : 0 occurrence ». Source : LifePlay, ligne OUTC-R1 de `REPO-JOURNAL.md`
|
||
corrigée par OUTC-R2 (`d1f7ce5`) ; ORGA1-R3 refusé une première fois (BOSS l. 322).
|
||
```
|
||
|
||
### B.2 `lp-repo/SKILL.md`
|
||
§ 4, ligne R-REPO1 : ajouter en fin de ligne (après « l'arbre est propre après chaque ticket. Un refus s'écrit de même
|
||
(statut `refusé`, ligne de journal) sans commit. ») la phrase :
|
||
```markdown
|
||
Un ticket `fait` sans commit (`git log --grep <ticket>` vide) = passage interrompu (`sk-repo` § 4).
|
||
```
|
||
§ 10, deux puces ajoutées après la puce A.2 :
|
||
```markdown
|
||
- Reprise d'un verrou après interruption (`sk-repo` § 2) : `Tools\Verrou.ps1` n'a pas d'action de reprise ; la ligne
|
||
de reprise s'ajoute à `qui.txt`, puis `Verrou.ps1 -Rendre -Ticket <ticket>` en fin de ticket (verrou 105, OUTC-R1,
|
||
2026-10-12).
|
||
- Trace d'un contrôle de nom d'utilisateur : le nom ne s'écrit jamais (`sk-repo` § 9) ; la ligne OUTC-R1 de
|
||
`REPO-JOURNAL.md` le portait (corrigée par OUTC-R2, `d1f7ce5` ; reste dans `f4ac257`, historique local non poussé).
|
||
```
|