0.0.2-alpha.1.fix.1
This commit is contained in:
180
deltas/0.0.2/alpha.1.fix.1.md
Normal file
180
deltas/0.0.2/alpha.1.fix.1.md
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
<!-- file: deltas/0.0.2/alpha.1.fix.1.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Delta 0.0.2-alpha.1.fix.1 — correction du cadrage, sizing et audit Markdown
|
||||||
|
|
||||||
|
## Baseline
|
||||||
|
|
||||||
|
Version attendue avant application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.2-alpha.1
|
||||||
|
```
|
||||||
|
|
||||||
|
La baseline doit correspondre au commit de `alpha.1` après application de `history/0.0.2/alpha.1.md` en statut `FAIL`.
|
||||||
|
|
||||||
|
Version après application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.2-alpha.1.fix.1
|
||||||
|
```
|
||||||
|
|
||||||
|
## Objet
|
||||||
|
|
||||||
|
Corriger exclusivement les défauts identifiés dans le cadrage `alpha.1` avant de commencer `alpha.2` :
|
||||||
|
|
||||||
|
- corriger l'alignement source du tableau `Inventaire des profils candidats` ;
|
||||||
|
- reconnaître la preuve post-tag `publish.001` déjà disponible sans modifier rétroactivement `v0.0.1` ;
|
||||||
|
- réduire le forecast `0.0.2` à un ensemble de profils compatible avec le sizing d'une session ;
|
||||||
|
- introduire le premier audit PGR monotâche réellement justifié par un défaut observé ;
|
||||||
|
- enregistrer cet audit dans la matrice de validation.
|
||||||
|
|
||||||
|
Aucune règle technologique détaillée n'est introduite par ce fix.
|
||||||
|
|
||||||
|
## Rapport post-tag reconnu
|
||||||
|
|
||||||
|
Le rapport externe à la baseline source :
|
||||||
|
|
||||||
|
```text
|
||||||
|
pgr-0.0.1-publish.001-report.md
|
||||||
|
```
|
||||||
|
|
||||||
|
est connu comme preuve post-publication `PASS` de l'archive `pgr-v0.0.1.zip`.
|
||||||
|
|
||||||
|
Il ne fait pas partie du tag stable et ne doit pas être copié dans le dépôt rétroactivement.
|
||||||
|
|
||||||
|
Le besoin futur d'indiquer automatiquement, dans le handoff/prompt manuel de reprise, si un rapport `publish.*` doit être fourni est conservé comme amélioration de workflow hors scope de `0.0.2`.
|
||||||
|
|
||||||
|
## Sizing corrigé
|
||||||
|
|
||||||
|
Le forecast actif devient :
|
||||||
|
|
||||||
|
```text
|
||||||
|
alpha.2 Rule profile model
|
||||||
|
alpha.3 Rust / Cargo
|
||||||
|
alpha.4 Java / Maven / Gradle
|
||||||
|
alpha.5 Android
|
||||||
|
beta.1 Profile reconciliation
|
||||||
|
rc.1 Rule profiles release candidate
|
||||||
|
stable 0.0.2
|
||||||
|
```
|
||||||
|
|
||||||
|
Les profils/compositions suivants restent explicitement différés :
|
||||||
|
|
||||||
|
```text
|
||||||
|
Rust + Android / JNI
|
||||||
|
Web / TypeScript / Vite / WASM / Rust server
|
||||||
|
Tauri desktop/mobile
|
||||||
|
C / C++ / CMake
|
||||||
|
PHP / Composer
|
||||||
|
Python 3 application/package
|
||||||
|
```
|
||||||
|
|
||||||
|
Leur différé ne vaut ni rejet ni oubli.
|
||||||
|
|
||||||
|
## Premier audit PGR matérialisé
|
||||||
|
|
||||||
|
Le fichier suivant est ajouté :
|
||||||
|
|
||||||
|
```text
|
||||||
|
scripts/audit_markdown_tables.py
|
||||||
|
```
|
||||||
|
|
||||||
|
Son contrat est volontairement limité :
|
||||||
|
|
||||||
|
```text
|
||||||
|
INPUT
|
||||||
|
fichiers/répertoires Markdown explicitement fournis
|
||||||
|
|
||||||
|
OUTPUT
|
||||||
|
diagnostics texte
|
||||||
|
exit code
|
||||||
|
|
||||||
|
SIDE EFFECTS
|
||||||
|
aucun
|
||||||
|
```
|
||||||
|
|
||||||
|
Il vérifie uniquement :
|
||||||
|
|
||||||
|
- la reconnaissance des tableaux hors fenced code blocks ;
|
||||||
|
- le nombre cohérent de colonnes ;
|
||||||
|
- l'alignement vertical des cellules dans le source ;
|
||||||
|
- la largeur des séparateurs ;
|
||||||
|
- le padding conforme à l'alignement Markdown.
|
||||||
|
|
||||||
|
Il ne vérifie pas les blank lines, headers `file/version`, liens, orthographe ou responsabilités documentaires. Ces propriétés appartiennent à d'autres contrôles présents ou futurs.
|
||||||
|
|
||||||
|
Il utilise uniquement la bibliothèque standard Python et doit être exécuté avec `python3 -B` afin de ne pas créer `__pycache__` ou `.pyc`.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
REPLACE :
|
||||||
|
|
||||||
|
```text
|
||||||
|
VERSION
|
||||||
|
docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||||
|
docs/validation/001-VALIDATION_MATRIX.md
|
||||||
|
```
|
||||||
|
|
||||||
|
ADD :
|
||||||
|
|
||||||
|
```text
|
||||||
|
scripts/audit_markdown_tables.py
|
||||||
|
deltas/0.0.2/alpha.1.fix.1.md
|
||||||
|
```
|
||||||
|
|
||||||
|
DELETE : aucun.
|
||||||
|
|
||||||
|
Aucun manifest de suppression n'est nécessaire.
|
||||||
|
|
||||||
|
## Validation opérateur
|
||||||
|
|
||||||
|
```bash
|
||||||
|
test "$(cat VERSION)" = "0.0.2-alpha.1.fix.1"
|
||||||
|
|
||||||
|
test -f scripts/audit_markdown_tables.py
|
||||||
|
test -f deltas/0.0.2/alpha.1.fix.1.md
|
||||||
|
|
||||||
|
grep -F '### Preuve post-tag `publish.001`' docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||||
|
grep -F '### alpha.5 — Android' docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||||
|
grep -F 'Rust + Android / JNI' docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||||
|
grep -F '`PGR-MD-TABLE-001`' docs/validation/001-VALIDATION_MATRIX.md
|
||||||
|
|
||||||
|
python3 -B scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
|
||||||
|
git diff --check
|
||||||
|
|
||||||
|
git add VERSION docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md docs/validation/001-VALIDATION_MATRIX.md scripts/audit_markdown_tables.py deltas/0.0.2/alpha.1.fix.1.md
|
||||||
|
|
||||||
|
git diff --cached --check
|
||||||
|
|
||||||
|
git status --short
|
||||||
|
```
|
||||||
|
|
||||||
|
La sortie attendue avant ajout du history du fix est :
|
||||||
|
|
||||||
|
```text
|
||||||
|
M VERSION
|
||||||
|
A deltas/0.0.2/alpha.1.fix.1.md
|
||||||
|
M docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||||
|
M docs/validation/001-VALIDATION_MATRIX.md
|
||||||
|
A scripts/audit_markdown_tables.py
|
||||||
|
```
|
||||||
|
|
||||||
|
Revue opérateur complémentaire :
|
||||||
|
|
||||||
|
- confirmer que le tableau `Inventaire des profils candidats` est lisible et aligné dans le source ;
|
||||||
|
- confirmer que le report `publish.001` est traité comme preuve post-tag externe et non comme fichier manquant du tag ;
|
||||||
|
- confirmer que le scope réduit reste suffisamment représentatif sans chercher à matérialiser les profils différés ;
|
||||||
|
- confirmer que l'audit Python est read-only et monotâche ;
|
||||||
|
- confirmer qu'aucune règle technologique de `alpha.2+` n'a été introduite.
|
||||||
|
|
||||||
|
## Transition
|
||||||
|
|
||||||
|
### PASS
|
||||||
|
|
||||||
|
Créer et appliquer séparément `history/0.0.2/alpha.1.fix.1.md`, committer le fix, puis seulement préparer `0.0.2-alpha.2` consacré au modèle de profils.
|
||||||
|
|
||||||
|
### FAIL
|
||||||
|
|
||||||
|
Rester dans `0.0.2-alpha.1.fix.M`. À partir de `.fix.3`, réexaminer obligatoirement le plan et la nécessité d'un REPLAN conformément aux règles PGR.
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<!-- file: docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md -->
|
<!-- file: docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md -->
|
||||||
<!-- version: 1 -->
|
<!-- version: 2 -->
|
||||||
|
|
||||||
# Plan 0.0.2 — premiers profils de règles technologiques
|
# Plan 0.0.2 — premiers profils de règles technologiques
|
||||||
|
|
||||||
@@ -62,32 +62,42 @@ L'inspection de l'archive taggée a constaté :
|
|||||||
|
|
||||||
Aucun défaut bloquant de gouvernance, de structure documentaire, de pairing delta/history ou de cohérence interne n'a été trouvé.
|
Aucun défaut bloquant de gouvernance, de structure documentaire, de pairing delta/history ou de cohérence interne n'a été trouvé.
|
||||||
|
|
||||||
### Observation post-tag non bloquante
|
### Preuve post-tag `publish.001`
|
||||||
|
|
||||||
Le history `rel.001` prévoit une vérification post-tag nommée `publish.001`, mais la baseline taggée ne contient pas de snapshot `publish.001`. Ce constat ne rend pas `v0.0.1` invalide : le contrôle est, par définition, postérieur au tag et les règles actuelles n'imposent pas un emplacement versionné pour sa preuve dans ce même tag.
|
Le rapport post-tag `pgr-0.0.1-publish.001-report.md` a été retrouvé dans la bibliothèque de travail après la première revue de `alpha.1`.
|
||||||
|
|
||||||
`0.0.2` ne doit pas inventer rétroactivement cette preuve. Une éventuelle décision durable sur la conservation des preuves post-publication relève d'un futur changement de gouvernance, hors du scope des profils technologiques sauf si elle devient bloquante.
|
Il enregistre `Status: PASS` pour `pgr-v0.0.1.zip` et confirme le SHA-256 déjà observé pour l'archive de baseline :
|
||||||
|
|
||||||
|
```text
|
||||||
|
48bfed6acc50d2c5bdd69db764ae29fe8c5a06b64375943f5d4120c7bb8429ef
|
||||||
|
```
|
||||||
|
|
||||||
|
Cette preuve est volontairement extérieure au tag `v0.0.1` parce qu'elle vérifie un artefact produit après le tag. Elle ne doit ni être injectée rétroactivement dans la stable ni remplacer l'audit d'intake de la session courante.
|
||||||
|
|
||||||
|
La revue a également identifié un besoin de maturité futur : un handoff/prompt de reprise doit finir par indiquer explicitement si une preuve post-publication telle que `publish.001` doit être fournie à la session suivante. Ce besoin de workflow reste hors scope fonctionnel de `0.0.2`.
|
||||||
|
|
||||||
## Inventaire des profils candidats
|
## Inventaire des profils candidats
|
||||||
|
|
||||||
Le prompt demande d'examiner le corpus suivant. `alpha.1` le classe selon son utilité immédiate pour une première release de profils, sans prétendre fermer définitivement la taxonomie.
|
Le prompt demande d'examiner le corpus suivant. Après revue du sizing initial, `0.0.2-alpha.1.fix.1` réduit volontairement le nombre de profils matérialisés afin de conserver une version terminable et correctement validable dans une session.
|
||||||
|
|
||||||
| Domaine candidat | Décision `0.0.2` | Propriétaire prévisionnel | Motif |
|
| Domaine candidat | Décision `0.0.2` | Propriétaire prévisionnel | Motif |
|
||||||
|------------------|------------------|---------------------------|-------|
|
|------------------------------------------------|------------------|------------------------------------------------------|------------------------------------------------------------------------------|
|
||||||
| modèle de profil et composition des scopes | inclure | architecture PGR | nécessaire avant de créer plusieurs profils cohérents |
|
| modèle de profil et composition des scopes | inclure | architecture PGR | nécessaire avant de créer plusieurs profils cohérents |
|
||||||
| Rust / Cargo | inclure | famille `500 — languages` | corpus éprouvé et directement réutilisable |
|
| Rust / Cargo | inclure | famille `500 — languages` | premier profil langage/écosystème, corpus éprouvé |
|
||||||
| Java / Maven / Gradle | inclure | famille `500 — languages` avec spécialisations build | nécessaire pour distinguer langage et build tool avant Android |
|
| Java / Maven / Gradle | inclure | famille `500 — languages` avec spécialisations build | permet de distinguer langage et build tool avant Android |
|
||||||
| Android | inclure | famille `600 — platforms` | premier vrai exemple de spécialisation plateforme |
|
| Android | inclure | famille `600 — platforms` | premier exemple de spécialisation plateforme sur des règles de langage/build |
|
||||||
| Rust + Android / JNI | inclure | famille `600 — platforms` comme composition spécialisée | vérifie l'interaction langage + plateforme + FFI sans généraliser JNI |
|
| Rust + Android / JNI | différer | future composition spécialisée | utile mais non nécessaire pour prouver le premier modèle |
|
||||||
| Web / TypeScript / Vite / WASM / serveurs Rust | inclure | famille `600 — platforms` et composition de composants | couvre frontend autonome, WASM et frontières client/serveur |
|
| Web / TypeScript / Vite / WASM / serveurs Rust | différer | future composition Web | scope autonome suffisamment large pour une release ultérieure |
|
||||||
| Tauri desktop/mobile | inclure | famille `700 — frameworks` | vérifie qu'un framework raffine Rust/Web/Android sans contaminer leurs règles générales |
|
| Tauri desktop/mobile | différer | future famille `700 — frameworks` | dépend de profils Rust/Web/plateforme suffisamment stabilisés |
|
||||||
| C / C++ / CMake | différer | future famille `500 — languages` | corpus utile mais non nécessaire pour prouver le premier modèle de composition |
|
| C / C++ / CMake | différer | future famille `500 — languages` | corpus utile mais non nécessaire au premier lot |
|
||||||
| PHP / Composer | différer | future famille `500 — languages` | ne pas matérialiser un profil uniquement pour remplir la taxonomie |
|
| PHP / Composer | différer | future famille `500 — languages` | ne pas matérialiser un profil uniquement pour remplir la taxonomie |
|
||||||
| Python 3 application/package | différer | future famille `500 — languages` | le dépôt PGR n'est pas lui-même une application Python ; le profil peut être ajouté lorsqu'un besoin concret le justifie |
|
| Python 3 application/package | différer | future famille `500 — languages` | à introduire lorsqu'un besoin concret le justifie |
|
||||||
| architecture/règles cross-cutting | inclure seulement si nécessaire | famille `800 — architecture` ou propriétaire général existant | ne créer un owner transversal que si plusieurs profils ont réellement besoin d'une règle commune non déjà possédée |
|
| architecture/règles cross-cutting | conditionnel | famille `800 — architecture` ou owner existant | uniquement si plusieurs profils révèlent une règle commune sans propriétaire |
|
||||||
|
|
||||||
Les domaines différés restent des candidats légitimes. Leur absence de `0.0.2` ne vaut ni rejet ni interdiction future.
|
Les domaines différés restent des candidats légitimes. Leur absence de `0.0.2` ne vaut ni rejet ni interdiction future.
|
||||||
|
|
||||||
|
Le choix retenu cherche le plus petit ensemble qui exerce réellement plusieurs niveaux de composition : un modèle commun, un profil langage/écosystème, une distinction langage/build et une plateforme. Les compositions FFI, Web et framework restent séparées afin de ne pas transformer la première release de profils en catalogue.
|
||||||
|
|
||||||
## Règles de consolidation
|
## Règles de consolidation
|
||||||
|
|
||||||
Chaque tranche technologique doit :
|
Chaque tranche technologique doit :
|
||||||
@@ -99,7 +109,7 @@ Chaque tranche technologique doit :
|
|||||||
5. documenter explicitement les overrides/contraintes spécialisées et leur scope ;
|
5. documenter explicitement les overrides/contraintes spécialisées et leur scope ;
|
||||||
6. préférer les structures canoniques de l'écosystème lorsqu'elles apportent une vraie valeur ;
|
6. préférer les structures canoniques de l'écosystème lorsqu'elles apportent une vraie valeur ;
|
||||||
7. ne pas fixer une version d'outil ou de dépendance sans raison de compatibilité, reproductibilité, support ou sécurité ;
|
7. ne pas fixer une version d'outil ou de dépendance sans raison de compatibilité, reproductibilité, support ou sécurité ;
|
||||||
8. garder les audits spécialisés hors scope tant qu'une propriété stable et objectivement automatisable n'est pas identifiée ;
|
8. ne créer un audit que lorsqu'une propriété stable, objectivement automatisable et réellement utile a été démontrée ;
|
||||||
9. conserver PGR lui-même indépendant des toolchains qu'il documente ;
|
9. conserver PGR lui-même indépendant des toolchains qu'il documente ;
|
||||||
10. réviser le plan si une tranche devient sensiblement plus large que prévu au lieu d'absorber silencieusement le scope.
|
10. réviser le plan si une tranche devient sensiblement plus large que prévu au lieu d'absorber silencieusement le scope.
|
||||||
|
|
||||||
@@ -113,37 +123,25 @@ Aucune règle technologique détaillée n'est consolidée dans cette tranche.
|
|||||||
|
|
||||||
### alpha.2 — Rule profile model
|
### alpha.2 — Rule profile model
|
||||||
|
|
||||||
Formaliser le contrat d'un profil PGR : ownership, composition général → spécifique, navigation des familles `500`/`600`/`700`/`800`, règles de non-duplication et traitement des choix encore ouverts.
|
Formaliser le contrat d'un profil PGR : ownership, composition général → spécifique, navigation des familles nécessaires, règles de non-duplication et traitement des choix encore ouverts.
|
||||||
|
|
||||||
Cette tranche doit créer uniquement les propriétaires documentaires réellement nécessaires aux profils suivants ; aucun placeholder vide n'est autorisé.
|
Cette tranche doit créer uniquement les propriétaires documentaires réellement nécessaires à `0.0.2`. Les familles `700` et `800` restent réservées tant qu'aucun contenu réel ne justifie leur matérialisation.
|
||||||
|
|
||||||
### alpha.3 — Rust / Cargo
|
### alpha.3 — Rust / Cargo
|
||||||
|
|
||||||
Consolider le premier profil langage/écosystème Rust/Cargo, notamment structure de workspace/crates, manifests et toolchain, dépendances/features, API/imports, erreurs/safety, tests et validation spécialisée lorsque ces sujets ne sont pas déjà possédés par une règle générale.
|
Consolider le premier profil langage/écosystème Rust/Cargo, notamment structure de workspace/crates, manifests et toolchain, dépendances/features, API/imports, erreurs/safety, tests et validation spécialisée lorsque ces sujets ne sont pas déjà possédés par une règle générale.
|
||||||
|
|
||||||
|
Cette tranche sert aussi de mesure réelle du coût d'un profil. Si elle montre que le modèle documentaire est sensiblement plus lourd que prévu, un REPLAN doit intervenir avant d'enchaîner les autres profils.
|
||||||
|
|
||||||
### alpha.4 — Java / Maven / Gradle
|
### alpha.4 — Java / Maven / Gradle
|
||||||
|
|
||||||
Consolider le profil Java et ses spécialisations de build Maven/Gradle en maintenant une frontière nette entre règles Java, contraintes de build tool et choix propres à une plateforme ou un framework.
|
Consolider le profil Java et ses spécialisations de build Maven/Gradle en maintenant une frontière nette entre règles Java, contraintes de build tool et choix propres à une plateforme ou un framework.
|
||||||
|
|
||||||
### alpha.5 — Android
|
### alpha.5 — Android
|
||||||
|
|
||||||
Consolider le profil plateforme Android : structure canonique, toolchain compatible, SDK/targets, configuration locale/signing, modules, packaging, tests/smokes et règles de compatibilité de target.
|
Consolider le premier profil plateforme Android : structure canonique, toolchain compatible, SDK/targets, configuration locale/signing, modules, packaging, tests/smokes et règles de compatibilité de target.
|
||||||
|
|
||||||
Les règles Rust/JNI ne doivent pas être absorbées dans le profil Android général.
|
Les règles Rust/JNI, Web et Tauri ne doivent pas être absorbées dans ce profil général. Elles restent différées jusqu'à une release où leurs compositions pourront être traitées sans surcharger `0.0.2`.
|
||||||
|
|
||||||
### alpha.6 — Rust + Android / JNI
|
|
||||||
|
|
||||||
Consolider la composition spécialisée Rust + Android/JNI : ownership des responsabilités, frontière FFI, localisation de l'unsafe lorsqu'il est techniquement requis, lifecycle/threading et validation en couches.
|
|
||||||
|
|
||||||
### alpha.7 — Web / TypeScript / Vite / WASM / Rust server
|
|
||||||
|
|
||||||
Consolider le profil Web et ses compositions utiles : frontend autonome, TypeScript/Vite, assets, outputs générés, WASM Rust comme composant, séparation client/serveur et validation/smokes associés.
|
|
||||||
|
|
||||||
Les choix de framework serveur particuliers restent des spécialisations lorsque le profil général n'a pas besoin de les imposer.
|
|
||||||
|
|
||||||
### alpha.8 — Tauri desktop/mobile
|
|
||||||
|
|
||||||
Consolider Tauri comme framework composant des profils Rust, Web et éventuellement Android. Les contraintes Tauri desktop/mobile restent locales au framework et ne doivent pas devenir des règles Rust, Web, Java ou Android générales.
|
|
||||||
|
|
||||||
### beta.1 — Profile reconciliation
|
### beta.1 — Profile reconciliation
|
||||||
|
|
||||||
@@ -161,11 +159,25 @@ Promouvoir mécaniquement la RC validée, finaliser les métadonnées de release
|
|||||||
|
|
||||||
## Dimensionnement et points de replan
|
## Dimensionnement et points de replan
|
||||||
|
|
||||||
Le découpage privilégie des responsabilités indépendamment validables plutôt qu'un nombre minimal de tranches.
|
Le premier forecast `alpha.2` à `alpha.8` a été jugé trop large pendant la revue opérateur de `alpha.1`. Le présent plan réduit donc la release avant tout développement technologique lourd.
|
||||||
|
|
||||||
Les tranches `alpha.4`, `alpha.5`, `alpha.7` et `alpha.8` présentent le plus grand risque de croissance. Si leur consolidation exige plusieurs propriétaires documentaires importants ou dépasse sensiblement une tranche cohérente, le plan MUST être révisé et le travail scindé en `alpha.N` supplémentaires avant de poursuivre.
|
Après `alpha.1.fix.1`, le chemin prévu est :
|
||||||
|
|
||||||
Si l'ensemble de `0.0.2` devient déraisonnablement large malgré la différenciation des profils C/C++, PHP et Python, un REPLAN peut encore réduire le scope de la release. Il ne faut pas forcer une taxonomie exhaustive pour fermer la version.
|
```text
|
||||||
|
alpha.2 modèle de profil
|
||||||
|
alpha.3 Rust / Cargo
|
||||||
|
alpha.4 Java / Maven / Gradle
|
||||||
|
alpha.5 Android
|
||||||
|
beta.1 réconciliation
|
||||||
|
rc.1 release candidate
|
||||||
|
stable 0.0.2
|
||||||
|
```
|
||||||
|
|
||||||
|
Ce découpage reste un forecast, pas une obligation de remplir tous les numéros coûte que coûte.
|
||||||
|
|
||||||
|
`alpha.3` est un point de mesure explicite. Si la construction du premier profil montre qu'un profil complet dépasse sensiblement le sizing envisagé, la release doit être REPLANifiée avant `alpha.4` au lieu de conserver mécaniquement le forecast.
|
||||||
|
|
||||||
|
Un nouveau besoin critique, plusieurs fixes consécutifs ou une évolution qui rend `0.0.2` non terminable dans la session doivent également déclencher un REPLAN. La qualité de la release prend le dessus sur la volonté de conserver artificiellement le nombre initial de profils.
|
||||||
|
|
||||||
## Hors périmètre
|
## Hors périmètre
|
||||||
|
|
||||||
@@ -175,7 +187,7 @@ Si l'ensemble de `0.0.2` devient déraisonnablement large malgré la différenci
|
|||||||
- créer les skeleton specifications complètes réservées à `0.0.4` ;
|
- créer les skeleton specifications complètes réservées à `0.0.4` ;
|
||||||
- créer un générateur ;
|
- créer un générateur ;
|
||||||
- réécrire KSP ou `sasedev-games` ;
|
- réécrire KSP ou `sasedev-games` ;
|
||||||
- créer des audits spécialisés uniquement parce qu'un profil existe ;
|
- multiplier les audits spécialisés ; `alpha.1.fix.1` introduit uniquement l'audit Markdown monotâche justifié par un défaut réellement observé ;
|
||||||
- transformer les exemples de technologies en dépendances du dépôt PGR ;
|
- transformer les exemples de technologies en dépendances du dépôt PGR ;
|
||||||
- modifier rétroactivement les deltas/histories `0.0.1` pour refléter des règles apparues après leur émission.
|
- modifier rétroactivement les deltas/histories `0.0.1` pour refléter des règles apparues après leur émission.
|
||||||
|
|
||||||
@@ -185,7 +197,7 @@ Si l'ensemble de `0.0.2` devient déraisonnablement large malgré la différenci
|
|||||||
|
|
||||||
- le modèle documentaire des profils est explicite et cohérent avec la hiérarchie PGR ;
|
- le modèle documentaire des profils est explicite et cohérent avec la hiérarchie PGR ;
|
||||||
- les profils retenus dans le scope possèdent chacun un propriétaire normatif réel ;
|
- les profils retenus dans le scope possèdent chacun un propriétaire normatif réel ;
|
||||||
- les spécialisations plateforme/framework ne contaminent pas les règles générales ;
|
- les spécialisations de build et de plateforme retenues ne contaminent pas les règles générales ;
|
||||||
- les choix encore ouverts restent identifiés comme tels ;
|
- les choix encore ouverts restent identifiés comme tels ;
|
||||||
- la navigation entre règles générales et profils spécifiques est claire ;
|
- la navigation entre règles générales et profils spécifiques est claire ;
|
||||||
- aucune duplication importante avec les familles `200`, `300` et `400` ne subsiste ;
|
- aucune duplication importante avec les familles `200`, `300` et `400` ne subsiste ;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!-- file: docs/validation/001-VALIDATION_MATRIX.md -->
|
<!-- file: docs/validation/001-VALIDATION_MATRIX.md -->
|
||||||
<!-- version: 4 -->
|
<!-- version: 5 -->
|
||||||
|
|
||||||
# Matrice de validation PGR
|
# Matrice de validation PGR
|
||||||
|
|
||||||
@@ -14,17 +14,20 @@ Les catégories et règles de sélection sont définies dans [`../rules/400-VALI
|
|||||||
## Contrôles actifs
|
## Contrôles actifs
|
||||||
|
|
||||||
| ID | Catégorie | Commande / contrôle | Prérequis | Trigger | Phase | Coût | Acteur |
|
| ID | Catégorie | Commande / contrôle | Prérequis | Trigger | Phase | Coût | Acteur |
|
||||||
|-------------------|-----------|------------------------------------------------------------------------------------------|------------------------|-------------------------------|----------------------|--------|-----------------|
|
|--------------------|-----------|------------------------------------------------------------------------------------------|------------------------|---------------------------------|----------------------|--------|-----------------|
|
||||||
| `PGR-GIT-001` | `CHECK` | `git diff --check` ou `git diff --cached --check` selon l'état de l'index | Git | toute modification suivie | alpha/beta/RC/stable | faible | opérateur |
|
| `PGR-GIT-001` | `CHECK` | `git diff --check` ou `git diff --cached --check` selon l'état de l'index | Git | toute modification suivie | alpha/beta/RC/stable | faible | opérateur |
|
||||||
| `PGR-VERSION-001` | `CHECK` | comparer `VERSION` à la version attendue par le delta courant | fichier `VERSION` | changement de tranche/version | alpha/beta/RC/stable | faible | opérateur |
|
| `PGR-VERSION-001` | `CHECK` | comparer `VERSION` à la version attendue par le delta courant | fichier `VERSION` | changement de tranche/version | alpha/beta/RC/stable | faible | opérateur |
|
||||||
| `PGR-LAYOUT-001` | `AUDIT` | comparer les fichiers ajoutés/remplacés/supprimés au scope déclaré du delta | scope du delta | changement de structure | alpha/beta/RC/stable | faible | opérateur/revue |
|
| `PGR-LAYOUT-001` | `AUDIT` | comparer les fichiers ajoutés/remplacés/supprimés au scope déclaré du delta | scope du delta | changement de structure | alpha/beta/RC/stable | faible | opérateur/revue |
|
||||||
| `PGR-DOC-001` | `AUDIT` | vérifier headers `file/version`, chemins, liens et responsabilités des documents touchés | fichiers documentaires | modification documentaire | alpha/beta/RC/stable | faible | opérateur/revue |
|
| `PGR-DOC-001` | `AUDIT` | vérifier headers `file/version`, chemins, liens et responsabilités des documents touchés | fichiers documentaires | modification documentaire | alpha/beta/RC/stable | faible | opérateur/revue |
|
||||||
|
| `PGR-MD-TABLE-001` | `AUDIT` | `python3 -B scripts/audit_markdown_tables.py <paths...>` | Python 3 | table Markdown ajoutée/modifiée | alpha/beta/RC/stable | faible | opérateur/CI |
|
||||||
| `PGR-NAV-001` | `AUDIT` | vérifier que les points d'entrée et liens canoniques ciblent des fichiers existants | index et docs racine | navigation ou réconciliation | beta/RC/stable | faible | opérateur/revue |
|
| `PGR-NAV-001` | `AUDIT` | vérifier que les points d'entrée et liens canoniques ciblent des fichiers existants | index et docs racine | navigation ou réconciliation | beta/RC/stable | faible | opérateur/revue |
|
||||||
| `PGR-SCOPE-001` | `AUDIT` | vérifier que les documents vivants pointent vers les propriétaires normatifs actuels | documents vivants | réconciliation de phase | beta/RC/stable | faible | revue |
|
| `PGR-SCOPE-001` | `AUDIT` | vérifier que les documents vivants pointent vers les propriétaires normatifs actuels | documents vivants | réconciliation de phase | beta/RC/stable | faible | revue |
|
||||||
| `PGR-STATUS-001` | `CHECK` | `git status --short` | Git | avant fermeture d'une tranche | alpha/beta/RC/stable | faible | opérateur |
|
| `PGR-STATUS-001` | `CHECK` | `git status --short` | Git | avant fermeture d'une tranche | alpha/beta/RC/stable | faible | opérateur |
|
||||||
|
|
||||||
Un contrôle manuel peut rester dans la matrice lorsqu'aucun audit automatisé fiable n'existe encore. PGR SHOULD automatiser uniquement les propriétés stables et objectivement contrôlables.
|
Un contrôle manuel peut rester dans la matrice lorsqu'aucun audit automatisé fiable n'existe encore. PGR SHOULD automatiser uniquement les propriétés stables et objectivement contrôlables.
|
||||||
|
|
||||||
|
`PGR-MD-TABLE-001` est le premier audit matérialisé dans PGR lui-même. Il reste volontairement monotâche : il contrôle uniquement la structure et l'alignement source des tableaux Markdown, sans vérifier les blank lines, les headers, les liens ou d'autres règles documentaires.
|
||||||
|
|
||||||
## Politique Eclipse actuelle
|
## Politique Eclipse actuelle
|
||||||
|
|
||||||
Les métadonnées Eclipse spécifiques à une machine restent ignorées, notamment `.project`, `.classpath` et les préférences non partagées.
|
Les métadonnées Eclipse spécifiques à une machine restent ignorées, notamment `.project`, `.classpath` et les préférences non partagées.
|
||||||
|
|||||||
104
history/0.0.2/alpha.1.fix.1.md
Normal file
104
history/0.0.2/alpha.1.fix.1.md
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
<!-- file: history/0.0.2/alpha.1.fix.1.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# History 0.0.2-alpha.1.fix.1 — correction du cadrage, sizing et audit Markdown
|
||||||
|
|
||||||
|
## Statut
|
||||||
|
|
||||||
|
PASS
|
||||||
|
|
||||||
|
Le correctif de cadrage `0.0.2-alpha.1.fix.1` a été validé par l'opérateur. Le sizing réduit, la reconnaissance de la preuve post-tag et le premier audit Markdown monotâche sont cohérents avec l'objectif de `alpha.1`.
|
||||||
|
|
||||||
|
## Baseline
|
||||||
|
|
||||||
|
La tranche précédente `0.0.2-alpha.1` a été enregistrée `FAIL`, puis committée et poussée sous le commit observé :
|
||||||
|
|
||||||
|
```text
|
||||||
|
d3f1e13
|
||||||
|
```
|
||||||
|
|
||||||
|
Version validée après application du fix :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.2-alpha.1.fix.1
|
||||||
|
```
|
||||||
|
|
||||||
|
## Validation opérateur observée
|
||||||
|
|
||||||
|
L'opérateur a confirmé la présence et le contenu attendu des artefacts du fix :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
test "$(cat VERSION)" = "0.0.2-alpha.1.fix.1"
|
||||||
|
|
||||||
|
test -f scripts/audit_markdown_tables.py
|
||||||
|
test -f deltas/0.0.2/alpha.1.fix.1.md
|
||||||
|
|
||||||
|
grep -F '### Preuve post-tag `publish.001`' docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||||
|
grep -F '### alpha.5 — Android' docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||||
|
grep -F 'Rust + Android / JNI' docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||||
|
grep -F '`PGR-MD-TABLE-001`' docs/validation/001-VALIDATION_MATRIX.md
|
||||||
|
```
|
||||||
|
|
||||||
|
L'audit Markdown PGR a ensuite été exécuté sur le corpus documentaire courant :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python3 -B scripts/audit_markdown_tables.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
```
|
||||||
|
|
||||||
|
Résultat observé :
|
||||||
|
|
||||||
|
```text
|
||||||
|
Markdown table audit: clean (2 table(s), 45 file(s))
|
||||||
|
```
|
||||||
|
|
||||||
|
Les contrôles Git ont également réussi :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git diff --check
|
||||||
|
|
||||||
|
git add VERSION \
|
||||||
|
docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md \
|
||||||
|
docs/validation/001-VALIDATION_MATRIX.md \
|
||||||
|
scripts/audit_markdown_tables.py \
|
||||||
|
deltas/0.0.2/alpha.1.fix.1.md
|
||||||
|
|
||||||
|
git diff --cached --check
|
||||||
|
git status --short
|
||||||
|
```
|
||||||
|
|
||||||
|
`git diff --check` et `git diff --cached --check` n'ont produit aucun diagnostic.
|
||||||
|
|
||||||
|
La sortie finale observée avant ajout du présent history était exactement :
|
||||||
|
|
||||||
|
```text
|
||||||
|
M VERSION
|
||||||
|
A deltas/0.0.2/alpha.1.fix.1.md
|
||||||
|
M docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md
|
||||||
|
M docs/validation/001-VALIDATION_MATRIX.md
|
||||||
|
A scripts/audit_markdown_tables.py
|
||||||
|
```
|
||||||
|
|
||||||
|
## Revue qualitative
|
||||||
|
|
||||||
|
Les décisions qualitatives ayant motivé le fix avaient déjà été explicitées par l'opérateur avant son application :
|
||||||
|
|
||||||
|
- conserver `publish.001` comme preuve post-tag externe plutôt que l'injecter dans le tag stable ;
|
||||||
|
- réduire le nombre de profils matérialisés afin de ne pas surcharger la session ;
|
||||||
|
- différer les profils C/C++/CMake, PHP/Composer, Python et les compositions plus larges au lieu de s'éparpiller ;
|
||||||
|
- commencer à introduire des audits PGR uniquement lorsque l'occasion révèle une propriété stable et objectivement contrôlable ;
|
||||||
|
- préférer des audits simples et monotâches aux scripts combinés historiques lorsqu'une responsabilité unique suffit.
|
||||||
|
|
||||||
|
Le résultat mécanique du fix est conforme à ces décisions.
|
||||||
|
|
||||||
|
## Résultat
|
||||||
|
|
||||||
|
`0.0.2-alpha.1.fix.1` est validée `PASS`.
|
||||||
|
|
||||||
|
Le cadrage de `0.0.2` est désormais autorisé à progresser vers :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.2-alpha.2
|
||||||
|
```
|
||||||
|
|
||||||
|
Cette tranche suivante est limitée au modèle de profils PGR : ownership, composition général → spécifique, résolution des overrides, non-duplication et activation des seules familles documentaires nécessaires aux profils retenus pour `0.0.2`.
|
||||||
205
scripts/audit_markdown_tables.py
Normal file
205
scripts/audit_markdown_tables.py
Normal file
@@ -0,0 +1,205 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# file: scripts/audit_markdown_tables.py
|
||||||
|
# version: 1
|
||||||
|
|
||||||
|
"""Validate source formatting of Markdown tables in explicitly selected paths."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import pathlib
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
|
||||||
|
_SEPARATOR = re.compile(r"^:?-{3,}:?$")
|
||||||
|
_IGNORED_DIRECTORIES = frozenset({".git", ".idea", ".venv", "__pycache__", "dist", "node_modules", "target"})
|
||||||
|
|
||||||
|
|
||||||
|
def _selected_files(raw_paths: list[str]) -> tuple[list[pathlib.Path], list[str]]:
|
||||||
|
files: list[pathlib.Path] = []
|
||||||
|
errors: list[str] = []
|
||||||
|
|
||||||
|
for raw_path in raw_paths:
|
||||||
|
path = pathlib.Path(raw_path)
|
||||||
|
if path.is_dir():
|
||||||
|
files.extend(
|
||||||
|
candidate
|
||||||
|
for candidate in path.rglob("*.md")
|
||||||
|
if candidate.is_file() and not any(part in _IGNORED_DIRECTORIES for part in candidate.parts)
|
||||||
|
)
|
||||||
|
elif path.is_file() and path.suffix.lower() == ".md":
|
||||||
|
files.append(path)
|
||||||
|
else:
|
||||||
|
errors.append(f"Markdown table audit: unsupported or missing path: {path}")
|
||||||
|
|
||||||
|
return sorted(set(files)), errors
|
||||||
|
|
||||||
|
|
||||||
|
def _is_row(line: str) -> bool:
|
||||||
|
return line.startswith("|") and line.endswith("|")
|
||||||
|
|
||||||
|
|
||||||
|
def _cells(line: str) -> list[str]:
|
||||||
|
return line.split("|")[1:-1]
|
||||||
|
|
||||||
|
|
||||||
|
def _separator_marker(cell: str) -> str | None:
|
||||||
|
marker = cell.strip()
|
||||||
|
return marker if _SEPARATOR.fullmatch(marker) is not None else None
|
||||||
|
|
||||||
|
|
||||||
|
def _is_separator_row(line: str) -> bool:
|
||||||
|
if not _is_row(line):
|
||||||
|
return False
|
||||||
|
cells = _cells(line)
|
||||||
|
return bool(cells) and all(_separator_marker(cell) is not None for cell in cells)
|
||||||
|
|
||||||
|
|
||||||
|
def _alignment(marker: str) -> str:
|
||||||
|
if marker.startswith(":") and marker.endswith(":"):
|
||||||
|
return "center"
|
||||||
|
if marker.endswith(":"):
|
||||||
|
return "right"
|
||||||
|
return "left"
|
||||||
|
|
||||||
|
|
||||||
|
def _padding(cell: str) -> tuple[int, int]:
|
||||||
|
return len(cell) - len(cell.lstrip(" ")), len(cell) - len(cell.rstrip(" "))
|
||||||
|
|
||||||
|
|
||||||
|
def _validate_table(path: pathlib.Path, start_line: int, rows: list[str]) -> list[str]:
|
||||||
|
errors: list[str] = []
|
||||||
|
|
||||||
|
if any("\\|" in row for row in rows):
|
||||||
|
errors.append(f"{path}:{start_line}: escaped pipe is forbidden inside a table cell")
|
||||||
|
|
||||||
|
parsed = [_cells(row) for row in rows]
|
||||||
|
column_count = len(parsed[0])
|
||||||
|
|
||||||
|
for offset, row in enumerate(parsed):
|
||||||
|
if len(row) != column_count:
|
||||||
|
errors.append(f"{path}:{start_line + offset}: table row has {len(row)} columns; expected {column_count}")
|
||||||
|
return errors
|
||||||
|
|
||||||
|
for column in range(column_count):
|
||||||
|
raw_cells = [row[column] for row in parsed]
|
||||||
|
widths = [len(cell) for cell in raw_cells]
|
||||||
|
expected_width = widths[0]
|
||||||
|
|
||||||
|
if any(width != expected_width for width in widths):
|
||||||
|
errors.append(f"{path}:{start_line}: column {column + 1} is not vertically aligned; raw widths are {widths}")
|
||||||
|
continue
|
||||||
|
|
||||||
|
marker = _separator_marker(raw_cells[1])
|
||||||
|
if marker is None:
|
||||||
|
errors.append(f"{path}:{start_line + 1}: separator for column {column + 1} is malformed")
|
||||||
|
continue
|
||||||
|
|
||||||
|
content_cells = [cell for index, cell in enumerate(raw_cells) if index != 1]
|
||||||
|
longest_content = max(len(cell.strip()) for cell in content_cells)
|
||||||
|
required_width = max(longest_content + 2, 3 + marker.count(":"))
|
||||||
|
|
||||||
|
if expected_width != required_width:
|
||||||
|
errors.append(
|
||||||
|
f"{path}:{start_line}: column {column + 1} width is {expected_width}; expected {required_width}"
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
|
||||||
|
alignment = _alignment(marker)
|
||||||
|
for cell in content_cells:
|
||||||
|
content_width = len(cell.strip())
|
||||||
|
left, right = _padding(cell)
|
||||||
|
expected_padding = expected_width - content_width
|
||||||
|
|
||||||
|
if content_width + left + right != len(cell) or left < 1 or right < 1:
|
||||||
|
errors.append(f"{path}:{start_line}: column {column + 1} must use spaces only for outer padding")
|
||||||
|
break
|
||||||
|
if alignment == "left" and (left != 1 or right != expected_padding - 1):
|
||||||
|
errors.append(f"{path}:{start_line}: column {column + 1} must be source-aligned to the left")
|
||||||
|
break
|
||||||
|
if alignment == "right" and (right != 1 or left != expected_padding - 1):
|
||||||
|
errors.append(f"{path}:{start_line}: column {column + 1} must be source-aligned to the right")
|
||||||
|
break
|
||||||
|
if alignment == "center" and abs(left - right) > 1:
|
||||||
|
errors.append(f"{path}:{start_line}: column {column + 1} must be source-aligned to the center")
|
||||||
|
break
|
||||||
|
|
||||||
|
if len(raw_cells[1]) != expected_width or _SEPARATOR.fullmatch(raw_cells[1]) is None:
|
||||||
|
errors.append(f"{path}:{start_line + 1}: separator for column {column + 1} must fill the column width")
|
||||||
|
|
||||||
|
return errors
|
||||||
|
|
||||||
|
|
||||||
|
def _audit_file(path: pathlib.Path) -> tuple[int, list[str]]:
|
||||||
|
lines = path.read_text(encoding="utf-8").splitlines()
|
||||||
|
errors: list[str] = []
|
||||||
|
tables = 0
|
||||||
|
fence: str | None = None
|
||||||
|
index = 0
|
||||||
|
|
||||||
|
while index < len(lines):
|
||||||
|
stripped = lines[index].lstrip()
|
||||||
|
if stripped.startswith("```") or stripped.startswith("~~~"):
|
||||||
|
marker = stripped[:3]
|
||||||
|
if fence is None:
|
||||||
|
fence = marker
|
||||||
|
elif fence == marker:
|
||||||
|
fence = None
|
||||||
|
index += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
if fence is not None:
|
||||||
|
index += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
if index + 1 < len(lines) and _is_row(lines[index]) and _is_separator_row(lines[index + 1]):
|
||||||
|
start = index
|
||||||
|
rows = [lines[index], lines[index + 1]]
|
||||||
|
index += 2
|
||||||
|
while index < len(lines) and _is_row(lines[index]):
|
||||||
|
rows.append(lines[index])
|
||||||
|
index += 1
|
||||||
|
tables += 1
|
||||||
|
errors.extend(_validate_table(path, start + 1, rows))
|
||||||
|
continue
|
||||||
|
|
||||||
|
index += 1
|
||||||
|
|
||||||
|
return tables, errors
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
"""Run the read-only Markdown table audit."""
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument("paths", nargs="+", help="Markdown files or directories to audit")
|
||||||
|
arguments = parser.parse_args()
|
||||||
|
|
||||||
|
files, selection_errors = _selected_files(arguments.paths)
|
||||||
|
if selection_errors:
|
||||||
|
for error in selection_errors:
|
||||||
|
print(error, file=sys.stderr)
|
||||||
|
return 2
|
||||||
|
if not files:
|
||||||
|
print("Markdown table audit: no Markdown files selected", file=sys.stderr)
|
||||||
|
return 2
|
||||||
|
|
||||||
|
table_count = 0
|
||||||
|
errors: list[str] = []
|
||||||
|
for path in files:
|
||||||
|
current_count, current_errors = _audit_file(path)
|
||||||
|
table_count += current_count
|
||||||
|
errors.extend(current_errors)
|
||||||
|
|
||||||
|
if errors:
|
||||||
|
for error in errors:
|
||||||
|
print(error, file=sys.stderr)
|
||||||
|
print(f"Markdown table audit: {len(errors)} error(s) across {len(files)} file(s)", file=sys.stderr)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
print(f"Markdown table audit: clean ({table_count} table(s), {len(files)} file(s))")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
raise SystemExit(main())
|
||||||
Reference in New Issue
Block a user