20 KiB
Fiche PUB3-T3 — Niveau N2 — Modèle prévu opus | utilisé opus-5-5 (claude-opus-5-5, déclaré par l'environnement) — Agent orchestrateur PUB3 (session principale) — Skills lp-repo, sk-repo (lecture), sk-change-safety, sk-windows-shell
PUB3-T3-SPEC : remplacement, contrôle PubCheck, hooks, publication C2 (2026-10-13)
SPEC sur papier, GO de Big Boss du 2026-10-13 ([BOSS→PUB3] GO T3). Rien n'est appliqué : aucun fichier suivi
modifié, aucun script écrit dans Tools\, aucun hook installé, aucune branche créée. Le nom du compte s'écrit
<compte> ; toute valeur cherchée se lit dans une variable ($env:USERNAME, $env:COMPUTERNAME).
1. Décisions appliquées
| Source | Décision |
|---|---|
| Utilisateur, 2026-10-13 : « Q1 a, Q2 a, Q8 PUB3 ; le reste comme recommandé » | voie A puis publication C2 ; %USERPROFILE% ; 5.5 laissée ; addon par commit A ; branches anciennes laissées ; lot PUB3 |
| Utilisateur (Q6), relayé par Big Boss | PubCheck à l'étape du gardien + hook pre-push : approuvés |
| Big Boss, GO T3 | D-REPO5 (core.hooksPath, pre-commit) soumise à l'utilisateur : SPEC écrite avec et sans (§ 5) |
| Big Boss, GO T3 | T4 et suite : DÉCLARATION des fichiers puis JOURNAL-DEMANDE ; commit placé par Big Boss quand aucun lot n'a de fichier etat\ en cours sur les mêmes chemins |
| Big Boss, GO T3 | pub/ue5.8 préparée en local par le gardien ; le push reste un geste de l'utilisateur |
2. Fichiers du lot
2.1 Liste fermée du remplacement (T4)
Jeu 5.8, branche ue5.8 : 69 fichiers = lignes "jeu-5.8","ue5.8" de PUB3-T1-fichiers.csv (liste figée ;
aucun autre fichier n'est touché, même s'il contient le motif) :
Docs/Journal_Modifications.md(6 lignes d'entrées CHG anciennes),Docs/28_Synthese_Migration_UE58.md(2) ;- sous
Docs/Migration/etat/(67) :AG/AG-T1-CONCEPTION.md,AG/AG-T3-DOC.md,AG/AG-T8-VAL.md,AG/fiches/AG-T2.md,AG/fiches/AG-T3.md,DOC/ETAT3/ETAT3-T1-INV.md,DOC/ETAT3/ETAT3-T1-references-5.5.csv,DOC/ETAT3/ETAT3-T3-T5-IMPL.md,EDIT1/EDIT1-IMPL.md,ETAT-INVENTAIRE-PROPOSITION.md,ETAT2/ETAT2-T1-CART.md,ETAT2/ETAT2-T2-IMPL.md,OB/OBB/(OBB-T1-SPEC,OBB-T1-VAL,OBB-T1a-INV,OBB-T1b-IMPL,OBB-T1b-VAL,OBB-T3-IMPL,OBB-T3-VAL,OBB-T6-INV,OBB-T7b-BUILD),OB/OBP/(OBP-T1-DOC,OBP-T1-IMPL,OBP-T1-VAL,OBP-T2-IMPL,OBP-T2-VAL,OBP-TACHES),OUT1/OUT1-UASSET.md,REPO/tickets/(ETAT3-R3,ETAT3-R4,OBP-R4,OBP-R8),SK/(SK-ARBRE,SK-T2-SKILLS-WEB,SK-T4-V1a,SK-T4-V1c),ST/STA/(STA-T1-INV,STA-T2a-INV,STA-T2a2-INV),ST/STB/STB-GIB-DATA-INV.md,ST/STE/(STE-H3c-SPEC,STE-H4-DIAG,STE-P1-BUILD,STE-VAL,fiches/STE-H4,fiches/STE-H5c),ST/STF/(STF-J-BUILD,STF-T5-J-BUILD),TPL1/TPL1-VAL.md,U58/U0/(U0-COPIE,U0-VS2026),U58/U1/(U1-BP-58,U1-T4b-BUILD),U58/U3/U3-T3b-TEST.md,U58/U4/(U4-T4-BUILD,U4-T6-VAL),U58/U7/(U7-T14-BUILD,U7-T16-T7,U7-T6-CART,U7-T7-IMPL,U7-T8-BUILD,U7-T9-IMPL),U58/U7b/(U7b-T4-IMPL,U7b-T6-VAL),U58/U8/(U8-T4-BUILD,U8-T5c-VAL),U58/UA/UA-OUTILS.md(tous.mdsauf le.csvnommé).
État relevé le 2026-10-13 : aucun des 69 n'est modifié dans l'arbre (git status --porcelain ∩ liste = vide).
Fins de ligne : 65 en LF, 4 en CRLF (REPO/tickets/ETAT3-R3.md, ETAT3-R4.md, U58/U1/U1-BP-58.md,
U58/U7/U7-T14-BUILD.md), à conserver ; aucun BOM.
Addon : Tools/claude/skills/lp-doc/SKILL.md (1 ligne), sur ue5.8 (D:\Game\LifePlay-Sandbox-5.8) et
lot/DC3-atelier (D:\Game\LifePlay-Sandbox), deux tickets jumeaux (modèle P7-R1 / R2). C'est un skill : règle
d'autorisation du 2026-10-12 (SPEC approuvée par l'utilisateur, fichier réservé par Big Boss).
Hors liste : Docs/CG/CG-METHODE.md de l'addon 5.8 (non suivi, 2 lignes, lot CG) : signalé à Big Boss, pas
touché ; PubCheck l'arrêtera s'il est un jour commité. Copie 5.5 : rien (Q3).
2.2 Fichiers créés par le lot
| Fichier | Suivi | Rôle |
|---|---|---|
Tools/PubCheck.ps1 |
oui (jeu) | contrôle, § 4 |
Tools/hooks/pre-push |
oui (jeu) | source versionnée du hook, § 5 |
Tools/hooks/pre-commit |
oui, seulement si D-REPO5 | copie de etat\REPO\hooks\pre-commit + règle PubCheck, § 5.3 |
etat/AG/PUB3/PUB3-T4-remplacer.ps1 |
non (ignoré) | script de remplacement du lot, § 3 |
etat/AG/PUB3/PUB3-*.md, PUB3-T1-fichiers.csv |
oui | livrables |
Fichiers partagés touchés : Docs/Journal_Modifications.md (6 lignes anciennes + 1 entrée CHG : jeton),
Docs/README.md (plage CHG), etat/REPO/NUMEROS.md (réservation), skills lp-repo (2 addons) et sk-repo
(~/.claude/skills) au T7.
3. Remplacement (T4) : PUB3-T4-remplacer.ps1
- Entrée :
PUB3-T1-fichiers.csvfiltré sur un dépôt et une réf. (-Depot jeu-5.8 -Ref ue5.8ou-Depot addon-5.8 -Ref ue5.8, …), chemins relatifs à-Racine. - Motif :
(?i)C:\\Users\\+[regex]::Escape($env:USERNAME)+(?![A-Za-z0-9._-]); remplacement :%USERPROFILE%. - Par fichier : lecture en octets ; décodage UTF-8 strict (refus si invalide) ; BOM et fins de ligne conservés
(aucune normalisation : on remplace dans le texte décodé, on réencode à l'identique) ; compte avant, remplacement,
compte après = 0 ; nombre de lignes changées = colonne
Occurrencesdu CSV ; écriture seulement avec-Appliquer. - Sans
-Appliquer(défaut) : à blanc, sortiechemin ; avant ; lignes ; aprèssans aucune valeur. - Refus (code 2, rien écrit) si : un fichier de la liste est absent, modifié dans l'arbre (
git status), d'encodage non UTF-8, ou si un compte diffère du CSV. - Avant
-Appliquer:Tools\Snapshot.ps1 -Lot PUB3 -Path <69 chemins>(puis addon :-ProjectRootde chaque arbre, sousBackup_5.5\PUB3\addon58etaddon55). Retour arrière :Tools\Restore.ps1 -Lot PUB3(ougit restoredes chemins par le gardien, fichiers non encore commités). - Le remplacement se fait juste avant le ticket, quand Big Boss donne la fenêtre (§ 8), pour ne pas laisser 69 fichiers d'autres lots modifiés dans l'arbre.
4. Tools\PubCheck.ps1 (lecture seule)
4.1 Modes et sorties
| Mode | Ce qui est lu | Usage |
|---|---|---|
-Fichiers <chemins> |
contenu entier des fichiers de l'arbre | orchestrateur, avant de déposer un ticket |
-Index |
lignes ajoutées de l'index (git diff --cached -U0), plus les blobs binaires indexés |
gardien, étape 4 ; pre-commit (D-REPO5) |
-Pointe <sha> -Distant <remote> |
tous les commits de git rev-list <sha> --not --remotes=<remote> : blobs nouveaux entiers (texte et binaire), messages, auteur et committer |
pre-push ; contrôle de pub/ue5.8 |
-Arbre <ref> |
texte de tous les fichiers suivis à <ref> (git grep -I) ; -Binaires ajoute les blobs binaires |
inventaire, VAL |
Option commune : -Depot <dossier> (défaut : git rev-parse --show-toplevel du dossier courant).
Sortie : une ligne par constat, <où>:<ligne>:<CATÉGORIE> (<où> = chemin, ou <commit court>:<chemin> en
-Pointe), jamais la valeur ; dernière ligne PubCheck : <n> constat(s).
Codes : 0 net ; 1 constat ; 2 erreur (dépôt introuvable, git en échec, variable vide). Les hooks
refusent sur 1 et 2.
4.2 Motifs (construits à l'exécution)
| Catégorie | Motif | Admis (pas de constat) |
|---|---|---|
NOM |
(?i)(?<![A-Za-z0-9]) + $env:USERNAME échappé + (?![A-Za-z0-9]) |
— |
PROFIL |
`(?i)(?:[A-Za-z]: | /[a-z])[\/]{1,2}Users[\/]{1,2}suivi d'un caractère[A-Za-z0-9._-]` |
MACHINE |
$env:COMPUTERNAME, mot entier, casse ignorée |
— |
ADRESSE |
[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,} |
domaine users.noreply.github.com ; noreply@anthropic.com ; @example.(com|org|net) ; git@github.com |
IDENTITE (-Pointe) |
auteur ou committer hors *@users.noreply.github.com |
— |
BINAIRE |
NOM et MACHINE en ASCII et UTF-16LE, casse ignorée, dans un blob non texte |
— |
EXTRA (option) |
valeurs littérales lues dans le fichier pointé par $env:LP_PUB_MOTIFS (hors dépôt, jamais commité ; ex. l'adresse réelle, un nom civil) |
— |
Faux positifs écartés : mot gmail / googlemail sans @ ; motif du script lui-même (Users[\\/]… suivi de [) ;
sous-chaînes du nom de machine (mot entier). Variable vide → code 2 (jamais « 0 constat » par défaut).
4.3 Performance attendue
-Pointe ue5.8 -Distant origin (103 commits, 292 binaires, 127 Mo) en moins de 60 s ; -Index d'un ticket courant en
moins de 5 s. Lecture des blobs par un seul git cat-file --batch.
5. Hooks
5.1 Tools/hooks/pre-push (approuvé)
#!/bin/sh
# pre-push — PUB3 : refuse un push dont les commits non publics portent une donnée personnelle (Tools/PubCheck.ps1).
# Vaut pour tous, utilisateur compris (pas d'exemption LP_REPO_HUMAIN). Arguments git : $1 = remote, $2 = URL.
remote="$1"
PUBCHECK="${LP_PUBCHECK:-D:/Game/LifePlay-master 5.8/Tools/PubCheck.ps1}"
refus() { echo "pre-push : push refusé : $1" >&2; exit 1; }
command -v pwsh >/dev/null 2>&1 || refus "pwsh introuvable"
[ -f "$PUBCHECK" ] || refus "$PUBCHECK introuvable"
TOP=$(git rev-parse --show-toplevel) || refus "dépôt introuvable"
Z=0000000000000000000000000000000000000000
while read -r lref lsha rref rsha; do
[ "$lsha" = "$Z" ] && continue # suppression d'une ref distante : rien ne part
pwsh -NoProfile -File "$PUBCHECK" -Depot "$TOP" -Pointe "$lsha" -Distant "$remote" >&2 \
|| refus "$lref → $rref (PubCheck, voir ci-dessus)"
done
exit 0
- Chemin absolu de
PubCheck.ps1dans la copie 5.8 : un seul script sert le jeu 5.8, les deux arbres de l'addon et le jeu 5.5 (variableLP_PUBCHECKpour le déplacer). - Push vers une URL au lieu d'un remote nommé :
--remotes=<URL>ne trouve rien, tout l'historique de la pointe est relu (lent, mais refus seulement s'il y a un constat ;origin/mainest à 0). git push --no-verifypasse outre : garde-fou contre l'accident, pas contre un geste délibéré (même limite que lepre-commit,lp-repo§ 9).git pushreste refusé aux agents (settings.local.json).
5.2 Installation du pre-push sans D-REPO5 (aucune configuration git modifiée)
Copie du fichier dans le dossier de hooks par défaut de chaque dépôt, par un ticket CONFIG du gardien (un par
dépôt), cmp de contrôle, sans toucher git config :
| Dépôt | Destination (git rev-parse --git-common-dir) |
Couvre |
|---|---|---|
| jeu 5.8 | D:\Game\LifePlay-master 5.8\.git\hooks\pre-push |
ue5.8, pub/ue5.8, branches ue5.5-v1.x, claude/… |
| addon | D:\Game\LifePlay-Sandbox\.git\hooks\pre-push |
les deux arbres (ue5.8 et lot/DC3-atelier), dossier commun |
| jeu 5.5 | D:\Game\LifePlay-master 5.5\.git\hooks\pre-push |
main (6 commits non publics, 2 avec le nom) : aucune correction de fichier (Q3), seulement la barrière |
Contrôle préalable : git config --get core.hooksPath vide dans les trois (sinon .git\hooks est ignoré ; relevé
du 2026-10-13 : vide partout). Retour arrière : déplacer le fichier vers Backup_5.5\PUB3\hooks\<dépôt>\.
Un git clone neuf ou une recopie du dépôt n'emporte pas .git\hooks : à réinstaller (piège à verser dans lp-repo).
5.3 Variante avec D-REPO5 (core.hooksPath)
git config core.hooksPath "D:/Game/LifePlay-master 5.8/Tools/hooks"dans le jeu 5.8, l'addon (configuration commune aux deux arbres) et le jeu 5.5 ;Tools/hooks/contientpre-pushetpre-commit.pre-commit= celui d'etat\REPO\hooks\(ticket, identité,Mods/vide, fichiers interdits) avec une règle 0 placée avant la sortieLP_REPO_HUMAIN=1:pwsh -NoProfile -File "$PUBCHECK" -Depot "$TOP" -Index >&2 || refus "donnée personnelle dans l'index (PubCheck)".- Le
pre-pushde.git\hooks(§ 5.2) devient inopérant dès quecore.hooksPathest posé : on le retire (déplacé vers le Backup) dans le même ticket. - Effet de bord à faire valider par l'utilisateur : le
pre-commitd'etat\REPO\refuse tout commit sans ticket du gardien, y compris ceux de l'utilisateur sansLP_REPO_HUMAIN=1; c'est l'objet propre de D-REPO5, au-delà de PUB3. - Retour arrière :
git config --unset core.hooksPathdans chaque dépôt.
5.4 Couverture comparée
| Situation | Sans pre-commit (§ 5.2) |
Avec pre-commit (§ 5.3) |
|---|---|---|
| ticket du gardien | arrêté à l'étape 4 (PubCheck -Index, discipline du skill) |
arrêté à l'étape 4 et par le hook |
commit hors gardien (utilisateur, agent par git -C, outil graphique) |
non vu au commit ; vu au push | arrêté au commit (sauf --no-verify) |
push de ue5.8 brute (23 commits avec le nom) |
refusé | refusé |
push de pub/ue5.8 (C2) |
contrôlé : seule la pointe nouvelle compte | idem |
| coût d'un oubli | un commit de correction ; avec C2 la publication reste propre (seul l'arbre de la pointe part) | aucun (le commit n'existe pas) |
| effet sur les autres commits | aucun | tous les commits passent par le hook (ticket exigé, LP_REPO_HUMAIN=1 pour l'utilisateur) |
En C2, un oubli local n'atteint jamais le public tant que la pointe est corrigée avant la publication : la variante
sans pre-commit suffit à protéger le public ; le pre-commit évite seulement des commits de correction.
6. Étape du gardien et de l'orchestrateur (textes pour T7)
sk-repo§ 4, étape 4 (fin) : « Contrôle de donnée personnelle :pwsh -NoProfile -File <Tools>\PubCheck.ps1 -Indexsur l'index privé ; code 0 exigé, sinon refus du ticket avec la sortie (chemin, ligne, catégorie). La ligne du journal du dépôt cite « PubCheck : 0 ». »lp-repo§ 8 (gabarit) : lignePubCheck : 0 (orchestrateur, -Fichiers)ajoutée au ticket ; § 9 :pre-pushet variante D-REPO5 ; § 10 :--remotes=origin(refc55/mainorpheline),.git\hooksnon emporté par une recopie, tague5.5-finallocal seulement (corriger § 1).lp-lot(dépôt d'un ticket) : l'orchestrateur lancePubCheck -Fichiers <liste du ticket>avant de l'écrire.
7. Publication C2 (préparation locale, push par l'utilisateur)
Ticket BRANCHE du gardien, après le commit A et la VAL :
- Entrée :
ue5.8= HEAD attendu ;PubCheck -Arbre ue5.8 -Binaires= 0. git commit-tree ue5.8^{tree} -p <parent> -F <message>;<parent>=origin/ue5.8s'il existe, sinonorigin/main; identité noreply (relevée : conforme dans les 3 dépôts). Message public neutre, sans contenu de jeu :LifePlay UE 5.8 : état de développement au <AAAA-MM-JJ>.git branch pub/ue5.8 <commit>(ou-fpour une publication suivante, sur accord, ancienne pointe citée).- Contrôles :
git diff ue5.8 pub/ue5.8vide ;git rev-list --count <parent>..pub/ue5.8= 1 ;PubCheck -Pointe pub/ue5.8 -Distant origin= 0 ;PubCheck -Arbre pub/ue5.8= 0 (arbre publié entier :-Pointene relit que les blobs nouveaux, un fichier inchangé depuisorigin/mainlui échapperait), en particulierDocs/Migration/etat/sandbox/DC2/DC2-BUILD.mdabsent de l'arbre publié ; hook simulé (§ 9, critère 7) passant pourpub/ue5.8et refusantue5.8.
Adresse personnelle publique sur origin/main (bd4ea43, DC2-BUILD.md l. 7) : option c de l'utilisateur
(relayée par Big Boss, 2026-10-13) : personne ne touche à main ; le fichier n'est plus suivi sur ue5.8 (retiré du suivi par
1542dfa, ignoré par .gitignore:80 ; la copie locale garde l'adresse, hors git) : la publication C2 le supprime de
la pointe publique (relevé T5 : -Arbre ue5.8 = 0 ADRESSE). bd4ea43 la garde dans l'historique public de
main : non corrigé, sauf nouvelle décision de l'utilisateur.
5. Commande donnée à l'utilisateur, à lancer par lui : git push origin pub/ue5.8:ue5.8 (une --dry-run d'abord
s'il le souhaite : elle exécute le pre-push).
7.2 Addon (ajout du 2026-10-13, question de Big Boss)
Le pre-push installé dans l'addon (PUB3-R5) refuse toute ref dont l'historique non public contient f0af432 (pin U1,
nom dans lp-doc/SKILL.md, corrigé par afe31e0 / ffc0fe5) : ue5.8 (48 commits non publics) et lot/DC3-atelier
(45), seules branches qui contiennent f0af432 (git branch --contains) ; les autres lot/* (SB0 à SB4, DC1, DC2)
sont antérieures et ne sont pas bloquées par ce commit (le hook les contrôle quand même au push). La publication C2 couvre aussi l'addon, même procédure que § 7 :
git -C D:\Game\LifePlay-Sandbox-5.8 commit-tree ue5.8^{tree} -p <parent> -F <message>;<parent>=origin/<b>si la branche distante existe, sinonorigin/main; ref localepub/ue5.8(oupub/<branche>pour une autre branche).- Contrôles :
git diff ue5.8 pub/ue5.8vide ; un seul commit ;PubCheck -Depot <arbre> -Pointe pub/ue5.8 -Distant origin= 0 ;PubCheck -Arbre pub/ue5.8= 0 ; hook simulé passant. - Push par l'utilisateur :
git push origin pub/ue5.8:ue5.8(dépôt privé ; même règle).lot/DC3-atelierne se publie qu'ainsi (pub/DC3-atelier), sur décision. Le pin du jeu (doc 21) cite le hash local de l'addon (ue5.8) : la branche publiée a un autre hash, comme pour le jeu ; le doc 21 le note au premier push.
Préalable hors PUB3, à trancher par Big Boss et l'utilisateur avant le push : contrôle des règles de publication du
doc 27 (contenu de jeu, contenu sexuel) sur tout ce que l'arbre publierait, Docs/Migration/etat/ compris.
8. Ordre et messages
- T3 (ce document) → Big Boss → utilisateur (D-REPO5 ; approbation de la SPEC, requise pour le skill
lp-doc). [PUB3→BOSS] PUB3 DÉCLARATION: les 69 chemins du § 2.1, l'addon (lp-doc/SKILL.md×2),Tools/PubCheck.ps1,Tools/hooks/*,Docs/README.md, puis au T7lp-repo(×2),sk-repo,lp-lot(×2).- T5
PubCheck.ps1+pre-push(fichiers neufs, aucun conflit) et T6a VAL dePubChecksur l'état actuel (attendu : 69 / 116 en-Arbre, refus deue5.8en-Pointe). - Fenêtre donnée par Big Boss →
JOURNAL-DEMANDE→ T4 remplacement (instantané,-Appliquer) → T6b VAL → entrée CHG → ticket jeu (69 M + 3 A + journal + README + NUMEROS + livrables) ; le ticket annonce que le diff du journal compte 6 lignes modifiées (anciennes entrées, chemins seulement) en plus de la ligne CHG, et que 4 tickets anciens d'etat\REPO\tickets\sont modifiés →JOURNAL-LIBRE <hash>. - Tickets addon jumeaux (
lp-doc/SKILL.md) ; tickets CONFIG d'installation des hooks (§ 5.2 ou § 5.3). - T7 DOC (skills, § 6) ; ticket BRANCHE
pub/ue5.8(§ 7) quand l'utilisateur veut publier.
9. Critères de VAL (T6, agent distinct de l'IMPL)
- Avant remplacement :
PubCheck -Arbre ue5.8= 69 fichiers / 116 constatsPROFIL+NOMsur les mêmes lignes (comptes recoupés pargit grep -cet-o) ; code 1. - Après le commit A :
PubCheck -Arbre ue5.8 -Binaires= 0, code 0 ;git grep -cdu nom = 0 ; addon idem sur ses deux branches. git diff --numstatdu commit A : pour chaque fichier,n navecn= colonneOccurrencesdu CSV ;--word-diffne montre queC:\Users\<compte>→%USERPROFILE%; 4 fichiers CRLF toujours CRLF (tr -cd '\r' | wc -cinchangé), 65 LF à 0 CR, aucun BOM ajouté.- Preuve par l'échec, sur un dépôt témoin jetable hors du projet (
git initdans le scratchpad) : une ligne de chaque catégorie (NOM,PROFIL,MACHINE,ADRESSE,IDENTITE,BINAIREen UTF-16LE) → code 1 et la bonne catégorie, sans la valeur dans la sortie ; puis chaque cas admis du § 4.2 → code 0. - Variable vide (
$env:USERNAME=''dans le processus du test) → code 2. -Pointe ue5.8 -Distant origin(avant C2) → code 1, constats sur les 23 commits ; durée < 60 s.- Hook simulé sans push :
printf 'refs/heads/ue5.8 <sha> refs/heads/ue5.8 <zéros>\n' | sh <hooks>/pre-push origin <url>→ code 1 ; même chose avec la pointe depub/ue5.8(une fois créée) → code 0 ;pwshabsent duPATH→ code 1. - Aucune sortie, aucun livrable, aucun ticket ne contient le nom :
Select-String -SimpleMatch $env:USERNAME= 0 suretat\AG\PUB3\etetat\REPO\tickets\PUB3-*.