104 lines
6.6 KiB
Markdown
104 lines
6.6 KiB
Markdown
|
|
Fiche OUT1-UASSET — Niveau N3 — Modèle prévu non précisé (session mère) | utilisé claude-opus-5-5 — Agent session annexe « uasset.py » (local_6c6597f8…) — Skills sk-protocol, lp-lot, lp-doc
|
||
|
|
|
||
|
|
# OUT1 — reconstitution du parseur `uasset.py` (compte rendu)
|
||
|
|
|
||
|
|
Date : 2026-10-09. Copie : `D:\Game\LifePlay-master 5.8` (branche `ue5.8`). Entrée au journal : **CHG-265**.
|
||
|
|
Commit **`8c6149e`** (non poussé), après `866e869` (CHG-264, outils OUT1). Instantané : `D:\Game\LifePlay_Backup_5.5\OUT1`
|
||
|
|
(entrée `Tools\uasset.py`, `Existed=False`).
|
||
|
|
|
||
|
|
## Résultat
|
||
|
|
Réussi. Le module est reconstitué à l'identique et rangé dans `Tools/uasset.py` de la copie 5.8. Il fonctionne sur les
|
||
|
|
Blueprints 4.27 mais **pas sur les paquets UE5** (5.5 et 5.8).
|
||
|
|
|
||
|
|
## Origine
|
||
|
|
L'audit des transcriptions du 2026-10-09 a trouvé le seul outil d'analyse de Blueprints hors éditeur. Il lit les `.uasset`
|
||
|
|
4.27 : tables de noms, d'imports et d'exports, propriétés balisées, graphes de nœuds K2. Il a servi dans 62 appels de
|
||
|
|
4 agents pour la cartographie de GI et Person. Il vivait dans `%TEMP%\lp\uasset.py` et a disparu ; seul
|
||
|
|
`%TEMP%\lp\__pycache__` subsiste, vide (dossier daté du 2026-10-06). `Tools/AssetHeaders.ps1` ne lit que l'en-tête.
|
||
|
|
|
||
|
|
## Méthode : rejeu des 19 appels Bash (établi)
|
||
|
|
- Source : session `d3ec373a`, sous-agent `agent-a139431644aa5f11d`, le 2026-09-28 de 22:09:17 à 22:19:08. Transcription :
|
||
|
|
`%USERPROFILE%\.claude\projects\D--Game-LifePlay-master-5-5\d3ec373a-7cb3-4357-8f24-8e9e0ff7f016\subagents\agent-a139431644aa5f11d.jsonl`.
|
||
|
|
- 20 appels écrivent le fichier. L'un a échoué à l'origine (outil `bash` en minuscules) et n'est pas rejoué. Restent
|
||
|
|
19 appels, dans l'ordre : 1 `cat >`, 9 `cat >>`, 2 `sed -i` et 7 `python -` de correctif (`s.replace`, octets NUL,
|
||
|
|
fins de ligne).
|
||
|
|
- Aucune autre session n'a écrit ce fichier : balayage de tous les `.jsonl` de `%USERPROFILE%\.claude\projects`.
|
||
|
|
- Rejeu par `OUT1_uasset_rejeu.py`. Chaque commande est écrite dans un script `.sh` puis exécutée par Git Bash
|
||
|
|
(`C:\Program Files\Git\usr\bin\bash.exe`), avec `TEMP` redirigé vers un dossier jetable.
|
||
|
|
- Le harnais Bash de Claude Code réécrit chaque `\\` d'une commande en `\` (essai du 2026-10-09 : `A\\B` → `A\B`,
|
||
|
|
`\\\\G` → `\\G`). C'est l'origine de l'octet NUL apparu à 22:13 : `b'\\0'` devient `b'\0'`. Le mode `1` du script
|
||
|
|
émule cette réécriture, le mode `0` non.
|
||
|
|
- Fidélité, mode `1` (journal `OUT1_uasset_rejeu_log_emulation.txt`) : chaque étape redonne la sortie d'origine.
|
||
|
|
- Tailles 11569 puis 11349 octets.
|
||
|
|
- 1 octet NUL, puis 0 après l'étape 10.
|
||
|
|
- `SyntaxError: source code string cannot contain null bytes` aux étapes 7 et 9.
|
||
|
|
- Tracebacks aux lignes 8, 21 et 370.
|
||
|
|
- `grep` aux lignes 140, 176 et 188.
|
||
|
|
- Mêmes sorties sur GI, Person et Save.
|
||
|
|
- Les seuls écarts portent sur le chemin du dossier de rejeu.
|
||
|
|
- Mode `0` (`OUT1_uasset_rejeu_log_sans_emulation.txt`) : les étapes 7 à 13 divergent (11570 octets, aucun NUL). Le
|
||
|
|
`sed` de l'étape 14 réécrit pourtant la ligne 176, et le **fichier final est identique dans les deux modes**.
|
||
|
|
- Fichier rejoué (`OUT1_uasset_rejeu_brut.py`) : 18888 octets, 410 lignes CRLF, sha256
|
||
|
|
`4d202f143f475c52d15107de923ecc010d1aabe6c14b8d8fac58ff9b82468d8c`.
|
||
|
|
- Fichier commité : le fichier rejoué octet pour octet, précédé d'un en-tête d'origine et d'usage. 20779 octets,
|
||
|
|
438 lignes CRLF, MD5 `82782b7556d1d17d84d915cf61e55dc0`, relu par `md5sum Tools/uasset.py` et
|
||
|
|
`git show HEAD:Tools/uasset.py | md5sum`. `.gitattributes` (`* -text`) conserve CRLF.
|
||
|
|
|
||
|
|
## Comparaison au .pyc (établi : impossible)
|
||
|
|
`%TEMP%\lp\__pycache__` est vide. Aucun `uasset*.pyc` n'existe sous `%TEMP%` ni sous `%USERPROFILE%` (recherche sur
|
||
|
|
6 niveaux de profondeur). On ne peut donc comparer ni la version de Python, ni la taille, ni `co_names`. La fidélité
|
||
|
|
repose sur la concordance des sorties étape par étape.
|
||
|
|
|
||
|
|
## Preuves sur 4.27 (établi)
|
||
|
|
Python 3.14.4, `PYTHONPATH="D:/Game/LifePlay-master 5.8/Tools"`, depuis `D:\Game\LifePlay-master 4.27\Content\BPs` :
|
||
|
|
`from uasset import *; u=UA('GI.uasset'); G=Graph(u); ev=evmap(G)`.
|
||
|
|
|
||
|
|
| Fichier | Résultat |
|
||
|
|
|---|---|
|
||
|
|
| GI | `u.nc` 8740, `u.ec` 20115, `u.ic` 4419, 19127 nœuds, `evmap` 229 événements |
|
||
|
|
| Person | nc 3331, ec 8945, 8124 nœuds, 122 événements |
|
||
|
|
| Save | `var_defs` 137 variables, imports de 28 octets |
|
||
|
|
|
||
|
|
Ces valeurs sont celles de la session d'origine, par exemple `8740 20115 4419` à 22:09:36 et 229 événements à 22:14:25.
|
||
|
|
Le module expose `UA`, `Graph`, `rd_props`, `rd_props2`, `rd_fstring`, `rd_ftext`, `graphs`, `owner_graph`,
|
||
|
|
`graph_info`, `var_defs`, `event_nodes`, `summ`, `show`, `trace`, `sig`, `evmap`, `evsig`, `MATHLIBS` et `NOISE`.
|
||
|
|
|
||
|
|
## UE5 non géré (établi)
|
||
|
|
Les GI et Save de `LifePlay-master 5.5` (LegacyFileVersion -8) et de `LifePlay-master 5.8` (-9) lèvent tous
|
||
|
|
`struct.error: unpack requires a buffer of 8 bytes` dès le constructeur `UA()`. Le parseur suppose :
|
||
|
|
- l'en-tête 4.27 (-7, offset fixe 20) ;
|
||
|
|
- des imports de 36 ou 28 octets ;
|
||
|
|
- des exports de 104 octets ;
|
||
|
|
- la sérialisation des propriétés balisées d'avant 5.4.
|
||
|
|
|
||
|
|
L'étendre à UE5 serait un autre lot (non demandé).
|
||
|
|
|
||
|
|
## Piège
|
||
|
|
Le Python du Microsoft Store (`WindowsApps`) ne voit pas `AppData\Roaming`. Il ne peut ni y écrire ni y importer : la
|
||
|
|
virtualisation MSIX renvoie `FileNotFoundError` ou `ModuleNotFoundError`. Il faut copier le fichier ailleurs avant de
|
||
|
|
l'importer.
|
||
|
|
|
||
|
|
## Usage
|
||
|
|
```
|
||
|
|
PYTHONPATH="D:/Game/LifePlay-master 5.8/Tools" python -c "from uasset import *; u=UA('GI.uasset'); G=Graph(u); print('\n'.join(trace(G,'GeneratePerson')))"
|
||
|
|
```
|
||
|
|
|
||
|
|
## Fichiers annexes (à côté de ce compte rendu)
|
||
|
|
|
||
|
|
| Fichier | Rôle |
|
||
|
|
|---|---|
|
||
|
|
| `OUT1_uasset_rejeu.py` | script de rejeu (extraction et exécution des 19 appels). Arguments : `<dossier de travail> 1` (émulation) ou `0`. Il contient les chemins de son dossier d'origine (scratchpad). |
|
||
|
|
| `OUT1_uasset_rejeu_log_emulation.txt` | pour chaque étape : ligne d'état (code, taille, NUL, CRLF, sha), sortie rejouée, sortie d'origine. Mode `1`. |
|
||
|
|
| `OUT1_uasset_rejeu_log_sans_emulation.txt` | idem, mode `0`. |
|
||
|
|
| `OUT1_uasset_rejeu_brut.py` | fichier rejoué sans en-tête (sha256 ci-dessus). |
|
||
|
|
|
||
|
|
## Écarts
|
||
|
|
- **Numéro CHG** : CHG-265 est le dernier numéro + 1 (CHG-263 était libre au moment de l'écriture, puis pris par STM).
|
||
|
|
- **Lot** : rattaché au lot OUT1, le même audit que CHG-264.
|
||
|
|
- **Commit** : fait après la demande de l'utilisateur relayée par la session « Commençons U7 », dans l'ordre convenu
|
||
|
|
avec la session « Outils communs ».
|
||
|
|
- **README** : sa plage n'a pas été touchée ; elle a été mise à jour par `866e869`.
|
||
|
|
|
||
|
|
Suite : la session « Outils communs » ajoute à `OUT1-IMPL.md` un renvoi vers ce fichier. Le parseur est livré et
|
||
|
|
commité, sans tâche ouverte.
|