Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| bd9aadf0cf | |||
| c6af96b6bc | |||
| 3f8fa6b34e | |||
| fdaaa357d4 | |||
| ea80396828 | |||
| c0735d1d63 | |||
| 5471ea6283 | |||
| 7408616909 | |||
| bf306daea6 | |||
| 1e10feba95 | |||
| ec3a101d9b | |||
| 47114fa96b | |||
| dee864e22b | |||
| 584a0d1586 | |||
| 8ad4987d38 | |||
| b3230b4da9 | |||
| a8dd8ae349 | |||
| 883e20e3c5 | |||
| 3472fe7094 |
18
CHANGELOG.md
18
CHANGELOG.md
@@ -1,5 +1,5 @@
|
||||
<!-- file: CHANGELOG.md -->
|
||||
<!-- version: 3 -->
|
||||
<!-- version: 7 -->
|
||||
|
||||
# Changelog Project Governance Rules
|
||||
|
||||
@@ -7,6 +7,22 @@ Ce fichier décrit les changements utiles aux utilisateurs ou intégrateurs des
|
||||
|
||||
Les tranches `alpha`, `beta`, `rc`, fixes, validations, audits et détails de développement appartiennent aux plans, deltas et historiques. Ils ne sont pas recopiés ici par défaut.
|
||||
|
||||
## 0.0.4
|
||||
|
||||
- définit un contrat transversal de skeleton specifications pour sélectionner et composer règles, profils, templates, décisions destinataire, overrides et validation sans dupliquer les propriétaires normatifs ;
|
||||
- ajoute une fondation composable de gouvernance locale pour initialiser version, documentation minimale, workflow retenu et validation proportionnée d'un projet utilisant PGR ;
|
||||
- ajoute une spécialisation Rust/Cargo workspace composant la fondation avec les profils `500 + 510` et les cinq templates Rust/Cargo existants ;
|
||||
- explicite les décisions à adapter avant instanciation, notamment version, édition/toolchain, membres, métadonnées, dépendances/features, `Cargo.lock`, lints, chemins d'artefacts et audits facultatifs ;
|
||||
- conserve Java/Maven/Gradle, Android, Web, JNI, Tauri et les autres familles insuffisamment matérialisées comme domaines différés plutôt que créer des skeletons prématurés.
|
||||
|
||||
## 0.0.3
|
||||
|
||||
- fournit cinq fichiers modèles Rust/Cargo : `rustfmt.toml`, `clippy.toml`, `.cargo/config.toml`, un manifest workspace et un manifest de crate membre, avec instructions d'adaptation ;
|
||||
- explicite l'héritage des métadonnées et lints Cargo, ainsi que les exceptions locales motivées ;
|
||||
- ajoute deux audits facultatifs et ciblés du style Rust, pour l'espacement des lignes vides et les blocs de constantes racine sans ordre sémantique, sans remplacer Rustfmt ni Clippy ;
|
||||
- ajoute un audit read-only des headers `file` et `version` des fichiers Markdown gouvernés par PGR ;
|
||||
- fournit une spécification courte pour rédiger le message manuel de reprise après publication d'une stable.
|
||||
|
||||
## 0.0.2
|
||||
|
||||
- introduit le modèle de profils PGR avec ownership normatif, applicabilité, composition du général vers le spécifique et overrides bornés ;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: README.md -->
|
||||
<!-- version: 4 -->
|
||||
<!-- version: 11 -->
|
||||
|
||||
# Project Governance Rules
|
||||
|
||||
@@ -13,7 +13,7 @@ Le dépôt officiel est `https://git.sasedev.com/Sasedev/pgr`.
|
||||
|
||||
PGR est actuellement en phase de fondation `0.0.x`.
|
||||
|
||||
La version courante est définie par [`VERSION`](VERSION). La release `0.0.1` établit la gouvernance normative et documentaire de PGR lui-même. La release `0.0.2` ajoute le premier modèle de profils réutilisables, les profils Rust/Cargo, Java/Maven/Gradle et Android, ainsi que deux audits Markdown génériques monotâches. Les releases suivantes de la série `0.0.x` poursuivent avec templates techniques et spécifications de skeletons.
|
||||
La version courante est définie par [`VERSION`](VERSION). La release `0.0.1` établit la gouvernance normative et documentaire de PGR lui-même. La release `0.0.2` ajoute les premiers profils réutilisables Rust/Cargo, Java/Maven/Gradle et Android, ainsi que deux audits Markdown. La release `0.0.3` fournit les premiers modèles Rust/Cargo, deux audits de style Rust facultatifs, l'audit des headers Markdown et la spécification du message manuel de reprise. La release `0.0.4` définit le contrat transversal des skeleton specifications, ajoute une fondation composable de gouvernance locale et une première spécialisation Rust/Cargo workspace fondée sur les profils `500 + 510` et les cinq templates existants. Les autres spécialisations technologiques restent différées tant que leurs pièces requises manquent.
|
||||
|
||||
## Entrées principales
|
||||
|
||||
@@ -26,6 +26,11 @@ La version courante est définie par [`VERSION`](VERSION). La release `0.0.1` é
|
||||
- [`docs/architecture/002-GOVERNANCE_ARCHITECTURE.md`](docs/architecture/002-GOVERNANCE_ARCHITECTURE.md) — architecture du référentiel ;
|
||||
- [`docs/plans/001-V0_0_1_FOUNDATION_PLAN.md`](docs/plans/001-V0_0_1_FOUNDATION_PLAN.md) — plan historique de fondation `0.0.1` ;
|
||||
- [`docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md`](docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md) — plan historique des premiers profils `0.0.2` ;
|
||||
- [`docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md`](docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md) — plan historique des templates et audits `0.0.3` ;
|
||||
- [`docs/plans/004-V0_0_4_SKELETONS_PLAN.md`](docs/plans/004-V0_0_4_SKELETONS_PLAN.md) — plan historique des skeleton specifications `0.0.4` ;
|
||||
- [`docs/skeletons/000-README.md`](docs/skeletons/000-README.md) — index des skeleton specifications et de leur contrat de composition ;
|
||||
- [`docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md`](docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md) — fondation composable de gouvernance locale pour un projet adoptant PGR ;
|
||||
- [`docs/skeletons/002-RUST_CARGO_WORKSPACE.md`](docs/skeletons/002-RUST_CARGO_WORKSPACE.md) — specialization composable pour un workspace Rust/Cargo gouverné ;
|
||||
- [`docs/validation/001-VALIDATION_MATRIX.md`](docs/validation/001-VALIDATION_MATRIX.md) — matrice de validation.
|
||||
|
||||
## Langue et nomenclature
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: ROADMAP.md -->
|
||||
<!-- version: 3 -->
|
||||
<!-- version: 5 -->
|
||||
|
||||
# Roadmap Project Governance Rules
|
||||
|
||||
@@ -11,8 +11,8 @@ Statuts : `( )` planifié, `(x)` terminé, `(d)` différé, `(c)` annulé.
|
||||
|
||||
- `(x) 0.0.1` — fondation normative et documentaire : gouvernance, lifecycle des releases, rôles documentaires, workflow delta/history/handoff et validation proportionnée ;
|
||||
- `(x) 0.0.2` — premiers profils de règles réutilisables : Rust/Cargo, Java/Maven/Gradle et Android, avec modèle de composition et audits Markdown initiaux ;
|
||||
- `( ) 0.0.3` — templates techniques initiaux et premiers patterns d'audit réutilisables issus de besoins réels ;
|
||||
- `( ) 0.0.4` — spécifications Markdown de skeletons et règles de composition des profils/templates ;
|
||||
- `(x) 0.0.3` — templates techniques initiaux et premiers patterns d'audit réutilisables issus de besoins réels ;
|
||||
- `(x) 0.0.4` — spécifications Markdown de skeletons et règles de composition des profils/templates ;
|
||||
- `( ) 0.0.5` — réconciliation réelle de PGR avec `khadhroony-solana-project` et `sasedev-games`.
|
||||
|
||||
## Première baseline réutilisable
|
||||
|
||||
3
RULES.md
3
RULES.md
@@ -1,5 +1,5 @@
|
||||
<!-- file: RULES.md -->
|
||||
<!-- version: 9 -->
|
||||
<!-- version: 10 -->
|
||||
|
||||
# Index normatif Project Governance Rules
|
||||
|
||||
@@ -76,6 +76,7 @@ Familles actuellement actives :
|
||||
|
||||
- [`docs/rules/200-GOVERNANCE.md`](docs/rules/200-GOVERNANCE.md) — versioning, lifecycle des releases, fixes, cadrage, replan et abandon/supersession.
|
||||
- [`docs/rules/210-WORKFLOW.md`](docs/rules/210-WORKFLOW.md) — plans, deltas, histories, prompts, handoffs, manifests, commits, baselines et reprise de session.
|
||||
- [`docs/rules/220-SKELETONS.md`](docs/rules/220-SKELETONS.md) — sélection, composition, adaptation et validation des skeleton specifications.
|
||||
- [`docs/rules/300-DOCUMENTATION.md`](docs/rules/300-DOCUMENTATION.md) — rôles documentaires, taxonomie, révisions internes, documents vivants et conservation historique.
|
||||
- [`docs/rules/400-VALIDATION.md`](docs/rules/400-VALIDATION.md) — sélection proportionnelle des preuves, catégories de validation, tests utiles, doubles de test et autorité opérateur.
|
||||
- [`docs/rules/500-LANGUAGES.md`](docs/rules/500-LANGUAGES.md) — contrat commun des profils langage, écosystème et spécialisations de build associées.
|
||||
|
||||
122
deltas/0.0.3/alpha.1.fix.1.md
Normal file
122
deltas/0.0.3/alpha.1.fix.1.md
Normal file
@@ -0,0 +1,122 @@
|
||||
<!-- file: deltas/0.0.3/alpha.1.fix.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.3-alpha.1.fix.1 — périmètre Rust/Cargo du plan
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline : tranche `0.0.3-alpha.1` validée par l'opérateur, avec `history/0.0.3/alpha.1.md` appliqué et committé. Ce fix ne doit pas être appliqué sur un état où le history `alpha.1` n'est pas encore dans le commit de base.
|
||||
|
||||
Version avant application :
|
||||
|
||||
```text
|
||||
0.0.3-alpha.1
|
||||
```
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.3-alpha.1.fix.1
|
||||
```
|
||||
|
||||
## Motif et observations
|
||||
|
||||
Le delta `alpha.1` a passé sa gate mécanique. La revue du plan ensuite a montré que la tranche Rust prévue autour du seul `rustfmt.toml` n'intégrait pas les réglages Clippy et les deux manifests Cargo communs déjà décrits dans `510-RUST_CARGO.md` et pratiqués dans KSP et Games.
|
||||
|
||||
Les archives de référence supplémentaires inspectées sont :
|
||||
|
||||
```text
|
||||
khadhroony-solana-project-v0.3.16.zip SHA-256 db3cc1b3fc3fb07ee864b02e2a7346c673d4cf63b33e8e872aca6c6458856ca0
|
||||
games-v0.3.5.zip SHA-256 5f5fdee1a271386766d059657d6eaa831acdc263b3e722fed738808335c0a105
|
||||
```
|
||||
|
||||
Les deux projets centralisent lints et métadonnées Cargo, et conservent `rustfmt.toml` ainsi qu'un `clippy.toml`. Les scripts Rust des projets mêlent plusieurs politiques ; le plan corrigé en tire des candidats de propriétés isolées sans les recopier. La seule exception de lints locaux constatée parmi les `45` crates inspectées concerne la frontière Android de Games.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
deltas/0.0.3/alpha.1.fix.1.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
Le plan passe de `<!-- version: 1 -->` à `<!-- version: 2 -->` pour sa révision réelle. Les snapshots `deltas/0.0.3/alpha.1.md` et `history/0.0.3/alpha.1.md` restent inchangés. Aucun template, script, règle normative ou manifest de suppression n'est ajouté dans ce fix.
|
||||
|
||||
## Contenu corrigé
|
||||
|
||||
- le template Rust prévu couvre `rustfmt.toml`, les niveaux de lint Rust/Clippy dans Cargo, les manifests workspace/membre et, seulement si justifié, des paramètres distincts dans `clippy.toml` ;
|
||||
- le plan compare les deux corpus réels, relève l'héritage explicite des lints et son exception Android bornée, distingue les options communes des seuils ou dépendances propres à un projet ;
|
||||
- les tranches sont redimensionnées : `alpha.2` formatage/Clippy, `alpha.3` manifests Cargo, `alpha.4` audit de headers Markdown, puis décision conditionnelle sur un template de workflow ;
|
||||
- les scripts Rust KSP/Games servent de corpus de comparaison pour des audits futurs read-only et monotâches, sans transfert direct de leurs règles locales vers PGR.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
Après application sur le commit `alpha.1` :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.3-alpha.1.fix.1'
|
||||
git cat-file -e HEAD:history/0.0.3/alpha.1.md
|
||||
test -f deltas/0.0.3/alpha.1.fix.1.md
|
||||
test -f history/0.0.3/alpha.1.md
|
||||
test ! -e history/0.0.3/alpha.1.fix.1.md
|
||||
|
||||
grep -Fx '<!-- version: 2 -->' docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
grep -F 'Les `22` crates KSP héritent des lints workspace' docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
grep -F '### alpha.2 — formatage et configuration Clippy' docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
grep -F '### alpha.3 — manifests Cargo workspace et crate membre' docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
grep -F '### alpha.4 — audit de headers Markdown' docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
files = [Path(name) for name in ('README.md', 'RULES.md', 'ROADMAP.md', 'CHANGELOG.md')]
|
||||
for directory in ('docs', 'deltas', 'history', 'prompts'):
|
||||
files.extend(Path(directory).rglob('*.md'))
|
||||
files = sorted(set(files))
|
||||
for path in files:
|
||||
lines = path.read_text(encoding='utf-8').splitlines()
|
||||
assert len(lines) >= 2 and lines[0] == f'<!-- file: {path.as_posix()} -->', path
|
||||
assert re.fullmatch(r'<!-- version: [1-9][0-9]* -->', lines[1]), path
|
||||
print(f'Markdown header audit: clean ({len(files)} file(s))')
|
||||
PY
|
||||
|
||||
git diff --check
|
||||
git add VERSION docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md deltas/0.0.3/alpha.1.fix.1.md
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
Avant ajout du history du fix, le scope indexé attendu est :
|
||||
|
||||
```text
|
||||
M VERSION
|
||||
A deltas/0.0.3/alpha.1.fix.1.md
|
||||
M docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
```
|
||||
|
||||
Revue complémentaire : confirmer que la correction ne copie pas de version de dépendance, de path Cargo ou de seuil Clippy arbitraire ; vérifier que le plan reste une prévision et que `alpha.1` demeure un snapshot historique inchangé.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Produire et appliquer séparément `history/0.0.3/alpha.1.fix.1.md` avec les résultats réellement observés, puis committer ce fix avant tout delta `alpha.2`.
|
||||
|
||||
### FAIL
|
||||
|
||||
Consigner le résultat réel dans le history du fix et poursuivre par `alpha.1.fix.2` limité au cadrage, ou engager un REPLAN explicite si le scope Rust doit changer davantage.
|
||||
101
deltas/0.0.3/alpha.1.md
Normal file
101
deltas/0.0.3/alpha.1.md
Normal file
@@ -0,0 +1,101 @@
|
||||
<!-- file: deltas/0.0.3/alpha.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.3-alpha.1 — audit de baseline et cadrage
|
||||
|
||||
## Baseline
|
||||
|
||||
Archive fournie `pgr-v0.0.2.zip`, déclarée téléchargée du tag Gitea `v0.0.2`, vérifiée avec SHA-256 :
|
||||
|
||||
```text
|
||||
8dc5c979a4d722b4ef6ec84b6227c8cbfffb3f865f4ea9063c03ecb1e365cdc4
|
||||
```
|
||||
|
||||
Le rapport post-tag externe `pgr-0.0.2-publish.001-report.md` indique `PASS` et le même hash. Il n'est pas ajouté rétroactivement à la stable. Aucun `.git` n'est attendu dans l'archive source.
|
||||
|
||||
Version avant application : `0.0.2`.
|
||||
|
||||
Version après application : `0.0.3-alpha.1`.
|
||||
|
||||
## Objet
|
||||
|
||||
Exécuter le cadrage demandé par `prompts/003-V0_0_3_START_PROMPT.md` : audit complet de la stable, vérification des règles et de la chaîne historique, inventaire des sujets utiles, choix d'un scope initial et découpage proportionné dans un plan actif.
|
||||
|
||||
Le résultat détaillé de l'audit, ses limites et les décisions de scope sont consignés dans `docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md`. L'archive est cohérente dans les contrôles réalisés ; aucune correction rétroactive de `0.0.2` n'est nécessaire avant cette tranche.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
deltas/0.0.3/alpha.1.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
L'archive delta contient exactement les fichiers complets ci-dessus, avec les mêmes chemins relatifs. Aucun manifest de suppression, history, nouveau template ou script d'audit n'appartient à cette tranche.
|
||||
|
||||
Les index et les documents historiques restent conformes sans mise à jour cérémonielle : la roadmap annonce déjà `0.0.3`, le changelog conserve les releases stables et les index documentaires pointent vers les collections existantes.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
Appliquer l'archive delta à la copie de travail du dépôt fondée sur `v0.0.2`. Depuis sa racine :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.3-alpha.1'
|
||||
test -f docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
test -f deltas/0.0.3/alpha.1.md
|
||||
test ! -e history/0.0.3/alpha.1.md
|
||||
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
files = [Path(name) for name in ('README.md', 'RULES.md', 'ROADMAP.md', 'CHANGELOG.md')]
|
||||
for directory in ('docs', 'deltas', 'history', 'prompts'):
|
||||
files.extend(Path(directory).rglob('*.md'))
|
||||
files = sorted(set(files))
|
||||
for path in files:
|
||||
lines = path.read_text(encoding='utf-8').splitlines()
|
||||
assert len(lines) >= 2 and lines[0] == f'<!-- file: {path.as_posix()} -->', path
|
||||
assert re.fullmatch(r'<!-- version: [1-9][0-9]* -->', lines[1]), path
|
||||
print(f'Markdown header audit: clean ({len(files)} file(s))')
|
||||
PY
|
||||
|
||||
git diff --check
|
||||
git add VERSION docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md deltas/0.0.3/alpha.1.md
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
Avant d'ajouter le history, le scope attendu des fichiers indexés est :
|
||||
|
||||
```text
|
||||
M VERSION
|
||||
A docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
A deltas/0.0.3/alpha.1.md
|
||||
```
|
||||
|
||||
L'opérateur confirme également que la baseline provient bien du tag déclaré, que le hash concorde avec la preuve post-tag, que les `24` couples historiques antérieurs sont conservés, que les profils différés ne sont pas matérialisés, et que le plan ne fait pas passer une prévision pour une règle déjà active.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Rédiger et livrer séparément `history/0.0.3/alpha.1.md` avec les résultats réellement observés ; l'appliquer et committer la tranche. Préparer seulement ensuite `0.0.3-alpha.2`.
|
||||
|
||||
### FAIL
|
||||
|
||||
Enregistrer le résultat réellement observé dans le history de `alpha.1`, puis corriger le cadrage dans `0.0.3-alpha.1.fix.1` ou produire un REPLAN motivé. Aucune implémentation `alpha.2` ne doit être absorbée dans le fix.
|
||||
123
deltas/0.0.3/alpha.2.md
Normal file
123
deltas/0.0.3/alpha.2.md
Normal file
@@ -0,0 +1,123 @@
|
||||
<!-- file: deltas/0.0.3/alpha.2.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.3-alpha.2 — outillage Rust/Cargo partagé
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline : `0.0.3-alpha.1.fix.1` avec `history/0.0.3/alpha.1.fix.1.md` appliqué et committé. Ce delta MUST NOT être appliqué avant ce commit.
|
||||
|
||||
Version avant application :
|
||||
|
||||
```text
|
||||
0.0.3-alpha.1.fix.1
|
||||
```
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.3-alpha.2
|
||||
```
|
||||
|
||||
## Objet
|
||||
|
||||
Matérialiser trois configurations Rust/Cargo directement issues des pratiques éprouvées dans KSP et Games, avec des instructions explicites d'adaptation. L'opérateur a précisé après le gate de `alpha.1.fix.1` que la sortie Cargo est généralement déportée vers `../builds/<projet>/target/` et que Rustfmt/Clippy constituent des conventions de départ qu'il réutilise avec des adaptations mineures.
|
||||
|
||||
Le `clippy.toml` livré conserve les réglages communs utiles aux deux corpus, sans copier leurs listes d'identifiants propres ni leurs entrées vides. Les niveaux des lints appartiendront aux templates `Cargo.toml` de `alpha.3`, conformément au profil `510`.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
docs/000-README.md
|
||||
docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
templates/rust-cargo/rustfmt.toml
|
||||
templates/rust-cargo/clippy.toml
|
||||
templates/rust-cargo/.cargo/config.toml
|
||||
docs/templates/001-RUST_CARGO_TOOLING.md
|
||||
deltas/0.0.3/alpha.2.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
Les fichiers complets sont livrés dans l'archive delta. Aucun history `alpha.2`, manifest de suppression, crate PGR ou script d'audit nouveau n'y est inclus.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
Depuis la racine du dépôt après application du delta :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.3-alpha.2'
|
||||
git cat-file -e HEAD:history/0.0.3/alpha.1.fix.1.md
|
||||
test ! -e history/0.0.3/alpha.2.md
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import tomllib
|
||||
|
||||
root = Path('templates/rust-cargo')
|
||||
rustfmt = tomllib.loads((root / 'rustfmt.toml').read_text(encoding='utf-8'))
|
||||
clippy = tomllib.loads((root / 'clippy.toml').read_text(encoding='utf-8'))
|
||||
cargo = tomllib.loads((root / '.cargo/config.toml').read_text(encoding='utf-8'))
|
||||
assert rustfmt['edition'] == '2024'
|
||||
assert rustfmt['max_width'] == 160
|
||||
assert clippy['allow-unwrap-in-tests'] is True
|
||||
assert clippy['allowed-idents-below-min-chars'] == ['id']
|
||||
assert cargo['build']['target-dir'] == '../builds/project-name/target'
|
||||
assert cargo['build']['build-dir'] == cargo['build']['target-dir']
|
||||
for path in (root / 'rustfmt.toml', root / 'clippy.toml', root / '.cargo/config.toml'):
|
||||
lines = path.read_text(encoding='utf-8').splitlines()
|
||||
assert lines[0] == f'# file: {path.as_posix()}', path
|
||||
assert lines[1] == '# version: 1', path
|
||||
print('Rust/Cargo template TOML audit: clean (3 file(s))')
|
||||
PY
|
||||
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
files = [Path(name) for name in ('README.md', 'RULES.md', 'ROADMAP.md', 'CHANGELOG.md')]
|
||||
for directory in ('docs', 'deltas', 'history', 'prompts'):
|
||||
files.extend(Path(directory).rglob('*.md'))
|
||||
files = sorted(set(files))
|
||||
for path in files:
|
||||
lines = path.read_text(encoding='utf-8').splitlines()
|
||||
assert len(lines) >= 2 and lines[0] == f'<!-- file: {path.as_posix()} -->', path
|
||||
assert re.fullmatch(r'<!-- version: [1-9][0-9]* -->', lines[1]), path
|
||||
print(f'Markdown header audit: clean ({len(files)} file(s))')
|
||||
PY
|
||||
|
||||
git diff --check
|
||||
git add VERSION docs/000-README.md docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md \
|
||||
docs/templates/001-RUST_CARGO_TOOLING.md deltas/0.0.3/alpha.2.md \
|
||||
templates/rust-cargo/rustfmt.toml templates/rust-cargo/clippy.toml \
|
||||
templates/rust-cargo/.cargo/config.toml
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
Scope attendu avant ajout du history : les trois `REPLACE` et les cinq `ADD` énumérés ci-dessus, sans modification des deltas ou histories précédents.
|
||||
|
||||
Revue opérateur : confirmer que la convention de sortie Cargo vers un dossier frère est expliquée avec son chemin relatif réel, que `project-name` est à remplacer avant copie et que les lints de niveau Cargo et les manifests restent bien au scope de `alpha.3`. La gate de cette tranche reste documentaire/TOML : PGR ne contient aucun workspace Rust à compiler.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Produire séparément `history/0.0.3/alpha.2.md` avec les sorties réellement observées, l'appliquer et committer avant de préparer `alpha.3` consacré aux manifests Cargo.
|
||||
|
||||
### FAIL
|
||||
|
||||
Enregistrer la défaillance réelle puis corriger ces seuls templates ou instructions dans `alpha.2.fix.1`, sauf besoin de REPLAN justifié.
|
||||
118
deltas/0.0.3/alpha.3.md
Normal file
118
deltas/0.0.3/alpha.3.md
Normal file
@@ -0,0 +1,118 @@
|
||||
<!-- file: deltas/0.0.3/alpha.3.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.3-alpha.3 — audits de style Rust ciblés
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline : `0.0.3-alpha.2`, avec `history/0.0.3/alpha.2.md` appliqué et committé. Ce delta MUST NOT être appliqué tant que ce commit n'existe pas.
|
||||
|
||||
Version avant application :
|
||||
|
||||
```text
|
||||
0.0.3-alpha.2
|
||||
```
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.3-alpha.3
|
||||
```
|
||||
|
||||
## Objet et REPLAN
|
||||
|
||||
Après la gate PASS de `alpha.2`, l'opérateur a signalé les audits Python de style Rust de KSP et Games et demandé leur découpage en scripts plus petits et monotâches. L'examen de leurs `audit_rust_general_rules.py` montre qu'ils combinent blancs, constantes, ordre de modules, headers, rustdoc et règles de façade. Résultat REPLAN : `SPLIT`. Les deux contrôles de style apportant une preuve autonome passent à `alpha.3` ; les manifests Cargo initialement prévus ici passent à `alpha.4`, l'audit des headers Markdown à `alpha.5` et la décision workflow à `alpha.6`.
|
||||
|
||||
Ajouter un contrôle facultatif d'espacement des lignes vides et un contrôle facultatif des blocs de constantes racine, avec un helper lexical commun sans politique autonome. Le profil `510` possède leurs conventions optionnelles, la documentation de validation explicite leur adoption et leurs limites ; la matrice répertorie leur test ciblé. Rustfmt reste propriétaire du tri interne qu'il effectue déjà ; Clippy garde ses lints. Aucun script KSP/Games complet ni gate Rust obligatoire n'est copié dans PGR.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
docs/rules/510-RUST_CARGO.md
|
||||
docs/templates/001-RUST_CARGO_TOOLING.md
|
||||
docs/validation/001-VALIDATION_MATRIX.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
docs/validation/002-RUST_STYLE_AUDITS.md
|
||||
scripts/_rust_audit_common.py
|
||||
scripts/audit_rust_blank_lines.py
|
||||
scripts/audit_rust_const_blocks.py
|
||||
tests/test_rust_audits.py
|
||||
deltas/0.0.3/alpha.3.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
Les fichiers complets figurent dans l'archive delta. Aucun history `alpha.3`, changement rétroactif de delta/history, manifest Cargo, suppression ou modification des corpus de référence n'est inclus.
|
||||
|
||||
## Limites et prévalidation
|
||||
|
||||
Les audits sont read-only, sélectionnent explicitement des fichiers `.rs` et signalent les violations avec chemin et ligne. La prévalidation hors dépôt PGR a porté sur `300` sources KSP et `59` sources Games : l'audit des blancs est propre sur les deux ; l'audit des constantes est propre sur Games mais affiche `17` signaux KSP lorsqu'il est lancé globalement. Des séquences KSP portent un ordre métier ou de schéma ; l'ordre alphabétique ne leur est pas imposé. La sélection du projet doit donc exclure les fichiers ayant une sémantique d'ordre incompatible. Les scripts ne parsèrent pas intégralement Rust et ne remplacent ni Rustfmt ni Clippy.
|
||||
|
||||
Cette prévalidation de corpus n'est pas une validation opérateur de la tranche. Le dépôt PGR ne contient ni crate Rust ni fichiers Rust sujets à un audit produit. Les cas de test Python du delta vérifient les contrats réellement livrés, y compris échecs attendus et statut CLI.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
Après application sur le commit `alpha.2` :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.3-alpha.3'
|
||||
git cat-file -e HEAD:history/0.0.3/alpha.2.md
|
||||
test -f history/0.0.3/alpha.2.md
|
||||
test -f deltas/0.0.3/alpha.3.md
|
||||
test ! -e history/0.0.3/alpha.3.md
|
||||
|
||||
grep -Fx '<!-- version: 4 -->' docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
grep -F '### alpha.4 — manifests Cargo workspace et crate membre' docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
grep -F '### alpha.5 — audit de headers Markdown' docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
|
||||
python3 -B -m unittest discover -s tests -p test_rust_audits.py -v
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
files = [Path(name) for name in ('README.md', 'RULES.md', 'ROADMAP.md', 'CHANGELOG.md')]
|
||||
for directory in ('docs', 'deltas', 'history', 'prompts'):
|
||||
files.extend(Path(directory).rglob('*.md'))
|
||||
files = sorted(set(files))
|
||||
for path in files:
|
||||
lines = path.read_text(encoding='utf-8').splitlines()
|
||||
assert len(lines) >= 2 and lines[0] == f'<!-- file: {path.as_posix()} -->', path
|
||||
assert re.fullmatch(r'<!-- version: [1-9][0-9]* -->', lines[1]), path
|
||||
print(f'Markdown header audit: clean ({len(files)} file(s))')
|
||||
PY
|
||||
|
||||
git diff --check
|
||||
git add VERSION docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md \
|
||||
docs/rules/510-RUST_CARGO.md docs/templates/001-RUST_CARGO_TOOLING.md \
|
||||
docs/validation/001-VALIDATION_MATRIX.md docs/validation/002-RUST_STYLE_AUDITS.md \
|
||||
scripts/_rust_audit_common.py scripts/audit_rust_blank_lines.py \
|
||||
scripts/audit_rust_const_blocks.py tests/test_rust_audits.py \
|
||||
deltas/0.0.3/alpha.3.md
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
Scope attendu avant ajout du history : cinq `REPLACE` et six `ADD` exactement comme ci-dessus. Revue opérateur : vérifier le rôle facultatif des deux scripts, leur dépendance commune, la sélection des fichiers Rust et la priorité de l'ordre sémantique ; confirmer que les manifests Cargo restent prévus en `alpha.4`.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Produire séparément `history/0.0.3/alpha.3.md` avec les résultats réellement exécutés, l'appliquer et committer cette tranche avant tout delta `alpha.4`.
|
||||
|
||||
### FAIL
|
||||
|
||||
Consigner le diagnostic dans le history `alpha.3`, puis corriger ce scope dans `alpha.3.fix.1` ou engager un nouveau REPLAN si la séparation des contrôles n'est plus adaptée.
|
||||
191
deltas/0.0.3/alpha.4.md
Normal file
191
deltas/0.0.3/alpha.4.md
Normal file
@@ -0,0 +1,191 @@
|
||||
<!-- file: deltas/0.0.3/alpha.4.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.3-alpha.4 — manifests Cargo workspace et membre
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline : `0.0.3-alpha.3`, avec `history/0.0.3/alpha.3.md` appliqué et committé. Ce delta MUST NOT être appliqué avant ce commit.
|
||||
|
||||
Version avant application :
|
||||
|
||||
```text
|
||||
0.0.3-alpha.3
|
||||
```
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.3-alpha.4
|
||||
```
|
||||
|
||||
## Objet
|
||||
|
||||
Fournir les deux manifests Cargo prévus dans le plan après son REPLAN `SPLIT` : un workspace virtuel à release commune et une crate bibliothèque membre. Les sections d'héritage, les lints Rust/Clippy communs, la version de release et le périmètre des dépendances doivent être compréhensibles sans figer les identités KSP/Games ni une liste de dépendances tierces.
|
||||
|
||||
Le manifest racine reprend les trois lints Rust et les `18` niveaux Clippy effectivement communs aux deux projets. Il déclare un bloc `[workspace.dependencies]` initialement vide. Le membre hérite explicitement des métadonnées présentes et des lints par `[lints] workspace = true`. La documentation distingue l'adaptation ordinaire d'une exception FFI locale, qui ne peut combiner cet héritage avec des lints locaux dans une même crate. La version `0.1.0` et le nom `project-core-lib` sont des exemples à remplacer, pas des valeurs de PGR ou d'un projet tiers.
|
||||
|
||||
Le plan vivant reçoit deux corrections factuelles : PGR possède désormais plus de deux utilitaires Python et la famille énumère cinq responsabilités, et non quatre. Ces corrections n'altèrent aucun delta ni history précédent.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
docs/templates/001-RUST_CARGO_TOOLING.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
templates/rust-cargo/Cargo.toml
|
||||
templates/rust-cargo/crates/project-core-lib/Cargo.toml
|
||||
docs/templates/002-CARGO_MANIFESTS.md
|
||||
deltas/0.0.3/alpha.4.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
L'archive contient uniquement ces fichiers complets. Aucun fichier source Rust, history `alpha.4`, suppression, dépendance de build de PGR ou version tierce n'est introduit.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
Après application sur le commit `alpha.3` :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.3-alpha.4'
|
||||
git cat-file -e HEAD:history/0.0.3/alpha.3.md
|
||||
test -f history/0.0.3/alpha.3.md
|
||||
test ! -e history/0.0.3/alpha.4.md
|
||||
test -f deltas/0.0.3/alpha.4.md
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import json
|
||||
import shutil
|
||||
import subprocess
|
||||
import tempfile
|
||||
import tomllib
|
||||
|
||||
source = Path('templates/rust-cargo')
|
||||
root_file = source / 'Cargo.toml'
|
||||
member_file = source / 'crates/project-core-lib/Cargo.toml'
|
||||
root = tomllib.loads(root_file.read_text(encoding='utf-8'))
|
||||
member = tomllib.loads(member_file.read_text(encoding='utf-8'))
|
||||
assert root['workspace']['resolver'] == '3'
|
||||
assert root['workspace']['members'] == ['crates/project-core-lib']
|
||||
assert root['workspace']['package']['version'] == '0.1.0' # Explicit example.
|
||||
assert root['workspace']['package']['edition'] == '2024'
|
||||
assert root['workspace']['package']['publish'] is False
|
||||
assert root['workspace']['dependencies'] == {}
|
||||
assert root['workspace']['lints']['rust'] == {
|
||||
'missing_docs': 'warn', 'unreachable_pub': 'deny', 'unsafe_code': 'forbid'
|
||||
}
|
||||
clippy = root['workspace']['lints']['clippy']
|
||||
assert len(clippy) == 18 and clippy['implicit_return'] == 'deny'
|
||||
assert clippy['needless_return'] == 'allow' and clippy['unwrap_used'] == 'deny'
|
||||
assert member['package']['name'] == 'project-core-lib'
|
||||
for field in ('version', 'edition', 'publish'):
|
||||
assert member['package'][field] == {'workspace': True}, field
|
||||
assert member['dependencies'] == {} and member['lints'] == {'workspace': True}
|
||||
for path in (root_file, member_file):
|
||||
lines = path.read_text(encoding='utf-8').splitlines()
|
||||
assert lines[:2] == [f'# file: {path.as_posix()}', '# version: 1'], path
|
||||
print('Cargo manifest TOML audit: clean (2 file(s))')
|
||||
|
||||
if shutil.which('cargo') is None:
|
||||
print('Cargo workspace smoke: toolchain unavailable; TOML audit only')
|
||||
else:
|
||||
with tempfile.TemporaryDirectory(prefix='pgr-cargo-manifests-') as folder:
|
||||
workspace = Path(folder)
|
||||
crate = workspace / 'crates/project-core-lib'
|
||||
(crate / 'src').mkdir(parents=True)
|
||||
shutil.copy2(root_file, workspace / 'Cargo.toml')
|
||||
shutil.copy2(member_file, crate / 'Cargo.toml')
|
||||
(crate / 'src/lib.rs').write_text(
|
||||
'//! Minimal template check.\n\n/// Return one.\n'
|
||||
'pub fn value() -> u8 {\n return 1;\n}\n', encoding='utf-8'
|
||||
)
|
||||
command = ['cargo', 'metadata', '--manifest-path', str(workspace / 'Cargo.toml'),
|
||||
'--format-version', '1', '--no-deps', '--offline']
|
||||
result = subprocess.run(command, cwd=workspace, text=True,
|
||||
capture_output=True, check=True)
|
||||
package = json.loads(result.stdout)['packages'][0]
|
||||
assert package['name'] == 'project-core-lib'
|
||||
assert package['version'] == '0.1.0' and package['edition'] == '2024'
|
||||
subprocess.run(['cargo', 'check', '--workspace', '--offline'],
|
||||
cwd=workspace, check=True)
|
||||
if subprocess.run(['cargo', 'clippy', '--version'], capture_output=True).returncode == 0:
|
||||
subprocess.run(['cargo', 'clippy', '--workspace', '--all-targets',
|
||||
'--all-features', '--offline', '--', '-D', 'warnings'],
|
||||
cwd=workspace, check=True)
|
||||
|
||||
# Inherited forbid must reject unsafe code before a local FFI exception.
|
||||
(crate / 'src/lib.rs').write_text(
|
||||
'//! Minimal FFI exception check.\n\n/// Return one.\n'
|
||||
'pub fn value() -> u8 {\n'
|
||||
' let value: u8 = 1;\n let ptr: *const u8 = &value;\n'
|
||||
' unsafe { return *ptr; }\n}\n', encoding='utf-8'
|
||||
)
|
||||
rejected = subprocess.run(['cargo', 'check', '--workspace', '--offline'],
|
||||
cwd=workspace, capture_output=True, text=True)
|
||||
assert rejected.returncode != 0 and 'unsafe' in rejected.stderr
|
||||
|
||||
# Cargo must accept a local lint table in place of inheritance.
|
||||
local = member_file.read_text(encoding='utf-8').replace(
|
||||
'[lints]\nworkspace = true\n',
|
||||
'[lints.rust]\nmissing_docs = "warn"\n'
|
||||
'unreachable_pub = "deny"\nunsafe_code = "allow"\n\n'
|
||||
'[lints.clippy]\n' + ''.join(
|
||||
f'{name} = {json.dumps(level)}\n' for name, level in clippy.items()
|
||||
)
|
||||
)
|
||||
assert '[lints.rust]' in local and '[lints]\nworkspace = true' not in local
|
||||
(crate / 'Cargo.toml').write_text(local, encoding='utf-8')
|
||||
subprocess.run(['cargo', 'check', '--workspace', '--offline'],
|
||||
cwd=workspace, check=True)
|
||||
print('Cargo workspace smoke: clean (inherited and local lints)')
|
||||
PY
|
||||
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
files = [Path(name) for name in ('README.md', 'RULES.md', 'ROADMAP.md', 'CHANGELOG.md')]
|
||||
for directory in ('docs', 'deltas', 'history', 'prompts'):
|
||||
files.extend(Path(directory).rglob('*.md'))
|
||||
files = sorted(set(files))
|
||||
for path in files:
|
||||
lines = path.read_text(encoding='utf-8').splitlines()
|
||||
assert len(lines) >= 2 and lines[0] == f'<!-- file: {path.as_posix()} -->', path
|
||||
assert re.fullmatch(r'<!-- version: [1-9][0-9]* -->', lines[1]), path
|
||||
print(f'Markdown header audit: clean ({len(files)} file(s))')
|
||||
PY
|
||||
|
||||
git diff --check
|
||||
git add VERSION docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md \
|
||||
docs/templates/001-RUST_CARGO_TOOLING.md docs/templates/002-CARGO_MANIFESTS.md \
|
||||
templates/rust-cargo/Cargo.toml templates/rust-cargo/crates/project-core-lib/Cargo.toml \
|
||||
deltas/0.0.3/alpha.4.md
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
Scope attendu avant ajout du history : les trois `REPLACE` et les quatre `ADD` ci-dessus. Revue opérateur : vérifier que le manifest membre hérite seulement des champs racine présents, que les lints Clippy sont ceux des deux corpus et que la version d'exemple ainsi que le nom de crate doivent être remplacés lors d'une adoption réelle. Si Cargo n'est pas disponible dans l'environnement de PGR, le smoke workspace est indiqué comme non exécuté et le parsing TOML reste la preuve locale ; l'adoption dans un projet Rust doit exécuter sa propre gate Cargo.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Fournir séparément `history/0.0.3/alpha.4.md` avec les sorties réellement observées, l'appliquer et committer la tranche avant le delta `alpha.5` relatif aux headers Markdown.
|
||||
|
||||
### FAIL
|
||||
|
||||
Consigner le défaut dans le history, puis corriger manifests ou instructions dans `alpha.4.fix.1` sauf besoin justifié d'un nouveau REPLAN.
|
||||
90
deltas/0.0.3/alpha.5.md
Normal file
90
deltas/0.0.3/alpha.5.md
Normal file
@@ -0,0 +1,90 @@
|
||||
<!-- file: deltas/0.0.3/alpha.5.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.3-alpha.5 — audit des headers Markdown
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline : `0.0.3-alpha.4`, avec `history/0.0.3/alpha.4.md` appliqué et committé. Ce delta MUST NOT être appliqué avant ce commit.
|
||||
|
||||
Version avant application :
|
||||
|
||||
```text
|
||||
0.0.3-alpha.4
|
||||
```
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.3-alpha.5
|
||||
```
|
||||
|
||||
## Objet
|
||||
|
||||
Extraire le contrôle des headers Markdown répété en Python inline dans les gates précédentes. `scripts/audit_markdown_headers.py` vérifie une seule propriété documentaire : les deux premières lignes de chaque fichier choisi doivent déclarer son chemin relatif canonique et une révision interne positive. Le script accepte des chemins explicites depuis la racine du projet, lit sans modifier, produit des erreurs déterministes avec chemin et ligne et distingue violation de sélection invalide.
|
||||
|
||||
`docs/rules/300-DOCUMENTATION.md` possède la convention pour le corpus Markdown de PGR. La matrice inscrit l'audit mécanique séparément de la revue des rôles documentaires, de l'audit des tableaux et de celui des liens. Une révision positive ne démontre pas qu'elle a été incrémentée à bon escient : cela reste une décision de revue.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
docs/rules/300-DOCUMENTATION.md
|
||||
docs/validation/001-VALIDATION_MATRIX.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
scripts/audit_markdown_headers.py
|
||||
tests/test_markdown_headers.py
|
||||
deltas/0.0.3/alpha.5.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
L'archive livre uniquement ces fichiers complets. Aucun history `alpha.5`, réécriture historique, nouveau profil de langage ou autre audit Markdown n'est inclus.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
Après application sur le commit `alpha.4`, depuis la racine du dépôt :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.3-alpha.5'
|
||||
git cat-file -e HEAD:history/0.0.3/alpha.4.md
|
||||
test -f history/0.0.3/alpha.4.md
|
||||
test -f deltas/0.0.3/alpha.5.md
|
||||
test ! -e history/0.0.3/alpha.5.md
|
||||
|
||||
grep -Fx '<!-- version: 2 -->' docs/rules/300-DOCUMENTATION.md
|
||||
grep -Fx '<!-- version: 8 -->' docs/validation/001-VALIDATION_MATRIX.md
|
||||
|
||||
python3 -B -m unittest discover -s tests -p test_markdown_headers.py -v
|
||||
python3 -B scripts/audit_markdown_headers.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
git diff --check
|
||||
git add VERSION docs/rules/300-DOCUMENTATION.md \
|
||||
docs/validation/001-VALIDATION_MATRIX.md scripts/audit_markdown_headers.py \
|
||||
tests/test_markdown_headers.py deltas/0.0.3/alpha.5.md
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
Scope attendu avant ajout du history : trois `REPLACE` et trois `ADD`, sans toucher à un delta ou history antérieur. Vérifier que le nouveau script reste monotâche, traite les headers faux et les chemins absents, et ne remplace ni la revue des documents ni les deux autres audits Markdown.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Produire séparément `history/0.0.3/alpha.5.md` avec les preuves réellement observées, l'appliquer et committer avant la tranche `alpha.6`, consacrée à la décision conditionnelle sur le template de workflow.
|
||||
|
||||
### FAIL
|
||||
|
||||
Enregistrer la défaillance et corriger ce scope dans `alpha.5.fix.1`, sauf REPLAN explicitement justifié.
|
||||
92
deltas/0.0.3/alpha.6.md
Normal file
92
deltas/0.0.3/alpha.6.md
Normal file
@@ -0,0 +1,92 @@
|
||||
<!-- file: deltas/0.0.3/alpha.6.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.3-alpha.6 — prompt manuel de reprise
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline : `0.0.3-alpha.5`, avec `history/0.0.3/alpha.5.md` appliqué et committé. Ce delta MUST NOT être appliqué avant ce commit.
|
||||
|
||||
Version avant application :
|
||||
|
||||
```text
|
||||
0.0.3-alpha.5
|
||||
```
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.3-alpha.6
|
||||
```
|
||||
|
||||
## Décision et objet
|
||||
|
||||
La comparaison des prompts `002` et `003` et des règles `210-WORKFLOW.md` confirme une répétition utile : baseline taggée, version cible, première tranche et consigne d'audit à la reprise. `003` ajoute une preuve de vérification post-tag distincte et une phrase manuelle à remettre à l'opérateur. La décision conditionnelle de la tranche est donc **retenir** une spécification courte dans `docs/templates/003-NEW_SESSION_PROMPT.md`.
|
||||
|
||||
Ce document rassemble les champs à renseigner et une forme de message manuel, avec une branche claire lorsque le rapport post-tag manque ou n'est pas `PASS`. Il ne génère rien, ne fige aucun nom de projet ni preuve et ne prépare pas encore le prompt versionné de `0.0.4`. `docs/rules/210-WORKFLOW.md` reste propriétaire de la séquence delta/history/commit et de la publication après tag ; le plan vivant enregistre la décision.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
docs/rules/210-WORKFLOW.md
|
||||
docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
docs/templates/003-NEW_SESSION_PROMPT.md
|
||||
deltas/0.0.3/alpha.6.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
L'archive contient uniquement ces fichiers complets. Aucun history `alpha.6`, prompt `004`, générateur, modification de prompts historiques ou changement de configuration Rust/Cargo n'est inclus.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
Après application sur le commit `alpha.5`, depuis la racine du dépôt :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.3-alpha.6'
|
||||
git cat-file -e HEAD:history/0.0.3/alpha.5.md
|
||||
test -f history/0.0.3/alpha.5.md
|
||||
test -f deltas/0.0.3/alpha.6.md
|
||||
test -f docs/templates/003-NEW_SESSION_PROMPT.md
|
||||
test ! -e history/0.0.3/alpha.6.md
|
||||
test ! -e prompts/004-V0_0_4_START_PROMPT.md
|
||||
|
||||
grep -Fx '<!-- version: 3 -->' docs/rules/210-WORKFLOW.md
|
||||
grep -Fx '<!-- version: 6 -->' docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
grep -F '### Retenu : spécification courte du prompt manuel de nouvelle session' \
|
||||
docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
|
||||
python3 -B scripts/audit_markdown_headers.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
git diff --check
|
||||
git add VERSION docs/rules/210-WORKFLOW.md \
|
||||
docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md \
|
||||
docs/templates/003-NEW_SESSION_PROMPT.md deltas/0.0.3/alpha.6.md
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
Scope attendu avant ajout du history : trois `REPLACE` et deux `ADD`. Revue opérateur : confirmer que le message manuel est actionnable sans supposer un rapport `PASS`, que son contrat versionné est distinct, que les prompts `002`/`003` restent historiques et que la préparation de `0.0.4` n'est pas anticipée.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Produire séparément `history/0.0.3/alpha.6.md` d'après la gate exécutée, l'appliquer et committer avant de passer à `beta.1` pour la réconciliation de release.
|
||||
|
||||
### FAIL
|
||||
|
||||
Enregistrer le diagnostic puis corriger uniquement cette spécification et ses renvois dans `alpha.6.fix.1`, sauf REPLAN justifié.
|
||||
115
deltas/0.0.3/beta.1.md
Normal file
115
deltas/0.0.3/beta.1.md
Normal file
@@ -0,0 +1,115 @@
|
||||
<!-- file: deltas/0.0.3/beta.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.3-beta.1 — réconciliation documentaire
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline : `0.0.3-alpha.6`, avec `history/0.0.3/alpha.6.md` appliqué et committé. Ce delta MUST NOT être appliqué avant ce commit.
|
||||
|
||||
Version avant application :
|
||||
|
||||
```text
|
||||
0.0.3-alpha.6
|
||||
```
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.3-beta.1
|
||||
```
|
||||
|
||||
## Objet et résultat de la revue
|
||||
|
||||
Réconcilier la navigation, les propriétaires et les contrôles après les six tranches alpha et le fix documentaire. Les sept deltas `alpha.1` à `alpha.6`, fix inclus, ont chacun un history `PASS` fourni par la gate opérateur ; leur chaîne de versions est continue depuis `0.0.2`. La règle `210` possède le workflow ; la règle `300` possède les headers Markdown ; le profil `510` possède les conventions Rust facultatives. Les documents `docs/templates/` expliquent comment adapter les cinq fichiers Rust/Cargo et le message de reprise, tandis que les scripts restent de petits contrôles de propriétés délimitées.
|
||||
|
||||
La revue relève quatre corrections de documents vivants : exposer le plan actif depuis `README.md`, ouvrir la navigation directe depuis `docs/000-README.md` et décrire son template de workflow, actualiser dans le plan l'audit des headers déjà livré, et rendre dans la matrice l'audit des liens applicable à une tranche alpha qui modifie la navigation. La réconciliation n'ajoute aucune famille normative, audit, règle de version universelle, dépendance de build ou prompt `0.0.4`. Les versions et seuils du modèle Cargo restent des exemples ou choix adaptables, et les snapshots antérieurs restent intacts.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
README.md
|
||||
docs/000-README.md
|
||||
docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
docs/validation/001-VALIDATION_MATRIX.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
deltas/0.0.3/beta.1.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
L'archive contient exactement ces fichiers complets. Le history de `alpha.6` est livré séparément, celui de `beta.1` n'existe pas encore ; `CHANGELOG.md`, les règles, templates techniques, scripts, tests et prompts ne sont pas modifiés.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
Après application de `history/0.0.3/alpha.6.md` et son commit, appliquer ce delta puis exécuter à la racine :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.3-beta.1'
|
||||
git cat-file -e HEAD:history/0.0.3/alpha.6.md
|
||||
test -f history/0.0.3/alpha.6.md
|
||||
test -f deltas/0.0.3/beta.1.md
|
||||
test ! -e history/0.0.3/beta.1.md
|
||||
test ! -e prompts/004-V0_0_4_START_PROMPT.md
|
||||
|
||||
grep -Fx '<!-- version: 5 -->' README.md
|
||||
grep -Fx '<!-- version: 3 -->' docs/000-README.md
|
||||
grep -Fx '<!-- version: 7 -->' docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
grep -Fx '<!-- version: 9 -->' docs/validation/001-VALIDATION_MATRIX.md
|
||||
|
||||
python3 -B -m unittest discover -s tests -p 'test_*.py' -v
|
||||
python3 -B scripts/audit_markdown_headers.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
import tomllib
|
||||
|
||||
tranches = ['alpha.1', 'alpha.1.fix.1', 'alpha.2', 'alpha.3',
|
||||
'alpha.4', 'alpha.5', 'alpha.6']
|
||||
version = '0.0.2'
|
||||
for name in tranches:
|
||||
delta = Path(f'deltas/0.0.3/{name}.md').read_text(encoding='utf-8')
|
||||
history = Path(f'history/0.0.3/{name}.md').read_text(encoding='utf-8')
|
||||
assert re.search(r'## Statut\s+PASS\s', history), name
|
||||
assert f'Version avant application : `{version}`.' in delta or \
|
||||
f'Version avant application :\n\n```text\n{version}\n```' in delta, name
|
||||
version = f'0.0.3-{name}'
|
||||
assert f'Version après application : `{version}`.' in delta or \
|
||||
f'Version après application :\n\n```text\n{version}\n```' in delta, name
|
||||
for path in sorted(Path('templates/rust-cargo').rglob('*.toml')):
|
||||
tomllib.loads(path.read_text(encoding='utf-8'))
|
||||
print(f'Reconciliation audit: clean ({len(tranches)} PASS histories, 5 TOML files)')
|
||||
PY
|
||||
|
||||
git diff --check
|
||||
git add VERSION README.md docs/000-README.md \
|
||||
docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md \
|
||||
docs/validation/001-VALIDATION_MATRIX.md deltas/0.0.3/beta.1.md
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
Scope attendu avant ajout du history : cinq `REPLACE` et un `ADD` exactement comme ci-dessus. Revue opérateur : confirmer que les liens pointent vers les documents propriétaires et que les valeurs du template Cargo restent des exemples adaptables ; les gates alpha déjà observées ne sont pas réinterprétées et la RC n'est pas déclarée acquise par cette prévalidation.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Produire séparément `history/0.0.3/beta.1.md` avec les résultats réellement observés, l'appliquer et committer `beta.1` avant de préparer `rc.1`.
|
||||
|
||||
### FAIL
|
||||
|
||||
Enregistrer le diagnostic dans le history de `beta.1`, puis corriger la réconciliation dans `beta.1.fix.1` ou faire un REPLAN explicite si le scope a changé.
|
||||
117
deltas/0.0.3/rc.1.md
Normal file
117
deltas/0.0.3/rc.1.md
Normal file
@@ -0,0 +1,117 @@
|
||||
<!-- file: deltas/0.0.3/rc.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.3-rc.1 — gel du scope et préparation de release
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline : `0.0.3-beta.1`, avec `history/0.0.3/beta.1.md` appliqué et committé. Ce delta MUST NOT être appliqué avant ce commit.
|
||||
|
||||
Version avant application :
|
||||
|
||||
```text
|
||||
0.0.3-beta.1
|
||||
```
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.3-rc.1
|
||||
```
|
||||
|
||||
## Objet et gel
|
||||
|
||||
La gate de `beta.1` est `PASS`. La RC gèle le scope fonctionnel : cinq modèles Rust/Cargo adaptables, deux audits facultatifs de style Rust, un audit de headers Markdown et une spécification du message manuel de reprise. La candidate `0.0.3` du changelog décrit ces résultats sans détailler les fixes ; le plan enregistre le gel et l'état observé de beta.
|
||||
|
||||
Le prompt `004` prépare le cadrage de `0.0.4` consacré aux skeleton specifications Markdown et à la composition des profils/templates. Il demande un audit de la future archive taggée `v0.0.3` et traite son rapport post-tag comme une preuve conditionnelle, jamais acquise en RC. Son message manuel doit être ajusté et remis après la publication et son contrôle réel. Aucun skeleton complet, générateur, règle normative nouvelle, audit nouveau ni projet source modifié n'appartient à `rc.1`.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
CHANGELOG.md
|
||||
docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
prompts/004-V0_0_4_START_PROMPT.md
|
||||
deltas/0.0.3/rc.1.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
L'archive contient exactement ces fichiers complets. Le history `beta.1` est livré séparément ; le history `rc.1` sera produit après la gate opérateur. Les histories et deltas antérieurs, les règles, modèles techniques, scripts, tests et `ROADMAP.md` restent inchangés.
|
||||
|
||||
## Gate opérateur de release candidate
|
||||
|
||||
Après application sur le commit `beta.1`, depuis la racine du dépôt :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.3-rc.1'
|
||||
git cat-file -e HEAD:history/0.0.3/beta.1.md
|
||||
test -f history/0.0.3/beta.1.md
|
||||
test -f deltas/0.0.3/rc.1.md
|
||||
test -f prompts/004-V0_0_4_START_PROMPT.md
|
||||
test ! -e history/0.0.3/rc.1.md
|
||||
|
||||
grep -Fx '<!-- version: 4 -->' CHANGELOG.md
|
||||
grep -Fx '## 0.0.3 (candidate)' CHANGELOG.md
|
||||
grep -Fx '<!-- version: 8 -->' docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
grep -F 'La gate opérateur de `beta.1` est `PASS`' docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
grep -F 'pgr-0.0.3-publish.001-report.md' prompts/004-V0_0_4_START_PROMPT.md
|
||||
grep -F "Si le rapport manque ou n'est pas PASS" prompts/004-V0_0_4_START_PROMPT.md
|
||||
|
||||
python3 -B -m unittest discover -s tests -p 'test_*.py' -v
|
||||
python3 -B scripts/audit_markdown_headers.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
import tomllib
|
||||
|
||||
names = ['alpha.1', 'alpha.1.fix.1', 'alpha.2', 'alpha.3',
|
||||
'alpha.4', 'alpha.5', 'alpha.6', 'beta.1']
|
||||
version = '0.0.2'
|
||||
for name in names:
|
||||
delta = Path(f'deltas/0.0.3/{name}.md').read_text(encoding='utf-8')
|
||||
history = Path(f'history/0.0.3/{name}.md').read_text(encoding='utf-8')
|
||||
assert re.search(r'## Statut\s+PASS\s', history), name
|
||||
assert f'Version avant application : `{version}`.' in delta or \
|
||||
f'Version avant application :\n\n```text\n{version}\n```' in delta, name
|
||||
version = f'0.0.3-{name}'
|
||||
assert f'Version après application : `{version}`.' in delta or \
|
||||
f'Version après application :\n\n```text\n{version}\n```' in delta, name
|
||||
assert {p.stem for p in Path('deltas/0.0.3').glob('*.md')} - \
|
||||
{p.stem for p in Path('history/0.0.3').glob('*.md')} == {'rc.1'}
|
||||
for path in Path('templates/rust-cargo').rglob('*.toml'):
|
||||
tomllib.loads(path.read_text(encoding='utf-8'))
|
||||
print(f'RC integration audit: clean ({len(names)} PASS histories, 5 TOML files)')
|
||||
PY
|
||||
|
||||
git diff --check
|
||||
git add VERSION CHANGELOG.md docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md \
|
||||
prompts/004-V0_0_4_START_PROMPT.md deltas/0.0.3/rc.1.md
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
Scope attendu avant ajout du history : trois `REPLACE` et deux `ADD`. Revue opérateur : contrôler que le changelog décrit la release et non les tranches, que les exemples Cargo restent adaptables, que `004` concerne exclusivement la future `0.0.4` et que sa preuve post-tag n'est pas présumée. Une gate RC PASS n'est pas un tag ni une vérification de l'archive publiée.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Produire séparément `history/0.0.3/rc.1.md` d'après la gate observée, l'appliquer puis committer la RC avant la promotion stable `rel.001`.
|
||||
|
||||
### FAIL
|
||||
|
||||
Consigner les échecs dans le history RC et corriger le scope gelé dans `rc.1.fix.1` ; réviser le plan si un changement fonctionnel plus large s'impose.
|
||||
116
deltas/0.0.3/rel.001.md
Normal file
116
deltas/0.0.3/rel.001.md
Normal file
@@ -0,0 +1,116 @@
|
||||
<!-- file: deltas/0.0.3/rel.001.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.3 rel.001 — promotion stable pré-tag
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline : `0.0.3-rc.1`, avec `history/0.0.3/rc.1.md` appliqué et committé. Ce delta MUST NOT être appliqué avant ce commit.
|
||||
|
||||
Version avant application :
|
||||
|
||||
```text
|
||||
0.0.3-rc.1
|
||||
```
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.3
|
||||
```
|
||||
|
||||
`rel.001` identifie la clôture opérationnelle ; il ne fait pas partie de la version SemVer du produit.
|
||||
|
||||
## Objet
|
||||
|
||||
Promouvoir la RC validée vers la stable `0.0.3`. La tranche finalise la présentation de la release, marque la roadmap terminée, retire la mention « candidate » du changelog et clôt le plan comme référence historique. Le prompt `004`, les règles, les modèles, les audits et les tests sont ceux validés en RC : aucune fonctionnalité, règle ou preuve post-tag nouvelle n'est introduite.
|
||||
|
||||
La validation de cette tranche est **pré-tag**. Ni le tag `v0.0.3` ni une archive téléchargée depuis Gitea ni un rapport `publish.001` ne sont déclarés existants par ce delta. Ils suivent le history PASS, le commit stable et la publication du tag.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
README.md
|
||||
ROADMAP.md
|
||||
CHANGELOG.md
|
||||
docs/000-README.md
|
||||
docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
deltas/0.0.3/rel.001.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
L'archive contient uniquement ces fichiers complets. `history/0.0.3/rc.1.md` arrive séparément ; le history de `rel.001` sera rédigé après sa gate. Le rapport post-tag sera hors de l'archive source taggée.
|
||||
|
||||
## Validation opérateur pré-tag
|
||||
|
||||
Après application sur le commit `rc.1`, depuis la racine du dépôt :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.3'
|
||||
git cat-file -e HEAD:history/0.0.3/rc.1.md
|
||||
test -f history/0.0.3/rc.1.md
|
||||
test -f deltas/0.0.3/rel.001.md
|
||||
test -f prompts/004-V0_0_4_START_PROMPT.md
|
||||
test ! -e history/0.0.3/rel.001.md
|
||||
|
||||
grep -Fx '<!-- version: 6 -->' README.md
|
||||
grep -Fx '<!-- version: 4 -->' ROADMAP.md
|
||||
grep -Fx '<!-- version: 5 -->' CHANGELOG.md
|
||||
grep -Fx '<!-- version: 4 -->' docs/000-README.md
|
||||
grep -Fx '<!-- version: 9 -->' docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
grep -F 'La release `0.0.3` fournit les premiers modèles Rust/Cargo' README.md
|
||||
grep -F 'plan historique des templates et audits `0.0.3`' README.md
|
||||
grep -F -- '- `(x) 0.0.3`' ROADMAP.md
|
||||
grep -Fx '## 0.0.3' CHANGELOG.md
|
||||
grep -F 'La gate opérateur de `rc.1` est `PASS`' docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
grep -F "La vérification de l'archive" docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
names = ['alpha.1', 'alpha.1.fix.1', 'alpha.2', 'alpha.3',
|
||||
'alpha.4', 'alpha.5', 'alpha.6', 'beta.1', 'rc.1']
|
||||
for name in names:
|
||||
history = Path(f'history/0.0.3/{name}.md')
|
||||
assert Path(f'deltas/0.0.3/{name}.md').is_file(), name
|
||||
assert re.search(r'## Statut\s+PASS\s', history.read_text(encoding='utf-8')), name
|
||||
assert {p.stem for p in Path('deltas/0.0.3').glob('*.md')} - \
|
||||
{p.stem for p in Path('history/0.0.3').glob('*.md')} == {'rel.001'}
|
||||
print(f'Stable history audit: clean ({len(names)} PASS histories, rel.001 pending)')
|
||||
PY
|
||||
|
||||
python3 -B scripts/audit_markdown_headers.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
git diff --check
|
||||
git add VERSION README.md ROADMAP.md CHANGELOG.md docs/000-README.md \
|
||||
docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md deltas/0.0.3/rel.001.md
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
Scope attendu avant ajout du history : six `REPLACE` et un `ADD` exactement comme ci-dessus. Revue opérateur : confirmer que le scope RC ne change pas, que la présentation du dépôt, le changelog et la roadmap décrivent la même stable, que le prompt `004` reste conditionnel au rapport post-tag et que les snapshots historiques restent intacts. Les `15` tests et les cinq TOML validés en RC restent des preuves utilisables parce qu'aucun code, script, test ou template n'a changé dans cette promotion.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Rédiger et livrer séparément `history/0.0.3/rel.001.md` avec le résultat réellement observé ; l'appliquer et committer la stable. Ensuite seulement, créer et publier le tag canonique `v0.0.3`, télécharger son archive source depuis Gitea, vérifier cette archive et conserver séparément la preuve post-tag `publish.001`. Le texte manuel du prompt `004` n'est remis à l'opérateur qu'après vérification de l'archive et d'un rapport post-tag PASS réel.
|
||||
|
||||
### FAIL
|
||||
|
||||
Consigner le diagnostic dans le history de `rel.001`, ne pas tagger, puis corriger la clôture dans une tranche explicite avant publication.
|
||||
150
deltas/0.0.4/alpha.1.md
Normal file
150
deltas/0.0.4/alpha.1.md
Normal file
@@ -0,0 +1,150 @@
|
||||
<!-- file: deltas/0.0.4/alpha.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.4-alpha.1 — audit de baseline et cadrage des skeletons
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline : archive source fournie `pgr-v0.0.3.zip`, déclarée téléchargée depuis le tag Gitea `v0.0.3`, accompagnée du rapport externe `pgr-0.0.3-publish.001-report.md` avec statut `PASS`.
|
||||
|
||||
SHA-256 vérifié de l'archive :
|
||||
|
||||
```text
|
||||
517fb46ada098fdc221ae53a8ff4b409b81e0244ec5ce4d0e6fca0c3da61b866
|
||||
```
|
||||
|
||||
Le rapport post-tag annonce le même hash et reste extérieur à la stable. L'archive sans `.git` est contrôlée par son contenu ; elle n'est pas utilisée comme preuve autonome du commit ou de la référence distante du tag.
|
||||
|
||||
Version avant application :
|
||||
|
||||
```text
|
||||
0.0.3
|
||||
```
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.4-alpha.1
|
||||
```
|
||||
|
||||
## Objet
|
||||
|
||||
Exécuter la gate de cadrage imposée par `prompts/004-V0_0_4_START_PROMPT.md` avant toute matérialisation importante : vérifier la stable, les règles `200` à `610`, la gouvernance documentaire, les templates et audits existants, la chaîne delta/history et les limites annoncées ; déterminer ensuite quels skeletons disposent déjà d'entrées suffisantes et planifier les tranches de `0.0.4`.
|
||||
|
||||
Le résultat détaillé de cette revue et le découpage prévisionnel sont consignés dans `docs/plans/004-V0_0_4_SKELETONS_PLAN.md`. Aucun défaut bloquant de `0.0.3` n'impose une correction rétroactive avant ce cadrage.
|
||||
|
||||
Le plan retient comme premières cibles la fondation composable d'un projet gouverné PGR puis un skeleton Rust/Cargo workspace. Java/Maven/Gradle, Android, Web, JNI, Tauri et les autres familles sans pièces suffisantes restent différés.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
README.md
|
||||
docs/000-README.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
docs/plans/004-V0_0_4_SKELETONS_PLAN.md
|
||||
deltas/0.0.4/alpha.1.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
L'archive delta contient uniquement ces cinq fichiers complets avec leurs chemins relatifs. Aucun history, skeleton concret, nouvelle règle, template technique, script ou manifest de suppression n'appartient à `alpha.1`.
|
||||
|
||||
`README.md` et `docs/000-README.md` sont des documents vivants : ils ajoutent le plan actif comme point d'entrée. `ROADMAP.md` annonce déjà `0.0.4` comme planifiée et `CHANGELOG.md` reste limité aux releases publiées ; ils n'ont pas besoin d'une modification cérémonielle dans cette tranche.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
Après application sur le commit stable `0.0.3`, depuis la racine du dépôt :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.4-alpha.1'
|
||||
test -f docs/plans/004-V0_0_4_SKELETONS_PLAN.md
|
||||
test -f deltas/0.0.4/alpha.1.md
|
||||
test ! -e history/0.0.4/alpha.1.md
|
||||
|
||||
grep -Fx '<!-- version: 7 -->' README.md
|
||||
grep -Fx '<!-- version: 5 -->' docs/000-README.md
|
||||
grep -F '004-V0_0_4_SKELETONS_PLAN.md' README.md
|
||||
grep -F '004-V0_0_4_SKELETONS_PLAN.md' docs/000-README.md
|
||||
|
||||
python3 -B -m unittest discover -s tests -v
|
||||
|
||||
python3 -B scripts/audit_markdown_headers.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
import tomllib
|
||||
|
||||
for path in (
|
||||
Path('templates/rust-cargo/rustfmt.toml'),
|
||||
Path('templates/rust-cargo/clippy.toml'),
|
||||
Path('templates/rust-cargo/.cargo/config.toml'),
|
||||
Path('templates/rust-cargo/Cargo.toml'),
|
||||
Path('templates/rust-cargo/crates/project-core-lib/Cargo.toml'),
|
||||
):
|
||||
with path.open('rb') as stream:
|
||||
tomllib.load(stream)
|
||||
|
||||
expected_counts = {'0.0.1': 12, '0.0.2': 12, '0.0.3': 10}
|
||||
for release, expected in expected_counts.items():
|
||||
deltas = {path.name for path in Path('deltas', release).glob('*.md')}
|
||||
histories = {path.name for path in Path('history', release).glob('*.md')}
|
||||
assert len(deltas) == expected, (release, len(deltas))
|
||||
assert deltas == histories, (release, sorted(deltas ^ histories))
|
||||
|
||||
for path in Path('history/0.0.3').glob('*.md'):
|
||||
text = path.read_text(encoding='utf-8')
|
||||
assert re.search(r'## Statut\s+PASS\s', text), path
|
||||
|
||||
for path in (
|
||||
Path('scripts/audit_rust_blank_lines.py'),
|
||||
Path('scripts/audit_rust_const_blocks.py'),
|
||||
Path('scripts/_rust_audit_common.py'),
|
||||
):
|
||||
assert path.is_file(), path
|
||||
|
||||
print('Baseline structural audit: clean (34 prior delta/history pairs, 10/10 histories 0.0.3 PASS, 5 TOML parsed)')
|
||||
PY
|
||||
|
||||
git diff --check
|
||||
git add VERSION README.md docs/000-README.md \
|
||||
docs/plans/004-V0_0_4_SKELETONS_PLAN.md deltas/0.0.4/alpha.1.md
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
Le scope indexé attendu avant ajout du history est :
|
||||
|
||||
```text
|
||||
M README.md
|
||||
M VERSION
|
||||
A deltas/0.0.4/alpha.1.md
|
||||
M docs/000-README.md
|
||||
A docs/plans/004-V0_0_4_SKELETONS_PLAN.md
|
||||
```
|
||||
|
||||
La vérification du ZIP et du rapport post-tag appartient à l'intake de cette tranche et a été utilisée pour préparer le plan. L'opérateur confirme également que les fichiers fournis sont bien ceux téléchargés pour la reprise, que le hash de l'archive concorde avec le rapport, que le rapport est `PASS` et qu'il n'est pas copié dans le dépôt.
|
||||
|
||||
La revue opérateur doit confirmer que le plan ne transforme pas une prévision en règle active, que les valeurs Rust/Cargo d'exemple restent adaptables et que les domaines différés ne sont pas matérialisés par anticipation.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Rédiger et livrer séparément `history/0.0.4/alpha.1.md` avec les résultats réellement observés ; l'appliquer et committer la tranche. Préparer seulement ensuite `0.0.4-alpha.2` pour le contrat de composition des skeletons.
|
||||
|
||||
### FAIL
|
||||
|
||||
Consigner le résultat réel dans le history de `alpha.1`, puis corriger le cadrage dans `0.0.4-alpha.1.fix.1` ou produire un REPLAN motivé. Aucun contenu de `alpha.2` ne doit être absorbé silencieusement dans un fix.
|
||||
189
deltas/0.0.4/alpha.2.md
Normal file
189
deltas/0.0.4/alpha.2.md
Normal file
@@ -0,0 +1,189 @@
|
||||
<!-- file: deltas/0.0.4/alpha.2.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.4-alpha.2 — contrat de composition des skeletons
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline : commit opérateur `bf306da` (`0.0.4-alpha.1`) après application de `history/0.0.4/alpha.1.md` avec statut `PASS`, puis push sur `origin/master`.
|
||||
|
||||
La baseline attendue contient donc le delta, le plan et le history de `alpha.1`, sans contenu `alpha.2` préalable.
|
||||
|
||||
Version avant application :
|
||||
|
||||
```text
|
||||
0.0.4-alpha.1
|
||||
```
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.4-alpha.2
|
||||
```
|
||||
|
||||
## Objet
|
||||
|
||||
Matérialiser le contrat transversal annoncé par le plan `0.0.4` sans anticiper les skeletons concrets des tranches suivantes.
|
||||
|
||||
La tranche crée `docs/rules/220-SKELETONS.md` comme propriétaire normatif unique de l'applicabilité, de la sélection, de la composition, des décisions projet, des overrides et de la validation initiale des skeleton specifications. Elle active également `docs/skeletons/` avec un index réel décrivant la responsabilité de la collection.
|
||||
|
||||
Les index normatifs et documentaires ainsi que les deux documents d'architecture concernés sont réconciliés avec ce nouveau propriétaire. Le modèle des profils reste possédé par `docs/architecture/003-RULE_PROFILE_MODEL.md` ; le nouveau document `220` le référence au lieu de dupliquer sa hiérarchie.
|
||||
|
||||
Aucun skeleton de fondation, Rust/Cargo, Java/Android, Web, JNI, Tauri ou autre domaine technologique n'appartient à cette tranche.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
README.md
|
||||
RULES.md
|
||||
docs/000-README.md
|
||||
docs/architecture/002-GOVERNANCE_ARCHITECTURE.md
|
||||
docs/architecture/003-RULE_PROFILE_MODEL.md
|
||||
docs/rules/000-README.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
docs/rules/220-SKELETONS.md
|
||||
docs/skeletons/000-README.md
|
||||
deltas/0.0.4/alpha.2.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
L'archive delta contient uniquement ces dix fichiers complets avec leurs chemins relatifs. Elle ne contient pas `history/0.0.4/alpha.1.md`, déjà committé dans la baseline, ni `history/0.0.4/alpha.2.md`, qui sera produit après la gate opérateur.
|
||||
|
||||
Le plan `docs/plans/004-V0_0_4_SKELETONS_PLAN.md` n'est pas modifié : la tranche réalise son étape `alpha.2` sans replan ni changement substantiel de trajectoire.
|
||||
|
||||
## Décisions normatives matérialisées
|
||||
|
||||
Le contrat commun impose notamment qu'un skeleton :
|
||||
|
||||
- déclare son objectif et son applicabilité à partir de faits du projet ;
|
||||
- identifie les règles, profils, templates, fichiers, décisions, options, overrides, ordre utile, validation et hors-scope nécessaires ;
|
||||
- référence les owners normatifs existants au lieu de devenir propriétaire implicite de leurs règles ;
|
||||
- conserve les projets instanciés autonomes et sans dépendance runtime/build vers PGR ;
|
||||
- distingue les valeurs obligatoires, exemples, recommandations et choix libres lorsqu'une confusion serait possible ;
|
||||
- n'applique pas tous les profils PGR par défaut ;
|
||||
- n'utilise pas l'ordre de composition comme priorité normative implicite ;
|
||||
- ne crée pas de skeleton composite sans interaction réelle à posséder ;
|
||||
- utilise une validation proportionnée au contenu réellement matérialisé.
|
||||
|
||||
La collection `docs/skeletons/` reste vide de specification concrète dans `alpha.2` hormis son index. Sa création n'est pas un placeholder : l'index documente le contrat de collection réellement activé par le nouveau owner normatif.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
Après application sur le commit `bf306da`, depuis la racine du dépôt :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.4-alpha.2'
|
||||
test -f history/0.0.4/alpha.1.md
|
||||
test -f deltas/0.0.4/alpha.2.md
|
||||
test -f docs/rules/220-SKELETONS.md
|
||||
test -f docs/skeletons/000-README.md
|
||||
test ! -e history/0.0.4/alpha.2.md
|
||||
|
||||
test ! -e docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md
|
||||
test ! -e docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||
|
||||
grep -Fx '<!-- version: 8 -->' README.md
|
||||
grep -Fx '<!-- version: 10 -->' RULES.md
|
||||
grep -Fx '<!-- version: 6 -->' docs/000-README.md
|
||||
grep -Fx '<!-- version: 3 -->' docs/architecture/002-GOVERNANCE_ARCHITECTURE.md
|
||||
grep -Fx '<!-- version: 3 -->' docs/architecture/003-RULE_PROFILE_MODEL.md
|
||||
grep -Fx '<!-- version: 11 -->' docs/rules/000-README.md
|
||||
grep -Fx '<!-- version: 1 -->' docs/rules/220-SKELETONS.md
|
||||
grep -Fx '<!-- version: 1 -->' docs/skeletons/000-README.md
|
||||
|
||||
grep -F 'docs/rules/220-SKELETONS.md' RULES.md
|
||||
grep -F '220-SKELETONS.md' docs/rules/000-README.md
|
||||
grep -F 'skeletons/' docs/000-README.md
|
||||
grep -F '220-SKELETONS.md' docs/architecture/002-GOVERNANCE_ARCHITECTURE.md
|
||||
grep -F '220-SKELETONS.md' docs/architecture/003-RULE_PROFILE_MODEL.md
|
||||
|
||||
python3 -B -m unittest discover -s tests -v
|
||||
|
||||
python3 -B scripts/audit_markdown_headers.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
expected_counts = {'0.0.1': 12, '0.0.2': 12, '0.0.3': 10, '0.0.4': 1}
|
||||
for release, expected in expected_counts.items():
|
||||
histories = {path.name for path in Path('history', release).glob('*.md')}
|
||||
if release == '0.0.4':
|
||||
assert histories == {'alpha.1.md'}, histories
|
||||
continue
|
||||
deltas = {path.name for path in Path('deltas', release).glob('*.md')}
|
||||
assert len(deltas) == expected, (release, len(deltas))
|
||||
assert deltas == histories, (release, sorted(deltas ^ histories))
|
||||
|
||||
text = Path('history/0.0.4/alpha.1.md').read_text(encoding='utf-8')
|
||||
assert re.search(r'## Statut\s+PASS\s', text)
|
||||
|
||||
assert sorted(path.name for path in Path('docs/skeletons').glob('*.md')) == ['000-README.md']
|
||||
|
||||
rule = Path('docs/rules/220-SKELETONS.md').read_text(encoding='utf-8')
|
||||
for phrase in (
|
||||
'## Applicabilité',
|
||||
'## Contenu minimal d\'une specification',
|
||||
'## Sélection des règles et profils',
|
||||
'## Templates et artefacts techniques',
|
||||
'## Décisions propres au projet',
|
||||
'## Composition de plusieurs skeletons',
|
||||
'## Overrides et exceptions',
|
||||
'## Validation de l\'instanciation',
|
||||
):
|
||||
assert phrase in rule, phrase
|
||||
|
||||
print('Skeleton contract audit: clean (alpha.1 PASS baseline, alpha.2 contract/index only)')
|
||||
PY
|
||||
|
||||
git diff --check
|
||||
git add VERSION README.md RULES.md docs/000-README.md \
|
||||
docs/architecture/002-GOVERNANCE_ARCHITECTURE.md \
|
||||
docs/architecture/003-RULE_PROFILE_MODEL.md \
|
||||
docs/rules/000-README.md docs/rules/220-SKELETONS.md \
|
||||
docs/skeletons/000-README.md deltas/0.0.4/alpha.2.md
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
Le scope indexé attendu avant ajout du history est :
|
||||
|
||||
```text
|
||||
M README.md
|
||||
M RULES.md
|
||||
M VERSION
|
||||
A deltas/0.0.4/alpha.2.md
|
||||
M docs/000-README.md
|
||||
M docs/architecture/002-GOVERNANCE_ARCHITECTURE.md
|
||||
M docs/architecture/003-RULE_PROFILE_MODEL.md
|
||||
M docs/rules/000-README.md
|
||||
A docs/rules/220-SKELETONS.md
|
||||
A docs/skeletons/000-README.md
|
||||
```
|
||||
|
||||
La revue opérateur doit également confirmer que `220-SKELETONS.md` reste transversal, ne duplique pas les règles de profils ou de validation et ne matérialise aucun choix technologique futur par anticipation.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Rédiger et livrer `history/0.0.4/alpha.2.md` avec les résultats réellement observés ; l'appliquer puis committer la tranche. La tranche suivante est `0.0.4-alpha.3`, consacrée à la première skeleton specification de fondation d'un projet gouverné.
|
||||
|
||||
Le history `alpha.2` et le delta `alpha.3` MAY être livrés dans la même réponse après la gate `PASS`, tout en restant deux archives séparées. Le delta `alpha.3` MUST NOT être appliqué avant le commit complet de `alpha.2`.
|
||||
|
||||
### FAIL
|
||||
|
||||
Consigner le résultat réel dans le history de `alpha.2`, puis corriger le contrat dans `0.0.4-alpha.2.fix.1` ou produire un REPLAN motivé. Aucun skeleton concret de `alpha.3` ne doit être absorbé silencieusement dans un fix.
|
||||
167
deltas/0.0.4/alpha.3.md
Normal file
167
deltas/0.0.4/alpha.3.md
Normal file
@@ -0,0 +1,167 @@
|
||||
<!-- file: deltas/0.0.4/alpha.3.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.4-alpha.3 — fondation de projet gouverné
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline attendue : commit opérateur de `0.0.4-alpha.2`, réalisé après application de `history/0.0.4/alpha.2.md` avec statut `PASS`.
|
||||
|
||||
Le hash de ce commit n'est volontairement pas anticipé : le history `alpha.2` et le présent delta peuvent être livrés dans le même échange, mais restent deux archives séparées et le delta `alpha.3` MUST NOT être appliqué avant le commit de `alpha.2`.
|
||||
|
||||
Version avant application :
|
||||
|
||||
```text
|
||||
0.0.4-alpha.2
|
||||
```
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.4-alpha.3
|
||||
```
|
||||
|
||||
## Objet
|
||||
|
||||
Matérialiser la première skeleton specification concrète prévue par le plan `0.0.4` : une fondation composable de gouvernance locale pour un projet qui adopte PGR, sans sélectionner de langage, plateforme, framework ou architecture applicative.
|
||||
|
||||
La specification doit rendre actionnables les responsabilités générales déjà possédées par `200`, `210`, `300` et `400` : version courante, point d'entrée normatif, documentation minimale, workflow réellement retenu, décisions destinataire, overrides et validation initiale proportionnée.
|
||||
|
||||
Elle ne crée aucun template générique, ne copie pas la structure complète du dépôt PGR et ne précrée aucun répertoire documentaire ou workflow sans contenu réel.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
README.md
|
||||
docs/000-README.md
|
||||
docs/skeletons/000-README.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md
|
||||
deltas/0.0.4/alpha.3.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
L'archive delta contient uniquement ces six fichiers complets avec leurs chemins relatifs. Elle ne contient ni `history/0.0.4/alpha.2.md`, livré séparément pour clôturer la tranche précédente, ni `history/0.0.4/alpha.3.md`, qui sera produit après la gate opérateur.
|
||||
|
||||
Le plan `docs/plans/004-V0_0_4_SKELETONS_PLAN.md` et la règle `docs/rules/220-SKELETONS.md` ne sont pas modifiés : cette tranche exécute leur trajectoire et leur contrat sans REPLAN.
|
||||
|
||||
## Contenu matérialisé
|
||||
|
||||
`docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md` :
|
||||
|
||||
- déclare son objectif, son applicabilité et son hors-scope ;
|
||||
- sélectionne les owners généraux `200`, `210`, `300` et `400` sans sélectionner de profil technologique ;
|
||||
- distingue le rôle de `220` comme contrat d'instanciation de celui des règles à reprendre localement ;
|
||||
- impose de résoudre les décisions destinataire avant de présenter l'instanciation comme terminée ;
|
||||
- rend le point d'entrée normatif local et la version courante explicites ;
|
||||
- rend `docs/`, `ROADMAP.md`, `CHANGELOG.md` et les collections spécialisées conditionnels à un contenu réel ;
|
||||
- conserve `deltas/`, `history/`, `prompts/`, `handoffs/` et `manifests/` comme répertoires créés à la demande ;
|
||||
- fournit une validation initiale proportionnée sans imposer de copier les scripts PGR ;
|
||||
- définit l'ordre de composition attendu pour les futures spécialisations ;
|
||||
- exclut explicitement architecture applicative, toolchain, CI/CD universel, branching universel et migration rétroactive.
|
||||
|
||||
Aucun template générique n'est nécessaire pour rendre cette specification actionnable : elle décrit les owners, décisions, fichiers conditionnels et preuves à matérialiser sans prétendre générer leur contenu automatiquement. Le point de REPLAN du plan n'est donc pas déclenché par cette tranche.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
Après avoir appliqué `history/0.0.4/alpha.2.md`, committé `0.0.4-alpha.2`, puis appliqué le présent delta, depuis la racine du dépôt :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.4-alpha.3'
|
||||
test -f history/0.0.4/alpha.2.md
|
||||
test -f deltas/0.0.4/alpha.3.md
|
||||
test -f docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md
|
||||
test ! -e history/0.0.4/alpha.3.md
|
||||
test ! -e docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||
|
||||
grep -Fx '<!-- version: 9 -->' README.md
|
||||
grep -Fx '<!-- version: 7 -->' docs/000-README.md
|
||||
grep -Fx '<!-- version: 2 -->' docs/skeletons/000-README.md
|
||||
grep -Fx '<!-- version: 1 -->' docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md
|
||||
|
||||
grep -F '001-PROJECT_GOVERNANCE_FOUNDATION.md' README.md
|
||||
grep -F '001-PROJECT_GOVERNANCE_FOUNDATION.md' docs/000-README.md
|
||||
grep -F '001-PROJECT_GOVERNANCE_FOUNDATION.md' docs/skeletons/000-README.md
|
||||
|
||||
python3 -B -m unittest discover -s tests -v
|
||||
|
||||
python3 -B scripts/audit_markdown_headers.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
histories = {path.name for path in Path('history/0.0.4').glob('*.md')}
|
||||
assert histories == {'alpha.1.md', 'alpha.2.md'}, histories
|
||||
for name in sorted(histories):
|
||||
text = Path('history/0.0.4', name).read_text(encoding='utf-8')
|
||||
assert re.search(r'## Statut\s+PASS\s', text), name
|
||||
|
||||
skeletons = sorted(path.name for path in Path('docs/skeletons').glob('*.md'))
|
||||
assert skeletons == ['000-README.md', '001-PROJECT_GOVERNANCE_FOUNDATION.md'], skeletons
|
||||
|
||||
text = Path('docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md').read_text(encoding='utf-8')
|
||||
for phrase in (
|
||||
'## Applicabilité',
|
||||
'## Owners sélectionnés',
|
||||
'## Décisions destinataire avant matérialisation',
|
||||
'## Baseline locale à matérialiser',
|
||||
'### Version',
|
||||
'### Documentation minimale',
|
||||
'### Workflow retenu',
|
||||
'### Validation initiale',
|
||||
'## Ordre de composition',
|
||||
'## Overrides et exceptions',
|
||||
'## Hors scope',
|
||||
):
|
||||
assert phrase in text, phrase
|
||||
|
||||
for owner in ('200-GOVERNANCE.md', '210-WORKFLOW.md', '300-DOCUMENTATION.md', '400-VALIDATION.md'):
|
||||
assert owner in text, owner
|
||||
|
||||
for forbidden in (
|
||||
'templates/generic',
|
||||
'docs/skeletons/002-RUST_CARGO_WORKSPACE.md',
|
||||
):
|
||||
assert forbidden not in text, forbidden
|
||||
|
||||
print('Governance foundation audit: clean (alpha.1/alpha.2 PASS baseline, one concrete non-technological skeleton)')
|
||||
PY
|
||||
|
||||
git diff --check
|
||||
git add VERSION README.md docs/000-README.md \
|
||||
docs/skeletons/000-README.md \
|
||||
docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md \
|
||||
deltas/0.0.4/alpha.3.md
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
## Revue opérateur
|
||||
|
||||
En complément des commandes, vérifier que :
|
||||
|
||||
- la fondation reste une procedure composable et non un template ou générateur implicite ;
|
||||
- aucun document ou répertoire n'est rendu obligatoire uniquement pour reproduire le layout PGR ;
|
||||
- aucune règle technologique `500+` ou `600+` n'est sélectionnée par défaut ;
|
||||
- les décisions destinataire restent explicites et aucune valeur d'exemple n'est universalisée ;
|
||||
- l'ordre de composition permet au futur skeleton Rust/Cargo d'ajouter ses responsabilités sans dupliquer les owners généraux.
|
||||
|
||||
## Transition
|
||||
|
||||
PASS : produire `history/0.0.4/alpha.3.md`, l'appliquer puis committer `0.0.4-alpha.3`. La tranche suivante prévue par le plan est `0.0.4-alpha.4`, consacrée au skeleton Rust/Cargo workspace et à sa validation d'instanciation.
|
||||
|
||||
FAIL : rester dans le scope de `alpha.3` via `alpha.3.fix.1` sauf si l'échec démontre qu'un template générique ou une nouvelle décision normative est indispensable, auquel cas déclencher le REPLAN prévu par le plan.
|
||||
231
deltas/0.0.4/alpha.4.fix.1.md
Normal file
231
deltas/0.0.4/alpha.4.fix.1.md
Normal file
@@ -0,0 +1,231 @@
|
||||
<!-- file: deltas/0.0.4/alpha.4.fix.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.4-alpha.4.fix.1 — correction du smoke Rust/Cargo
|
||||
|
||||
## Baseline
|
||||
|
||||
Version attendue avant application :
|
||||
|
||||
```text
|
||||
0.0.4-alpha.4
|
||||
```
|
||||
|
||||
Le history `history/0.0.4/alpha.4.md` avec statut `FAIL` MUST avoir été appliqué et committé avant ce correctif.
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.4-alpha.4.fix.1
|
||||
```
|
||||
|
||||
## Objet
|
||||
|
||||
Corriger uniquement la procédure de smoke Rust/Cargo qui a échoué pendant la gate opérateur de `alpha.4`.
|
||||
|
||||
Le workspace temporaire était fonctionnel et les commandes Cargo ont réussi, mais l'adaptation de `.cargo/config.toml` remplaçait les chemins contenant `project-name` sans adapter le commentaire de guidance qui contenait encore ce placeholder. L'assertion d'absence de placeholders échouait donc avant le smoke Cargo.
|
||||
|
||||
Ce fix adapte explicitement ce commentaire dans la fixture temporaire avant de vérifier l'absence de placeholders.
|
||||
|
||||
Aucune règle, aucun skeleton, aucun template et aucun script PGR n'est ajouté ou modifié.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
deltas/0.0.4/alpha.4.fix.1.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
Les snapshots suivants restent inchangés :
|
||||
|
||||
```text
|
||||
deltas/0.0.4/alpha.4.md
|
||||
docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||
templates/rust-cargo/rustfmt.toml
|
||||
templates/rust-cargo/clippy.toml
|
||||
templates/rust-cargo/.cargo/config.toml
|
||||
templates/rust-cargo/Cargo.toml
|
||||
templates/rust-cargo/crates/project-core-lib/Cargo.toml
|
||||
```
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.4-alpha.4.fix.1'
|
||||
test -f history/0.0.4/alpha.4.md
|
||||
test -f deltas/0.0.4/alpha.4.md
|
||||
test -f deltas/0.0.4/alpha.4.fix.1.md
|
||||
test -f docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||
test ! -e history/0.0.4/alpha.4.fix.1.md
|
||||
|
||||
grep -A2 '^## Statut$' history/0.0.4/alpha.4.md | grep -Fx 'FAIL'
|
||||
|
||||
python3 -B -m unittest discover -s tests -v
|
||||
|
||||
python3 -B scripts/audit_markdown_headers.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
import tomllib
|
||||
|
||||
expected = {
|
||||
'alpha.1.md': 'PASS',
|
||||
'alpha.2.md': 'PASS',
|
||||
'alpha.3.md': 'PASS',
|
||||
'alpha.4.md': 'FAIL',
|
||||
}
|
||||
histories = {path.name for path in Path('history/0.0.4').glob('*.md')}
|
||||
assert histories == set(expected), histories
|
||||
for name, status in expected.items():
|
||||
text = Path('history/0.0.4', name).read_text(encoding='utf-8')
|
||||
assert re.search(rf'## Statut\s+{status}\s', text), (name, status)
|
||||
|
||||
skeletons = sorted(path.name for path in Path('docs/skeletons').glob('*.md'))
|
||||
assert skeletons == [
|
||||
'000-README.md',
|
||||
'001-PROJECT_GOVERNANCE_FOUNDATION.md',
|
||||
'002-RUST_CARGO_WORKSPACE.md',
|
||||
], skeletons
|
||||
|
||||
for path in (
|
||||
Path('templates/rust-cargo/rustfmt.toml'),
|
||||
Path('templates/rust-cargo/clippy.toml'),
|
||||
Path('templates/rust-cargo/.cargo/config.toml'),
|
||||
Path('templates/rust-cargo/Cargo.toml'),
|
||||
Path('templates/rust-cargo/crates/project-core-lib/Cargo.toml'),
|
||||
):
|
||||
with path.open('rb') as stream:
|
||||
tomllib.load(stream)
|
||||
|
||||
print('Rust/Cargo fix audit: clean (alpha.4 FAIL recorded, skeleton/templates unchanged)')
|
||||
PY
|
||||
|
||||
command -v cargo
|
||||
command -v rustfmt
|
||||
cargo --version
|
||||
rustc --version
|
||||
rustfmt --version
|
||||
cargo clippy --version
|
||||
|
||||
tmp="$(mktemp -d)"
|
||||
trap 'rm -rf "$tmp"' EXIT
|
||||
mkdir -p "$tmp/.cargo" "$tmp/crates/smoke-core-lib/src"
|
||||
cp templates/rust-cargo/Cargo.toml "$tmp/Cargo.toml"
|
||||
cp templates/rust-cargo/rustfmt.toml "$tmp/rustfmt.toml"
|
||||
cp templates/rust-cargo/clippy.toml "$tmp/clippy.toml"
|
||||
cp templates/rust-cargo/.cargo/config.toml "$tmp/.cargo/config.toml"
|
||||
cp templates/rust-cargo/crates/project-core-lib/Cargo.toml "$tmp/crates/smoke-core-lib/Cargo.toml"
|
||||
printf '1.2.3\n' > "$tmp/VERSION"
|
||||
|
||||
python3 -B - "$tmp" <<'PY'
|
||||
from pathlib import Path
|
||||
import sys
|
||||
|
||||
root = Path(sys.argv[1])
|
||||
|
||||
replacements = {
|
||||
root / 'Cargo.toml': (
|
||||
('# file: templates/rust-cargo/Cargo.toml', '# file: Cargo.toml'),
|
||||
('members = ["crates/project-core-lib"]', 'members = ["crates/smoke-core-lib"]'),
|
||||
('version = "0.1.0"', 'version = "1.2.3"'),
|
||||
),
|
||||
root / 'rustfmt.toml': (
|
||||
('# file: templates/rust-cargo/rustfmt.toml', '# file: rustfmt.toml'),
|
||||
),
|
||||
root / 'clippy.toml': (
|
||||
('# file: templates/rust-cargo/clippy.toml', '# file: clippy.toml'),
|
||||
),
|
||||
root / '.cargo/config.toml': (
|
||||
('# file: templates/rust-cargo/.cargo/config.toml', '# file: .cargo/config.toml'),
|
||||
(
|
||||
'# Replace project-name with a unique name before using this configuration.',
|
||||
'# Smoke fixture: project-specific build directory already selected.',
|
||||
),
|
||||
('../builds/project-name/target', 'target-smoke'),
|
||||
),
|
||||
root / 'crates/smoke-core-lib/Cargo.toml': (
|
||||
(
|
||||
'# file: templates/rust-cargo/crates/project-core-lib/Cargo.toml',
|
||||
'# file: crates/smoke-core-lib/Cargo.toml',
|
||||
),
|
||||
('name = "project-core-lib"', 'name = "smoke-core-lib"'),
|
||||
),
|
||||
}
|
||||
|
||||
for path, pairs in replacements.items():
|
||||
text = path.read_text(encoding='utf-8')
|
||||
for old, new in pairs:
|
||||
assert old in text, (path, old)
|
||||
text = text.replace(old, new)
|
||||
path.write_text(text, encoding='utf-8')
|
||||
|
||||
for path in root.rglob('*'):
|
||||
if path.is_file() and path.name != 'Cargo.lock':
|
||||
text = path.read_text(encoding='utf-8')
|
||||
assert 'project-name' not in text, path
|
||||
assert 'project-core-lib' not in text, path
|
||||
|
||||
print('Temporary Rust/Cargo template adaptation: clean')
|
||||
PY
|
||||
|
||||
cat > "$tmp/crates/smoke-core-lib/src/lib.rs" <<'RS'
|
||||
//! Minimal crate used to validate the PGR Rust/Cargo templates.
|
||||
|
||||
/// Returns the deterministic smoke value.
|
||||
pub fn smoke_value() -> u8 {
|
||||
return 1;
|
||||
}
|
||||
RS
|
||||
|
||||
(
|
||||
cd "$tmp"
|
||||
cargo metadata --format-version 1 --no-deps >/dev/null
|
||||
cargo fmt --all -- --check
|
||||
cargo check --workspace
|
||||
cargo clippy --workspace --all-targets --all-features -- -D warnings
|
||||
)
|
||||
|
||||
rm -rf "$tmp"
|
||||
trap - EXIT
|
||||
|
||||
git diff --check
|
||||
|
||||
git add VERSION deltas/0.0.4/alpha.4.fix.1.md
|
||||
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
La sortie Git attendue avant ajout du history du fix est exactement :
|
||||
|
||||
```text
|
||||
M VERSION
|
||||
A deltas/0.0.4/alpha.4.fix.1.md
|
||||
```
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Créer et appliquer séparément `history/0.0.4/alpha.4.fix.1.md`, committer et pousser le correctif, puis reprendre le plan `0.0.4` à la tranche suivante prévue.
|
||||
|
||||
Le history `alpha.4.fix.1` et le delta de la tranche suivante MAY être livrés ensemble sous forme de deux archives séparées après observation de la gate opérateur.
|
||||
|
||||
### FAIL
|
||||
|
||||
Rester dans `0.0.4-alpha.4.fix.M`. Le scope MUST rester limité au smoke Rust/Cargo de cette tranche tant qu'aucun défaut plus large ne justifie un REPLAN.
|
||||
277
deltas/0.0.4/alpha.4.md
Normal file
277
deltas/0.0.4/alpha.4.md
Normal file
@@ -0,0 +1,277 @@
|
||||
<!-- file: deltas/0.0.4/alpha.4.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.4-alpha.4 — skeleton Rust/Cargo workspace
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline attendue : commit opérateur de `0.0.4-alpha.3`, réalisé après application de `history/0.0.4/alpha.3.md` avec statut `PASS`.
|
||||
|
||||
Le hash de ce commit n'est volontairement pas anticipé : le history `alpha.3` et le présent delta peuvent être livrés dans le même échange, mais restent deux archives séparées et le delta `alpha.4` MUST NOT être appliqué avant le commit de `alpha.3`.
|
||||
|
||||
Version avant application :
|
||||
|
||||
```text
|
||||
0.0.4-alpha.3
|
||||
```
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.4-alpha.4
|
||||
```
|
||||
|
||||
## Objet
|
||||
|
||||
Matérialiser la première specialization technologique prévue par le plan `0.0.4` : un skeleton Rust/Cargo workspace composable avec la fondation `001`, les profils `500 + 510`, les cinq templates Rust/Cargo existants et leurs guides d'adaptation.
|
||||
|
||||
La specification doit rendre explicites les décisions destinataire avant copie, la relation entre `VERSION` et la version Cargo, les membres du workspace, l'édition/toolchain, les métadonnées, les dépendances/features, `Cargo.lock`, les lints, les paramètres Rustfmt/Clippy, les artefacts Cargo et la sélection éventuelle des audits de style Rust.
|
||||
|
||||
Aucun template Rust/Cargo ni owner normatif n'est modifié dans cette tranche : la spécialisation doit composer les pièces déjà éprouvées sans universaliser leurs valeurs d'exemple.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
README.md
|
||||
docs/000-README.md
|
||||
docs/skeletons/000-README.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||
deltas/0.0.4/alpha.4.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
L'archive delta contient uniquement ces six fichiers complets avec leurs chemins relatifs. Elle ne contient ni `history/0.0.4/alpha.3.md`, livré séparément pour clôturer la tranche précédente, ni `history/0.0.4/alpha.4.md`, qui sera produit après la gate opérateur.
|
||||
|
||||
Les documents suivants restent inchangés :
|
||||
|
||||
```text
|
||||
docs/rules/220-SKELETONS.md
|
||||
docs/rules/500-LANGUAGES.md
|
||||
docs/rules/510-RUST_CARGO.md
|
||||
docs/templates/001-RUST_CARGO_TOOLING.md
|
||||
docs/templates/002-CARGO_MANIFESTS.md
|
||||
docs/validation/002-RUST_STYLE_AUDITS.md
|
||||
templates/rust-cargo/rustfmt.toml
|
||||
templates/rust-cargo/clippy.toml
|
||||
templates/rust-cargo/.cargo/config.toml
|
||||
templates/rust-cargo/Cargo.toml
|
||||
templates/rust-cargo/crates/project-core-lib/Cargo.toml
|
||||
```
|
||||
|
||||
La tranche exécute donc le plan sans REPLAN et sans déplacer les propriétaires existants.
|
||||
|
||||
## Contenu matérialisé
|
||||
|
||||
`docs/skeletons/002-RUST_CARGO_WORKSPACE.md` :
|
||||
|
||||
- se compose explicitement avec `001-PROJECT_GOVERNANCE_FOUNDATION.md` ;
|
||||
- sélectionne `500-LANGUAGES.md` et `510-RUST_CARGO.md` sans absorber leurs règles ;
|
||||
- référence les guides `001-RUST_CARGO_TOOLING.md` et `002-CARGO_MANIFESTS.md` ;
|
||||
- identifie exactement les cinq templates Rust/Cargo copiables existants ;
|
||||
- rend explicites les décisions de release unit, membres, édition/toolchain, publication, métadonnées, dépendances/features, lockfile, lints, formatage, Clippy et artefacts ;
|
||||
- rappelle que `0.1.0`, `2024`, `project-name`, `project-core-lib`, les seuils Clippy et les chemins de build doivent être revus avant adoption ;
|
||||
- ne fournit aucun `src/lib.rs` ou `src/main.rs` universel ;
|
||||
- conserve les audits de style Rust comme option explicitement sélectionnée avec corpus ciblé ;
|
||||
- définit une validation Cargo initiale fondée sur `cargo metadata`, Rustfmt, `cargo check` et Clippy ;
|
||||
- permet aux futurs profils plateforme/framework de s'ajouter après le workspace sans créer un composite artificiel.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
Après avoir appliqué `history/0.0.4/alpha.3.md`, committé `0.0.4-alpha.3`, puis appliqué le présent delta, depuis la racine du dépôt :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.4-alpha.4'
|
||||
test -f history/0.0.4/alpha.3.md
|
||||
test -f deltas/0.0.4/alpha.4.md
|
||||
test -f docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||
test ! -e history/0.0.4/alpha.4.md
|
||||
|
||||
grep -Fx '<!-- version: 10 -->' README.md
|
||||
grep -Fx '<!-- version: 8 -->' docs/000-README.md
|
||||
grep -Fx '<!-- version: 3 -->' docs/skeletons/000-README.md
|
||||
grep -Fx '<!-- version: 1 -->' docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||
|
||||
grep -F '002-RUST_CARGO_WORKSPACE.md' README.md
|
||||
grep -F '002-RUST_CARGO_WORKSPACE.md' docs/000-README.md
|
||||
grep -F '002-RUST_CARGO_WORKSPACE.md' docs/skeletons/000-README.md
|
||||
|
||||
python3 -B -m unittest discover -s tests -v
|
||||
|
||||
python3 -B scripts/audit_markdown_headers.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
import tomllib
|
||||
|
||||
histories = {path.name for path in Path('history/0.0.4').glob('*.md')}
|
||||
assert histories == {'alpha.1.md', 'alpha.2.md', 'alpha.3.md'}, histories
|
||||
for name in sorted(histories):
|
||||
text = Path('history/0.0.4', name).read_text(encoding='utf-8')
|
||||
assert re.search(r'## Statut\s+PASS\s', text), name
|
||||
|
||||
skeletons = sorted(path.name for path in Path('docs/skeletons').glob('*.md'))
|
||||
assert skeletons == [
|
||||
'000-README.md',
|
||||
'001-PROJECT_GOVERNANCE_FOUNDATION.md',
|
||||
'002-RUST_CARGO_WORKSPACE.md',
|
||||
], skeletons
|
||||
|
||||
text = Path('docs/skeletons/002-RUST_CARGO_WORKSPACE.md').read_text(encoding='utf-8')
|
||||
for phrase in (
|
||||
'## Applicabilité et composition',
|
||||
'## Owners, guides et artefacts sélectionnés',
|
||||
'## Décisions destinataire avant copie',
|
||||
'## Matérialisation du workspace',
|
||||
'### Cargo.lock',
|
||||
'### Audits de style facultatifs',
|
||||
'## Validation initiale',
|
||||
'## Ordre de composition et extensions',
|
||||
'## Overrides et exceptions',
|
||||
'## Hors scope',
|
||||
):
|
||||
assert phrase in text, phrase
|
||||
|
||||
for owner in ('500-LANGUAGES.md', '510-RUST_CARGO.md'):
|
||||
assert owner in text, owner
|
||||
|
||||
for template in (
|
||||
'templates/rust-cargo/rustfmt.toml',
|
||||
'templates/rust-cargo/clippy.toml',
|
||||
'templates/rust-cargo/.cargo/config.toml',
|
||||
'templates/rust-cargo/Cargo.toml',
|
||||
'templates/rust-cargo/crates/project-core-lib/Cargo.toml',
|
||||
):
|
||||
assert template in text, template
|
||||
|
||||
for path in (
|
||||
Path('templates/rust-cargo/rustfmt.toml'),
|
||||
Path('templates/rust-cargo/clippy.toml'),
|
||||
Path('templates/rust-cargo/.cargo/config.toml'),
|
||||
Path('templates/rust-cargo/Cargo.toml'),
|
||||
Path('templates/rust-cargo/crates/project-core-lib/Cargo.toml'),
|
||||
):
|
||||
with path.open('rb') as stream:
|
||||
tomllib.load(stream)
|
||||
|
||||
print('Rust/Cargo skeleton audit: clean (alpha.1-alpha.3 PASS baseline, five templates parsed)')
|
||||
PY
|
||||
|
||||
command -v cargo
|
||||
command -v rustfmt
|
||||
cargo --version
|
||||
rustc --version
|
||||
rustfmt --version
|
||||
cargo clippy --version
|
||||
|
||||
tmp="$(mktemp -d)"
|
||||
trap 'rm -rf "$tmp"' EXIT
|
||||
mkdir -p "$tmp/.cargo" "$tmp/crates/smoke-core-lib/src"
|
||||
cp templates/rust-cargo/Cargo.toml "$tmp/Cargo.toml"
|
||||
cp templates/rust-cargo/rustfmt.toml "$tmp/rustfmt.toml"
|
||||
cp templates/rust-cargo/clippy.toml "$tmp/clippy.toml"
|
||||
cp templates/rust-cargo/.cargo/config.toml "$tmp/.cargo/config.toml"
|
||||
cp templates/rust-cargo/crates/project-core-lib/Cargo.toml "$tmp/crates/smoke-core-lib/Cargo.toml"
|
||||
printf '1.2.3\n' > "$tmp/VERSION"
|
||||
|
||||
python3 -B - "$tmp" <<'PY'
|
||||
from pathlib import Path
|
||||
import sys
|
||||
|
||||
root = Path(sys.argv[1])
|
||||
|
||||
replacements = {
|
||||
root / 'Cargo.toml': (
|
||||
('# file: templates/rust-cargo/Cargo.toml', '# file: Cargo.toml'),
|
||||
('members = ["crates/project-core-lib"]', 'members = ["crates/smoke-core-lib"]'),
|
||||
('version = "0.1.0"', 'version = "1.2.3"'),
|
||||
),
|
||||
root / 'rustfmt.toml': (
|
||||
('# file: templates/rust-cargo/rustfmt.toml', '# file: rustfmt.toml'),
|
||||
),
|
||||
root / 'clippy.toml': (
|
||||
('# file: templates/rust-cargo/clippy.toml', '# file: clippy.toml'),
|
||||
),
|
||||
root / '.cargo/config.toml': (
|
||||
('# file: templates/rust-cargo/.cargo/config.toml', '# file: .cargo/config.toml'),
|
||||
('../builds/project-name/target', 'target-smoke'),
|
||||
),
|
||||
root / 'crates/smoke-core-lib/Cargo.toml': (
|
||||
('# file: templates/rust-cargo/crates/project-core-lib/Cargo.toml', '# file: crates/smoke-core-lib/Cargo.toml'),
|
||||
('name = "project-core-lib"', 'name = "smoke-core-lib"'),
|
||||
),
|
||||
}
|
||||
|
||||
for path, pairs in replacements.items():
|
||||
text = path.read_text(encoding='utf-8')
|
||||
for old, new in pairs:
|
||||
assert old in text, (path, old)
|
||||
text = text.replace(old, new)
|
||||
path.write_text(text, encoding='utf-8')
|
||||
|
||||
for path in root.rglob('*'):
|
||||
if path.is_file() and path.name != 'Cargo.lock':
|
||||
text = path.read_text(encoding='utf-8')
|
||||
assert 'project-name' not in text, path
|
||||
assert 'project-core-lib' not in text, path
|
||||
PY
|
||||
|
||||
cat > "$tmp/crates/smoke-core-lib/src/lib.rs" <<'RS'
|
||||
//! Minimal crate used to validate the PGR Rust/Cargo templates.
|
||||
|
||||
/// Returns the deterministic smoke value.
|
||||
pub fn smoke_value() -> u8 {
|
||||
return 1;
|
||||
}
|
||||
RS
|
||||
|
||||
(
|
||||
cd "$tmp"
|
||||
cargo metadata --format-version 1 --no-deps >/dev/null
|
||||
cargo fmt --all -- --check
|
||||
cargo check --workspace
|
||||
cargo clippy --workspace --all-targets --all-features -- -D warnings
|
||||
)
|
||||
|
||||
rm -rf "$tmp"
|
||||
trap - EXIT
|
||||
|
||||
git diff --check
|
||||
git add VERSION README.md docs/000-README.md \
|
||||
docs/skeletons/000-README.md \
|
||||
docs/skeletons/002-RUST_CARGO_WORKSPACE.md \
|
||||
deltas/0.0.4/alpha.4.md
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
## Revue opérateur
|
||||
|
||||
En complément des commandes, vérifier que :
|
||||
|
||||
- `002` reste une specialization composable de `001` et ne redéfinit pas les owners généraux ;
|
||||
- les cinq templates sont référencés comme artefacts à adapter, jamais comme valeurs universelles ;
|
||||
- la politique `Cargo.lock`, les membres, dépendances/features, métadonnées et éventuelles exceptions de lints/safety restent des décisions explicites du projet ;
|
||||
- les audits Rust facultatifs ne sont ni copiés ni exécutés sans sélection de leur convention et de leur corpus ;
|
||||
- aucune règle Java/Android/Web/JNI/Tauri ou autre plateforme/framework n'entre dans la tranche ;
|
||||
- l'instanciation temporaire prouve l'adoption minimale des templates sans ajouter de workspace Rust au dépôt PGR.
|
||||
|
||||
## Transition
|
||||
|
||||
PASS : produire `history/0.0.4/alpha.4.md`, l'appliquer puis committer `0.0.4-alpha.4`. La tranche suivante prévue par le plan est `0.0.4-beta.1`, consacrée à la réconciliation interne de la release : ownership, liens, index, duplication normative, valeurs d'exemple, limites des audits et confirmation des domaines différés.
|
||||
|
||||
FAIL : rester dans le scope de `alpha.4` via `alpha.4.fix.1` sauf si l'instanciation démontre qu'un template ou une décision normative existante est insuffisante, auquel cas déclencher le REPLAN prévu par le plan.
|
||||
200
deltas/0.0.4/beta.1.fix.1.md
Normal file
200
deltas/0.0.4/beta.1.fix.1.md
Normal file
@@ -0,0 +1,200 @@
|
||||
<!-- file: deltas/0.0.4/beta.1.fix.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.4-beta.1.fix.1 — correction de la gate de réconciliation
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline : tranche `0.0.4-beta.1` enregistrée `FAIL`, avec `history/0.0.4/beta.1.md` appliqué, committé et poussé. Le delta et le history `beta.1` restent des snapshots historiques et MUST NOT être réécrits.
|
||||
|
||||
Version avant application :
|
||||
|
||||
```text
|
||||
0.0.4-beta.1
|
||||
```
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.4-beta.1.fix.1
|
||||
```
|
||||
|
||||
## Motif
|
||||
|
||||
La gate `beta.1` a échoué avant l'exécution de son audit Python de réconciliation à cause d'une chaîne délimitée par apostrophes simples contenant l'apostrophe de `l'arborescence` :
|
||||
|
||||
```text
|
||||
SyntaxError: unterminated string literal
|
||||
```
|
||||
|
||||
Les tests, audits Markdown et contrôles précédant cette commande ont réussi. Aucun défaut des règles, skeletons, templates ou documents vivants n'a été observé.
|
||||
|
||||
Le présent fix corrige uniquement la gate en utilisant une chaîne Python correctement délimitée, puis rejoue les preuves nécessaires de la réconciliation.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
deltas/0.0.4/beta.1.fix.1.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
Aucun document vivant, règle, skeleton, template, script, test ou history antérieur n'est modifié.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
Après commit et push de `0.0.4-beta.1` avec son history `FAIL`, appliquer ce delta puis exécuter à la racine :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.4-beta.1.fix.1'
|
||||
git cat-file -e HEAD:history/0.0.4/beta.1.md
|
||||
test -f history/0.0.4/beta.1.md
|
||||
test -f deltas/0.0.4/beta.1.md
|
||||
test -f deltas/0.0.4/beta.1.fix.1.md
|
||||
test ! -e history/0.0.4/beta.1.fix.1.md
|
||||
|
||||
grep -A2 '^## Statut$' history/0.0.4/beta.1.md | grep -Fx 'FAIL'
|
||||
grep -A2 '^## Statut$' history/0.0.4/alpha.4.fix.1.md | grep -Fx 'PASS'
|
||||
|
||||
python3 -B -m unittest discover -s tests -v
|
||||
|
||||
python3 -B scripts/audit_markdown_headers.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
import tomllib
|
||||
|
||||
expected_histories = {
|
||||
'alpha.1.md': 'PASS',
|
||||
'alpha.2.md': 'PASS',
|
||||
'alpha.3.md': 'PASS',
|
||||
'alpha.4.md': 'FAIL',
|
||||
'alpha.4.fix.1.md': 'PASS',
|
||||
'beta.1.md': 'FAIL',
|
||||
}
|
||||
histories = {path.name for path in Path('history/0.0.4').glob('*.md')}
|
||||
assert histories == set(expected_histories), histories
|
||||
for name, status in expected_histories.items():
|
||||
text = Path('history/0.0.4', name).read_text(encoding='utf-8')
|
||||
assert re.search(rf'## Statut\s+{status}\s', text), (name, status)
|
||||
|
||||
deltas = {path.name for path in Path('deltas/0.0.4').glob('*.md')}
|
||||
assert deltas == set(expected_histories) | {'beta.1.fix.1.md'}, deltas
|
||||
|
||||
skeletons = sorted(path.name for path in Path('docs/skeletons').glob('*.md'))
|
||||
assert skeletons == [
|
||||
'000-README.md',
|
||||
'001-PROJECT_GOVERNANCE_FOUNDATION.md',
|
||||
'002-RUST_CARGO_WORKSPACE.md',
|
||||
], skeletons
|
||||
|
||||
root_index = Path('README.md').read_text(encoding='utf-8')
|
||||
docs_index = Path('docs/000-README.md').read_text(encoding='utf-8')
|
||||
skel_index = Path('docs/skeletons/000-README.md').read_text(encoding='utf-8')
|
||||
for name in (
|
||||
'001-PROJECT_GOVERNANCE_FOUNDATION.md',
|
||||
'002-RUST_CARGO_WORKSPACE.md',
|
||||
):
|
||||
assert name in root_index, name
|
||||
assert name in docs_index, name
|
||||
assert name in skel_index, name
|
||||
|
||||
foundation = Path('docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md').read_text(encoding='utf-8')
|
||||
for owner in (
|
||||
'200-GOVERNANCE.md',
|
||||
'210-WORKFLOW.md',
|
||||
'300-DOCUMENTATION.md',
|
||||
'400-VALIDATION.md',
|
||||
):
|
||||
assert owner in foundation, owner
|
||||
|
||||
rust = Path('docs/skeletons/002-RUST_CARGO_WORKSPACE.md').read_text(encoding='utf-8')
|
||||
for owner in ('500-LANGUAGES.md', '510-RUST_CARGO.md'):
|
||||
assert owner in rust, owner
|
||||
for value in ('0.1.0', '2024', 'project-name', 'project-core-lib'):
|
||||
assert value in rust, value
|
||||
assert 'Ils ne deviennent jamais des valeurs universelles par simple copie.' in rust
|
||||
assert 'Cargo.lock' in rust
|
||||
|
||||
rule = Path('docs/rules/220-SKELETONS.md').read_text(encoding='utf-8')
|
||||
assert 'Un skeleton sélectionne les owners normatifs applicables ; il ne redéfinit pas leur contenu.' in rule
|
||||
assert 'MUST NOT devenir une valeur universelle par simple copie' in rule
|
||||
|
||||
validation = Path('docs/validation/001-VALIDATION_MATRIX.md').read_text(encoding='utf-8')
|
||||
for audit_id in ('PGR-MD-HEADER-001', 'PGR-MD-TABLE-001', 'PGR-NAV-001'):
|
||||
assert audit_id in validation, audit_id
|
||||
assert "vérifie uniquement l'existence des cibles de liens Markdown locaux inline" in validation
|
||||
|
||||
rust_audits = Path('docs/validation/002-RUST_STYLE_AUDITS.md').read_text(encoding='utf-8')
|
||||
assert 'facultatif' in rust_audits.lower()
|
||||
assert "Les audits ne modifient ni les fichiers inspectés ni l'arborescence de build." in rust_audits
|
||||
|
||||
plan = Path('docs/plans/004-V0_0_4_SKELETONS_PLAN.md').read_text(encoding='utf-8')
|
||||
for deferred in (
|
||||
'Java / Maven / Gradle — différé',
|
||||
'Android — différé',
|
||||
'Web, JNI, Tauri et autres familles absentes — différés',
|
||||
):
|
||||
assert deferred in plan, deferred
|
||||
|
||||
for path in (
|
||||
Path('templates/rust-cargo/rustfmt.toml'),
|
||||
Path('templates/rust-cargo/clippy.toml'),
|
||||
Path('templates/rust-cargo/.cargo/config.toml'),
|
||||
Path('templates/rust-cargo/Cargo.toml'),
|
||||
Path('templates/rust-cargo/crates/project-core-lib/Cargo.toml'),
|
||||
):
|
||||
with path.open('rb') as stream:
|
||||
tomllib.load(stream)
|
||||
|
||||
print('Skeleton beta reconciliation fix audit: clean (beta.1 FAIL recorded, 3 skeleton docs, 5 TOML parsed)')
|
||||
PY
|
||||
|
||||
git diff --check
|
||||
git add VERSION deltas/0.0.4/beta.1.fix.1.md
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
La sortie Git attendue avant ajout du history du fix est exactement :
|
||||
|
||||
```text
|
||||
M VERSION
|
||||
A deltas/0.0.4/beta.1.fix.1.md
|
||||
```
|
||||
|
||||
## Revue opérateur complémentaire
|
||||
|
||||
Confirmer que :
|
||||
|
||||
- le `FAIL beta.1` reste visible et n'est pas réécrit ;
|
||||
- le fix ne change aucune règle, aucun skeleton, aucun template et aucun audit ;
|
||||
- `220` reste le propriétaire du contrat transversal et `001`/`002` restent des orchestrateurs/compositeurs de leurs owners ;
|
||||
- les valeurs de templates restent adaptables et non universelles ;
|
||||
- Java/Android/Web/JNI/Tauri restent différés sans placeholder anticipé.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Créer et appliquer séparément `history/0.0.4/beta.1.fix.1.md`, committer et pousser le fix, puis préparer `0.0.4-rc.1`.
|
||||
|
||||
Le history du fix et le delta `rc.1` MAY être livrés ensemble sous forme de deux archives séparées après observation de cette gate opérateur.
|
||||
|
||||
### FAIL
|
||||
|
||||
Enregistrer le diagnostic réel dans `history/0.0.4/beta.1.fix.1.md`, puis poursuivre par `beta.1.fix.2` limité à la réconciliation ou faire un REPLAN explicite si un défaut de contenu est réellement découvert.
|
||||
225
deltas/0.0.4/beta.1.md
Normal file
225
deltas/0.0.4/beta.1.md
Normal file
@@ -0,0 +1,225 @@
|
||||
<!-- file: deltas/0.0.4/beta.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.4-beta.1 — réconciliation interne des skeletons
|
||||
|
||||
## Baseline
|
||||
|
||||
Version attendue avant application :
|
||||
|
||||
```text
|
||||
0.0.4-alpha.4.fix.1
|
||||
```
|
||||
|
||||
Le history `history/0.0.4/alpha.4.fix.1.md` avec statut `PASS` MUST avoir été appliqué, committé et poussé avant ce delta. Le `FAIL` de `history/0.0.4/alpha.4.md` reste un snapshot historique et MUST NOT être réécrit.
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.4-beta.1
|
||||
```
|
||||
|
||||
## Objet
|
||||
|
||||
Exécuter la réconciliation interne prévue par `docs/plans/004-V0_0_4_SKELETONS_PLAN.md` après la fondation gouvernée, le skeleton Rust/Cargo et la correction de sa gate d'instanciation.
|
||||
|
||||
La revue porte sur :
|
||||
|
||||
```text
|
||||
ownership normatif
|
||||
navigation et index
|
||||
absence de duplication normative
|
||||
composition 001 -> 002
|
||||
valeurs d'exemple non universalisées
|
||||
limites des audits et de la validation
|
||||
spécialisations technologiques différées
|
||||
continuité delta/history de 0.0.4
|
||||
```
|
||||
|
||||
Cette tranche n'ajoute aucune fonctionnalité, aucun profil, aucun skeleton, aucun template et aucun audit.
|
||||
|
||||
## Résultat de la réconciliation préparatoire
|
||||
|
||||
Aucune correction de document vivant n'est nécessaire pour entrer en beta.
|
||||
|
||||
Le contrat transversal reste possédé par `docs/rules/220-SKELETONS.md`. La fondation `001-PROJECT_GOVERNANCE_FOUNDATION.md` orchestre les owners généraux sans les redéfinir. La specialization `002-RUST_CARGO_WORKSPACE.md` ajoute uniquement `500 + 510`, les guides/templates Rust/Cargo et les décisions de son scope.
|
||||
|
||||
La navigation courante expose les deux specifications depuis `README.md`, `docs/000-README.md` et `docs/skeletons/000-README.md`. Aucun troisième skeleton ou placeholder de skeleton n'existe.
|
||||
|
||||
Les valeurs Rust/Cargo telles que `0.1.0`, `2024`, `project-name`, `project-core-lib`, les seuils Clippy et les chemins de build restent explicitement décrites comme exemples, baselines ou décisions destinataire à revoir. `Cargo.lock` reste une décision propre au type de produit et au besoin de reproductibilité.
|
||||
|
||||
Les limites des audits restent séparées : headers, tableaux et liens Markdown sont des contrôles monotâches ; les audits de style Rust sont facultatifs, read-only et ne remplacent ni Rustfmt, ni Clippy, ni la toolchain Cargo. La validation d'instanciation appartient au skeleton qui prétend matérialiser une baseline utilisable et n'est pas transformée en build global permanent de PGR.
|
||||
|
||||
Java/Maven/Gradle et Android possèdent des profils normatifs mais pas encore les templates/corpus nécessaires à un skeleton concret. Web, JNI, Tauri et les autres domaines insuffisamment cadrés restent également différés. Aucun fichier placeholder n'est créé pour réserver ces futurs scopes.
|
||||
|
||||
Le `FAIL` de `alpha.4` et le `PASS` attendu de `alpha.4.fix.1` forment une chaîne historique explicite ; le fix ne réécrit pas le delta ou le history échoué.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
deltas/0.0.4/beta.1.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
Les documents vivants, règles, skeletons, templates, scripts, tests et histories antérieurs restent inchangés. Cette absence de modification supplémentaire est intentionnelle : la réconciliation n'a pas identifié de correction réelle qui justifierait une révision artificielle.
|
||||
|
||||
## Validation opérateur
|
||||
|
||||
Après commit et push de `0.0.4-alpha.4.fix.1`, appliquer ce delta puis exécuter à la racine :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.4-beta.1'
|
||||
git cat-file -e HEAD:history/0.0.4/alpha.4.fix.1.md
|
||||
test -f history/0.0.4/alpha.4.fix.1.md
|
||||
test -f deltas/0.0.4/beta.1.md
|
||||
test ! -e history/0.0.4/beta.1.md
|
||||
|
||||
test -f docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md
|
||||
test -f docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||
test ! -e docs/skeletons/003-JAVA_MAVEN_GRADLE.md
|
||||
test ! -e docs/skeletons/003-ANDROID.md
|
||||
|
||||
grep -A2 '^## Statut$' history/0.0.4/alpha.4.md | grep -Fx 'FAIL'
|
||||
grep -A2 '^## Statut$' history/0.0.4/alpha.4.fix.1.md | grep -Fx 'PASS'
|
||||
|
||||
python3 -B -m unittest discover -s tests -v
|
||||
|
||||
python3 -B scripts/audit_markdown_headers.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
import tomllib
|
||||
|
||||
expected_histories = {
|
||||
'alpha.1.md': 'PASS',
|
||||
'alpha.2.md': 'PASS',
|
||||
'alpha.3.md': 'PASS',
|
||||
'alpha.4.md': 'FAIL',
|
||||
'alpha.4.fix.1.md': 'PASS',
|
||||
}
|
||||
histories = {path.name for path in Path('history/0.0.4').glob('*.md')}
|
||||
assert histories == set(expected_histories), histories
|
||||
for name, status in expected_histories.items():
|
||||
text = Path('history/0.0.4', name).read_text(encoding='utf-8')
|
||||
assert re.search(rf'## Statut\s+{status}\s', text), (name, status)
|
||||
|
||||
deltas = {path.name for path in Path('deltas/0.0.4').glob('*.md')}
|
||||
assert deltas == set(expected_histories) | {'beta.1.md'}, deltas
|
||||
|
||||
skeletons = sorted(path.name for path in Path('docs/skeletons').glob('*.md'))
|
||||
assert skeletons == [
|
||||
'000-README.md',
|
||||
'001-PROJECT_GOVERNANCE_FOUNDATION.md',
|
||||
'002-RUST_CARGO_WORKSPACE.md',
|
||||
], skeletons
|
||||
|
||||
root_index = Path('README.md').read_text(encoding='utf-8')
|
||||
docs_index = Path('docs/000-README.md').read_text(encoding='utf-8')
|
||||
skel_index = Path('docs/skeletons/000-README.md').read_text(encoding='utf-8')
|
||||
for name in (
|
||||
'001-PROJECT_GOVERNANCE_FOUNDATION.md',
|
||||
'002-RUST_CARGO_WORKSPACE.md',
|
||||
):
|
||||
assert name in root_index, name
|
||||
assert name in docs_index, name
|
||||
assert name in skel_index, name
|
||||
|
||||
foundation = Path('docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md').read_text(encoding='utf-8')
|
||||
for owner in (
|
||||
'200-GOVERNANCE.md',
|
||||
'210-WORKFLOW.md',
|
||||
'300-DOCUMENTATION.md',
|
||||
'400-VALIDATION.md',
|
||||
):
|
||||
assert owner in foundation, owner
|
||||
|
||||
rust = Path('docs/skeletons/002-RUST_CARGO_WORKSPACE.md').read_text(encoding='utf-8')
|
||||
for owner in ('500-LANGUAGES.md', '510-RUST_CARGO.md'):
|
||||
assert owner in rust, owner
|
||||
for value in ('0.1.0', '2024', 'project-name', 'project-core-lib'):
|
||||
assert value in rust, value
|
||||
assert 'Ils ne deviennent jamais des valeurs universelles par simple copie.' in rust
|
||||
assert 'Cargo.lock' in rust
|
||||
|
||||
rule = Path('docs/rules/220-SKELETONS.md').read_text(encoding='utf-8')
|
||||
assert 'Un skeleton sélectionne les owners normatifs applicables ; il ne redéfinit pas leur contenu.' in rule
|
||||
assert 'MUST NOT devenir une valeur universelle par simple copie' in rule
|
||||
|
||||
validation = Path('docs/validation/001-VALIDATION_MATRIX.md').read_text(encoding='utf-8')
|
||||
for audit_id in ('PGR-MD-HEADER-001', 'PGR-MD-TABLE-001', 'PGR-NAV-001'):
|
||||
assert audit_id in validation, audit_id
|
||||
assert 'vérifie uniquement l\'existence des cibles de liens Markdown locaux inline' in validation
|
||||
|
||||
rust_audits = Path('docs/validation/002-RUST_STYLE_AUDITS.md').read_text(encoding='utf-8')
|
||||
assert 'facultatif' in rust_audits.lower()
|
||||
assert 'Les audits ne modifient ni les fichiers inspectés ni l'arborescence de build.' in rust_audits
|
||||
|
||||
plan = Path('docs/plans/004-V0_0_4_SKELETONS_PLAN.md').read_text(encoding='utf-8')
|
||||
for deferred in ('Java / Maven / Gradle — différé', 'Android — différé', 'Web, JNI, Tauri et autres familles absentes — différés'):
|
||||
assert deferred in plan, deferred
|
||||
|
||||
for path in (
|
||||
Path('templates/rust-cargo/rustfmt.toml'),
|
||||
Path('templates/rust-cargo/clippy.toml'),
|
||||
Path('templates/rust-cargo/.cargo/config.toml'),
|
||||
Path('templates/rust-cargo/Cargo.toml'),
|
||||
Path('templates/rust-cargo/crates/project-core-lib/Cargo.toml'),
|
||||
):
|
||||
with path.open('rb') as stream:
|
||||
tomllib.load(stream)
|
||||
|
||||
print('Skeleton beta reconciliation audit: clean (5 prior histories, 3 skeleton docs, 5 TOML parsed)')
|
||||
PY
|
||||
|
||||
git diff --check
|
||||
git add VERSION deltas/0.0.4/beta.1.md
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
La sortie Git attendue avant ajout du history `beta.1` est exactement :
|
||||
|
||||
```text
|
||||
M VERSION
|
||||
A deltas/0.0.4/beta.1.md
|
||||
```
|
||||
|
||||
## Revue opérateur complémentaire
|
||||
|
||||
Confirmer que :
|
||||
|
||||
- `220` reste le propriétaire du contrat transversal et que `001`/`002` n'en dupliquent pas les obligations ;
|
||||
- `001` reste sans spécialisation technologique et `002` n'élargit pas `510` vers Android, WASM, Tauri, FFI ou un framework ;
|
||||
- les valeurs de templates restent des exemples adaptables et non des politiques globales ;
|
||||
- les audits documentaires et Rust restent délimités par leur propriété réellement vérifiée ;
|
||||
- Java/Android/Web/JNI/Tauri restent différés faute de pièces suffisantes, sans placeholder ni skeleton composite anticipé ;
|
||||
- le `FAIL alpha.4` reste visible et la correction `alpha.4.fix.1` est enregistrée séparément.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Créer et appliquer séparément `history/0.0.4/beta.1.md`, committer et pousser `beta.1`, puis préparer `0.0.4-rc.1`.
|
||||
|
||||
La RC doit geler le scope, préparer l'entrée candidate `0.0.4` du changelog et `prompts/005-V0_0_5_START_PROMPT.md` si la trajectoire est confirmée, puis rejouer uniquement les validations réellement invalidées par la release.
|
||||
|
||||
Le history `beta.1` et le delta `rc.1` MAY être livrés ensemble sous forme de deux archives séparées après observation de la gate opérateur.
|
||||
|
||||
### FAIL
|
||||
|
||||
Enregistrer le diagnostic réel dans `history/0.0.4/beta.1.md`, puis corriger uniquement la réconciliation dans `0.0.4-beta.1.fix.N` ou faire un REPLAN explicite si un défaut révèle un changement de scope.
|
||||
265
deltas/0.0.4/rc.1.md
Normal file
265
deltas/0.0.4/rc.1.md
Normal file
@@ -0,0 +1,265 @@
|
||||
<!-- file: deltas/0.0.4/rc.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.4-rc.1 — gel du scope et préparation de release
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline : `0.0.4-beta.1.fix.1`, avec `history/0.0.4/beta.1.fix.1.md` appliqué et committé. Ce delta MUST NOT être appliqué avant ce commit.
|
||||
|
||||
Le commit exact de cette baseline sera celui produit par l'opérateur après la gate `beta.1.fix.1` ; il n'est pas anticipé dans cette livraison simultanée du history et du delta suivant.
|
||||
|
||||
Version avant application :
|
||||
|
||||
```text
|
||||
0.0.4-beta.1.fix.1
|
||||
```
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.4-rc.1
|
||||
```
|
||||
|
||||
## Objet et gel
|
||||
|
||||
La réconciliation `beta.1.fix.1` est `PASS`. La RC gèle le scope fonctionnel de `0.0.4` sur :
|
||||
|
||||
- le contrat transversal des skeleton specifications sous `docs/rules/220-SKELETONS.md` ;
|
||||
- la collection `docs/skeletons/` et son index ;
|
||||
- `001-PROJECT_GOVERNANCE_FOUNDATION.md` comme fondation composable sans spécialisation technologique ;
|
||||
- `002-RUST_CARGO_WORKSPACE.md` comme première spécialisation technologique, composée avec les profils `500 + 510` ;
|
||||
- les cinq templates Rust/Cargo déjà introduits avant `0.0.4`, utilisés avec des décisions destinataire explicites et une instanciation temporaire vérifiable.
|
||||
|
||||
Le changelog reçoit une entrée candidate `0.0.4` orientée utilisateurs. Le plan enregistre les résultats `FAIL → fix PASS` des gates `alpha.4` et `beta.1`, puis le gel RC. Le prompt `005` prépare `0.0.5`, dont la roadmap confirme la mission de réconciliation réelle avec `khadhroony-solana-project` et `sasedev-games` à partir de baselines explicitement fournies.
|
||||
|
||||
Aucun nouveau skeleton, profil, template, audit, générateur ou domaine technologique n'entre en RC. Java/Maven/Gradle, Android, Web, JNI, Tauri et les autres familles différées restent hors scope.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
CHANGELOG.md
|
||||
docs/plans/004-V0_0_4_SKELETONS_PLAN.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
prompts/005-V0_0_5_START_PROMPT.md
|
||||
deltas/0.0.4/rc.1.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
L'archive contient exactement ces fichiers complets. Le history `beta.1.fix.1` est livré séparément ; le history `rc.1` sera produit après la gate opérateur.
|
||||
|
||||
## Gate opérateur de release candidate
|
||||
|
||||
Après application sur le commit `beta.1.fix.1`, depuis la racine du dépôt :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.4-rc.1'
|
||||
git cat-file -e HEAD:history/0.0.4/beta.1.fix.1.md
|
||||
test -f history/0.0.4/beta.1.fix.1.md
|
||||
test -f deltas/0.0.4/rc.1.md
|
||||
test -f prompts/005-V0_0_5_START_PROMPT.md
|
||||
test ! -e history/0.0.4/rc.1.md
|
||||
|
||||
grep -Fx '<!-- version: 6 -->' CHANGELOG.md
|
||||
grep -Fx '## 0.0.4 (candidate)' CHANGELOG.md
|
||||
grep -Fx '<!-- version: 2 -->' docs/plans/004-V0_0_4_SKELETONS_PLAN.md
|
||||
grep -F '`beta.1.fix.1` a rejoué la réconciliation et est `PASS`' docs/plans/004-V0_0_4_SKELETONS_PLAN.md
|
||||
grep -F 'pgr-v0.0.4.zip' prompts/005-V0_0_5_START_PROMPT.md
|
||||
grep -F 'khadhroony-solana-project' prompts/005-V0_0_5_START_PROMPT.md
|
||||
grep -F 'sasedev-games' prompts/005-V0_0_5_START_PROMPT.md
|
||||
|
||||
python3 -B -m unittest discover -s tests -v
|
||||
|
||||
python3 -B scripts/audit_markdown_headers.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
import tomllib
|
||||
|
||||
expected_histories = {
|
||||
'alpha.1.md': 'PASS',
|
||||
'alpha.2.md': 'PASS',
|
||||
'alpha.3.md': 'PASS',
|
||||
'alpha.4.md': 'FAIL',
|
||||
'alpha.4.fix.1.md': 'PASS',
|
||||
'beta.1.md': 'FAIL',
|
||||
'beta.1.fix.1.md': 'PASS',
|
||||
}
|
||||
histories = {path.name for path in Path('history/0.0.4').glob('*.md')}
|
||||
assert histories == set(expected_histories), histories
|
||||
for name, status in expected_histories.items():
|
||||
text = Path('history/0.0.4', name).read_text(encoding='utf-8')
|
||||
assert re.search(rf'## Statut\s+{status}\s', text), (name, status)
|
||||
|
||||
deltas = {path.name for path in Path('deltas/0.0.4').glob('*.md')}
|
||||
assert deltas == set(expected_histories) | {'rc.1.md'}, deltas
|
||||
|
||||
skeletons = sorted(path.name for path in Path('docs/skeletons').glob('*.md'))
|
||||
assert skeletons == [
|
||||
'000-README.md',
|
||||
'001-PROJECT_GOVERNANCE_FOUNDATION.md',
|
||||
'002-RUST_CARGO_WORKSPACE.md',
|
||||
], skeletons
|
||||
|
||||
rule = Path('docs/rules/220-SKELETONS.md').read_text(encoding='utf-8')
|
||||
assert 'Un skeleton sélectionne les owners normatifs applicables ; il ne redéfinit pas leur contenu.' in rule
|
||||
|
||||
foundation = Path('docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md').read_text(encoding='utf-8')
|
||||
for owner in ('200-GOVERNANCE.md', '210-WORKFLOW.md', '300-DOCUMENTATION.md', '400-VALIDATION.md'):
|
||||
assert owner in foundation, owner
|
||||
|
||||
rust = Path('docs/skeletons/002-RUST_CARGO_WORKSPACE.md').read_text(encoding='utf-8')
|
||||
for owner in ('500-LANGUAGES.md', '510-RUST_CARGO.md'):
|
||||
assert owner in rust, owner
|
||||
assert 'Ils ne deviennent jamais des valeurs universelles par simple copie.' in rust
|
||||
|
||||
for path in (
|
||||
Path('templates/rust-cargo/rustfmt.toml'),
|
||||
Path('templates/rust-cargo/clippy.toml'),
|
||||
Path('templates/rust-cargo/.cargo/config.toml'),
|
||||
Path('templates/rust-cargo/Cargo.toml'),
|
||||
Path('templates/rust-cargo/crates/project-core-lib/Cargo.toml'),
|
||||
):
|
||||
with path.open('rb') as stream:
|
||||
tomllib.load(stream)
|
||||
|
||||
prompt = Path('prompts/005-V0_0_5_START_PROMPT.md').read_text(encoding='utf-8')
|
||||
for value in ('pgr-v0.0.4.zip', 'pgr-0.0.4-publish.001-report.md', '0.0.5-alpha.1', 'khadhroony-solana-project', 'sasedev-games'):
|
||||
assert value in prompt, value
|
||||
assert 'Ne pas déduire leur version, leur commit ou leur contenu' in prompt
|
||||
|
||||
print('RC integration audit: clean (7 prior histories, 3 skeleton docs, 5 TOML parsed, prompt 005 ready)')
|
||||
PY
|
||||
|
||||
command -v cargo
|
||||
command -v rustfmt
|
||||
cargo --version
|
||||
rustc --version
|
||||
rustfmt --version
|
||||
cargo clippy --version
|
||||
|
||||
tmp="$(mktemp -d)"
|
||||
trap 'rm -rf "$tmp"' EXIT
|
||||
mkdir -p "$tmp/.cargo" "$tmp/crates/smoke-core-lib/src"
|
||||
cp templates/rust-cargo/Cargo.toml "$tmp/Cargo.toml"
|
||||
cp templates/rust-cargo/rustfmt.toml "$tmp/rustfmt.toml"
|
||||
cp templates/rust-cargo/clippy.toml "$tmp/clippy.toml"
|
||||
cp templates/rust-cargo/.cargo/config.toml "$tmp/.cargo/config.toml"
|
||||
cp templates/rust-cargo/crates/project-core-lib/Cargo.toml "$tmp/crates/smoke-core-lib/Cargo.toml"
|
||||
printf '1.2.3\n' > "$tmp/VERSION"
|
||||
|
||||
python3 -B - "$tmp" <<'PY'
|
||||
from pathlib import Path
|
||||
import sys
|
||||
|
||||
root = Path(sys.argv[1])
|
||||
replacements = {
|
||||
root / 'Cargo.toml': (
|
||||
('# file: templates/rust-cargo/Cargo.toml', '# file: Cargo.toml'),
|
||||
('members = ["crates/project-core-lib"]', 'members = ["crates/smoke-core-lib"]'),
|
||||
('version = "0.1.0"', 'version = "1.2.3"'),
|
||||
),
|
||||
root / 'rustfmt.toml': (
|
||||
('# file: templates/rust-cargo/rustfmt.toml', '# file: rustfmt.toml'),
|
||||
),
|
||||
root / 'clippy.toml': (
|
||||
('# file: templates/rust-cargo/clippy.toml', '# file: clippy.toml'),
|
||||
),
|
||||
root / '.cargo/config.toml': (
|
||||
('# file: templates/rust-cargo/.cargo/config.toml', '# file: .cargo/config.toml'),
|
||||
(
|
||||
'# Replace project-name with a unique name before using this configuration.',
|
||||
'# Smoke fixture: project-specific build directory already selected.',
|
||||
),
|
||||
('../builds/project-name/target', 'target-smoke'),
|
||||
),
|
||||
root / 'crates/smoke-core-lib/Cargo.toml': (
|
||||
(
|
||||
'# file: templates/rust-cargo/crates/project-core-lib/Cargo.toml',
|
||||
'# file: crates/smoke-core-lib/Cargo.toml',
|
||||
),
|
||||
('name = "project-core-lib"', 'name = "smoke-core-lib"'),
|
||||
),
|
||||
}
|
||||
for path, pairs in replacements.items():
|
||||
text = path.read_text(encoding='utf-8')
|
||||
for old, new in pairs:
|
||||
assert old in text, (path, old)
|
||||
text = text.replace(old, new)
|
||||
path.write_text(text, encoding='utf-8')
|
||||
for path in root.rglob('*'):
|
||||
if path.is_file() and path.name != 'Cargo.lock':
|
||||
text = path.read_text(encoding='utf-8')
|
||||
assert 'project-name' not in text, path
|
||||
assert 'project-core-lib' not in text, path
|
||||
print('RC temporary Rust/Cargo template adaptation: clean')
|
||||
PY
|
||||
|
||||
cat > "$tmp/crates/smoke-core-lib/src/lib.rs" <<'RS'
|
||||
//! Minimal crate used to validate the PGR Rust/Cargo templates.
|
||||
|
||||
/// Returns the deterministic smoke value.
|
||||
pub fn smoke_value() -> u8 {
|
||||
return 1;
|
||||
}
|
||||
RS
|
||||
|
||||
(
|
||||
cd "$tmp"
|
||||
cargo metadata --format-version 1 --no-deps >/dev/null
|
||||
cargo fmt --all -- --check
|
||||
cargo check --workspace
|
||||
cargo clippy --workspace --all-targets --all-features -- -D warnings
|
||||
)
|
||||
|
||||
rm -rf "$tmp"
|
||||
trap - EXIT
|
||||
|
||||
git diff --check
|
||||
git add VERSION CHANGELOG.md docs/plans/004-V0_0_4_SKELETONS_PLAN.md \
|
||||
prompts/005-V0_0_5_START_PROMPT.md deltas/0.0.4/rc.1.md
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
Le scope attendu avant ajout du history est exactement :
|
||||
|
||||
```text
|
||||
M CHANGELOG.md
|
||||
M VERSION
|
||||
A deltas/0.0.4/rc.1.md
|
||||
M docs/plans/004-V0_0_4_SKELETONS_PLAN.md
|
||||
A prompts/005-V0_0_5_START_PROMPT.md
|
||||
```
|
||||
|
||||
## Revue opérateur complémentaire
|
||||
|
||||
Confirmer que le changelog décrit la release et non ses tranches internes, que les deux `FAIL` historiques restent visibles avec leurs fixes `PASS`, que le prompt `005` ne présume aucune version KSP/Games non fournie et que la RC n'étend pas le périmètre fonctionnel.
|
||||
|
||||
Une gate RC `PASS` n'est ni la promotion stable, ni le tag `v0.0.4`, ni la vérification de l'archive publiée après le tag.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Produire séparément `history/0.0.4/rc.1.md`, l'appliquer puis committer/pousser la RC avant le delta stable `rel.001`.
|
||||
|
||||
Le history RC et le delta stable MAY être livrés ensemble sous forme de deux archives séparées après observation de cette gate opérateur.
|
||||
|
||||
### FAIL
|
||||
|
||||
Consigner l'échec réel dans `history/0.0.4/rc.1.md` et corriger uniquement le scope gelé dans `rc.1.fix.1`, sauf REPLAN explicite si la candidate révèle un défaut fonctionnel plus large.
|
||||
152
deltas/0.0.4/rel.001.md
Normal file
152
deltas/0.0.4/rel.001.md
Normal file
@@ -0,0 +1,152 @@
|
||||
<!-- file: deltas/0.0.4/rel.001.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.0.4 rel.001 — promotion stable pré-tag
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline : `0.0.4-rc.1`, avec `history/0.0.4/rc.1.md` appliqué et committé. Ce delta MUST NOT être appliqué avant ce commit.
|
||||
|
||||
Le commit exact de cette baseline sera celui produit par l'opérateur après application du history RC ; il n'est pas anticipé dans cette livraison simultanée du history et du delta stable.
|
||||
|
||||
Version avant application :
|
||||
|
||||
```text
|
||||
0.0.4-rc.1
|
||||
```
|
||||
|
||||
Version après application :
|
||||
|
||||
```text
|
||||
0.0.4
|
||||
```
|
||||
|
||||
`rel.001` identifie la clôture opérationnelle ; il ne fait pas partie de la version SemVer du produit.
|
||||
|
||||
## Objet
|
||||
|
||||
Promouvoir la RC validée vers la stable `0.0.4`. La tranche finalise uniquement la présentation de la release : version stable, roadmap terminée, changelog sans marqueur candidate, index documentaires et plan historique.
|
||||
|
||||
Le scope fonctionnel reste celui validé en RC : contrat transversal des skeleton specifications, fondation gouvernée `001`, spécialisation Rust/Cargo `002`, utilisation gouvernée des cinq templates Rust/Cargo existants et différé explicite des autres familles non suffisamment matérialisées.
|
||||
|
||||
La validation de cette tranche est **pré-tag**. Ni le tag `v0.0.4`, ni l'archive `pgr-v0.0.4.zip` téléchargée depuis Gitea, ni un rapport `pgr-0.0.4-publish.001-report.md` ne sont déclarés existants par ce delta. Ils suivent le history PASS, le commit stable et la publication réelle du tag.
|
||||
|
||||
## Scope
|
||||
|
||||
REPLACE :
|
||||
|
||||
```text
|
||||
VERSION
|
||||
README.md
|
||||
ROADMAP.md
|
||||
CHANGELOG.md
|
||||
docs/000-README.md
|
||||
docs/plans/004-V0_0_4_SKELETONS_PLAN.md
|
||||
```
|
||||
|
||||
ADD :
|
||||
|
||||
```text
|
||||
deltas/0.0.4/rel.001.md
|
||||
```
|
||||
|
||||
DELETE : aucun.
|
||||
|
||||
L'archive contient uniquement ces fichiers complets. `history/0.0.4/rc.1.md` est livré séparément ; le history de `rel.001` sera produit après sa gate. Le rapport post-tag restera extérieur à l'archive source taggée.
|
||||
|
||||
## Validation opérateur pré-tag
|
||||
|
||||
Après application sur le commit `rc.1`, depuis la racine du dépôt :
|
||||
|
||||
```bash
|
||||
test "$(cat VERSION)" = '0.0.4'
|
||||
git cat-file -e HEAD:history/0.0.4/rc.1.md
|
||||
test -f history/0.0.4/rc.1.md
|
||||
test -f deltas/0.0.4/rel.001.md
|
||||
test -f prompts/005-V0_0_5_START_PROMPT.md
|
||||
test ! -e history/0.0.4/rel.001.md
|
||||
|
||||
grep -Fx '<!-- version: 11 -->' README.md
|
||||
grep -Fx '<!-- version: 5 -->' ROADMAP.md
|
||||
grep -Fx '<!-- version: 7 -->' CHANGELOG.md
|
||||
grep -Fx '<!-- version: 9 -->' docs/000-README.md
|
||||
grep -Fx '<!-- version: 3 -->' docs/plans/004-V0_0_4_SKELETONS_PLAN.md
|
||||
grep -F 'La release `0.0.4` définit le contrat transversal des skeleton specifications' README.md
|
||||
grep -F 'plan historique des skeleton specifications `0.0.4`' README.md
|
||||
grep -F -- '- `(x) 0.0.4`' ROADMAP.md
|
||||
grep -Fx '## 0.0.4' CHANGELOG.md
|
||||
grep -F 'périmètre et décisions de la release `0.0.4`' docs/000-README.md
|
||||
grep -F 'La gate opérateur de `rc.1` est `PASS`' docs/plans/004-V0_0_4_SKELETONS_PLAN.md
|
||||
grep -F 'pgr-0.0.4-publish.001-report.md' docs/plans/004-V0_0_4_SKELETONS_PLAN.md
|
||||
|
||||
python3 -B - <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
expected = {
|
||||
'alpha.1.md': 'PASS',
|
||||
'alpha.2.md': 'PASS',
|
||||
'alpha.3.md': 'PASS',
|
||||
'alpha.4.md': 'FAIL',
|
||||
'alpha.4.fix.1.md': 'PASS',
|
||||
'beta.1.md': 'FAIL',
|
||||
'beta.1.fix.1.md': 'PASS',
|
||||
'rc.1.md': 'PASS',
|
||||
}
|
||||
for name, status in expected.items():
|
||||
delta = Path('deltas/0.0.4', name)
|
||||
history = Path('history/0.0.4', name)
|
||||
assert delta.is_file(), name
|
||||
assert history.is_file(), name
|
||||
text = history.read_text(encoding='utf-8')
|
||||
assert re.search(rf'## Statut\s+{status}\s', text), (name, status)
|
||||
|
||||
pending = {p.name for p in Path('deltas/0.0.4').glob('*.md')} - \
|
||||
{p.name for p in Path('history/0.0.4').glob('*.md')}
|
||||
assert pending == {'rel.001.md'}, pending
|
||||
print('Stable history audit: clean (8 prior histories with expected statuses, rel.001 pending)')
|
||||
PY
|
||||
|
||||
python3 -B scripts/audit_markdown_headers.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_tables.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
python3 -B scripts/audit_markdown_links.py \
|
||||
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||
|
||||
git diff --check
|
||||
git add VERSION README.md ROADMAP.md CHANGELOG.md docs/000-README.md \
|
||||
docs/plans/004-V0_0_4_SKELETONS_PLAN.md deltas/0.0.4/rel.001.md
|
||||
git diff --cached --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
Le scope attendu avant ajout du history est exactement :
|
||||
|
||||
```text
|
||||
M CHANGELOG.md
|
||||
M README.md
|
||||
M ROADMAP.md
|
||||
M VERSION
|
||||
A deltas/0.0.4/rel.001.md
|
||||
M docs/000-README.md
|
||||
M docs/plans/004-V0_0_4_SKELETONS_PLAN.md
|
||||
```
|
||||
|
||||
Les `15` tests, les cinq TOML et le smoke Rust/Cargo complets validés en RC restent des preuves applicables parce qu'aucun code, script, test, template ou skeleton technique n'est modifié pendant `rel.001`. La gate stable se concentre donc sur l'intégrité de la chaîne historique, la présentation stable et les audits documentaires affectés.
|
||||
|
||||
## Revue opérateur complémentaire
|
||||
|
||||
Confirmer que le scope fonctionnel de la RC ne change pas, que README/roadmap/changelog/index/plan décrivent la même stable, que les `FAIL` historiques restent conservés avec leurs fixes `PASS`, que le prompt `005` reste conditionnel à une vraie publication et à des baselines KSP/Games fournies, et qu'aucune preuve post-tag n'est anticipée.
|
||||
|
||||
## Transition
|
||||
|
||||
### PASS
|
||||
|
||||
Produire séparément `history/0.0.4/rel.001.md`, l'appliquer puis committer la stable. Ensuite seulement créer et publier le tag canonique `v0.0.4`, télécharger son archive source depuis Gitea, vérifier cette archive et conserver séparément la preuve post-tag `pgr-0.0.4-publish.001-report.md`.
|
||||
|
||||
Le message manuel de reprise de `prompts/005-V0_0_5_START_PROMPT.md` n'est remis à l'opérateur qu'après vérification effective de l'archive et d'un rapport post-tag PASS réel.
|
||||
|
||||
### FAIL
|
||||
|
||||
Consigner le diagnostic réel dans `history/0.0.4/rel.001.md`, ne pas tagger et corriger la clôture dans une tranche explicite avant publication.
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/000-README.md -->
|
||||
<!-- version: 1 -->
|
||||
<!-- version: 9 -->
|
||||
|
||||
# Documentation PGR
|
||||
|
||||
@@ -11,8 +11,21 @@ Ce fichier est l'index d'entrée de la documentation structurée de Project Gove
|
||||
- [`architecture/`](architecture/) — état architectural courant de PGR et profils applicables ;
|
||||
- [`plans/`](plans/) — plans vivants des releases en cours, puis références historiques après fermeture ;
|
||||
- [`rules/`](rules/) — règles normatives détaillées, organisées progressivement par scope ;
|
||||
- [`skeletons/`](skeletons/) — spécifications Markdown de composition et d'initialisation de projets ;
|
||||
- [`templates/`](templates/) — instructions d'adaptation des templates techniques et spécification du message manuel de reprise ;
|
||||
- [`validation/`](validation/) — matrices de validation et contrats de preuve.
|
||||
|
||||
D'autres collections telles que `ideas/`, `studies/`, `reference/`, `formats/` ou `templates/` ne sont créées que lorsqu'un premier artefact réel les justifie.
|
||||
D'autres collections telles que `ideas/`, `studies/`, `reference/` ou `formats/` ne sont créées que lorsqu'un premier artefact réel les justifie.
|
||||
|
||||
Les répertoires workflow de racine (`deltas/`, `history/`, `handoffs/`, `manifests/`, `prompts/`, `scripts/`) restent séparés de `docs/` parce qu'ils portent le processus de développement et de livraison lui-même.
|
||||
Les templates techniques copiables sous `templates/` restent séparés des instructions documentaires sous `docs/templates/`. Les répertoires workflow de racine (`deltas/`, `history/`, `handoffs/`, `manifests/`, `prompts/`, `scripts/`) restent séparés de `docs/` parce qu'ils portent le processus de développement et de livraison lui-même.
|
||||
|
||||
## Points d'entrée de 0.0.4
|
||||
|
||||
- [`plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md`](plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md) — périmètre et décisions de la release `0.0.3` ;
|
||||
- [`plans/004-V0_0_4_SKELETONS_PLAN.md`](plans/004-V0_0_4_SKELETONS_PLAN.md) — périmètre et décisions de la release `0.0.4` ;
|
||||
- [`skeletons/000-README.md`](skeletons/000-README.md) — contrat de collection des skeleton specifications ;
|
||||
- [`skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md`](skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md) — fondation de gouvernance locale composable et sans spécialisation technologique ;
|
||||
- [`skeletons/002-RUST_CARGO_WORKSPACE.md`](skeletons/002-RUST_CARGO_WORKSPACE.md) — specialization Rust/Cargo workspace composable avec la fondation et les cinq templates existants ;
|
||||
- [`templates/001-RUST_CARGO_TOOLING.md`](templates/001-RUST_CARGO_TOOLING.md) et [`templates/002-CARGO_MANIFESTS.md`](templates/002-CARGO_MANIFESTS.md) — adaptation des cinq fichiers Rust/Cargo copiables ;
|
||||
- [`templates/003-NEW_SESSION_PROMPT.md`](templates/003-NEW_SESSION_PROMPT.md) — spécification du message manuel après une stable publiée ;
|
||||
- [`validation/001-VALIDATION_MATRIX.md`](validation/001-VALIDATION_MATRIX.md) et [`validation/002-RUST_STYLE_AUDITS.md`](validation/002-RUST_STYLE_AUDITS.md) — gates PGR et limites des audits de style Rust facultatifs.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/architecture/002-GOVERNANCE_ARCHITECTURE.md -->
|
||||
<!-- version: 2 -->
|
||||
<!-- version: 3 -->
|
||||
|
||||
# Architecture de gouvernance PGR
|
||||
|
||||
@@ -25,9 +25,9 @@ Après instanciation, le projet possède sa copie et ne dépend plus de PGR.
|
||||
|
||||
Un skeleton est une recette Markdown décrivant comment initialiser un type de projet ou composer plusieurs profils.
|
||||
|
||||
Il décrit notamment les profils applicables, la structure requise ou optionnelle, les templates à utiliser, les points de décision, la politique de version et la validation de base.
|
||||
Il décrit notamment les profils applicables, la structure requise ou optionnelle, les templates à utiliser, les points de décision, la politique de version et la validation de base. Le contrat transversal de sélection et de composition appartient à [`../rules/220-SKELETONS.md`](../rules/220-SKELETONS.md) ; les spécifications concrètes sont indexées sous [`../skeletons/`](../skeletons/000-README.md).
|
||||
|
||||
Un skeleton n'est pas un générateur et ne doit pas figer l'évolution future du projet.
|
||||
Un skeleton n'est pas un générateur et ne doit pas figer l'évolution future du projet. Il orchestre des owners normatifs et des artefacts existants sans devenir lui-même propriétaire d'une règle déjà possédée ailleurs.
|
||||
|
||||
### Audit
|
||||
|
||||
@@ -44,11 +44,11 @@ Le flux conceptuel est :
|
||||
```text
|
||||
PGR rules + templates + skeleton specifications
|
||||
↓
|
||||
sélection humaine / IA
|
||||
applicabilité + décisions du projet
|
||||
↓
|
||||
nouveau projet
|
||||
copie / adaptation contrôlée
|
||||
↓
|
||||
copies et règles locales
|
||||
validation de la baseline
|
||||
↓
|
||||
projet autonome et gouverné
|
||||
```
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/architecture/003-RULE_PROFILE_MODEL.md -->
|
||||
<!-- version: 2 -->
|
||||
<!-- version: 3 -->
|
||||
|
||||
# Modèle de profils de règles PGR
|
||||
|
||||
@@ -196,8 +196,8 @@ La revue beta n'a pas justifié l'activation d'une famille `700 — frameworks`
|
||||
|
||||
La réconciliation a également confirmé qu'une règle générale ne doit pas être recopiée comme si le profil spécifique en devenait propriétaire. Un profil peut rappeler une conséquence spécifique au contexte, mais doit référencer l'owner général lorsque le contrat lui-même n'est pas spécialisé.
|
||||
|
||||
## Instanciation future
|
||||
## Instanciation par skeleton
|
||||
|
||||
Les futures skeleton specifications sélectionneront les profils applicables et recopieront leurs règles pertinentes dans la baseline locale du projet créé.
|
||||
Les skeleton specifications sélectionnent les profils applicables et identifient les règles à reprendre ou adapter dans la baseline locale du projet créé. Leur contrat transversal de composition appartient à [`../rules/220-SKELETONS.md`](../rules/220-SKELETONS.md) ; le présent document reste propriétaire de la hiérarchie et de la résolution des profils eux-mêmes.
|
||||
|
||||
Le projet instancié restera autonome : la composition de profils sert à construire sa baseline initiale, pas à créer une dépendance dynamique vers PGR.
|
||||
Le projet instancié reste autonome : la composition de profils sert à construire sa baseline initiale, pas à créer une dépendance dynamique vers PGR.
|
||||
|
||||
159
docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
Normal file
159
docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
Normal file
@@ -0,0 +1,159 @@
|
||||
<!-- file: docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md -->
|
||||
<!-- version: 9 -->
|
||||
|
||||
# Plan 0.0.3 — templates initiaux et audits réutilisables
|
||||
|
||||
## Statut et sources
|
||||
|
||||
Plan de cadrage créé dans `0.0.3-alpha.1` et corrigé dans `0.0.3-alpha.1.fix.1` après sa validation mécanique. `alpha.2` intègre la convention opérateur sur les fichiers d'outillage Rust et matérialise les premiers templates ; sa gate opérateur est PASS. Après cette gate, la demande de décomposer les audits de style Rust KSP/Games modifie le calendrier prévisionnel. Le résultat REPLAN de `alpha.3` est `SPLIT` : deux audits de style ciblés sont traités d'abord, les manifests Cargo puis les headers Markdown suivent dans des tranches distinctes. Les tranches suivantes restent une prévision, non un état validé.
|
||||
|
||||
La source autoritaire est l'archive Gitea fournie `pgr-v0.0.2.zip`, issue selon l'opérateur du tag `v0.0.2`. Son SHA-256 vérifié localement est :
|
||||
|
||||
```text
|
||||
8dc5c979a4d722b4ef6ec84b6227c8cbfffb3f865f4ea9063c03ecb1e365cdc4
|
||||
```
|
||||
|
||||
Le rapport séparé `pgr-0.0.2-publish.001-report.md` indique `PASS` et donne le même hash. Il atteste la publication post-tag sans appartenir au tag. L'archive sans `.git` ne peut prouver indépendamment le commit ni l'identité du tag ; ces éléments sont les déclarations et preuves de publication de l'opérateur.
|
||||
|
||||
Le contrat de démarrage est `prompts/003-V0_0_3_START_PROMPT.md`. Les règles applicables partent de `RULES.md`, puis des familles `200`, `210`, `300`, `400`, du modèle de profils `003` et des profils `500`/`510`, `520`, `600`/`610` selon leur scope. PGR reste un dépôt documentaire doté d'outils Python ; les toolchains Rust, Java et Android ne deviennent pas des prérequis du dépôt.
|
||||
|
||||
Deux corpus de comparaison supplémentaires, fournis après le gate initial de `alpha.1`, ont été inspectés pour ce fix documentaire :
|
||||
|
||||
```text
|
||||
khadhroony-solana-project-v0.3.16.zip SHA-256 db3cc1b3fc3fb07ee864b02e2a7346c673d4cf63b33e8e872aca6c6458856ca0
|
||||
games-v0.3.5.zip SHA-256 5f5fdee1a271386766d059657d6eaa831acdc263b3e722fed738808335c0a105
|
||||
```
|
||||
|
||||
Ce sont des sources de comparaison pour les décisions de templates et d'audits, non la baseline PGR et non des dépendances de build. Leur présence ne rend pas les conventions locales de KSP ou Games normatives pour tous les projets.
|
||||
|
||||
## Audit indépendant de la stable `v0.0.2`
|
||||
|
||||
L'inspection de l'archive, sa lecture et la comparaison des fichiers extraits avec les membres ZIP ont établi :
|
||||
|
||||
- ZIP lisible, `94` entrées : `78` fichiers et `16` répertoires, une seule racine `pgr/` ; aucun doublon, chemin absolu, traversée `..`, chemin Windows ambigu ou lien symbolique ;
|
||||
- exactement `78` fichiers extraits ; `VERSION` contient `0.0.2` avec un seul retour final à la ligne ; `.git` absent comme attendu ;
|
||||
- octets des fichiers distribués décodables en UTF-8, sans NUL, CR, espace de fin de ligne ou retour final manquant ;
|
||||
- `73` fichiers Markdown dont les deux premières lignes correspondent exactement au chemin relatif `file` et à une révision positive `version` ;
|
||||
- contrôle local des deux scripts existants : `Markdown table audit: clean (2 table(s), 73 file(s))` et `Markdown link audit: clean (50 local link(s), 73 file(s))` ;
|
||||
- aucun répertoire de build/cache ou fichier local sensible connu dans les chemins distribués ; seule la préférence Eclipse UTF-8 intentionnellement conservée est présente sous `.settings/`.
|
||||
|
||||
La vérification de structure et de gouvernance a constaté :
|
||||
|
||||
- `12` deltas et `12` histories appariés exactement dans chacune des séries `0.0.1` et `0.0.2`, y compris `rel.001` ; chaque history possède un statut explicite ;
|
||||
- les versions `avant`/`après` déclarées dans tous les deltas `0.0.2` forment une chaîne continue de `0.0.1` à `0.0.2` ; les deltas `0.0.1` au format homogène depuis `alpha.1.fix.2` forment également une chaîne continue jusqu'à la stable ;
|
||||
- dans `0.0.1`, les `FAIL` de `alpha.1`, `alpha.1.fix.1`, `alpha.4` et `rc.1` sont suivis d'une tranche corrective `PASS` ; dans `0.0.2`, même traitement pour `alpha.1`, `alpha.4`, `beta.1` et `rc.1` ; les deux `rel.001` sont `PASS` ;
|
||||
- `README.md`, `ROADMAP.md` et `CHANGELOG.md` présentent `0.0.2` comme terminé et `0.0.3` comme prévu ; les plans `001` et `002` restent historiques ; le prompt `003` nomme l'archive et la preuve post-tag fournies ;
|
||||
- séparation cohérente entre objectifs durables, architecture, règles normatives, validation, plans, deltas prospectifs, histories rétrospectifs et changelog stable ; les index pointent vers les familles et profils réellement présents ;
|
||||
- les profils réellement matérialisés sont `510` Rust/Cargo, `520` Java/Maven/Gradle et `610` Android ; les seuls scripts d'audit PGR sont ceux des tableaux et des liens Markdown locaux. Aucun skeleton, générateur ou profil différé n'est présent.
|
||||
|
||||
Aucun écart bloquant n'a été constaté dans ces contrôles. Les scripts Markdown ont chacun une portée volontairement limitée : le contrôle des liens vérifie l'existence des cibles inline locales, pas les ancres ; celui des tableaux vérifie leur structure source. Leur PASS n'atteste donc pas des propriétés hors de leur contrat.
|
||||
|
||||
## Comparaison réelle des corpus Rust
|
||||
|
||||
KSP `0.3.16` et Games `0.3.5` possèdent chacun un workspace Cargo virtuel avec `resolver = "3"` et centralisent réellement dans `[workspace.package]` `version`, `edition`, `license`, `repository`, `authors` et `publish`. Ils utilisent `[workspace.dependencies]` pour des dépendances tierces, mais avec respectivement `37` et `19` entrées propres à leur projet. Les deux racines déclarent les mêmes trois lints Rust de base (`missing_docs`, `unreachable_pub`, `unsafe_code`) et les mêmes `18` niveaux Clippy ; les éventuels `allow` doivent être revus un par un avant réemploi.
|
||||
|
||||
Les `22` crates KSP héritent des lints workspace par `[lints] workspace = true`. Parmi `23` crates Games, `22` utilisent ce même héritage ; l'entrée Android déclare des lints locaux pour ajuster `unsafe_code` à sa frontière FFI. La capacité d'exception locale est donc réelle et doit être expliquée sans rendre l'exception Android générale.
|
||||
|
||||
Les deux `rustfmt.toml` ont un contenu technique identique et seulement un numéro de révision de fichier différent. Les deux `clippy.toml` partagent leurs seuils principaux et divergent sur les identifiants courts autorisés et quelques entrées vides. L'opérateur confirme qu'il réutilise ces conventions comme baseline de départ, telles quelles ou avec de petites adaptations. Les deux `.cargo/config.toml` déplacent les artefacts de build vers `../builds/<projet>/target/` ; Games ajoute des flags Web propres à sa cible. La configuration générique de déplacement est donc retenue avec un nom de projet à remplacer.
|
||||
|
||||
## Sélection des templates
|
||||
|
||||
### Retenu : famille Rust/Cargo minimale
|
||||
|
||||
Le besoin concret n'est pas limité à `rustfmt.toml`. La première famille doit couvrir cinq responsabilités distinctes :
|
||||
|
||||
1. `rustfmt.toml` : options communes dont la valeur est justifiée ; alignement de `edition` avec le projet destinataire ; ne pas reprendre mécaniquement chaque préférence des deux sources ;
|
||||
2. configuration Clippy : niveaux de lint Rust/Clippy dans les sections Cargo `[workspace.lints.rust]` et `[workspace.lints.clippy]`, plus `clippy.toml` pour les seuils et réglages conservés dans le profil de départ éprouvé ; chaque projet peut adapter ces choix ;
|
||||
3. `.cargo/config.toml` : `target-dir` et `build-dir` vers un dossier frère `../builds/<projet>/target/`, après remplacement explicite du nom ; les flags Web et les autres particularités restent locaux ;
|
||||
4. `Cargo.toml` workspace : sections `[workspace]`, `[workspace.package]`, `[workspace.dependencies]` et `[workspace.lints.*]` avec les responsabilités et champs de décision explicités ; `VERSION` doit correspondre à `workspace.package.version` seulement pour une unité de release commune ;
|
||||
5. `Cargo.toml` d'une crate membre ordinaire : identité locale, héritage explicite des métadonnées communes et des lints, et dépendances/features limitées aux besoins de la crate. Une adaptation locale des lints doit être documentée comme exception ciblée ; elle ne devient pas un deuxième jeu de valeurs globales.
|
||||
|
||||
Ces fichiers ou extraits doivent être copiables et compréhensibles sans figer le nom de projet, la version, les dépendances, le layout de toutes les crates, la publication, la toolchain ni le minimum de plateforme. Lorsqu'un champ obligatoire ne peut pas avoir de valeur générique sûre, des instructions Markdown guident son remplacement avant l'usage ; un fichier TOML présenté comme prêt à l'emploi doit être valide. Les crates bibliothèque et application peuvent partager un tronc commun, leurs différences réelles restant documentées sans créer des dizaines de variantes.
|
||||
|
||||
Pour la validation, comparer les templates au profil `510`, parser les configs/manifests avec un parseur TOML et exercer sur un workspace d'essai les héritages et le cas d'une exception locale quand les toolchains sont disponibles. Tester `rustfmt` et Clippy pour les réglages réellement livrés dans un projet Rust concerné ; une compilation de KSP/Games n'est pas une gate de PGR.
|
||||
|
||||
### Retenu : spécification courte du prompt manuel de nouvelle session
|
||||
|
||||
Les prompts `002` et `003` répètent la transmission de la baseline taggée, de la cible et de la première tranche ; `003` ajoute le rapport post-tag et le texte manuel remis à l'opérateur. Après comparaison, `alpha.6` retient une courte spécification Markdown des champs et de la phrase de reprise. Elle facilite la prochaine clôture sans créer un générateur, un nouveau prompt versionné prématuré ou une copie du plan. Le rapport ne devient un champ rempli que s'il existe et que son résultat est réellement connu.
|
||||
|
||||
### Différés
|
||||
|
||||
Les fichiers Maven/Gradle complets, wrappers, Android `local.properties` ou signing, règles `.gitignore` universelles et versions de dépendances ne sont pas copiés par anticipation. Games fournit un exemple Android concret, mais sa matrice AGP/Gradle/JDK, son build natif et ses flags Cargo Web restent propres à ce projet. Les wrappers restent soumis aux outils officiels et à la décision du projet ; un `local.properties` entièrement régénéré ne justifie pas d'exemple.
|
||||
|
||||
Les spécifications complètes de skeleton restent réservées à `0.0.4` ; Rust/JNI, Web/WASM, Tauri et les autres profils différés n'entrent pas dans cette release par simple proximité technologique.
|
||||
|
||||
## Sélection des audits et patterns
|
||||
|
||||
Les trois audits Markdown (`headers`, `tables`, `liens locaux`) restent séparés : une propriété chacun, sélection explicite des chemins et lecture seule. L'audit des headers, livré en `alpha.5`, applique le contrat de `docs/rules/300-DOCUMENTATION.md` avec des cas positifs et négatifs ciblés ; il ne juge ni le rôle du document ni la pertinence de l'incrément de sa révision.
|
||||
|
||||
La comparaison des scripts Python KSP `0.3.16` et Games `0.3.5` montre que `audit_rust_general_rules.py` (~580 lignes dans chaque corpus) mélange headers et versions Rust, imports, rustdoc, structure des items, blancs, constantes et modules. `audit_rust_export_completeness.py` possède le contrat particulier des façades et réexports ; KSP ajoute `audit_ksp_workspace_rules.py` pour manifests/frontières/tracing, tandis que Games regroupe plusieurs intégrations Web/Android/Gradle dans `audit_distribution_layout.py`. `audit_rust_workspace_rules.py` est un orchestrateur ; il peut rester un lanceur sans devenir propriétaire de ces contrats.
|
||||
|
||||
| Propriété | Owner | Suite |
|
||||
|------------------------------------------|-------------------------|----------------------------------------|
|
||||
| Ordre interne des `use` et `mod` | Rustfmt | `cargo fmt --all -- --check` |
|
||||
| Diagnostics du langage et des lints | Rust/Clippy | Outils officiels du projet |
|
||||
| Espacement des lignes vides | Profil `510` facultatif | `audit_rust_blank_lines.py` |
|
||||
| Blocs de constantes racine | Profil `510` facultatif | `audit_rust_const_blocks.py` |
|
||||
| Headers, rustdoc, API, tests, plateforme | Profils locaux | Audits séparés uniquement si justifiés |
|
||||
|
||||
Le balayage préalable des vrais sources `crates/**/src/**/*.rs` donne `300` fichiers KSP et `59` Games. Le contrôle des blancs passe les deux corpus. Un tri naïf de toutes les constantes racine trouve `17` signaux dans KSP et zéro dans Games ; plusieurs listes KSP sont ordonnées par contrat de protocole ou de schéma. Cela interdit de déclarer le tri globalement obligatoire ou de corriger ces fichiers sans revue. Les scripts livrés sont des patrons facultatifs : le propriétaire d'un projet choisit le sous-ensemble de sources concerné, applique `cargo fmt` avant ces audits et conserve l'ordre sémantique là où il existe. Un petit helper lexical partagé masque commentaires et littéraux ; il n'est pas un troisième audit ni un parseur Rust exhaustif. Les limites et le mode d'emploi sont dans `docs/validation/002-RUST_STYLE_AUDITS.md`.
|
||||
|
||||
Les autres candidats demeurent conditionnels : miroir `VERSION`/`workspace.package.version` si une release unit est partagée, héritage explicite des lints dans les crates et façade publique seulement lorsqu'un projet possède ce contrat. Aucun audit spécialisé de ces domaines ni de layout Android/Web n'est justifié par le dépôt documentaire PGR lui-même.
|
||||
|
||||
## Trajectoire prévisionnelle
|
||||
|
||||
### alpha.1 — intake et dimensionnement
|
||||
|
||||
Enregistrer l'audit de la stable, confronter le prompt au dépôt réel, inventorier les candidats, fixer le scope et produire le présent plan ainsi que le delta. Aucune matérialisation technique importante. Attendre la validation opérateur, le history distinct et le commit avant tout delta suivant.
|
||||
|
||||
### alpha.1.fix.1 — correction documentaire du plan
|
||||
|
||||
Après le history et le commit de `alpha.1`, documenter la comparaison réelle de KSP/Games, élargir les templates Rust à Cargo et Clippy et redimensionner les tranches. Aucun template ou audit nouveau dans ce fix.
|
||||
|
||||
### alpha.2 — outillage Rust/Cargo partagé
|
||||
|
||||
Créer les templates `rustfmt.toml`, `clippy.toml` et `.cargo/config.toml` à partir du noyau éprouvé dans KSP et Games. Documenter les responsabilités distinctes : formatage, paramètres Clippy, sortie Cargo hors du dépôt. Le nom du projet, l'édition Rust et les seuils ajustables sont explicités au point de copie ; vérifier syntaxe et chemins relatifs. Les niveaux de lint dans `Cargo.toml` restent à `alpha.4` après le REPLAN, qui les reliera au profil Clippy retenu.
|
||||
|
||||
### alpha.3 — audits de style Rust découpés (REPLAN : SPLIT)
|
||||
|
||||
Suite à la demande post-gate `alpha.2`, isoler deux contrôles réutilisables des scripts composites KSP/Games : espacement des lignes vides et blocs de constantes racine sans ordre sémantique. Posséder leur convention facultative dans le profil `510`, documenter sélection/limites et exécuter des cas ciblés positifs et négatifs. Vérifier sur les corpus réels que les ordres contractuels ne deviennent pas de faux changements imposés. Les manifests initialement prévus ici passent à `alpha.4` : aucune validation anticipée n'est déduite du PASS de `alpha.2`.
|
||||
|
||||
### alpha.4 — manifests Cargo workspace et crate membre
|
||||
|
||||
Fournir des modèles minimaux de `Cargo.toml` racine et membre, incluant l'héritage des métadonnées et des lints et une explication des variations de scope. Vérifier les exemples sur un workspace d'essai lorsque la toolchain est disponible, sans recopier les listes de dépendances, versions et chemins de KSP/Games. Si les modèles exigent trop de décisions pour former des fichiers TOML valides, livrer des extraits complets avec procédure de substitution documentée, sans prétendre qu'un placeholder est prêt à compiler.
|
||||
|
||||
### alpha.5 — audit de headers Markdown
|
||||
|
||||
Extraire le contrôle récurrent en un script read-only monotâche, documenter sa portée dans la matrice et vérifier des cas positifs et négatifs utiles. Ne pas fusionner cet audit avec les deux audits Markdown existants.
|
||||
|
||||
### alpha.6 — décision sur le template de workflow
|
||||
|
||||
La comparaison des prompts `002` et `003` confirme une répétition utile à factoriser : baseline source, preuve post-tag éventuelle, prompt versionné et gate d'intake. Livrer une spécification courte de rédaction manuelle, détenue par `210-WORKFLOW.md`, sans générateur ni prompt de version suivante avant la clôture stable. Le template reste distinct des configurations Rust/Cargo et ne modifie pas les prompts historiques.
|
||||
|
||||
### beta.1 — réconciliation
|
||||
|
||||
Vérifier ownership, navigation, séparation règle/template/audit, absence de versions universelles arbitraires et proportion des contrôles. Aucun nouveau domaine majeur sans REPLAN.
|
||||
|
||||
La revue préparatoire de cette tranche a constaté que les sept deltas `0.0.3` de `alpha.1` à `alpha.6`, fix inclus, forment une chaîne de versions continue depuis `0.0.2` et possèdent chacun un history `PASS` fondé sur la gate opérateur. Les propriétaires restent distincts : profil `510` pour les conventions Rust facultatives, règles `210` et `300` pour workflow et headers, documents de `docs/templates/` pour l'adaptation, scripts monotâches pour les contrôles. Leurs validations ciblées avaient été acquises dans les tranches précédentes ; `beta.1` a vérifié leur intégration et la navigation sans exiger de nouveau build des projets sources.
|
||||
|
||||
Trois écarts documentaires justifiaient le delta : l'index de `docs/` présentait tous ses templates comme techniques alors que le troisième décrit la reprise de session ; le plan désignait toujours les headers Markdown comme candidat après leur livraison ; la matrice réservait l'audit de liens à `beta/RC/stable` alors que les gates `alpha` l'emploient également sur des changements de navigation. L'index racine ne pointait pas vers le plan actif. Ces renvois ont été corrigés dans les documents vivants sans modifier les snapshots ni les choix de version `0.1.0` et d'édition `2024` explicitement présentés comme exemples adaptables dans les manifests et instructions Rust/Cargo.
|
||||
|
||||
### rc.1 — gate de release candidate
|
||||
|
||||
Geler le scope, préparer le changelog et le prompt de la version suivante si la trajectoire est confirmée ; exécuter la gate documentaire et les vérifications ciblées des scripts réellement ajoutés.
|
||||
|
||||
La gate opérateur de `beta.1` est `PASS` : `15` tests ciblés, trois audits Markdown, chaîne des sept histories alpha et cinq TOML vérifiés. Son résultat détaillé appartient à `history/0.0.3/beta.1.md`. À l'entrée de `rc.1`, le scope est gelé sur les cinq fichiers Rust/Cargo avec leurs deux guides techniques, la spécification du message manuel, les deux audits de style Rust facultatifs et l'audit des headers Markdown. Les règles et scripts antérieurs restent en place ; aucun profil technologique nouveau, générateur ou skeleton complet n'entre dans cette release.
|
||||
|
||||
La RC a préparé une entrée candidate `0.0.3` dans le changelog et le prompt `004` de `0.0.4`. La gate opérateur de `rc.1` est `PASS` : `15` tests, trois audits Markdown, chaîne des huit histories précédents et cinq TOML vérifiés. Son résultat détaillé appartient à `history/0.0.3/rc.1.md`. La première tranche de `0.0.4` décidera des skeleton specifications réellement justifiées après audit de la stable publiée ; son rapport post-tag reste une preuve ultérieure distincte.
|
||||
|
||||
### stable — 0.0.3
|
||||
|
||||
Promouvoir la RC validée, produire le history de clôture pré-tag, committer et tagger, puis contrôler séparément l'archive du tag publiée.
|
||||
|
||||
Le delta `rel.001` prépare mécaniquement la version stable `0.0.3` : `VERSION`, statut de la roadmap, présentation du dépôt et des index, et conversion de l'entrée candidate du changelog en entrée stable. Ce plan devient une référence historique à la clôture, sans ajout de règle, profil, template ou audit. Le résultat réel de la gate pré-tag appartient à `history/0.0.3/rel.001.md`, fourni après exécution opérateur ; commit et tag `v0.0.3` suivent uniquement un PASS. La vérification de l'archive effectivement publiée depuis le tag constitue ensuite une preuve post-tag séparée, typiquement `publish.001`, et ne doit pas être présumée par le history pré-tag.
|
||||
|
||||
## Points de décision et validation
|
||||
|
||||
Le résultat `SPLIT` de `alpha.3` répond à la découverte post-gate de contrôles de style Rust utiles mais mêlés dans deux scripts de référence. Le plan doit encore être revu si les manifests Cargo exigent des choix de projet incompatibles avec un modèle minimal, si l'audit de headers ne peut rester fiable et monotâche, si le template de workflow duplique le plan, ou si un autre examen des corpus révèle des contraintes nouvelles. Un REPLAN explicite indique `CONTINUE`, `SPLIT`, `CONTINUE-NEXT-SESSION` ou `ABANDON` ; la durée d'une conversation ne crée pas une nouvelle version.
|
||||
|
||||
La validation `alpha.1` a porté sur l'identité de `VERSION`, la portée du delta, les headers et audits Markdown, l'absence de changement historique rétroactif et le contrôle Git du dépôt de l'opérateur. Ses résultats observés sont conservés dans `history/0.0.3/alpha.1.md`. Le fix documentaire décrit ci-dessus possède sa propre gate et son propre history : le PASS de `alpha.1` ne vaut pas validation anticipée de `alpha.1.fix.1`.
|
||||
158
docs/plans/004-V0_0_4_SKELETONS_PLAN.md
Normal file
158
docs/plans/004-V0_0_4_SKELETONS_PLAN.md
Normal file
@@ -0,0 +1,158 @@
|
||||
<!-- file: docs/plans/004-V0_0_4_SKELETONS_PLAN.md -->
|
||||
<!-- version: 3 -->
|
||||
|
||||
# Plan 0.0.4 — skeleton specifications et composition
|
||||
|
||||
## Statut et sources
|
||||
|
||||
Plan historique créé pendant `0.0.4-alpha.1` après audit indépendant de la stable publiée `v0.0.3` demandé par `prompts/004-V0_0_4_START_PROMPT.md`. Les tranches `alpha.1` à `alpha.3` sont `PASS`. `alpha.4` a enregistré `FAIL` sur sa gate d'instanciation, puis `alpha.4.fix.1` a corrigé cette gate et est `PASS`. `beta.1` a enregistré `FAIL` sur une erreur de syntaxe de sa gate de réconciliation, puis `beta.1.fix.1` a rejoué la réconciliation et est `PASS`. La gate opérateur de `rc.1` est `PASS` : intégration documentaire, prompt `005`, cinq TOML et instanciation temporaire Rust/Cargo avec `cargo metadata`, `fmt`, `check` et `clippy -D warnings` ont été validés. Le scope fonctionnel est gelé et `rel.001` ne réalise qu'une promotion stable pré-tag.
|
||||
|
||||
La baseline autoritaire est l'archive source fournie `pgr-v0.0.3.zip`, déclarée téléchargée depuis le tag Gitea `v0.0.3`. Son SHA-256 vérifié pendant le cadrage est :
|
||||
|
||||
```text
|
||||
517fb46ada098fdc221ae53a8ff4b409b81e0244ec5ce4d0e6fca0c3da61b866
|
||||
```
|
||||
|
||||
Le rapport externe `pgr-0.0.3-publish.001-report.md` est fourni séparément, conclut `PASS` et annonce le même hash. Il atteste une vérification post-tag distincte et ne fait pas partie de la stable. L'archive source ne contient pas `.git`, ce qui est conforme au contrat de reprise ; l'identité du commit et du tag décrite dans le rapport n'est pas déduite du contenu du ZIP.
|
||||
|
||||
Les règles applicables au cadrage sont `RULES.md`, les familles `200`, `210`, `300`, `400`, `500`, `510`, `520`, `600`, `610`, ainsi que `docs/architecture/003-RULE_PROFILE_MODEL.md`. Les guides `docs/templates/001` à `003`, les cinq modèles Rust/Cargo, les trois audits Markdown et les deux audits facultatifs de style Rust complètent l'inventaire réel de la stable.
|
||||
|
||||
## Audit indépendant de la stable `v0.0.3`
|
||||
|
||||
L'archive fournie est lisible et son contenu distribué est cohérent dans les contrôles effectués :
|
||||
|
||||
- SHA-256 égal au rapport post-tag ;
|
||||
- `140` entrées ZIP : `115` fichiers et `25` répertoires, avec une seule racine `pgr/` ;
|
||||
- test CRC propre, aucun doublon, aucune collision de casse, aucun chemin absolu ou avec traversée `..`, aucun chemin Windows ambigu et aucun lien symbolique ;
|
||||
- extraction propre de `115` fichiers ; `VERSION` contient exactement `0.0.3` suivi d'un retour à la ligne ; `.git` est absent comme attendu ;
|
||||
- les fichiers distribués sont UTF-8, sans octet NUL, retour CR, espace de fin de ligne ou retour final manquant ;
|
||||
- aucun chemin distribué de build/cache ou secret contrôlé n'est présent ; `.settings/org.eclipse.core.resources.prefs` reste l'exception Eclipse versionnée prévue ;
|
||||
- `99` fichiers Markdown possèdent des headers `file/version` mécaniquement conformes ;
|
||||
- les trois audits Markdown sont propres : `99` fichiers pour les headers, `3` tableaux et `79` liens locaux ;
|
||||
- les `15` tests Python ciblés réussissent ;
|
||||
- les cinq fichiers TOML sous `templates/rust-cargo/` se parsèrent correctement ;
|
||||
- les deux audits de style Rust facultatifs n'ont pas de corpus Rust produit à inspecter dans PGR ; leur comportement est couvert par `tests/test_rust_audits.py` et leur sélection doit rester explicite dans un projet destinataire.
|
||||
|
||||
La chaîne workflow est complète :
|
||||
|
||||
```text
|
||||
0.0.1 : 12 deltas / 12 histories
|
||||
0.0.2 : 12 deltas / 12 histories
|
||||
0.0.3 : 10 deltas / 10 histories
|
||||
```
|
||||
|
||||
Chaque delta possède son history homonyme. Les histories `0.0.3`, de `alpha.1` à `rel.001`, sont tous `PASS`. Les échecs historiques des séries antérieures sont conservés comme snapshots et sont suivis par leurs corrections explicites ; ils ne sont pas réécrits rétroactivement.
|
||||
|
||||
Les limites annoncées restent visibles et cohérentes : l'audit des liens ne valide pas les anchors, l'audit des headers ne juge pas la pertinence sémantique d'une révision, les audits Rust utilisent une analyse lexicale ciblée et l'archive source ne prouve pas elle-même une référence Git distante. Aucun de ces points ne constitue un défaut bloquant de la stable.
|
||||
|
||||
## Revue des règles, profils et propriétaires
|
||||
|
||||
La hiérarchie normative reste cohérente avec le modèle de profils : règles générales, langage/écosystème, plateforme, puis scopes plus spécifiques et exceptions explicites. Aucun profil n'est applicable par simple fréquence ou provenance historique.
|
||||
|
||||
Les responsabilités utiles à `0.0.4` sont distinctes :
|
||||
|
||||
- `200` possède le lifecycle et le rôle de `alpha.1` comme gate de cadrage ;
|
||||
- `210` possède plans, deltas, histories, prompts, baselines et séparation pré-tag/post-tag ;
|
||||
- `300` possède rôles documentaires, documents vivants, snapshots et headers ;
|
||||
- `400` possède la sélection proportionnelle des preuves et l'autorité du gate opérateur ;
|
||||
- `500` et `600` possèdent les contrats communs des profils langage et plateforme ;
|
||||
- `510`, `520` et `610` possèdent respectivement Rust/Cargo, Java/Maven/Gradle et Android ;
|
||||
- `docs/architecture/003-RULE_PROFILE_MODEL.md` possède le modèle de composition et interdit les profils composites sans contrat propre réel.
|
||||
|
||||
La séparation règle / template / skeleton / audit de `docs/architecture/002-GOVERNANCE_ARCHITECTURE.md` reste adaptée. `0.0.4` doit l'étendre par des artefacts concrets sans déplacer les propriétaires normatifs existants.
|
||||
|
||||
## Inventaire des capacités disponibles pour des skeletons
|
||||
|
||||
### Fondation gouvernée PGR — prête à être spécifiée
|
||||
|
||||
Une baseline de projet gouverné constitue une fondation composable, pas une architecture applicative. Les contrats nécessaires existent déjà : versioning, workflow, documentation, validation et modèle de profils. Le skeleton devra indiquer quels artefacts locaux créer ou copier, comment sélectionner les règles réellement applicables et quelles décisions restent propres au projet.
|
||||
|
||||
Il ne doit pas recopier l'historique de PGR, imposer toutes les familles de règles ni créer une dépendance dynamique vers le dépôt PGR.
|
||||
|
||||
### Rust/Cargo workspace — prêt à être spécifié
|
||||
|
||||
Le besoin est suffisamment couvert par des artefacts réels : profil `510`, deux guides d'adaptation, cinq templates Rust/Cargo et deux audits de style facultatifs documentés. Le skeleton pourra composer une fondation gouvernée avec `500 + 510` et sélectionner uniquement les templates nécessaires.
|
||||
|
||||
Les décisions destinataire restent explicites : nom du projet et des crates, version de release, édition/toolchain, métadonnées de publication, membres du workspace, dépendances et features, politique `Cargo.lock`, chemin des artefacts Cargo, seuils Clippy, politique de lints et sélection éventuelle des audits de style. Les valeurs d'exemple `0.1.0`, `2024`, `project-name`, `project-core-lib`, les seuils Clippy et les chemins de build ne deviennent jamais universels.
|
||||
|
||||
### Java / Maven / Gradle — différé
|
||||
|
||||
Le profil `520` définit des règles, mais PGR ne possède encore aucun template Maven/Gradle ou corpus technique éprouvé à instancier. Le choix Maven/Gradle, la politique de wrapper et les versions de toolchain doivent être déterminés dans un chantier justifié avant de produire un skeleton concret.
|
||||
|
||||
### Android — différé
|
||||
|
||||
Le profil `610` définit la structure de responsabilité et les décisions Android, mais aucun template AGP/Gradle, manifest applicatif, matrice SDK ou projet réel n'existe dans PGR. Un skeleton Android serait prématuré avant ces pièces et avant la sélection explicite de sa composition avec Java/Gradle ou un autre stack réel.
|
||||
|
||||
### Web, JNI, Tauri et autres familles absentes — différés
|
||||
|
||||
Ces domaines ne possèdent pas encore tous leurs propriétaires normatifs et templates nécessaires. `0.0.4` ne crée pas de profils ou skeletons placeholders pour eux.
|
||||
|
||||
## Contrat visé pour une skeleton specification
|
||||
|
||||
La tranche de composition devra fixer un contrat commun minimal. Chaque skeleton doit au moins permettre d'identifier :
|
||||
|
||||
```text
|
||||
applicabilité et objectif
|
||||
profils/règles sélectionnés
|
||||
fichiers à créer, copier ou adapter
|
||||
templates applicables et source de leurs choix
|
||||
décisions obligatoires propres au destinataire
|
||||
options et exceptions explicites
|
||||
ordre de composition
|
||||
validation initiale proportionnée
|
||||
éléments volontairement hors scope
|
||||
```
|
||||
|
||||
Un skeleton reste une procédure Markdown. Il ne génère pas le projet, ne télécharge pas de dépendances, ne remplace pas les toolchains et ne fige pas l'architecture future. Après instanciation, le projet possède ses copies locales et ses décisions.
|
||||
|
||||
Les règles communes de sélection et de composition doivent avoir un propriétaire normatif unique sous `docs/rules/`. Les spécifications concrètes vivront dans une collection documentaire dédiée créée seulement avec son premier contenu réel. Les fichiers techniques copiables restent sous `templates/` et leurs instructions d'adaptation sous `docs/templates/`.
|
||||
|
||||
## Découpage prévisionnel de `0.0.4`
|
||||
|
||||
### alpha.1 — audit de stable et cadrage
|
||||
|
||||
Vérifier indépendamment `v0.0.3`, le rapport post-tag, les règles `200` à `610`, les cinq templates Rust/Cargo, les trois audits Markdown, les deux audits Rust facultatifs et la chaîne de deltas/histories. Inventorier les skeletons réellement justifiés et fixer le présent plan avant toute matérialisation importante.
|
||||
|
||||
### alpha.2 — contrat de composition des skeletons
|
||||
|
||||
Créer le propriétaire normatif des règles de sélection et de composition des skeletons, puis la collection documentaire des skeleton specifications avec son index. Définir la frontière entre règles copiées/adaptées, templates techniques, décisions propres au projet, overrides et validation. Réconcilier les index et l'architecture sans créer encore de domaine technologique supplémentaire.
|
||||
|
||||
Le nom et le numéro exacts du document normatif seront choisis à l'application selon la responsabilité finale ; le plan ne transforme pas un chemin prévisionnel en règle déjà active.
|
||||
|
||||
### alpha.3 — fondation de projet gouverné
|
||||
|
||||
Matérialiser une première specification composable décrivant la baseline de gouvernance locale d'un projet utilisant PGR : version, règles sélectionnées, documentation minimale, workflow réellement retenu et validation initiale. Elle doit rester proportionnée et permettre d'omettre les collections ou artefacts sans contenu réel.
|
||||
|
||||
Cette fondation n'est ni un framework ni une architecture applicative et ne doit pas recopier les deltas, histories ou décisions propres au dépôt PGR.
|
||||
|
||||
### alpha.4 — skeleton Rust/Cargo workspace
|
||||
|
||||
Matérialiser la première specialization technologique en composant la fondation gouvernée avec `500 + 510`, les cinq templates Rust/Cargo et les guides d'adaptation existants. Documenter les décisions destinataire avant copie et les audits facultatifs explicitement sélectionnés.
|
||||
|
||||
La gate doit inclure une instanciation temporaire minimale ou une vérification équivalente lorsque la toolchain Rust est disponible, afin de distinguer la validité syntaxique des templates de leur adoption correcte. Cette preuve ne transforme pas PGR lui-même en workspace Rust.
|
||||
|
||||
### beta.1 — réconciliation interne
|
||||
|
||||
Vérifier ownership, liens, index, absence de duplication normative, non-universalisation des valeurs d'exemple, limites des audits et cohérence des deux premières specifications. Confirmer explicitement que Java/Android/Web/JNI/Tauri restent différés tant que leurs pièces requises manquent.
|
||||
|
||||
Aucun chantier de réconciliation complète avec KSP ou Games n'entre ici : la roadmap réserve cette mission à `0.0.5`.
|
||||
|
||||
La première gate `beta.1` a enregistré `FAIL` uniquement parce qu'une chaîne Python de contrôle contenait une apostrophe non échappée. `beta.1.fix.1` a corrigé la gate sans modifier de contenu vivant et a confirmé la réconciliation : owners distincts, trois documents skeletons seulement, valeurs Rust/Cargo adaptables, limites des audits explicites, cinq TOML valides et domaines différés toujours absents.
|
||||
|
||||
### rc.1 — gate de release candidate
|
||||
|
||||
Geler le scope, préparer l'entrée `0.0.4` du changelog et le prompt `005` de `0.0.5` si la trajectoire est confirmée. Rejouer les validations documentaires, tests et smokes réellement invalidés par la release.
|
||||
|
||||
Le scope gelé comprend le contrat transversal `220-SKELETONS.md`, l'index de collection, la fondation gouvernée `001`, la spécialisation Rust/Cargo `002` et l'utilisation des cinq templates Rust/Cargo déjà présents. Aucun nouveau domaine technologique, générateur, template, audit ou règle normative n'entre en RC. La trajectoire `0.0.5` reste celle de la roadmap : réconciliation réelle de PGR avec `khadhroony-solana-project` et `sasedev-games`, à partir de baselines explicites qui devront être fournies à cette future session plutôt que déduites d'un état local implicite.
|
||||
|
||||
### stable — 0.0.4
|
||||
|
||||
La gate opérateur de `rc.1` est `PASS`. Le delta `rel.001` prépare mécaniquement la stable `0.0.4` : `VERSION`, présentation du dépôt et des index, statut de la roadmap, conversion de l'entrée candidate du changelog et clôture du présent plan comme référence historique. Aucun nouveau skeleton, profil, template, audit ou domaine technologique n'est ajouté pendant cette promotion.
|
||||
|
||||
Le résultat réel de la gate pré-tag appartient à `history/0.0.4/rel.001.md`, produit après exécution opérateur. Le commit stable et le tag `v0.0.4` suivent uniquement un `PASS`. La vérification de l'archive effectivement publiée depuis Gitea et le rapport `pgr-0.0.4-publish.001-report.md` constituent ensuite une preuve post-tag séparée ; ils ne sont pas présumés par le delta ni par le history pré-tag.
|
||||
|
||||
## Points de décision et stratégie de validation
|
||||
|
||||
Un REPLAN devient nécessaire si la fondation gouvernée exige des templates génériques inexistants pour rester actionnable, si le contrat de composition duplique des règles existantes au lieu de les référencer, si le skeleton Rust impose une architecture plus étroite que le profil `510`, ou si l'instanciation minimale révèle qu'un template technique ne peut pas être adopté sans nouvelle décision normative.
|
||||
|
||||
Les tranches documentaires utilisent les trois audits Markdown et les contrôles Git applicables. Toute modification des scripts ou de leurs contrats rejoue leurs tests ciblés. Toute modification d'un template Rust/Cargo vérifie sa syntaxe et, lorsqu'elle prétend à une instanciation fonctionnelle, une gate Cargo proportionnée dans un environnement temporaire. Aucun build Java/Android n'est demandé tant qu'aucun artefact concret de ces écosystèmes n'entre dans le scope.
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/rules/000-README.md -->
|
||||
<!-- version: 10 -->
|
||||
<!-- version: 11 -->
|
||||
|
||||
# Index des règles PGR
|
||||
|
||||
@@ -13,6 +13,7 @@ Les règles générales actuellement nécessaires restent dans `RULES.md`. La fa
|
||||
|
||||
- [`200-GOVERNANCE.md`](200-GOVERNANCE.md) — versioning, lifecycle des releases, fixes, cadrage, replan et abandon/supersession.
|
||||
- [`210-WORKFLOW.md`](210-WORKFLOW.md) — contrats des artefacts workflow, ordre delta/history/commit, reprise et baselines de release.
|
||||
- [`220-SKELETONS.md`](220-SKELETONS.md) — contrat commun des skeleton specifications, sélection des profils/templates, décisions, overrides et validation.
|
||||
- [`300-DOCUMENTATION.md`](300-DOCUMENTATION.md) — rôles des documents, taxonomie, révisions internes, documents vivants et snapshots historiques.
|
||||
- [`400-VALIDATION.md`](400-VALIDATION.md) — matrice de validation, preuves proportionnelles, tests/audits/diagnostics, doubles de test et autorité du gate opérateur.
|
||||
- [`500-LANGUAGES.md`](500-LANGUAGES.md) — contrat commun des profils langage/écosystème et de leurs spécialisations de build.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/rules/210-WORKFLOW.md -->
|
||||
<!-- version: 2 -->
|
||||
<!-- version: 3 -->
|
||||
|
||||
# Workflow artifact rules
|
||||
|
||||
@@ -193,6 +193,8 @@ Le prompt :
|
||||
|
||||
Une interruption au milieu d'une version MUST NOT produire artificiellement le prompt de la version suivante.
|
||||
|
||||
Lors d'une nouvelle session ouverte depuis une stable publiée, une courte consigne manuelle MAY identifier l'archive du tag, le rapport post-tag lorsqu'il existe réellement, le prompt versionné à lire et la première gate. [`../templates/003-NEW_SESSION_PROMPT.md`](../templates/003-NEW_SESSION_PROMPT.md) décrit une forme réutilisable ; elle ne remplace ni le prompt versionné ni la preuve de publication.
|
||||
|
||||
## Handoff
|
||||
|
||||
Un handoff est un snapshot de continuité utilisé lorsqu'un travail doit être repris sans changer artificiellement de version ou de tranche.
|
||||
|
||||
123
docs/rules/220-SKELETONS.md
Normal file
123
docs/rules/220-SKELETONS.md
Normal file
@@ -0,0 +1,123 @@
|
||||
<!-- file: docs/rules/220-SKELETONS.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Skeleton specification rules
|
||||
|
||||
## Scope
|
||||
|
||||
Ce document définit le contrat transversal des skeleton specifications PGR : applicabilité, sélection des règles et profils, composition de skeletons, usage des templates, décisions propres au projet, overrides, instanciation et validation initiale.
|
||||
|
||||
Il ne définit pas les règles propres à une technologie. Les profils restent possédés par leurs documents normatifs, notamment le modèle de composition de [`../architecture/003-RULE_PROFILE_MODEL.md`](../architecture/003-RULE_PROFILE_MODEL.md). Les règles de validation restent possédées par [`400-VALIDATION.md`](400-VALIDATION.md) et le workflow delta/history par [`210-WORKFLOW.md`](210-WORKFLOW.md).
|
||||
|
||||
Les skeleton specifications concrètes vivent sous [`../skeletons/`](../skeletons/000-README.md).
|
||||
|
||||
## Nature d'un skeleton
|
||||
|
||||
Un skeleton PGR est une spécification Markdown procédurale permettant de construire une baseline locale cohérente à partir de règles, profils, templates et décisions explicites.
|
||||
|
||||
Un skeleton MUST NOT devenir :
|
||||
|
||||
- un générateur obligatoire de projet ;
|
||||
- une dépendance runtime ou build vers PGR ;
|
||||
- un nouveau propriétaire implicite de règles déjà possédées ailleurs ;
|
||||
- un moyen de figer une architecture au-delà du scope qu'il déclare ;
|
||||
- un catalogue de technologies ou de fichiers créés par anticipation.
|
||||
|
||||
Après instanciation, le projet destinataire possède ses fichiers, ses décisions et ses règles locales. Une évolution ultérieure de PGR ne modifie pas automatiquement ce projet.
|
||||
|
||||
## Applicabilité
|
||||
|
||||
Chaque skeleton MUST rendre explicites son objectif et les faits qui déterminent son applicabilité.
|
||||
|
||||
L'applicabilité MUST reposer sur le besoin réel du projet : type de baseline recherchée, langage ou écosystème utilisé, plateforme ciblée, framework réellement présent ou autre propriété concrète du scope.
|
||||
|
||||
Un skeleton MUST NOT être appliqué uniquement parce qu'il est fréquent, recommandé dans un autre projet ou disponible dans PGR.
|
||||
|
||||
Un skeleton spécialisé MAY déclarer un autre skeleton comme fondation. Cette relation doit être explicite et ne rend pas les spécialisations sœurs applicables entre elles.
|
||||
|
||||
## Contenu minimal d'une specification
|
||||
|
||||
Une skeleton specification MUST permettre d'identifier sans ambiguïté :
|
||||
|
||||
- son objectif et son applicabilité ;
|
||||
- les règles et profils sélectionnés ou requis ;
|
||||
- les autres skeletons dont elle dépend éventuellement pour sa composition ;
|
||||
- les fichiers à créer, copier, adapter ou omettre ;
|
||||
- les templates techniques utilisés et les décisions d'adaptation associées ;
|
||||
- les décisions obligatoires qui appartiennent au projet destinataire ;
|
||||
- les options, exceptions et overrides explicitement permis ;
|
||||
- l'ordre d'instanciation lorsque cet ordre est significatif ;
|
||||
- la validation initiale proportionnée ;
|
||||
- les éléments volontairement hors scope.
|
||||
|
||||
La structure Markdown exacte MAY varier si ces responsabilités restent clairement séparées. PGR MUST NOT imposer des sections vides uniquement pour respecter un format cérémoniel.
|
||||
|
||||
## Sélection des règles et profils
|
||||
|
||||
Un skeleton sélectionne les owners normatifs applicables ; il ne redéfinit pas leur contenu.
|
||||
|
||||
La sélection des profils MUST respecter l'applicabilité, la hiérarchie et la résolution définies dans [`../architecture/003-RULE_PROFILE_MODEL.md`](../architecture/003-RULE_PROFILE_MODEL.md).
|
||||
|
||||
Lorsqu'une règle générale est déjà applicable sans spécialisation, le skeleton SHOULD la référencer plutôt que la recopier comme si elle lui appartenait. Lors de l'instanciation, le projet destinataire doit néanmoins disposer localement des règles nécessaires à son fonctionnement autonome, sous la forme documentaire réellement adaptée à son propre référentiel.
|
||||
|
||||
Un skeleton MUST NOT sélectionner toute la bibliothèque PGR par défaut. Les profils ou familles sans rapport avec le projet restent absents.
|
||||
|
||||
## Templates et artefacts techniques
|
||||
|
||||
Un template reste un artefact technique copiable distinct du skeleton et de la règle qui justifie son usage.
|
||||
|
||||
Lorsqu'un skeleton utilise un template, il MUST identifier le template source et les valeurs qui doivent être revues ou adaptées avant adoption. Une valeur d'exemple, un placeholder, une version de toolchain, un nom de crate, un chemin de build ou un seuil de lint présent dans un template MUST NOT devenir une valeur universelle par simple copie.
|
||||
|
||||
Un skeleton MAY demander de copier un template tel quel seulement lorsque le contrat du template indique qu'aucune décision locale n'est requise pour le scope visé.
|
||||
|
||||
Un skeleton MUST NOT télécharger des dépendances, installer des toolchains ou exécuter implicitement des commandes externes à la place du projet destinataire. Ces opérations peuvent faire partie d'une validation explicitement demandée lorsque l'environnement et le scope les justifient.
|
||||
|
||||
## Décisions propres au projet
|
||||
|
||||
Toute décision qui ne découle pas d'une règle applicable ou d'une contrainte technique établie reste une décision du projet destinataire.
|
||||
|
||||
Le skeleton MUST distinguer une obligation normative d'une valeur d'exemple, d'un choix recommandé et d'une option libre lorsque cette distinction est nécessaire pour éviter une adoption accidentelle.
|
||||
|
||||
Les décisions nécessaires à une baseline fonctionnelle MUST être résolues ou laissées comme entrées explicites avant que l'instanciation soit présentée comme terminée. Un choix encore ouvert MUST NOT être converti silencieusement en règle ou valeur par défaut arbitraire.
|
||||
|
||||
Les décisions locales SHOULD être consignées dans les documents ou configurations qui les possèdent durablement dans le projet créé, et non uniquement dans une trace temporaire d'instanciation.
|
||||
|
||||
## Composition de plusieurs skeletons
|
||||
|
||||
La composition SHOULD partir de la fondation la plus générale explicitement requise, puis ajouter les spécialisations réellement applicables.
|
||||
|
||||
Un skeleton spécialisé SHOULD référencer les responsabilités déjà couvertes par sa fondation plutôt que les recopier. Il MAY ajouter des fichiers, décisions, templates ou validations propres à son scope.
|
||||
|
||||
L'ordre de composition ne crée aucune priorité normative implicite. Une règle plus spécifique ne remplace une règle plus générale que selon la hiérarchie normative, un profil applicable ou une exception explicitement documentée.
|
||||
|
||||
Si deux skeletons applicables exigent des choix incompatibles sans relation de spécialisation ou override défini, l'instanciation MUST s'arrêter sur cette décision au lieu de choisir arbitrairement le dernier appliqué.
|
||||
|
||||
PGR SHOULD NOT créer un skeleton composite pour chaque combinaison de technologies. Un skeleton composite n'est justifié que lorsqu'une interaction réelle possède des étapes, artefacts ou décisions qui ne peuvent pas être correctement possédés par les skeletons composants.
|
||||
|
||||
## Overrides et exceptions
|
||||
|
||||
Un override ou une exception MUST identifier la règle, le template, le choix ou l'étape concerné, son scope et sa raison.
|
||||
|
||||
Un skeleton MAY prévoir des points d'override lorsqu'ils correspondent à une variabilité légitime du projet. Il MUST NOT utiliser cette possibilité pour affaiblir silencieusement une règle applicable ou masquer une incompatibilité entre profils.
|
||||
|
||||
Une exception propre au projet est possédée par le projet destinataire après instanciation. Elle ne devient pas automatiquement une règle générale PGR.
|
||||
|
||||
## Validation de l'instanciation
|
||||
|
||||
Chaque skeleton MUST définir une validation initiale proportionnée à ce qu'il matérialise réellement.
|
||||
|
||||
La validation SHOULD utiliser le mécanisme le plus fiable disponible : parseur ou build tool officiel, linter, audit structurel read-only, test ciblé ou revue humaine selon la propriété à prouver.
|
||||
|
||||
Lorsqu'un skeleton prétend produire une baseline directement utilisable par une toolchain, une instanciation temporaire MAY être utilisée pour vérifier les fichiers copiés ou adaptés. Les ressources temporaires SHOULD être isolées et nettoyées après la gate.
|
||||
|
||||
La réussite d'un audit structurel ne remplace pas une validation de toolchain lorsque le contrat à prouver appartient à cette toolchain. Inversement, PGR SHOULD NOT imposer un build coûteux lorsqu'une propriété purement documentaire ou structurelle suffit à la tranche.
|
||||
|
||||
Une prévalidation réalisée lors de la préparation d'un delta ne remplace jamais la gate opérateur autoritaire définie par les règles de validation.
|
||||
|
||||
## Évolution
|
||||
|
||||
Une skeleton specification est un document vivant tant qu'elle reste la specification courante de son type de projet. Sa révision interne suit les règles documentaires PGR.
|
||||
|
||||
Modifier un skeleton PGR n'altère pas rétroactivement les projets déjà instanciés. Une migration depuis une ancienne baseline est une décision explicite du projet concerné.
|
||||
|
||||
PGR matérialise un nouveau skeleton uniquement lorsqu'un besoin réel, des owners normatifs suffisants et les artefacts nécessaires existent. Une technologie encore insuffisamment cadrée reste différée plutôt que représentée par un skeleton placeholder.
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/rules/300-DOCUMENTATION.md -->
|
||||
<!-- version: 1 -->
|
||||
<!-- version: 2 -->
|
||||
|
||||
# Documentation rules
|
||||
|
||||
@@ -165,6 +165,8 @@ La syntaxe de commentaire dépend du format. Pour Markdown :
|
||||
<!-- version: 1 -->
|
||||
```
|
||||
|
||||
Dans le dépôt PGR, `README.md`, `RULES.md`, `ROADMAP.md`, `CHANGELOG.md` et les fichiers Markdown gouvernés sous `docs/`, `deltas/`, `history/` et `prompts/` MUST placer ces deux commentaires sur leurs deux premières lignes. Le `file` MUST être le chemin relatif depuis la racine du dépôt et `version` MUST être un entier positif sans zéro initial. `scripts/audit_markdown_headers.py` contrôle mécaniquement ces deux champs pour les chemins explicitement sélectionnés. Ce contrôle ne juge ni le contenu du document, ni si le numéro de révision a réellement été incrémenté lors d'un changement.
|
||||
|
||||
`file` identifie le chemin relatif canonique du fichier.
|
||||
|
||||
`version` est une révision interne du fichier. Elle est indépendante de `VERSION`, de SemVer produit, des versions de protocole, de schema ou de package.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/rules/510-RUST_CARGO.md -->
|
||||
<!-- version: 1 -->
|
||||
<!-- version: 2 -->
|
||||
|
||||
# Profil Rust / Cargo
|
||||
|
||||
@@ -129,7 +129,11 @@ L'édition de ce fichier MUST rester cohérente avec l'édition réellement util
|
||||
|
||||
Après une modification Rust, `cargo fmt --all` applique le formatage canonique puis `cargo fmt --all -- --check` vérifie l'état livré. Une modification produite uniquement par le formatter officiel ne crée pas artificiellement une nouvelle révision documentaire d'un fichier si aucun contenu réel n'a changé.
|
||||
|
||||
Les micro-règles de mise en page qui ne sont pas communes aux corpus ou qui sont déjà correctement possédées par `rustfmt` ne sont pas élevées automatiquement au niveau PGR.
|
||||
Le profil de style strict supplémentaire peut être adopté par un projet qui souhaite appliquer les conventions KSP/Games. Dans ce scope choisi, les lignes vides consécutives SHOULD être supprimées, ainsi que les lignes vides à l'intérieur des fonctions/méthodes et des définitions `struct`/`enum`. Ces propriétés ne sont pas entièrement possédées par Rustfmt. L'audit facultatif `scripts/audit_rust_blank_lines.py` contrôle ces deux formes d'espacement sur les seuls fichiers Rust sélectionnés.
|
||||
|
||||
Les constantes de module qui constituent un bloc homogène sans ordre sémantique SHOULD être regroupées dans l'ordre `pub`, `pub(crate)`, privé, puis par nom dans chaque visibilité : aucune ligne vide entre constantes d'une même visibilité et exactement une entre niveaux différents. `scripts/audit_rust_const_blocks.py` vérifie cette convention uniquement sur les constantes au niveau racine des fichiers choisis. Son exécution requiert une sélection explicite des fichiers pour lesquels cet ordre est réellement souhaité. Une table de protocole, une séquence de migrations ou tout autre ordre contractuel conserve son ordre propre ; le lecteur ne doit pas réordonner une telle séquence pour faire passer l'audit.
|
||||
|
||||
L'ordre des `use`, réexports et déclarations `mod` que Rustfmt sait réordonner dans ses groupes appartient au formatteur ; les modules de test après les modules de production et l'organisation d'une façade relèvent de leur contrat local, avec revue ou audit dédié seulement si celui-ci apporte une preuve fiable. Les règles rustdoc et d'API conservent leurs propriétaires ci-dessus. Les scripts PGR ne prétendent pas parser toutes les macros ou les items Rust : une décision sémantique reste une revue.
|
||||
|
||||
## Configuration Cargo et artefacts générés
|
||||
|
||||
@@ -188,4 +192,4 @@ Lorsqu'une règle Rust devient objectivement automatisable dans un projet ou ske
|
||||
|
||||
Un éventuel wrapper d'orchestration MAY appeler plusieurs audits, mais chaque audit propriétaire doit conserver une responsabilité identifiable et rester read-only.
|
||||
|
||||
Aucun nouvel audit Rust n'est imposé par cette tranche à PGR lui-même : le dépôt PGR courant ne contient pas de workspace Rust sur lequel une telle gate fournirait une preuve réelle.
|
||||
Les deux audits de style disponibles sont documentés dans [`../validation/002-RUST_STYLE_AUDITS.md`](../validation/002-RUST_STYLE_AUDITS.md). Ils restent optionnels et prennent un corpus Rust explicitement sélectionné ; le dépôt PGR lui-même ne contient pas de workspace Rust sur lequel une telle gate fournirait une preuve réelle.
|
||||
|
||||
25
docs/skeletons/000-README.md
Normal file
25
docs/skeletons/000-README.md
Normal file
@@ -0,0 +1,25 @@
|
||||
<!-- file: docs/skeletons/000-README.md -->
|
||||
<!-- version: 3 -->
|
||||
|
||||
# Index des skeleton specifications PGR
|
||||
|
||||
Cette collection contient les recettes Markdown utilisées pour initialiser des baselines de projet ou composer plusieurs profils PGR sans transformer PGR en générateur.
|
||||
|
||||
Le contrat normatif commun des skeletons appartient à [`../rules/220-SKELETONS.md`](../rules/220-SKELETONS.md). Le modèle de composition des profils reste défini par [`../architecture/003-RULE_PROFILE_MODEL.md`](../architecture/003-RULE_PROFILE_MODEL.md).
|
||||
|
||||
## Rôle de la collection
|
||||
|
||||
Chaque specification concrète doit décrire un besoin réel et actionnable. Elle sélectionne les owners normatifs et templates nécessaires, rend visibles les décisions propres au projet, définit l'ordre de composition utile et fournit une validation initiale proportionnée.
|
||||
|
||||
Les fichiers techniques copiables ne vivent pas ici : ils restent sous `templates/`. Leurs guides d'adaptation restent sous `docs/templates/`. Les règles restent sous `docs/rules/`.
|
||||
|
||||
Une specification peut se composer avec une fondation plus générale, mais la collection ne duplique pas artificiellement une recette pour chaque combinaison possible de technologies.
|
||||
|
||||
## Specifications actives
|
||||
|
||||
- [`001-PROJECT_GOVERNANCE_FOUNDATION.md`](001-PROJECT_GOVERNANCE_FOUNDATION.md) — fondation composable pour établir la gouvernance locale, la version, la documentation minimale, le workflow retenu et sa validation initiale sans imposer d'architecture applicative.
|
||||
- [`002-RUST_CARGO_WORKSPACE.md`](002-RUST_CARGO_WORKSPACE.md) — specialization composable d'un workspace Rust/Cargo fondée sur `001`, les profils `500 + 510`, les cinq templates Rust/Cargo et une validation réelle de la toolchain.
|
||||
|
||||
Les familles Java/Android, Web, JNI, Tauri et autres domaines sans pièces suffisantes restent différées selon le plan [`../plans/004-V0_0_4_SKELETONS_PLAN.md`](../plans/004-V0_0_4_SKELETONS_PLAN.md).
|
||||
|
||||
Aucun fichier placeholder ne doit être ajouté pour réserver un skeleton futur.
|
||||
154
docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md
Normal file
154
docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md
Normal file
@@ -0,0 +1,154 @@
|
||||
<!-- file: docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Skeleton — Project governance foundation
|
||||
|
||||
## Objectif
|
||||
|
||||
Cette specification décrit une fondation composable pour un projet qui choisit d'adopter la gouvernance PGR sans sélectionner encore de langage, plateforme, framework ou architecture applicative.
|
||||
|
||||
Elle permet d'établir une baseline locale cohérente : identité de version, point d'entrée normatif, documentation réellement utile, workflow de changement effectivement retenu et validation initiale proportionnée.
|
||||
|
||||
Le contrat commun des skeletons appartient à [`../rules/220-SKELETONS.md`](../rules/220-SKELETONS.md). La présente specification sélectionne et adapte les owners généraux utiles ; elle n'en devient pas propriétaire.
|
||||
|
||||
## Applicabilité
|
||||
|
||||
Appliquer cette fondation lorsqu'un dépôt ou release unit veut utiliser PGR comme source de gouvernance locale et qu'aucune specialization technologique n'est nécessaire pour définir cette base commune.
|
||||
|
||||
Elle MAY servir de fondation à un skeleton spécialisé, qui ajoute ensuite uniquement les profils, templates, décisions et validations propres à son scope.
|
||||
|
||||
Ne pas l'appliquer comme cérémonie à un dépôt qui ne souhaite pas adopter le lifecycle ou les règles PGR. Elle ne transforme pas PGR en dépendance du projet destinataire.
|
||||
|
||||
## Owners sélectionnés
|
||||
|
||||
La fondation s'appuie sur les responsabilités PGR suivantes :
|
||||
|
||||
```text
|
||||
docs/rules/200-GOVERNANCE.md
|
||||
versioning, phases et discipline de changement
|
||||
|
||||
docs/rules/210-WORKFLOW.md
|
||||
plans, deltas, histories, commits de tranche et artefacts à la demande
|
||||
|
||||
docs/rules/300-DOCUMENTATION.md
|
||||
rôles documentaires, taxonomie, révisions et snapshots
|
||||
|
||||
docs/rules/400-VALIDATION.md
|
||||
preuves proportionnées, statuts de gate et autorité opérateur
|
||||
```
|
||||
|
||||
`docs/rules/220-SKELETONS.md` gouverne l'instanciation elle-même. Il n'est pas automatiquement une règle à recopier dans le projet destinataire si ce projet ne maintient pas sa propre collection de skeletons.
|
||||
|
||||
Aucun profil `500+` ou `600+` n'est sélectionné par cette fondation. Un skeleton spécialisé les ajoute seulement lorsqu'ils sont réellement applicables.
|
||||
|
||||
## Décisions destinataire avant matérialisation
|
||||
|
||||
Avant de considérer la fondation comme instanciée, résoudre explicitement les décisions suivantes :
|
||||
|
||||
1. identifier le release unit gouverné et sa version SemVer courante ;
|
||||
2. décider si le projet utilise le fichier racine `VERSION` comme repère canonique simple ;
|
||||
3. identifier les règles PGR réellement reprises et les adaptations locales nécessaires ;
|
||||
4. déterminer quels documents vivants ont une responsabilité réelle dès la baseline ;
|
||||
5. déterminer quels artefacts du workflow PGR sont effectivement utilisés et à partir de quel état gouverné ;
|
||||
6. sélectionner les validations disponibles qui prouvent réellement cette baseline ;
|
||||
7. consigner toute exception ou divergence intentionnelle dans le propriétaire local approprié.
|
||||
|
||||
Une décision non résolue MUST rester visible comme décision à prendre. Elle ne doit pas être remplacée par une valeur arbitraire provenant de PGR ou d'un autre projet.
|
||||
|
||||
## Baseline locale à matérialiser
|
||||
|
||||
### Point d'entrée normatif
|
||||
|
||||
Le projet destinataire MUST disposer d'un point d'entrée normatif local clairement identifiable. Lorsqu'il adopte la convention PGR, ce point d'entrée est `RULES.md`.
|
||||
|
||||
Ce document doit au minimum :
|
||||
|
||||
- déclarer le scope qu'il gouverne ;
|
||||
- identifier les owners généraux ou spécialisés réellement applicables ;
|
||||
- expliquer la priorité ou la spécialisation locale lorsqu'une adaptation existe ;
|
||||
- renvoyer vers les documents détaillés au lieu de recopier leur contenu sans nécessité.
|
||||
|
||||
Le projet doit rester autonome : ses règles nécessaires vivent dans son dépôt ou dans un mécanisme de dépendance documentaire explicitement choisi par lui. Une URL vers PGR ne remplace pas à elle seule une baseline locale exploitable.
|
||||
|
||||
### Version
|
||||
|
||||
Le release unit MUST posséder une version SemVer courante explicite conformément au contrat local retenu.
|
||||
|
||||
Si le fichier racine `VERSION` est choisi, l'instanciation doit le créer ou l'adapter selon [`../rules/200-GOVERNANCE.md`](../rules/200-GOVERNANCE.md). Si l'écosystème possède un autre owner canonique, la relation avec `VERSION` doit être décidée explicitement plutôt que dupliquée par défaut.
|
||||
|
||||
La valeur de version initiale appartient au projet destinataire. Cette specification ne fournit pas de numéro universel.
|
||||
|
||||
### Documentation minimale
|
||||
|
||||
`README.md` SHOULD fournir l'onboarding et les points d'entrée de premier niveau du projet.
|
||||
|
||||
Créer `docs/000-README.md` uniquement si une documentation structurée sous `docs/` existe réellement. Créer ensuite uniquement les collections possédant un premier contenu utile. Une collection vide ou un document placeholder n'est pas requis par cette fondation.
|
||||
|
||||
Selon la réalité du projet :
|
||||
|
||||
- `ROADMAP.md` est utile lorsqu'une trajectoire macro doit être rendue explicite ;
|
||||
- `CHANGELOG.md` est utile lorsque des changements de release doivent être communiqués aux utilisateurs ou intégrateurs ;
|
||||
- `docs/objectives/` est utile lorsqu'une mission durable, des contraintes ou non-objectifs méritent un owner distinct ;
|
||||
- `docs/architecture/` est utile lorsqu'un état architectural ou un profil local doit être possédé durablement ;
|
||||
- `docs/validation/` est utile lorsqu'une matrice ou un contrat de preuve mérite un document séparé.
|
||||
|
||||
Ne pas créer ces fichiers uniquement pour reproduire l'arborescence du dépôt PGR.
|
||||
|
||||
### Workflow retenu
|
||||
|
||||
Si le projet adopte le workflow de tranches PGR, il doit préserver la séquence définie par [`../rules/210-WORKFLOW.md`](../rules/210-WORKFLOW.md) : intention prospective dans le delta, gate réelle, preuve rétrospective dans le history, puis commit de tranche avant application du delta suivant.
|
||||
|
||||
Les répertoires `deltas/`, `history/`, `prompts/`, `handoffs/` et `manifests/` sont créés à la demande lorsqu'un artefact réel les justifie. Ils ne constituent pas un layout obligatoire à précréer.
|
||||
|
||||
Un projet qui n'adopte qu'une partie du workflow PGR doit l'indiquer dans ses règles locales et ne pas présenter les artefacts omis comme s'ils étaient encore obligatoires.
|
||||
|
||||
### Validation initiale
|
||||
|
||||
La validation de la fondation doit prouver seulement les propriétés réellement matérialisées. Elle SHOULD combiner selon le scope :
|
||||
|
||||
```text
|
||||
CHECK version courante conforme au mécanisme choisi
|
||||
CHECK git diff --check ou équivalent du VCS retenu
|
||||
AUDIT chemins et rôles documentaires réellement créés
|
||||
AUDIT liens locaux principaux si la navigation Markdown a été modifiée
|
||||
AUDIT owners sélectionnés et exceptions locales explicites
|
||||
REVIEW absence de collections, profils ou placeholders non justifiés
|
||||
```
|
||||
|
||||
Si le projet possède déjà des audits fiables pour ses headers, liens, structure ou règles, ils MAY être ajoutés. Cette fondation n'impose pas de copier les scripts du dépôt PGR sans décision explicite de réutilisation.
|
||||
|
||||
La prévalidation qui accompagne une instanciation ou un delta ne remplace pas la gate opérateur autoritaire du projet destinataire.
|
||||
|
||||
## Ordre de composition
|
||||
|
||||
Cette fondation SHOULD être appliquée avant une specialization qui la déclare comme base.
|
||||
|
||||
Une specialization technologique peut ensuite :
|
||||
|
||||
- sélectionner ses familles et profils applicables ;
|
||||
- copier ou adapter les templates techniques correspondants ;
|
||||
- ajouter ses décisions spécifiques ;
|
||||
- étendre la validation initiale avec la toolchain réellement concernée.
|
||||
|
||||
Elle MUST NOT redéfinir les responsabilités générales déjà possédées par la fondation sauf specialization ou override explicitement justifié.
|
||||
|
||||
## Overrides et exceptions
|
||||
|
||||
Un projet MAY adapter la structure documentaire, le mécanisme de version, le VCS, le workflow ou une convention PGR lorsqu'une contrainte réelle le justifie et que l'owner local reste clair.
|
||||
|
||||
Une exception doit identifier son scope et sa raison. Elle ne devient pas une règle générale PGR et ne doit pas être masquée par la simple copie d'un fichier provenant de PGR.
|
||||
|
||||
## Hors scope
|
||||
|
||||
Cette fondation ne définit pas :
|
||||
|
||||
- l'architecture applicative ou les crates/modules/packages du produit ;
|
||||
- un langage, une plateforme, un framework ou une toolchain ;
|
||||
- des noms de package, versions de dépendances ou chemins de build ;
|
||||
- des templates techniques génériques inexistants ;
|
||||
- un CI/CD universel ;
|
||||
- une politique de branching universelle ;
|
||||
- une obligation de recopier la structure complète du dépôt PGR ;
|
||||
- la migration rétroactive des anciennes releases ou anciens commits du projet destinataire.
|
||||
|
||||
Les spécialisations futures doivent rester indépendantes et composables au-dessus de cette fondation.
|
||||
206
docs/skeletons/002-RUST_CARGO_WORKSPACE.md
Normal file
206
docs/skeletons/002-RUST_CARGO_WORKSPACE.md
Normal file
@@ -0,0 +1,206 @@
|
||||
<!-- file: docs/skeletons/002-RUST_CARGO_WORKSPACE.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Skeleton — Rust/Cargo workspace
|
||||
|
||||
## Objectif
|
||||
|
||||
Cette specification décrit la specialization Rust/Cargo d'un projet gouverné par PGR lorsque plusieurs packages Rust partagent réellement une même unité de release, une politique Cargo commune ou une validation de workspace commune.
|
||||
|
||||
Elle se compose avec [`001-PROJECT_GOVERNANCE_FOUNDATION.md`](001-PROJECT_GOVERNANCE_FOUNDATION.md), sélectionne les profils [`../rules/500-LANGUAGES.md`](../rules/500-LANGUAGES.md) et [`../rules/510-RUST_CARGO.md`](../rules/510-RUST_CARGO.md), puis utilise les templates et guides Rust/Cargo déjà présents dans PGR. Le contrat transversal des skeletons reste possédé par [`../rules/220-SKELETONS.md`](../rules/220-SKELETONS.md).
|
||||
|
||||
Cette specification ne transforme pas PGR en générateur Cargo et ne crée aucune dépendance build ou runtime vers le dépôt PGR après instanciation.
|
||||
|
||||
## Applicabilité et composition
|
||||
|
||||
Appliquer ce skeleton lorsqu'un projet utilise Rust avec Cargo et qu'un workspace représente réellement son unité de gouvernance ou de release.
|
||||
|
||||
La composition normale est :
|
||||
|
||||
```text
|
||||
001-PROJECT_GOVERNANCE_FOUNDATION
|
||||
↓
|
||||
500-LANGUAGES
|
||||
↓
|
||||
510-RUST_CARGO
|
||||
↓
|
||||
002-RUST_CARGO_WORKSPACE
|
||||
```
|
||||
|
||||
Un dépôt contenant plusieurs unités de release indépendantes ne doit pas être forcé dans un workspace à version globale fictive. Un framework, une plateforme, WASM, Android, Tauri, une FFI ou un autre scope plus spécifique peut ajouter ses propres règles sans modifier le contrat Rust/Cargo général.
|
||||
|
||||
## Owners, guides et artefacts sélectionnés
|
||||
|
||||
Les responsabilités générales de version, workflow, documentation et validation sont déjà couvertes par la fondation `001`. La présente specialization ajoute :
|
||||
|
||||
```text
|
||||
docs/rules/500-LANGUAGES.md
|
||||
contrat commun langage/écosystème
|
||||
|
||||
docs/rules/510-RUST_CARGO.md
|
||||
workspace, manifests, dépendances, lints, safety, formatage et validation Cargo
|
||||
|
||||
docs/templates/001-RUST_CARGO_TOOLING.md
|
||||
adaptation de rustfmt.toml, clippy.toml et .cargo/config.toml
|
||||
|
||||
docs/templates/002-CARGO_MANIFESTS.md
|
||||
adaptation du manifest workspace et du manifest membre
|
||||
```
|
||||
|
||||
Les cinq artefacts techniques copiables sélectionnés sont :
|
||||
|
||||
```text
|
||||
templates/rust-cargo/rustfmt.toml
|
||||
templates/rust-cargo/clippy.toml
|
||||
templates/rust-cargo/.cargo/config.toml
|
||||
templates/rust-cargo/Cargo.toml
|
||||
templates/rust-cargo/crates/project-core-lib/Cargo.toml
|
||||
```
|
||||
|
||||
[`../validation/002-RUST_STYLE_AUDITS.md`](../validation/002-RUST_STYLE_AUDITS.md) est seulement une option supplémentaire. Les scripts `audit_rust_blank_lines.py`, `audit_rust_const_blocks.py` et `_rust_audit_common.py` ne sont copiés que si le projet choisit explicitement les conventions correspondantes et sait quels fichiers Rust doivent être audités.
|
||||
|
||||
## Décisions destinataire avant copie
|
||||
|
||||
Avant de considérer la specialization comme instanciée, résoudre explicitement au minimum :
|
||||
|
||||
1. le release unit gouverné et la relation entre son `VERSION` et `[workspace.package].version` ;
|
||||
2. la liste réelle des packages membres, leurs noms, leurs rôles et leurs chemins ;
|
||||
3. l'édition Rust, le resolver Cargo et la toolchain stable compatible ;
|
||||
4. la politique de publication et les métadonnées réelles communes (`license`, `repository`, `authors`) lorsqu'elles existent ;
|
||||
5. les dépendances réellement partagées, leurs contraintes de version et les features qui doivent rester locales à chaque membre ;
|
||||
6. la politique de versionnement de `Cargo.lock` adaptée au type de produit ;
|
||||
7. les niveaux de lints hérités, les éventuelles exceptions locales et tout besoin réel d'`unsafe` dans un scope étroit ;
|
||||
8. les paramètres `rustfmt.toml` et `clippy.toml` à conserver ou adapter ;
|
||||
9. l'emplacement des artefacts Cargo et l'identifiant unique utilisé dans `.cargo/config.toml` si cette politique externe au dépôt est retenue ;
|
||||
10. les audits de style Rust facultatifs réellement adoptés et leur corpus exact ;
|
||||
11. les validations Cargo réellement nécessaires au code et aux manifests créés.
|
||||
|
||||
Les valeurs `0.1.0`, `2024`, `project-name`, `project-core-lib`, les seuils Clippy et les chemins de build présents dans les templates sont des exemples ou baselines à revoir. Ils ne deviennent jamais des valeurs universelles par simple copie.
|
||||
|
||||
## Matérialisation du workspace
|
||||
|
||||
### Fondation gouvernée
|
||||
|
||||
Appliquer d'abord la fondation `001` et résoudre ses décisions générales. Ne recopier ni le workflow ni la structure documentaire complète de PGR lorsqu'ils ne sont pas nécessaires au projet destinataire.
|
||||
|
||||
La version canonique du release unit doit être décidée avant d'adapter les manifests. Pour un train de release Cargo unique, `[workspace.package].version` reflète cette version selon `510-RUST_CARGO.md`.
|
||||
|
||||
### Manifest workspace
|
||||
|
||||
Copier `templates/rust-cargo/Cargo.toml` vers `Cargo.toml`, puis :
|
||||
|
||||
- adapter le header `# file:` et démarrer la révision locale selon la convention documentaire retenue ;
|
||||
- remplacer `members` par les packages réellement présents ;
|
||||
- remplacer la version d'exemple par la version du release unit lorsque le workspace partage une seule release ;
|
||||
- aligner `edition` et `resolver` sur la toolchain réellement choisie ;
|
||||
- décider explicitement `publish` et les métadonnées communes ;
|
||||
- ajouter sous `[workspace.dependencies]` uniquement les dépendances réellement partagées ;
|
||||
- conserver, adapter ou documenter les niveaux de lints selon le profil local retenu.
|
||||
|
||||
Le projet ne doit pas remplir les champs manquants avec des identités fictives provenant de PGR, KSP ou Games.
|
||||
|
||||
### Packages membres
|
||||
|
||||
Pour chaque crate réellement nécessaire, utiliser `templates/rust-cargo/crates/project-core-lib/Cargo.toml` comme exemple de manifest membre puis adapter son chemin et son nom.
|
||||
|
||||
`project-core-lib` n'est pas un nom de crate imposé. Une crate bibliothèque, binaire ou spécialisée doit conserver le layout et les héritages qui correspondent à son rôle réel.
|
||||
|
||||
Lorsque le membre hérite de la politique commune, `version.workspace = true`, `edition.workspace = true`, `publish.workspace = true` et `[lints] workspace = true` restent cohérents. Une exception locale, notamment de lint ou de safety, doit suivre le contrat de `510-RUST_CARGO.md` et ne pas affaiblir silencieusement les autres membres.
|
||||
|
||||
Le code source minimal requis par Cargo appartient au projet destinataire. PGR ne fournit pas de `src/lib.rs` ou `src/main.rs` universel, car leur contenu dépend du rôle réel de la crate.
|
||||
|
||||
### Outillage Rust/Cargo
|
||||
|
||||
Copier et adapter :
|
||||
|
||||
```text
|
||||
rustfmt.toml
|
||||
clippy.toml
|
||||
.cargo/config.toml
|
||||
```
|
||||
|
||||
Suivre [`../templates/001-RUST_CARGO_TOOLING.md`](../templates/001-RUST_CARGO_TOOLING.md) pour leurs décisions d'adaptation.
|
||||
|
||||
L'édition de `rustfmt.toml` doit rester cohérente avec le workspace. Les seuils de `clippy.toml` doivent être revus au regard des API réelles. Dans `.cargo/config.toml`, remplacer `project-name` ou choisir un autre emplacement d'artefacts ; ne pas copier un chemin machine ou un identifiant appartenant à un autre projet.
|
||||
|
||||
### Cargo.lock
|
||||
|
||||
Décider explicitement si `Cargo.lock` est versionné selon le type de produit, le mode de publication et le besoin de reproductibilité. La présence ou l'absence du lockfile dans un projet source historique ne constitue pas une règle suffisante pour le nouveau workspace.
|
||||
|
||||
### Audits de style facultatifs
|
||||
|
||||
Si le projet adopte les conventions documentées dans [`../validation/002-RUST_STYLE_AUDITS.md`](../validation/002-RUST_STYLE_AUDITS.md), copier les trois scripts concernés et adapter leurs headers à leurs chemins locaux.
|
||||
|
||||
La sélection des fichiers doit rester explicite. En particulier, l'audit des blocs de constantes ne doit jamais réordonner une table de protocole, une séquence de migrations ou toute autre structure dont l'ordre possède une sémantique propre.
|
||||
|
||||
Ne pas copier ces scripts uniquement parce qu'ils existent dans PGR.
|
||||
|
||||
## Validation initiale
|
||||
|
||||
Une instanciation minimale doit d'abord prouver que les manifests adaptés décrivent bien le workspace voulu, puis que les outils Rust/Cargo retenus acceptent la baseline réelle.
|
||||
|
||||
Lorsque la toolchain est disponible et que du code source minimal ou réel existe, la séquence normale comprend :
|
||||
|
||||
```bash
|
||||
cargo metadata --format-version 1 --no-deps
|
||||
cargo fmt --all -- --check
|
||||
cargo check --workspace
|
||||
cargo clippy --workspace --all-targets --all-features -- -D warnings
|
||||
```
|
||||
|
||||
Ajouter des tests ciblés pour les crates qui possèdent déjà un comportement à vérifier. Un `cargo build` n'est nécessaire que lorsqu'un artefact de build doit réellement être produit.
|
||||
|
||||
Si les audits de style facultatifs ont été sélectionnés, les exécuter après le formatage sur les seuls chemins concernés.
|
||||
|
||||
La validation doit aussi confirmer :
|
||||
|
||||
```text
|
||||
CHECK VERSION et workspace.package.version cohérents pour un train de release unique
|
||||
CHECK aucun placeholder project-name/project-core-lib non résolu dans les fichiers adoptés
|
||||
CHECK édition Rust cohérente entre Cargo.toml et rustfmt.toml
|
||||
CHECK membres du workspace existants et correctement nommés
|
||||
CHECK politique Cargo.lock explicitement décidée
|
||||
CHECK artefacts Cargo hors des livraisons source selon la politique locale
|
||||
REVIEW dépendances/features, lints et métadonnées réellement nécessaires
|
||||
REVIEW aucune specialization plateforme/framework ajoutée sans besoin réel
|
||||
```
|
||||
|
||||
Pour valider les templates PGR eux-mêmes, une instanciation temporaire minimale peut remplacer les placeholders, créer une crate source triviale et exécuter les commandes Cargo ci-dessus. Cette preuve vérifie l'adoption des templates sans transformer le dépôt PGR en workspace Rust.
|
||||
|
||||
Une prévalidation PGR ou générateur ne remplace jamais la gate opérateur autoritaire du projet destinataire.
|
||||
|
||||
## Ordre de composition et extensions
|
||||
|
||||
La specialization Rust/Cargo doit être appliquée après `001` lorsqu'elle l'utilise comme fondation. Les profils plateforme ou framework viennent ensuite uniquement s'ils sont applicables.
|
||||
|
||||
Une specialization plus précise peut :
|
||||
|
||||
- ajouter des packages ou cibles spécifiques ;
|
||||
- imposer une matrice de toolchain ou de SDK ;
|
||||
- raffiner la politique d'artefacts ou de lockfile ;
|
||||
- ajouter des features, dépendances ou validations propres à son scope ;
|
||||
- définir une exception locale de safety strictement justifiée.
|
||||
|
||||
Elle ne doit pas réécrire les règles générales Cargo ou inventer un nouveau workspace composite si les owners existants suffisent.
|
||||
|
||||
## Overrides et exceptions
|
||||
|
||||
Toute divergence par rapport aux templates ou au profil `510` doit identifier le choix concerné, son scope et sa raison lorsqu'elle affecte le contrat durable du projet.
|
||||
|
||||
Un projet peut notamment choisir un layout sans `crates/`, un autre chemin d'artefacts, une autre largeur Rustfmt, une politique de lockfile différente, des seuils Clippy différents ou une crate à lints locaux. Ces choix restent locaux et ne modifient pas les defaults PGR pour les autres projets.
|
||||
|
||||
## Hors scope
|
||||
|
||||
Cette specification ne définit pas :
|
||||
|
||||
- un nom universel de workspace ou de crate ;
|
||||
- une version Rust ou Cargo exacte à pinner sans justification ;
|
||||
- une liste universelle de dépendances ou features ;
|
||||
- une politique `Cargo.lock` identique pour bibliothèques et applications ;
|
||||
- une architecture applicative au-delà du workspace Cargo ;
|
||||
- une plateforme, un framework, WASM, Android, Tauri ou une FFI ;
|
||||
- un CI/CD, packaging ou mécanisme de publication universel ;
|
||||
- une obligation de copier les audits Rust facultatifs ;
|
||||
- un `src/lib.rs` ou `src/main.rs` générique sans rôle réel.
|
||||
|
||||
Les spécialisations futures doivent rester composables au-dessus de ce skeleton plutôt que modifier rétroactivement son scope.
|
||||
45
docs/templates/001-RUST_CARGO_TOOLING.md
vendored
Normal file
45
docs/templates/001-RUST_CARGO_TOOLING.md
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
<!-- file: docs/templates/001-RUST_CARGO_TOOLING.md -->
|
||||
<!-- version: 3 -->
|
||||
|
||||
# Templates d'outillage Rust/Cargo
|
||||
|
||||
## Rôle et sélection
|
||||
|
||||
Ces trois fichiers fournissent une baseline de configuration issue des conventions réellement utilisées dans KSP et Games. Ils s'appliquent à un projet Rust/Cargo qui choisit ce profil d'outillage ; ils ne créent pas une dépendance vers PGR après copie.
|
||||
|
||||
- [`rustfmt.toml`](../../templates/rust-cargo/rustfmt.toml) — formatage canonique, avec notamment largeur `160` et édition `2024` dans l'exemple ;
|
||||
- [`clippy.toml`](../../templates/rust-cargo/clippy.toml) — paramètres de lints (seuils, exceptions de tests, identifiants courts) issus du noyau partagé des deux projets ;
|
||||
- [`.cargo/config.toml`](../../templates/rust-cargo/.cargo/config.toml) — emplacements des artefacts Cargo hors de la racine source.
|
||||
|
||||
Les niveaux `deny`, `allow`, `warn` et `forbid` des lints Rust/Clippy appartiennent au `Cargo.toml` du workspace, selon [`510-RUST_CARGO.md`](../rules/510-RUST_CARGO.md). `clippy.toml` règle des paramètres de lints, pas leur niveau. Les deux modèles Cargo et l'héritage `[lints] workspace = true` sont documentés dans [`002-CARGO_MANIFESTS.md`](002-CARGO_MANIFESTS.md).
|
||||
|
||||
## Copier et adapter
|
||||
|
||||
Copier ces fichiers aux chemins suivants dans le projet destinataire :
|
||||
|
||||
```text
|
||||
rustfmt.toml
|
||||
clippy.toml
|
||||
.cargo/config.toml
|
||||
```
|
||||
|
||||
Adapter le header `# file:` de chacun à son nouveau chemin relatif. Comme il s'agit de nouveaux fichiers locaux, leur révision interne commence à `1` si le projet suit cette convention. Vérifier les choix avant de les utiliser :
|
||||
|
||||
1. `rustfmt.toml` : aligner `edition` sur l'édition déclarée dans le manifeste du projet. La largeur et les autres options constituent la convention de départ de KSP/Games et peuvent être ajustées pour le projet ;
|
||||
2. `clippy.toml` : revoir les seuils au regard des types et API du projet ; adapter `allowed-idents-below-min-chars` à ses abréviations réelles. Les exceptions `allow-*-in-tests` sont une décision explicite du profil retenu ; elles ne relâchent pas les lints de production ;
|
||||
3. `.cargo/config.toml` : remplacer `project-name` par un identifiant propre au projet pour éviter la collision de deux workspaces sous `../builds/`. Depuis une configuration placée dans `<racine>/.cargo/`, Cargo résout ici les chemins relatifs par rapport à `<racine>/` : la sortie se trouve donc sous le dossier frère `<parent>/builds/<projet>/target/` ;
|
||||
4. conserver les deux entrées `target-dir` et `build-dir` lorsque cette politique est choisie. Elles ciblent volontairement le même dossier, même si Cargo utilise actuellement `target-dir` comme valeur par défaut de `build-dir` ;
|
||||
5. ajouter séparément les flags de cible, chemins particuliers ou ajustements Clippy nécessaires à un projet. Les flags Web présents dans Games ne sont pas un défaut de tous les projets Rust.
|
||||
|
||||
Le chemin de sortie sous `builds/` est externe au dépôt source ; il ne doit pas être inclus dans les archives du projet. Si l'environnement impose un autre emplacement, ajuster la configuration du projet au lieu de copier un chemin machine depuis KSP ou Games.
|
||||
|
||||
## Validation dans un projet Rust
|
||||
|
||||
Après adaptation, les contrôles utiles dépendent du code et des manifests effectivement présents :
|
||||
|
||||
```bash
|
||||
cargo fmt --all -- --check
|
||||
cargo clippy --workspace --all-targets --all-features -- -D warnings
|
||||
```
|
||||
|
||||
Vérifier l'emplacement effectif des artefacts sur un build ou un check pertinent. La validation de PGR lui-même peut vérifier la syntaxe TOML et la cohérence des chemins sans demander de compiler un workspace Rust absent de son dépôt.
|
||||
47
docs/templates/002-CARGO_MANIFESTS.md
vendored
Normal file
47
docs/templates/002-CARGO_MANIFESTS.md
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
<!-- file: docs/templates/002-CARGO_MANIFESTS.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Modèles de manifests Cargo workspace et crate membre
|
||||
|
||||
## Rôle des deux fichiers
|
||||
|
||||
Le [manifest racine](../../templates/rust-cargo/Cargo.toml) est celui d'un workspace virtuel à une unité de release ; le [manifest membre](../../templates/rust-cargo/crates/project-core-lib/Cargo.toml) montre une crate bibliothèque ordinaire. Les deux fichiers forment un exemple TOML syntaxiquement valide. Après copie dans un nouveau projet, il faut aussi fournir le code source de la crate avant de demander à Cargo de la compiler. Le dépôt PGR ne devient pas lui-même un workspace Cargo.
|
||||
|
||||
Ces modèles prolongent les trois configurations de [`001-RUST_CARGO_TOOLING.md`](001-RUST_CARGO_TOOLING.md). Le propriétaire des choix normatifs reste [`510-RUST_CARGO.md`](../rules/510-RUST_CARGO.md). Les chemins `project-core-lib`, le nom du package et la version `0.1.0` sont des **valeurs d'exemple à remplacer** : cette version ne reflète pas `VERSION` de PGR et ne définit pas la version d'un autre projet.
|
||||
|
||||
## Adopter le manifest racine
|
||||
|
||||
Copier `templates/rust-cargo/Cargo.toml` vers `Cargo.toml` du projet, corriger son header `# file:` et commencer sa propre révision de fichier à `1`. Adapter `members` aux répertoires qui existent effectivement, puis choisir la version canonique de l'unité de release. Lorsque toutes les crates partagent une seule release, aligner `[workspace.package].version` sur le `VERSION` de ce projet ; plusieurs unités de release indépendantes ne doivent pas hériter d'une version fictive commune.
|
||||
|
||||
L'édition `2024` et `resolver = "3"` sont cohérents avec l'exemple [`rustfmt.toml`](../../templates/rust-cargo/rustfmt.toml). Pour un workspace virtuel, fixer explicitement le resolver souhaité ; adapter ensemble l'édition, Rustfmt et la toolchain compatible si le projet prend d'autres valeurs. `publish = false` est un défaut prudent pour cet exemple ; définir la politique de publication réelle avant de publier une crate.
|
||||
|
||||
`license`, `repository` et `authors` ne sont volontairement pas renseignés avec des identités fictives. Si ces métadonnées ont une valeur vraie et commune, les déclarer dans `[workspace.package]` et les hériter explicitement dans chaque crate concernée, par exemple `license.workspace = true` seulement après avoir déclaré `license` à la racine. Ne pas imposer un auteur, une licence ou une URL propres à KSP/Games.
|
||||
|
||||
Le bloc `[workspace.dependencies]` est vide tant qu'aucune dépendance concrète ne sert plusieurs crates. Déclarer à la racine seulement les contraintes et features réellement communes ; les features propres à un membre sont activées sur sa dépendance locale. Cargo ajoute les features demandées au membre à celles déjà sélectionnées au workspace ; éviter d'activer globalement une feature de test ou de plateforme par facilité. Les dépendances de test appartiennent à `[dev-dependencies]` du membre qui les utilise.
|
||||
|
||||
Les trois lints Rust et les `18` niveaux Clippy reprennent la politique partagée observée dans KSP et Games. Les `allow` retiennent leurs choix de style explicite, notamment `needless_return` malgré `implicit_return = "deny"`, et évitent qu'un lint de suggestion réécrive systématiquement ce style. Réviser leur pertinence pour le projet avant adoption. Les seuils et réglages supplémentaires appartiennent au [`clippy.toml`](../../templates/rust-cargo/clippy.toml) distinct : ce fichier ne définit aucun niveau de lint.
|
||||
|
||||
## Adopter le manifest membre
|
||||
|
||||
Copier le membre vers `crates/<nom>/Cargo.toml`, adapter `name`, son chemin dans `members` et le header `# file:`. `version.workspace = true`, `edition.workspace = true` et `publish.workspace = true` rendent visibles les héritages choisis ; ajouter séparément `license.workspace = true`, `repository.workspace = true` ou `authors.workspace = true` si les valeurs existent à la racine et concernent cette crate. `[lints] workspace = true` est requis pour reprendre les niveaux du workspace : leur présence à la racine ne suffit pas à les appliquer automatiquement aux membres.
|
||||
|
||||
Le bloc `[dependencies]` vide se remplit selon les besoins de la crate. Pour une dépendance déjà déclarée sous `[workspace.dependencies]`, utiliser localement `nom = { workspace = true }`, avec `features = [...]` au besoin. Pour une dépendance strictement locale, choisir sa contrainte directement dans ce membre ; aucune liste tierce arbitraire n'est copiée par ce modèle.
|
||||
|
||||
Une application binaire peut reprendre les mêmes héritages après adaptation du nom, du layout et de sa cible `src/main.rs` ; ne pas fabriquer un deuxième manifest quasi identique. Une crate à version ou politique de publication réellement indépendante doit déclarer ses valeurs locales et ne plus hériter ces champs par automatisme.
|
||||
|
||||
## Exception locale de lints
|
||||
|
||||
Une frontière FFI peut avoir besoin de `unsafe_code = "allow"` dans une crate particulière, comme l'entrée Android observée dans Games. Cette exception demande justification, portée étroite et validation du code `unsafe` concerné. Cargo ne permet pas de combiner `workspace = true` avec des définitions de lints locaux dans le même manifest membre : retirer l'héritage `[lints]` pour cette crate et déclarer localement `[lints.rust]` ainsi que `[lints.clippy]`, en recopiant les niveaux partagés réellement conservés puis en ajustant seulement l'exception motivée. Les autres membres continuent d'hériter des lints racine.
|
||||
|
||||
## Vérification dans le projet destinataire
|
||||
|
||||
Après avoir ajouté le code source nécessaire, vérifier d'abord la résolution des manifests et les héritages, puis les contrôles réellement applicables :
|
||||
|
||||
```bash
|
||||
cargo metadata --format-version 1 --no-deps
|
||||
cargo fmt --all -- --check
|
||||
cargo check --workspace
|
||||
cargo clippy --workspace --all-targets --all-features -- -D warnings
|
||||
```
|
||||
|
||||
Vérifier séparément le cas d'une crate à lints locaux lorsque le projet comporte réellement une exception. `Cargo.lock` et les artefacts créés par ces commandes suivent la politique du projet et la configuration Cargo de [`001-RUST_CARGO_TOOLING.md`](001-RUST_CARGO_TOOLING.md).
|
||||
29
docs/templates/003-NEW_SESSION_PROMPT.md
vendored
Normal file
29
docs/templates/003-NEW_SESSION_PROMPT.md
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
<!-- file: docs/templates/003-NEW_SESSION_PROMPT.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Spécification du prompt manuel de nouvelle session
|
||||
|
||||
## Usage
|
||||
|
||||
Cette spécification sert à préparer un court message de reprise après une stable publiée. Le prompt de démarrage propre à la version suivante reste un fichier `prompts/NNN-VX_Y_Z_START_PROMPT.md` finalisé selon [`210-WORKFLOW.md`](../rules/210-WORKFLOW.md). Le message manuel indique où commencer et quelles preuves fournir ; il ne copie ni ce prompt, ni le plan, ni le history de la release.
|
||||
|
||||
La comparaison des prompts PGR `002` et `003` montre une structure récurrente (baseline taggée, cible, première tranche et mission). `003` ajoute le rapport de vérification post-tag et un texte transmis explicitement à l'opérateur. Une forme courte commune réduit les oublis lors de la clôture suivante, sans rendre obligatoires des champs propres à PGR dans les autres projets.
|
||||
|
||||
## Champs à renseigner
|
||||
|
||||
1. **Baseline** : identifier le tag stable, le nom réel de l'archive source téléchargée depuis ce tag et la forge d'origine. Une archive sans `.git` demande une vérification interne ; elle ne prouve pas à elle seule le commit du tag.
|
||||
2. **Preuve post-tag** : si un rapport de publication/vérification distinct existe et est réellement `PASS`, indiquer son chemin exact et le joindre. Sinon, signaler explicitement qu'il est absent ou que son état n'est pas `PASS` ; ne jamais fabriquer cette preuve ni la confondre avec le tag.
|
||||
3. **Contrat de reprise** : indiquer le chemin du prompt `prompts/NNN-VX_Y_Z_START_PROMPT.md` existant dans la baseline, la version cible et la première tranche attendue. Le prompt versionné possède la mission détaillée et le scope de la release.
|
||||
4. **Intake** : demander la vérification de l'archive, des règles applicables, de la gouvernance, de la structure documentaire et des deltas/histories avant de préparer la première tranche. Adapter la liste aux artefacts effectivement présents et aux risques du projet.
|
||||
|
||||
## Forme à remplir et à remettre
|
||||
|
||||
Après vérification des chemins et de l'état réel du rapport, écrire **une seule phrase** adaptée au projet. Si le rapport est `PASS` et fourni :
|
||||
|
||||
```text
|
||||
Partir de l'archive <nom exact du ZIP issu du tag vX.Y.Z> et du rapport post-tag <chemin exact du rapport PASS>. Lire et exécuter <chemin du prompt de démarrage dans la baseline>. Vérifier l'archive, les règles, la gouvernance, la structure documentaire, les deltas/histories et la cohérence globale avant de préparer <version cible-alpha.1>.
|
||||
```
|
||||
|
||||
Si le rapport est absent ou non validé, retirer « et du rapport post-tag ... » de la phrase et préciser séparément son état réel à la nouvelle session. Conserver les noms exacts de la forge et des fichiers du projet : la forme `<nom exact du ZIP>` n'est qu'un champ de rédaction.
|
||||
|
||||
Rédiger le texte manuel à la clôture après le contrôle de l'archive publiée et le remettre à l'opérateur. Une interruption au milieu d'une prerelease suit le mécanisme de reprise de la tranche courante prévu dans `210-WORKFLOW.md` ; elle ne crée pas artificiellement un nouveau prompt de version.
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/validation/001-VALIDATION_MATRIX.md -->
|
||||
<!-- version: 6 -->
|
||||
<!-- version: 9 -->
|
||||
|
||||
# Matrice de validation PGR
|
||||
|
||||
@@ -14,13 +14,14 @@ Les catégories et règles de sélection sont définies dans [`../rules/400-VALI
|
||||
## Contrôles actifs
|
||||
|
||||
| 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-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-DOC-001` | `AUDIT` | vérifier headers `file/version`, chemins 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 chemins, rôles et responsabilités des documents touchés | fichiers documentaires | modification documentaire | alpha/beta/RC/stable | faible | opérateur/revue |
|
||||
| `PGR-MD-HEADER-001` | `AUDIT` | `python3 -B scripts/audit_markdown_headers.py <paths...>` | Python 3 | Markdown gouverné modifié | alpha/beta/RC/stable | faible | opérateur/CI |
|
||||
| `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` | `python3 -B scripts/audit_markdown_links.py <paths...>` | Python 3 | navigation ou réconciliation | beta/RC/stable | faible | opérateur/CI |
|
||||
| `PGR-NAV-001` | `AUDIT` | `python3 -B scripts/audit_markdown_links.py <paths...>` | Python 3 | navigation ou réconciliation | alpha/beta/RC/stable | faible | opérateur/CI |
|
||||
| `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 |
|
||||
|
||||
@@ -28,10 +29,18 @@ Un contrôle manuel peut rester dans la matrice lorsqu'aucun audit automatisé f
|
||||
|
||||
`PGR-MD-TABLE-001` reste volontairement monotâche : il contrôle uniquement la structure et l'alignement source des tableaux Markdown.
|
||||
|
||||
`PGR-MD-HEADER-001` contrôle seulement les deux premières lignes des fichiers Markdown sélectionnés : chemin relatif depuis la racine et révision interne positive. La revue `PGR-DOC-001` reste responsable du rôle documentaire et de la pertinence réelle d'un incrément de révision.
|
||||
|
||||
`PGR-NAV-001` est automatisé séparément par `audit_markdown_links.py`. Il vérifie uniquement l'existence des cibles de liens Markdown locaux inline, sans contrôler les anchors, les headers, les responsabilités documentaires ou la forme des tableaux.
|
||||
|
||||
PGR préfère plusieurs audits simples avec une responsabilité identifiable à un script unique qui agrège des règles indépendantes.
|
||||
|
||||
## Contrôles Rust réutilisables, hors gate du dépôt PGR
|
||||
|
||||
[`002-RUST_STYLE_AUDITS.md`](002-RUST_STYLE_AUDITS.md) décrit deux audits facultatifs : `audit_rust_blank_lines.py` contrôle l'espacement des lignes vides, `audit_rust_const_blocks.py` contrôle l'ordre et l'espacement des blocs de constantes au niveau racine. Ils acceptent des chemins Rust sélectionnés et partagent un petit support lexical ; leur validation ciblée dans PGR est `python3 -B -m unittest discover -s tests -p test_rust_audits.py`.
|
||||
|
||||
Leur disponibilité ne transforme pas PGR en workspace Rust et ne rend pas automatiquement l'ordre alphabétique applicable à chaque fichier d'un projet. Lors d'une adoption, le projet propriétaire sélectionne ses chemins après `cargo fmt` et applique sa propre gate ; Rustfmt et Clippy conservent les contrôles qu'ils possèdent.
|
||||
|
||||
## 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.
|
||||
|
||||
34
docs/validation/002-RUST_STYLE_AUDITS.md
Normal file
34
docs/validation/002-RUST_STYLE_AUDITS.md
Normal file
@@ -0,0 +1,34 @@
|
||||
<!-- file: docs/validation/002-RUST_STYLE_AUDITS.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Audits facultatifs de style Rust
|
||||
|
||||
## Responsabilité et provenance
|
||||
|
||||
Les sources KSP `0.3.16` et Games `0.3.5` possèdent chacune un `audit_rust_general_rules.py` qui mêle plusieurs règles. Le découpage PGR fournit deux contrôles ciblés sans copier l'orchestrateur ni les règles propres aux deux projets. Le contrat de style facultatif est dans [`510-RUST_CARGO.md`](../rules/510-RUST_CARGO.md), et la sélection des preuves dans [`400-VALIDATION.md`](../rules/400-VALIDATION.md).
|
||||
|
||||
`scripts/audit_rust_blank_lines.py` contrôle les lignes vides consécutives et les lignes vides dans un corps de fonction/méthode, `struct` ou `enum`. `scripts/audit_rust_const_blocks.py` contrôle l'ordre `pub`, `pub(crate)`, privé, le tri naturel des noms dans chaque visibilité et l'espacement entre constantes consécutives au niveau racine du fichier. `scripts/_rust_audit_common.py` partage la sélection des chemins et le masquage des commentaires/littéraux : il ne définit aucune nouvelle politique.
|
||||
|
||||
## Adoption et commandes
|
||||
|
||||
Dans un projet Rust qui choisit ces conventions, copier les trois fichiers `scripts/*.py` concernés en gardant le helper à côté des deux audits. Adapter les headers `file` au chemin du projet et maintenir une révision de fichier propre à cette copie.
|
||||
|
||||
Choisir explicitement les fichiers concernés par chaque contrat. Après formatage :
|
||||
|
||||
```bash
|
||||
cargo fmt --all -- --check
|
||||
python3 -B scripts/audit_rust_blank_lines.py crates/example/src
|
||||
python3 -B scripts/audit_rust_const_blocks.py crates/example/src/constants.rs
|
||||
```
|
||||
|
||||
Une invocation sans chemin est une erreur, de même qu'un chemin absent ou aucun fichier Rust sélectionné. Un répertoire sélectionne récursivement les fichiers `.rs` hors répertoires générés habituels. Les audits ne modifient ni les fichiers inspectés ni l'arborescence de build. Les sorties utilisent le chemin et la ligne ; le code de sortie est `0` si propre, `1` pour violation, `2` pour sélection/lecture impossible.
|
||||
|
||||
Ne sélectionner pour l'audit des constantes que les fichiers dont les blocs racine sans sémantique d'ordre doivent effectivement suivre ce contrat. Un tri de table de protocole, des migrations, des champs de wire format ou de toute séquence métier peut casser le programme : sa revue appartient au projet. Ne pas utiliser la sortie du script comme justification pour les réordonner.
|
||||
|
||||
## Limites mesurées
|
||||
|
||||
La prévalidation des sources réels a porté sur `300` fichiers KSP et `59` Games sous `crates/**/src/`. L'audit des lignes vides n'y détecte aucun écart. L'audit de constantes détecte `17` signaux KSP et aucun Games lorsque tous ces fichiers lui sont soumis ; des fichiers KSP contiennent des séquences ordonnées selon le protocole ou le schéma, ce qui rend une gate globale du tri inappropriée. Ces observations ne sont pas une gate de validation opérateur PGR.
|
||||
|
||||
L'analyse lexicale masque littéraux et commentaires courants, y compris commentaires imbriqués et chaînes Rust brutes. Elle n'est pas un parseur Rust : les macros élaborées, syntaxe nouvelle, attributs complexes, items associés dans `impl` et constantes dans modules inline n'entrent pas dans le contrat garanti de l'audit des blocs racine. Les lignes vides à l'intérieur d'un littéral multilignes sont exclues. Les cas qui demandent une interprétation sémantique nécessitent la revue humaine ou les outils Rust du projet.
|
||||
|
||||
Rustfmt reste propriétaire de l'ordre qu'il réécrit déjà dans les groupes de `use`/`mod`. Clippy et le compilateur restent responsables de leurs diagnostics. La suite `tests/test_rust_audits.py` vérifie les propriétés ciblées avec des cas propres, des violations et des littéraux/commentaires qui contiennent des accolades.
|
||||
46
history/0.0.3/alpha.1.fix.1.md
Normal file
46
history/0.0.3/alpha.1.fix.1.md
Normal file
@@ -0,0 +1,46 @@
|
||||
<!-- file: history/0.0.3/alpha.1.fix.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# History 0.0.3-alpha.1.fix.1 — correction du plan Rust/Cargo
|
||||
|
||||
## Statut
|
||||
|
||||
PASS
|
||||
|
||||
La gate documentaire du fix a été exécutée par l'opérateur avec succès. La précision apportée ensuite sur `.cargo/config.toml` et sur la valeur des conventions Rustfmt/Clippy des projets constitue un apport au cadrage de `alpha.2`, sans invalider le résultat observé du fix.
|
||||
|
||||
## Baseline et version
|
||||
|
||||
La présence de `history/0.0.3/alpha.1.md` dans `HEAD` a été vérifiée par l'opérateur avec `git cat-file -e`. La version contrôlée après application est :
|
||||
|
||||
```text
|
||||
0.0.3-alpha.1.fix.1
|
||||
```
|
||||
|
||||
## Validation opérateur observée
|
||||
|
||||
Le terminal fourni pour `~/Projects/pgr` le `2026-09-23` affiche la réussite des contrôles de version, de présence du delta et du history précédent, et d'absence du history courant. Les recherches dans le plan retrouvent sa révision `2`, les `22` crates KSP héritant des lints et les titres des tranches `alpha.2`, `alpha.3` et `alpha.4`.
|
||||
|
||||
Les trois audits ont produit :
|
||||
|
||||
```text
|
||||
Markdown table audit: clean (2 table(s), 77 file(s))
|
||||
Markdown link audit: clean (50 local link(s), 77 file(s))
|
||||
Markdown header audit: clean (77 file(s))
|
||||
```
|
||||
|
||||
`git diff --check` et `git diff --cached --check` n'ont émis aucun diagnostic. Après ajout des fichiers du delta, le scope observé est :
|
||||
|
||||
```text
|
||||
M VERSION
|
||||
A deltas/0.0.3/alpha.1.fix.1.md
|
||||
M docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
```
|
||||
|
||||
Le collage du terminal intercale une portion du futur script de contrôle près de la sortie de l'audit de liens, mais la commande Python, son résultat et les contrôles Git apparaissent ensuite séparément. Aucun résultat d'échec n'est présent dans les sorties fournies.
|
||||
|
||||
## Décision et transition
|
||||
|
||||
`alpha.1.fix.1` est validé `PASS`. Appliquer ce history et committer le fix avant toute application du delta `alpha.2`.
|
||||
|
||||
La clarification métier post-gate fixe une convention de départ pour `alpha.2` : `rustfmt.toml` et `clippy.toml` dérivent des configurations éprouvées des deux projets, avec adaptations mineures selon le projet, et `.cargo/config.toml` déplace ordinairement `target-dir` et `build-dir` vers `../builds/<nom-du-projet>/target/`. `alpha.2` peut adapter le plan vivant et livrer ces templates sans réécrire rétrospectivement le delta ou le présent history. Aucun commit de `alpha.1.fix.1` ni résultat de `alpha.2` n'est prétendu observé ici.
|
||||
55
history/0.0.3/alpha.1.md
Normal file
55
history/0.0.3/alpha.1.md
Normal file
@@ -0,0 +1,55 @@
|
||||
<!-- file: history/0.0.3/alpha.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# History 0.0.3-alpha.1 — cadrage initial
|
||||
|
||||
## Statut
|
||||
|
||||
PASS
|
||||
|
||||
Les contrôles mécaniques demandés par le delta `alpha.1` ont été exécutés par l'opérateur et ont réussi. La revue complémentaire, après ce gate, demande d'élargir le plan des templates Rust à Cargo et Clippy en examinant les archives de référence KSP et Games. Cette précision documentaire sera une tranche `.fix.1` distincte, après application du présent history et commit de `alpha.1`.
|
||||
|
||||
## Baseline et version
|
||||
|
||||
Baseline déclarée : archive issue du tag `v0.0.2`, accompagnée du rapport `pgr-0.0.2-publish.001-report.md` contrôlé pendant le cadrage. Version validée après application de `alpha.1` :
|
||||
|
||||
```text
|
||||
0.0.3-alpha.1
|
||||
```
|
||||
|
||||
## Validation opérateur observée
|
||||
|
||||
L'opérateur a fourni les sorties du `2026-09-23` à `16:41:08`–`16:41:09` depuis `~/Projects/pgr`. Les quatre contrôles de version, présence du plan et du delta, et absence du history courant ont terminé sans erreur :
|
||||
|
||||
```text
|
||||
test "$(cat VERSION)" = '0.0.3-alpha.1'
|
||||
test -f docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
test -f deltas/0.0.3/alpha.1.md
|
||||
test ! -e history/0.0.3/alpha.1.md
|
||||
```
|
||||
|
||||
Audits documentaires observés :
|
||||
|
||||
```text
|
||||
Markdown table audit: clean (2 table(s), 75 file(s))
|
||||
Markdown link audit: clean (50 local link(s), 75 file(s))
|
||||
Markdown header audit: clean (75 file(s))
|
||||
```
|
||||
|
||||
Les commandes `git diff --check` et `git diff --cached --check` n'ont émis aucun diagnostic. Après `git add` des trois chemins du delta, `git status --short` a affiché :
|
||||
|
||||
```text
|
||||
M VERSION
|
||||
A deltas/0.0.3/alpha.1.md
|
||||
A docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
```
|
||||
|
||||
La copie fournie du terminal contient un fragment de collage `ck` après le heredoc Python ; les commandes Git et leur sortie apparaissent ensuite séparément et sans erreur. Ce fragment ne modifie pas les trois résultats d'audit ni le scope Git observé.
|
||||
|
||||
## Revue post-gate et décision
|
||||
|
||||
La revue du plan après réussite mécanique a relevé une lacune de dimensionnement : le profil PGR `510` et les deux projets de référence justifient d'examiner `Cargo.toml` racine, `Cargo.toml` de crate membre et les deux niveaux de configuration Clippy en plus de `rustfmt.toml`.
|
||||
|
||||
Les archives de référence ont été fournies après l'exécution de la gate initiale. Leur étude et la correction du plan constituent le scope documentaire de `alpha.1.fix.1` ; elles ne sont pas présentées rétroactivement comme des preuves exécutées par l'opérateur pendant `alpha.1`.
|
||||
|
||||
Appliquer le présent history puis committer `alpha.1` avant d'appliquer le delta `alpha.1.fix.1`. Aucun commit, push ou gate de fix n'est déclaré observé ici.
|
||||
55
history/0.0.3/alpha.2.md
Normal file
55
history/0.0.3/alpha.2.md
Normal file
@@ -0,0 +1,55 @@
|
||||
<!-- file: history/0.0.3/alpha.2.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# History 0.0.3-alpha.2 — outillage Rust/Cargo partagé
|
||||
|
||||
## Statut
|
||||
|
||||
PASS
|
||||
|
||||
La gate documentaire et TOML de `alpha.2` a été exécutée par l'opérateur avec succès. Une demande ultérieure complète le cadrage des audits Rust à partir des scripts KSP et Games ; elle concerne les tranches suivantes et ne modifie pas rétroactivement le résultat des templates de cette tranche.
|
||||
|
||||
## Baseline et version
|
||||
|
||||
La présence de `history/0.0.3/alpha.1.fix.1.md` dans `HEAD` a été vérifiée par `git cat-file -e`. Version contrôlée après application :
|
||||
|
||||
```text
|
||||
0.0.3-alpha.2
|
||||
```
|
||||
|
||||
## Validation opérateur observée
|
||||
|
||||
Les commandes fournies depuis `~/Projects/pgr` le `2026-09-23` à `22:29:19` confirment la version, la baseline committée et l'absence du history courant. Le contrôle TOML de `rustfmt.toml`, `clippy.toml` et `.cargo/config.toml` affiche :
|
||||
|
||||
```text
|
||||
Rust/Cargo template TOML audit: clean (3 file(s))
|
||||
```
|
||||
|
||||
Les audits documentaires affichent :
|
||||
|
||||
```text
|
||||
Markdown table audit: clean (2 table(s), 80 file(s))
|
||||
Markdown link audit: clean (55 local link(s), 80 file(s))
|
||||
Markdown header audit: clean (80 file(s))
|
||||
```
|
||||
|
||||
`git diff --check` et `git diff --cached --check` n'ont émis aucun diagnostic. Après `git add`, le scope observé est :
|
||||
|
||||
```text
|
||||
M VERSION
|
||||
A deltas/0.0.3/alpha.2.md
|
||||
M docs/000-README.md
|
||||
M docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
A docs/templates/001-RUST_CARGO_TOOLING.md
|
||||
A templates/rust-cargo/.cargo/config.toml
|
||||
A templates/rust-cargo/clippy.toml
|
||||
A templates/rust-cargo/rustfmt.toml
|
||||
```
|
||||
|
||||
Le collage du terminal intercale quelques lignes de la commande `git add` dans la zone de sortie des audits ; chaque commande et son résultat apparaissent ensuite séparément. Aucune erreur n'est signalée par les sorties fournies.
|
||||
|
||||
## Suite
|
||||
|
||||
Le travail approuvé après ce gate demande de comparer les contrôles de format Rust des scripts KSP et Games, de les répartir par propriété monotâche lorsqu'ils doivent être réutilisés, et de distinguer ce que Rustfmt/Clippy possèdent déjà de ce qui exige un audit dédié. Cette revue n'a pas été exécutée par l'opérateur pendant le gate `alpha.2` et ne constitue pas sa preuve PASS.
|
||||
|
||||
Appliquer le présent history et committer `alpha.2` avant tout nouveau delta. Aucun commit ou gate ultérieur n'est déclaré observé ici.
|
||||
48
history/0.0.3/alpha.3.md
Normal file
48
history/0.0.3/alpha.3.md
Normal file
@@ -0,0 +1,48 @@
|
||||
<!-- file: history/0.0.3/alpha.3.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# History 0.0.3-alpha.3 — audits de style Rust ciblés
|
||||
|
||||
## Statut
|
||||
|
||||
PASS
|
||||
|
||||
L'opérateur a exécuté la gate prescrite pour `alpha.3` dans son dépôt le `2026-09-24`. Les neuf tests des audits Rust et les contrôles documentaires passent. Ce history constate les preuves fournies pour cette tranche, sans préjuger de la validation des manifests Cargo de `alpha.4`.
|
||||
|
||||
## Baseline et version
|
||||
|
||||
`git cat-file -e HEAD:history/0.0.3/alpha.2.md` a confirmé la présence dans `HEAD` du history de la tranche précédente. L'opérateur a vérifié `VERSION = 0.0.3-alpha.3`, la présence du delta courant, celle du history précédent et l'absence de `history/0.0.3/alpha.3.md` avant sa livraison.
|
||||
|
||||
## Validation opérateur observée
|
||||
|
||||
Les recherches sur le plan ont confirmé sa révision `4`, la tranche Cargo prévue en `alpha.4` et l'audit des headers Markdown prévu en `alpha.5`.
|
||||
|
||||
La commande `python3 -B -m unittest discover -s tests -p test_rust_audits.py -v` a exécuté `9` cas, tous `ok` ; le résultat final est `OK`. Les contrôles documentaires ont affiché :
|
||||
|
||||
```text
|
||||
Markdown table audit: clean (3 table(s), 83 file(s))
|
||||
Markdown link audit: clean (59 local link(s), 83 file(s))
|
||||
Markdown header audit: clean (83 file(s))
|
||||
```
|
||||
|
||||
`git diff --check` et `git diff --cached --check` n'ont affiché aucun diagnostic. Après `git add`, le scope indexé fourni est :
|
||||
|
||||
```text
|
||||
M VERSION
|
||||
A deltas/0.0.3/alpha.3.md
|
||||
M docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
M docs/rules/510-RUST_CARGO.md
|
||||
M docs/templates/001-RUST_CARGO_TOOLING.md
|
||||
M docs/validation/001-VALIDATION_MATRIX.md
|
||||
A docs/validation/002-RUST_STYLE_AUDITS.md
|
||||
A scripts/_rust_audit_common.py
|
||||
A scripts/audit_rust_blank_lines.py
|
||||
A scripts/audit_rust_const_blocks.py
|
||||
A tests/test_rust_audits.py
|
||||
```
|
||||
|
||||
Le collage du terminal intercale le début de la commande de contrôle des headers avant la sortie des tests. Les neuf résultats des tests, les sorties des audits et les commandes Git apparaissent ensuite dans la transcription, sans échec signalé.
|
||||
|
||||
## Transition
|
||||
|
||||
Appliquer ce history et committer la tranche `alpha.3` avant d'appliquer le delta `alpha.4`. Le commit lui-même n'est pas observé dans la preuve fournie. La suite conforme au plan est la livraison des deux templates `Cargo.toml` et de leur documentation d'adaptation, avec sa propre gate opérateur.
|
||||
54
history/0.0.3/alpha.4.md
Normal file
54
history/0.0.3/alpha.4.md
Normal file
@@ -0,0 +1,54 @@
|
||||
<!-- file: history/0.0.3/alpha.4.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# History 0.0.3-alpha.4 — manifests Cargo workspace et membre
|
||||
|
||||
## Statut
|
||||
|
||||
PASS
|
||||
|
||||
L'opérateur a exécuté le `2026-09-24` la gate de `alpha.4` avec Cargo disponible. Les deux manifests sont valides ; la vérification en workspace temporaire couvre l'héritage des lints, une erreur `unsafe` attendue sous `forbid`, puis la réussite avec une exception locale déclarée dans la crate.
|
||||
|
||||
## Baseline et version
|
||||
|
||||
`git cat-file -e HEAD:history/0.0.3/alpha.3.md` a confirmé la présence du history précédent dans `HEAD`. La version après application est `0.0.3-alpha.4`, le delta et le history `alpha.3` sont présents, et `history/0.0.3/alpha.4.md` était absent lors du contrôle.
|
||||
|
||||
## Validation opérateur observée
|
||||
|
||||
Le contrôle TOML a affiché :
|
||||
|
||||
```text
|
||||
Cargo manifest TOML audit: clean (2 file(s))
|
||||
```
|
||||
|
||||
Le smoke a effectué `cargo metadata` sur un workspace d'essai, puis `cargo check --workspace --offline` et `cargo clippy --workspace --all-targets --all-features --offline -- -D warnings` sur une crate minimale. Après insertion d'un bloc `unsafe`, le test attendu d'interdiction a été satisfait ; `cargo check` est redevenu propre après remplacement de l'héritage par les lints locaux ciblés. Résultat affiché :
|
||||
|
||||
```text
|
||||
Cargo workspace smoke: clean (inherited and local lints)
|
||||
```
|
||||
|
||||
Les audits documentaires affichent :
|
||||
|
||||
```text
|
||||
Markdown table audit: clean (3 table(s), 86 file(s))
|
||||
Markdown link audit: clean (67 local link(s), 86 file(s))
|
||||
Markdown header audit: clean (86 file(s))
|
||||
```
|
||||
|
||||
`git diff --check` et `git diff --cached --check` n'ont pas affiché de diagnostic. Après `git add`, l'état indexé fourni contient exactement :
|
||||
|
||||
```text
|
||||
M VERSION
|
||||
A deltas/0.0.3/alpha.4.md
|
||||
M docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
M docs/templates/001-RUST_CARGO_TOOLING.md
|
||||
A docs/templates/002-CARGO_MANIFESTS.md
|
||||
A templates/rust-cargo/Cargo.toml
|
||||
A templates/rust-cargo/crates/project-core-lib/Cargo.toml
|
||||
```
|
||||
|
||||
Le terminal intercale certains fragments de la commande de validation dans les sorties du smoke ; les résultats Cargo et les résultats finaux des audits restent identifiables. Aucun échec n'est signalé dans la transcription fournie.
|
||||
|
||||
## Transition
|
||||
|
||||
Appliquer le présent history et committer la tranche `alpha.4` avant d'appliquer un delta `alpha.5`. La présence de ce futur commit n'est pas déduite des commandes fournies. La tranche suivante concerne le contrôle monotâche des headers Markdown déjà effectué manuellement dans les gates précédentes.
|
||||
41
history/0.0.3/alpha.5.md
Normal file
41
history/0.0.3/alpha.5.md
Normal file
@@ -0,0 +1,41 @@
|
||||
<!-- file: history/0.0.3/alpha.5.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# History 0.0.3-alpha.5 — audit des headers Markdown
|
||||
|
||||
## Statut
|
||||
|
||||
PASS
|
||||
|
||||
La gate de `alpha.5` exécutée par l'opérateur le `2026-09-24` a validé le script monotâche des headers Markdown, ses cas positifs et négatifs, et les audits documentaires de PGR.
|
||||
|
||||
## Baseline et version
|
||||
|
||||
L'opérateur a confirmé `VERSION = 0.0.3-alpha.5`, la présence dans `HEAD` de `history/0.0.3/alpha.4.md` par `git cat-file -e`, l'existence du delta `alpha.5` et l'absence du history courant avant sa livraison. Les révisions internes attendues de `docs/rules/300-DOCUMENTATION.md` et de la matrice sont respectivement `2` et `8`.
|
||||
|
||||
## Validation opérateur observée
|
||||
|
||||
`python3 -B -m unittest discover -s tests -p test_markdown_headers.py -v` a exécuté `6` tests, tous `ok`, avec résultat final `OK`. Les audits ont affiché :
|
||||
|
||||
```text
|
||||
Markdown header audit: clean (88 file(s))
|
||||
Markdown table audit: clean (3 table(s), 88 file(s))
|
||||
Markdown link audit: clean (67 local link(s), 88 file(s))
|
||||
```
|
||||
|
||||
`git diff --check` et `git diff --cached --check` n'ont affiché aucun diagnostic. Après ajout des fichiers du delta, le statut indexé transmis est exactement :
|
||||
|
||||
```text
|
||||
M VERSION
|
||||
A deltas/0.0.3/alpha.5.md
|
||||
M docs/rules/300-DOCUMENTATION.md
|
||||
M docs/validation/001-VALIDATION_MATRIX.md
|
||||
A scripts/audit_markdown_headers.py
|
||||
A tests/test_markdown_headers.py
|
||||
```
|
||||
|
||||
Le collage du terminal intercale un fragment d'une commande `git status --short` dans la sortie d'un test. Les six cas, le résumé `OK` et les résultats finaux des trois audits restent lisibles ; aucun échec n'est signalé.
|
||||
|
||||
## Transition
|
||||
|
||||
Appliquer ce history puis committer `alpha.5` avant le delta `alpha.6`. Le commit futur n'est pas attesté par la transcription fournie. La suite prévue consiste à décider, après comparaison des prompts existants, si une courte spécification de prompt manuel améliore réellement la clôture stable.
|
||||
40
history/0.0.3/alpha.6.md
Normal file
40
history/0.0.3/alpha.6.md
Normal file
@@ -0,0 +1,40 @@
|
||||
<!-- file: history/0.0.3/alpha.6.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# History 0.0.3-alpha.6 — prompt manuel de reprise
|
||||
|
||||
## Statut
|
||||
|
||||
PASS
|
||||
|
||||
La gate de `alpha.6` exécutée par l'opérateur le `2026-09-24` valide la spécification courte du prompt manuel de nouvelle session et les renvois documentaires associés.
|
||||
|
||||
## Baseline et version
|
||||
|
||||
L'opérateur a confirmé `VERSION = 0.0.3-alpha.6`, la présence dans `HEAD` de `history/0.0.3/alpha.5.md` par `git cat-file -e`, la présence de ce history dans le répertoire de travail, du delta `alpha.6` et du template `003`, ainsi que l'absence du history courant et de `prompts/004-V0_0_4_START_PROMPT.md` avant cette livraison. Les révisions internes du workflow et du plan sont respectivement `3` et `6` ; la décision de retenir une spécification manuelle figure bien dans le plan.
|
||||
|
||||
## Validation opérateur observée
|
||||
|
||||
Les trois audits ont affiché :
|
||||
|
||||
```text
|
||||
Markdown header audit: clean (91 file(s))
|
||||
Markdown table audit: clean (3 table(s), 91 file(s))
|
||||
Markdown link audit: clean (69 local link(s), 91 file(s))
|
||||
```
|
||||
|
||||
`git diff --check` et `git diff --cached --check` n'ont affiché aucun diagnostic. Après ajout des fichiers du delta, le statut indexé transmis est exactement :
|
||||
|
||||
```text
|
||||
M VERSION
|
||||
A deltas/0.0.3/alpha.6.md
|
||||
M docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
M docs/rules/210-WORKFLOW.md
|
||||
A docs/templates/003-NEW_SESSION_PROMPT.md
|
||||
```
|
||||
|
||||
Le collage du terminal intercale un fragment de la commande `git add` dans la sortie de l'audit des liens ; son résultat final `clean` et les autres contrôles restent lisibles. Aucun échec n'est signalé.
|
||||
|
||||
## Transition
|
||||
|
||||
Appliquer ce history puis committer `alpha.6` avant le delta `beta.1`. Le commit futur n'est pas attesté par la transcription fournie. La suite prévue est la réconciliation des responsabilités, de la navigation, des templates et des audits avant la RC.
|
||||
47
history/0.0.3/beta.1.md
Normal file
47
history/0.0.3/beta.1.md
Normal file
@@ -0,0 +1,47 @@
|
||||
<!-- file: history/0.0.3/beta.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# History 0.0.3-beta.1 — réconciliation documentaire
|
||||
|
||||
## Statut
|
||||
|
||||
PASS
|
||||
|
||||
La gate `beta.1` exécutée par l'opérateur le `2026-09-24` confirme la navigation des documents vivants, la chaîne des tranches alpha et les validations d'intégration prévues pour la réconciliation.
|
||||
|
||||
## Baseline et version
|
||||
|
||||
L'opérateur a confirmé `VERSION = 0.0.3-beta.1`, la présence dans `HEAD` de `history/0.0.3/alpha.6.md` par `git cat-file -e`, la présence de ce history et du delta `beta.1`, ainsi que l'absence du history courant et du prompt `004` avant cette livraison. Les révisions attendues sont `5` pour `README.md`, `3` pour l'index documentaire, `7` pour le plan et `9` pour la matrice.
|
||||
|
||||
## Validation opérateur observée
|
||||
|
||||
`python3 -B -m unittest discover -s tests -p 'test_*.py' -v` a exécuté `15` tests, tous `ok`, avec résultat final `OK`. Les audits documentaires ont affiché :
|
||||
|
||||
```text
|
||||
Markdown header audit: clean (93 file(s))
|
||||
Markdown table audit: clean (3 table(s), 93 file(s))
|
||||
Markdown link audit: clean (76 local link(s), 93 file(s))
|
||||
```
|
||||
|
||||
La vérification de la chaîne et des modèles TOML a affiché :
|
||||
|
||||
```text
|
||||
Reconciliation audit: clean (7 PASS histories, 5 TOML files)
|
||||
```
|
||||
|
||||
`git diff --check` et `git diff --cached --check` n'ont affiché aucun diagnostic. Après ajout des fichiers du delta, le statut indexé transmis est exactement :
|
||||
|
||||
```text
|
||||
M README.md
|
||||
M VERSION
|
||||
A deltas/0.0.3/beta.1.md
|
||||
M docs/000-README.md
|
||||
M docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
M docs/validation/001-VALIDATION_MATRIX.md
|
||||
```
|
||||
|
||||
Le collage du terminal intercale des fragments de commandes et de sorties des tests ; leurs résumés `OK`, les résultats finaux des audits et le statut Git restent lisibles. Aucun échec n'est signalé.
|
||||
|
||||
## Transition
|
||||
|
||||
Appliquer ce history et committer `beta.1` avant le delta `rc.1`. Le commit futur n'est pas attesté par la transcription fournie. La RC préparera l'entrée candidate du changelog et le prompt de `0.0.4`, puis exécutera sa propre gate ; le présent PASS ne valide pas cette RC par anticipation.
|
||||
41
history/0.0.3/rc.1.md
Normal file
41
history/0.0.3/rc.1.md
Normal file
@@ -0,0 +1,41 @@
|
||||
<!-- file: history/0.0.3/rc.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# History 0.0.3-rc.1 — gel du scope et préparation de release
|
||||
|
||||
## Statut
|
||||
|
||||
PASS
|
||||
|
||||
La gate de release candidate `rc.1` exécutée par l'opérateur le `2026-09-24` confirme le gel du périmètre, l'entrée candidate du changelog, le prompt `004` et l'intégration documentaire.
|
||||
|
||||
## Baseline et version
|
||||
|
||||
L'opérateur a confirmé `VERSION = 0.0.3-rc.1`, la présence dans `HEAD` de `history/0.0.3/beta.1.md` par `git cat-file -e`, la présence de ce history, du delta RC et du prompt `004`, ainsi que l'absence du history RC avant cette livraison. Les révisions internes attendues sont `4` pour `CHANGELOG.md` et `8` pour le plan. Le changelog porte l'intitulé `0.0.3 (candidate)` ; le prompt prévoit le rapport post-tag seulement si son résultat réel est PASS.
|
||||
|
||||
## Validation opérateur observée
|
||||
|
||||
`python3 -B -m unittest discover -s tests -p 'test_*.py' -v` a exécuté `15` tests, tous `ok`, et s'est terminé par `OK`. Les audits ont affiché :
|
||||
|
||||
```text
|
||||
Markdown header audit: clean (96 file(s))
|
||||
Markdown table audit: clean (3 table(s), 96 file(s))
|
||||
Markdown link audit: clean (79 local link(s), 96 file(s))
|
||||
RC integration audit: clean (8 PASS histories, 5 TOML files)
|
||||
```
|
||||
|
||||
`git diff --check` et `git diff --cached --check` n'ont affiché aucun diagnostic. Le statut indexé observé après ajout des fichiers du delta est :
|
||||
|
||||
```text
|
||||
M CHANGELOG.md
|
||||
M VERSION
|
||||
A deltas/0.0.3/rc.1.md
|
||||
M docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
A prompts/004-V0_0_4_START_PROMPT.md
|
||||
```
|
||||
|
||||
Le collage du terminal intercale des fragments de commandes et la sortie des tests ; les résumés `OK`, les résultats finaux des audits et le statut Git restent lisibles. Aucun échec n'est signalé.
|
||||
|
||||
## Transition
|
||||
|
||||
Appliquer ce history puis committer `rc.1` avant le delta stable `rel.001`. Le commit futur n'est pas attesté par la transcription fournie. Ce PASS n'atteste ni la promotion stable, ni le tag `v0.0.3`, ni le contrôle de l'archive publiée après le tag.
|
||||
50
history/0.0.3/rel.001.md
Normal file
50
history/0.0.3/rel.001.md
Normal file
@@ -0,0 +1,50 @@
|
||||
<!-- file: history/0.0.3/rel.001.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# History 0.0.3 rel.001 — clôture stable pré-tag
|
||||
|
||||
## Statut
|
||||
|
||||
PASS
|
||||
|
||||
La gate stable pré-tag `rel.001` exécutée par l'opérateur le `2026-09-24` valide la promotion documentaire de `0.0.3`. Ce résultat porte sur l'état du dépôt avant le commit et le tag stables ; il ne valide pas l'archive téléchargée ensuite depuis Gitea.
|
||||
|
||||
## Baseline et version
|
||||
|
||||
L'opérateur a confirmé `VERSION = 0.0.3`, la présence dans `HEAD` de `history/0.0.3/rc.1.md` par `git cat-file -e`, la présence de ce history, du delta stable et du prompt `004`, ainsi que l'absence du présent history avant sa livraison. Les révisions attendues sont `6` pour `README.md`, `4` pour `ROADMAP.md`, `5` pour `CHANGELOG.md`, `4` pour l'index `docs/` et `9` pour le plan.
|
||||
|
||||
La présentation de la release dans `README.md`, le statut `(x)` de `0.0.3` dans la roadmap, l'entrée `## 0.0.3` du changelog, le statut historique du plan et la séparation du contrôle post-tag ont été vérifiés par les commandes de la gate.
|
||||
|
||||
## Validation opérateur observée
|
||||
|
||||
La vérification des deltas et histories antérieurs a affiché :
|
||||
|
||||
```text
|
||||
Stable history audit: clean (9 PASS histories, rel.001 pending)
|
||||
```
|
||||
|
||||
Les trois audits Markdown ont affiché :
|
||||
|
||||
```text
|
||||
Markdown header audit: clean (98 file(s))
|
||||
Markdown table audit: clean (3 table(s), 98 file(s))
|
||||
Markdown link audit: clean (79 local link(s), 98 file(s))
|
||||
```
|
||||
|
||||
`git diff --check` et `git diff --cached --check` n'ont affiché aucun diagnostic. Après ajout des fichiers du delta, le statut indexé transmis est :
|
||||
|
||||
```text
|
||||
M CHANGELOG.md
|
||||
M README.md
|
||||
M ROADMAP.md
|
||||
M VERSION
|
||||
A deltas/0.0.3/rel.001.md
|
||||
M docs/000-README.md
|
||||
M docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
|
||||
```
|
||||
|
||||
Le collage du terminal intercale un fragment de commande dans la sortie de l'audit des tableaux ; son résultat final `clean` et les autres résultats restent lisibles. Les tests et la syntaxe des modèles TOML validés en RC n'ont pas été rejoués dans cette gate documentaire ; aucun code, script, test ni modèle technique ne change pendant `rel.001`.
|
||||
|
||||
## Transition
|
||||
|
||||
Appliquer ce history puis committer la stable. Ensuite seulement, créer et publier le tag `v0.0.3`, télécharger l'archive source associée depuis Gitea et exécuter une vérification post-tag séparée. Le commit stable, le tag, la publication et le résultat de cette vérification ne sont pas attestés par la transcription reçue ; aucun statut `publish.001` ne peut encore être consigné.
|
||||
76
history/0.0.4/alpha.1.md
Normal file
76
history/0.0.4/alpha.1.md
Normal file
@@ -0,0 +1,76 @@
|
||||
<!-- file: history/0.0.4/alpha.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# History 0.0.4-alpha.1 — audit de baseline et cadrage des skeletons
|
||||
|
||||
## Statut
|
||||
|
||||
PASS
|
||||
|
||||
La gate de `0.0.4-alpha.1` exécutée par l'opérateur le `2026-09-24` valide la reprise depuis la stable `0.0.3`, le cadrage des premières skeleton specifications et le plan actif de `0.0.4`. Les contrôles mécaniques demandés sont propres et le scope Git observé correspond exactement au delta.
|
||||
|
||||
## Baseline et version
|
||||
|
||||
La tranche a été appliquée sur l'état stable `0.0.3` contrôlé pendant le cadrage depuis l'archive `pgr-v0.0.3.zip` et le rapport post-tag externe `pgr-0.0.3-publish.001-report.md` déclaré `PASS`.
|
||||
|
||||
La version contrôlée après application est :
|
||||
|
||||
```text
|
||||
0.0.4-alpha.1
|
||||
```
|
||||
|
||||
Le plan `docs/plans/004-V0_0_4_SKELETONS_PLAN.md` et le delta `deltas/0.0.4/alpha.1.md` sont présents ; `history/0.0.4/alpha.1.md` était absent pendant la gate. Les révisions attendues de `README.md` et `docs/000-README.md` sont respectivement `7` et `5`, et les deux documents référencent le plan actif.
|
||||
|
||||
## Validation opérateur observée
|
||||
|
||||
L'opérateur a fourni les sorties du `2026-09-24` depuis `~/Projects/pgr`. Le contrôle de `VERSION` a été exécuté à `13:48:46`, puis les autres contrôles et validations à `13:53:25`–`13:53:26`.
|
||||
|
||||
La suite Python globale a exécuté `15` tests, tous réussis :
|
||||
|
||||
```text
|
||||
Ran 15 tests in 0.223s
|
||||
|
||||
OK
|
||||
```
|
||||
|
||||
Les trois audits documentaires affichent :
|
||||
|
||||
```text
|
||||
Markdown header audit: clean (101 file(s))
|
||||
Markdown table audit: clean (3 table(s), 101 file(s))
|
||||
Markdown link audit: clean (81 local link(s), 101 file(s))
|
||||
```
|
||||
|
||||
Le contrôle structurel de la baseline affiche :
|
||||
|
||||
```text
|
||||
Baseline structural audit: clean (34 prior delta/history pairs, 10/10 histories 0.0.3 PASS, 5 TOML parsed)
|
||||
```
|
||||
|
||||
Il confirme notamment l'appariement des `12` deltas/histories de `0.0.1`, des `12` de `0.0.2` et des `10` de `0.0.3`, le statut `PASS` des dix histories `0.0.3`, la présence des trois scripts d'audit Rust attendus et le parsing des cinq fichiers TOML du template Rust/Cargo.
|
||||
|
||||
`git diff --check` et `git diff --cached --check` n'ont affiché aucun diagnostic. Après ajout des fichiers du delta, le statut indexé transmis est exactement :
|
||||
|
||||
```text
|
||||
M README.md
|
||||
M VERSION
|
||||
A deltas/0.0.4/alpha.1.md
|
||||
M docs/000-README.md
|
||||
A docs/plans/004-V0_0_4_SKELETONS_PLAN.md
|
||||
```
|
||||
|
||||
La transcription du terminal intercale un fragment du heredoc Python avec le début de la sortie `unittest`. Les quinze cas individuels, le résumé final `OK`, les trois audits documentaires, le contrôle structurel et le statut Git restent néanmoins identifiables et ne signalent aucun échec.
|
||||
|
||||
## Revue de cadrage
|
||||
|
||||
La revue du contenu livré confirme que le plan distingue bien les prévisions des règles déjà actives : le contrat commun des skeletons est présenté comme une cible à fixer dans `alpha.2`, et aucun chemin prévisionnel n'est transformé en propriétaire normatif avant sa création effective.
|
||||
|
||||
Les valeurs Rust/Cargo citées dans le plan restent explicitement des exemples ou décisions destinataire à adapter, notamment `0.1.0`, `2024`, `project-name`, `project-core-lib`, les seuils Clippy et les chemins de build. Aucun de ces choix n'est promu en valeur universelle.
|
||||
|
||||
Java/Maven/Gradle, Android, Web, JNI, Tauri et les autres familles sans pièces suffisantes restent explicitement différés. Aucun skeleton concret, profil supplémentaire, template ou artefact technologique de ces domaines n'est matérialisé dans `alpha.1`.
|
||||
|
||||
## Transition
|
||||
|
||||
Appliquer le présent history puis committer `0.0.4-alpha.1` avant tout delta `alpha.2`. Le commit futur n'est pas attesté par les sorties fournies.
|
||||
|
||||
Après ce commit, la tranche suivante est `0.0.4-alpha.2` et doit rester limitée au contrat de sélection et de composition des skeletons, à son propriétaire normatif et à l'index de la collection documentaire correspondante, conformément au plan actif.
|
||||
103
history/0.0.4/alpha.2.md
Normal file
103
history/0.0.4/alpha.2.md
Normal file
@@ -0,0 +1,103 @@
|
||||
<!-- file: history/0.0.4/alpha.2.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# History 0.0.4-alpha.2 — contrat de composition des skeletons
|
||||
|
||||
## Statut
|
||||
|
||||
PASS
|
||||
|
||||
La gate de `0.0.4-alpha.2` exécutée par l'opérateur le `2026-09-24` valide le propriétaire normatif transversal des skeleton specifications, l'activation de leur collection documentaire et la réconciliation des index et documents d'architecture concernés. Les contrôles mécaniques demandés sont propres et le scope Git observé correspond exactement au delta.
|
||||
|
||||
## Baseline et version
|
||||
|
||||
La tranche a été appliquée après le commit opérateur `bf306da` de `0.0.4-alpha.1`, qui contenait `history/0.0.4/alpha.1.md` avec statut `PASS` et avait été poussé sur `origin/master`.
|
||||
|
||||
La version contrôlée après application est :
|
||||
|
||||
```text
|
||||
0.0.4-alpha.2
|
||||
```
|
||||
|
||||
`history/0.0.4/alpha.1.md`, `deltas/0.0.4/alpha.2.md`, `docs/rules/220-SKELETONS.md` et `docs/skeletons/000-README.md` sont présents ; `history/0.0.4/alpha.2.md` était absent pendant la gate.
|
||||
|
||||
Les skeleton specifications concrètes prévues pour les tranches suivantes étaient bien absentes :
|
||||
|
||||
```text
|
||||
docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md
|
||||
docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||
```
|
||||
|
||||
## Validation opérateur observée
|
||||
|
||||
L'opérateur a fourni les sorties du `2026-09-24` depuis `~/Projects/pgr`, à `14:15:19`–`14:15:20`.
|
||||
|
||||
Les révisions documentaires attendues ont été confirmées :
|
||||
|
||||
```text
|
||||
README.md version 8
|
||||
RULES.md version 10
|
||||
docs/000-README.md version 6
|
||||
docs/architecture/002-GOVERNANCE_ARCHITECTURE.md version 3
|
||||
docs/architecture/003-RULE_PROFILE_MODEL.md version 3
|
||||
docs/rules/000-README.md version 11
|
||||
docs/rules/220-SKELETONS.md version 1
|
||||
docs/skeletons/000-README.md version 1
|
||||
```
|
||||
|
||||
Les références attendues vers `docs/rules/220-SKELETONS.md` et `docs/skeletons/` sont présentes dans les points d'entrée, l'index normatif et les deux documents d'architecture concernés.
|
||||
|
||||
La suite Python globale a exécuté `15` tests, tous réussis :
|
||||
|
||||
```text
|
||||
Ran 15 tests in 0.256s
|
||||
|
||||
OK
|
||||
```
|
||||
|
||||
Les trois audits documentaires affichent :
|
||||
|
||||
```text
|
||||
Markdown header audit: clean (105 file(s))
|
||||
Markdown table audit: clean (3 table(s), 105 file(s))
|
||||
Markdown link audit: clean (97 local link(s), 105 file(s))
|
||||
```
|
||||
|
||||
Le contrôle structurel spécifique affiche :
|
||||
|
||||
```text
|
||||
Skeleton contract audit: clean (alpha.1 PASS baseline, alpha.2 contract/index only)
|
||||
```
|
||||
|
||||
Il confirme notamment que `history/0.0.4/alpha.1.md` est le seul history `0.0.4` présent pendant la gate, qu'il est `PASS`, que la collection `docs/skeletons/` ne contient encore que son index et que les huit responsabilités prévues du contrat `220` sont présentes.
|
||||
|
||||
`git diff --check` et `git diff --cached --check` n'ont affiché aucun diagnostic. Après ajout des fichiers du delta, le statut indexé transmis est exactement :
|
||||
|
||||
```text
|
||||
M README.md
|
||||
M RULES.md
|
||||
M VERSION
|
||||
A deltas/0.0.4/alpha.2.md
|
||||
M docs/000-README.md
|
||||
M docs/architecture/002-GOVERNANCE_ARCHITECTURE.md
|
||||
M docs/architecture/003-RULE_PROFILE_MODEL.md
|
||||
M docs/rules/000-README.md
|
||||
A docs/rules/220-SKELETONS.md
|
||||
A docs/skeletons/000-README.md
|
||||
```
|
||||
|
||||
La transcription du terminal intercale à deux endroits des fragments de commandes/heredoc avec la sortie de `unittest`. Les quinze cas individuels, le résumé final `OK`, les audits documentaires, le contrôle structurel et le statut Git restent néanmoins identifiables et ne signalent aucun échec.
|
||||
|
||||
## Revue de scope
|
||||
|
||||
La tranche reste conforme au plan `0.0.4` : `docs/rules/220-SKELETONS.md` possède le contrat transversal de sélection et composition, tandis que `docs/architecture/003-RULE_PROFILE_MODEL.md` conserve la propriété de la hiérarchie et de la résolution des profils.
|
||||
|
||||
La collection `docs/skeletons/` est réellement activée par son index mais ne contient aucun placeholder de specialization. Aucun skeleton de fondation, Rust/Cargo, Java/Android, Web, JNI, Tauri ou autre domaine technologique n'a été matérialisé dans `alpha.2`.
|
||||
|
||||
## Transition
|
||||
|
||||
Appliquer le présent history puis committer `0.0.4-alpha.2` avant d'appliquer le delta `0.0.4-alpha.3`.
|
||||
|
||||
Le history `alpha.2` et le delta `alpha.3` peuvent être livrés dans le même échange sous deux archives distinctes. Cette livraison simultanée ne change pas l'ordre d'application : le delta suivant MUST rester absent du dépôt jusqu'au commit de la tranche `alpha.2`.
|
||||
|
||||
La tranche suivante est `0.0.4-alpha.3` et doit rester limitée à la première skeleton specification composable de fondation de projet gouverné, sans specialization technologique.
|
||||
96
history/0.0.4/alpha.3.md
Normal file
96
history/0.0.4/alpha.3.md
Normal file
@@ -0,0 +1,96 @@
|
||||
<!-- file: history/0.0.4/alpha.3.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# History 0.0.4-alpha.3 — fondation de projet gouverné
|
||||
|
||||
## Statut
|
||||
|
||||
PASS
|
||||
|
||||
La gate de `0.0.4-alpha.3` exécutée par l'opérateur le `2026-09-24` valide la première skeleton specification concrète de PGR : une fondation composable de gouvernance locale sans specialization technologique. Les contrôles mécaniques demandés sont propres et le scope Git observé correspond exactement au delta.
|
||||
|
||||
## Baseline et version
|
||||
|
||||
La tranche a été appliquée après le commit opérateur `7408616` de `0.0.4-alpha.2`, qui contenait `history/0.0.4/alpha.2.md` avec statut `PASS` et avait été poussé sur `origin/master`.
|
||||
|
||||
La version contrôlée après application est :
|
||||
|
||||
```text
|
||||
0.0.4-alpha.3
|
||||
```
|
||||
|
||||
`history/0.0.4/alpha.2.md`, `deltas/0.0.4/alpha.3.md` et `docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md` sont présents ; `history/0.0.4/alpha.3.md` était absent pendant la gate.
|
||||
|
||||
Le skeleton technologique suivant était bien absent :
|
||||
|
||||
```text
|
||||
docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||
```
|
||||
|
||||
## Validation opérateur observée
|
||||
|
||||
L'opérateur a fourni les sorties du `2026-09-24` depuis `~/Projects/pgr`, à `14:30:21`–`14:31:25`.
|
||||
|
||||
Les révisions documentaires attendues ont été confirmées :
|
||||
|
||||
```text
|
||||
README.md version 9
|
||||
docs/000-README.md version 7
|
||||
docs/skeletons/000-README.md version 2
|
||||
docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md version 1
|
||||
```
|
||||
|
||||
Les références attendues vers `001-PROJECT_GOVERNANCE_FOUNDATION.md` sont présentes dans `README.md`, `docs/000-README.md` et l'index `docs/skeletons/000-README.md`.
|
||||
|
||||
La suite Python globale a exécuté `15` tests, tous réussis :
|
||||
|
||||
```text
|
||||
Ran 15 tests in 0.229s
|
||||
|
||||
OK
|
||||
```
|
||||
|
||||
Les trois audits documentaires affichent :
|
||||
|
||||
```text
|
||||
Markdown header audit: clean (108 file(s))
|
||||
Markdown table audit: clean (3 table(s), 108 file(s))
|
||||
Markdown link audit: clean (103 local link(s), 108 file(s))
|
||||
```
|
||||
|
||||
Le contrôle structurel spécifique affiche :
|
||||
|
||||
```text
|
||||
Governance foundation audit: clean (alpha.1/alpha.2 PASS baseline, one concrete non-technological skeleton)
|
||||
```
|
||||
|
||||
Il confirme notamment que les seuls histories `0.0.4` présents pendant la gate étaient `alpha.1.md` et `alpha.2.md`, tous deux `PASS`, que la collection des skeletons contenait uniquement son index et la fondation `001`, et que les sections et owners généraux attendus étaient présents.
|
||||
|
||||
`git diff --check` et `git diff --cached --check` n'ont affiché aucun diagnostic. Après ajout des fichiers du delta, le statut indexé transmis est exactement :
|
||||
|
||||
```text
|
||||
M README.md
|
||||
M VERSION
|
||||
A deltas/0.0.4/alpha.3.md
|
||||
M docs/000-README.md
|
||||
M docs/skeletons/000-README.md
|
||||
A docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md
|
||||
```
|
||||
|
||||
La transcription du terminal intercale des fragments de commandes/heredoc avec la sortie de `unittest`. Les quinze cas individuels, le résumé final `OK`, les audits documentaires, le contrôle structurel et le statut Git restent néanmoins identifiables et ne signalent aucun échec.
|
||||
|
||||
## Revue de scope
|
||||
|
||||
La fondation reste une procédure composable et non un template ou générateur implicite. Elle sélectionne uniquement les owners généraux `200`, `210`, `300` et `400`, conserve `220` comme contrat d'instanciation et ne sélectionne aucun profil `500+` ou `600+` par défaut.
|
||||
|
||||
Les documents et répertoires sont créés à la demande selon un contenu réel ; aucune copie exhaustive du layout PGR n'est imposée. Les décisions destinataire restent explicites et aucune valeur d'exemple technologique n'est introduite dans cette tranche.
|
||||
|
||||
L'ordre de composition permet à une specialization telle que Rust/Cargo d'ajouter ses profils, templates et validations sans redéfinir les responsabilités générales de la fondation.
|
||||
|
||||
## Transition
|
||||
|
||||
Appliquer le présent history puis committer `0.0.4-alpha.3` avant d'appliquer le delta `0.0.4-alpha.4`.
|
||||
|
||||
Le history `alpha.3` et le delta `alpha.4` peuvent être livrés dans le même échange sous deux archives distinctes. Cette livraison simultanée ne change pas l'ordre d'application : le delta suivant MUST rester absent du dépôt jusqu'au commit de la tranche `alpha.3`.
|
||||
|
||||
La tranche suivante est `0.0.4-alpha.4` et doit rester limitée au skeleton Rust/Cargo workspace, à sa composition avec la fondation `001`, aux cinq templates Rust/Cargo existants, aux décisions destinataire et à une validation d'instanciation proportionnée.
|
||||
117
history/0.0.4/alpha.4.fix.1.md
Normal file
117
history/0.0.4/alpha.4.fix.1.md
Normal file
@@ -0,0 +1,117 @@
|
||||
<!-- file: history/0.0.4/alpha.4.fix.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# History 0.0.4-alpha.4.fix.1 — correction du smoke Rust/Cargo
|
||||
|
||||
## Statut
|
||||
|
||||
PASS
|
||||
|
||||
La gate de `0.0.4-alpha.4.fix.1` exécutée par l'opérateur le `2026-09-24` valide la correction locale du smoke d'instanciation Rust/Cargo. Le `FAIL` historique de `alpha.4` reste inchangé ; le fix prouve que l'adaptation temporaire élimine désormais les placeholders avant l'exécution de la toolchain.
|
||||
|
||||
## Baseline et version
|
||||
|
||||
La tranche `0.0.4-alpha.4` a été committée et poussée sous le commit observé :
|
||||
|
||||
```text
|
||||
c0735d1
|
||||
```
|
||||
|
||||
Ce commit contient `history/0.0.4/alpha.4.md` avec statut `FAIL`.
|
||||
|
||||
La version contrôlée après application du correctif est :
|
||||
|
||||
```text
|
||||
0.0.4-alpha.4.fix.1
|
||||
```
|
||||
|
||||
Les deltas `alpha.4.md` et `alpha.4.fix.1.md`, le history `alpha.4.md` et le skeleton `docs/skeletons/002-RUST_CARGO_WORKSPACE.md` sont présents. `history/0.0.4/alpha.4.fix.1.md` était absent pendant la gate.
|
||||
|
||||
## Validation opérateur observée
|
||||
|
||||
La suite Python globale a exécuté `15` tests, tous réussis :
|
||||
|
||||
```text
|
||||
Ran 15 tests in 0.225s
|
||||
|
||||
OK
|
||||
```
|
||||
|
||||
Les trois audits Markdown ont réussi :
|
||||
|
||||
```text
|
||||
Markdown header audit: clean (113 file(s))
|
||||
Markdown table audit: clean (3 table(s), 113 file(s))
|
||||
Markdown link audit: clean (113 local link(s), 113 file(s))
|
||||
```
|
||||
|
||||
Le contrôle structurel du correctif a affiché :
|
||||
|
||||
```text
|
||||
Rust/Cargo fix audit: clean (alpha.4 FAIL recorded, skeleton/templates unchanged)
|
||||
```
|
||||
|
||||
Il confirme les histories `alpha.1`, `alpha.2` et `alpha.3` en `PASS`, `alpha.4` en `FAIL`, les trois fichiers de skeleton attendus et le parsing TOML des cinq templates Rust/Cargo sans modification de ces artefacts.
|
||||
|
||||
La toolchain opérateur observée est :
|
||||
|
||||
```text
|
||||
cargo 1.94.1 (29ea6fb6a 2026-03-24)
|
||||
rustc 1.94.1 (e408947bf 2026-03-25)
|
||||
rustfmt 1.8.0-stable (e408947bfd 2026-03-25)
|
||||
clippy 0.1.94 (e408947bfd 2026-03-25)
|
||||
```
|
||||
|
||||
La procédure temporaire corrigée a remplacé le commentaire de guidance de `.cargo/config.toml` en plus des chemins et autres placeholders, puis a affiché :
|
||||
|
||||
```text
|
||||
Temporary Rust/Cargo template adaptation: clean
|
||||
```
|
||||
|
||||
Aucun `project-name` ni `project-core-lib` ne subsiste donc dans les fichiers adoptés de la fixture temporaire avant la validation Cargo.
|
||||
|
||||
La séquence suivante a ensuite été exécutée dans le workspace temporaire :
|
||||
|
||||
```text
|
||||
cargo metadata --format-version 1 --no-deps
|
||||
cargo fmt --all -- --check
|
||||
cargo check --workspace
|
||||
cargo clippy --workspace --all-targets --all-features -- -D warnings
|
||||
```
|
||||
|
||||
Aucun diagnostic d'échec n'a été transmis pour `cargo metadata` ou `cargo fmt`. `cargo check` et `cargo clippy` ont tous deux terminé avec succès pour :
|
||||
|
||||
```text
|
||||
smoke-core-lib v1.2.3
|
||||
```
|
||||
|
||||
Le workspace temporaire a ensuite été supprimé et le trap désarmé.
|
||||
|
||||
`git diff --check` et `git diff --cached --check` n'ont produit aucun diagnostic. Le scope Git observé avant le présent history est exactement :
|
||||
|
||||
```text
|
||||
M VERSION
|
||||
A deltas/0.0.4/alpha.4.fix.1.md
|
||||
```
|
||||
|
||||
La transcription du terminal contient quelques fragments de heredoc intercalés avec la sortie des tests ; les résultats finaux des commandes, audits, contrôles structurels et du scope Git restent toutefois identifiables et cohérents.
|
||||
|
||||
## Résultat du correctif
|
||||
|
||||
Le défaut de `alpha.4` appartenait uniquement à la fixture de validation et non aux règles, au skeleton `002` ou aux cinq templates distribués. `alpha.4.fix.1` corrige ce défaut sans modifier ces artefacts.
|
||||
|
||||
La preuve d'instanciation est désormais complète pour le scope prévu : adaptation des placeholders, parsing/metadata Cargo, formatage, compilation de vérification et Clippy avec `-D warnings` sur une crate minimale.
|
||||
|
||||
Aucun REPLAN n'est requis.
|
||||
|
||||
## Transition
|
||||
|
||||
Appliquer le présent history puis committer et pousser `0.0.4-alpha.4.fix.1` avant d'appliquer le delta suivant.
|
||||
|
||||
La tranche suivante prévue par le plan est :
|
||||
|
||||
```text
|
||||
0.0.4-beta.1
|
||||
```
|
||||
|
||||
Elle doit rester une réconciliation interne : ownership, liens/index, absence de duplication normative, non-universalisation des valeurs d'exemple, limites des audits et confirmation des spécialisations différées. Elle ne doit pas créer de nouveau skeleton ou template sans défaut réel découvert pendant cette revue.
|
||||
142
history/0.0.4/alpha.4.md
Normal file
142
history/0.0.4/alpha.4.md
Normal file
@@ -0,0 +1,142 @@
|
||||
<!-- file: history/0.0.4/alpha.4.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# History 0.0.4-alpha.4 — skeleton Rust/Cargo workspace
|
||||
|
||||
## Statut
|
||||
|
||||
FAIL
|
||||
|
||||
La tranche `0.0.4-alpha.4` n'est pas enregistrée `PASS` telle quelle.
|
||||
|
||||
Le contenu documentaire, les audits PGR et l'exécution réelle de Cargo sont cohérents, mais une assertion obligatoire de la gate d'instanciation a échoué : après adaptation du template `.cargo/config.toml`, le commentaire de guidance conservait encore le placeholder littéral `project-name`.
|
||||
|
||||
## Baseline
|
||||
|
||||
La tranche précédente `0.0.4-alpha.3` a été committée et poussée sous le commit observé :
|
||||
|
||||
```text
|
||||
5471ea6
|
||||
```
|
||||
|
||||
Version contrôlée après application de `alpha.4` :
|
||||
|
||||
```text
|
||||
0.0.4-alpha.4
|
||||
```
|
||||
|
||||
Les fichiers attendus sont présents et `history/0.0.4/alpha.4.md` était absent avant cette validation.
|
||||
|
||||
## Contrôles réussis observés
|
||||
|
||||
Les `15` tests Python ont tous réussi :
|
||||
|
||||
```text
|
||||
Ran 15 tests in 0.251s
|
||||
OK
|
||||
```
|
||||
|
||||
Les audits Markdown ont réussi :
|
||||
|
||||
```text
|
||||
Markdown header audit: clean (111 file(s))
|
||||
Markdown table audit: clean (3 table(s), 111 file(s))
|
||||
Markdown link audit: clean (113 local link(s), 111 file(s))
|
||||
```
|
||||
|
||||
L'audit structurel du skeleton Rust/Cargo a également réussi :
|
||||
|
||||
```text
|
||||
Rust/Cargo skeleton audit: clean (alpha.1-alpha.3 PASS baseline, five templates parsed)
|
||||
```
|
||||
|
||||
Il confirme notamment les trois skeletons attendus, les histories `alpha.1` à `alpha.3` en `PASS`, les owners `500-LANGUAGES.md` et `510-RUST_CARGO.md`, les cinq templates Rust/Cargo référencés et leur parsing TOML.
|
||||
|
||||
La toolchain opérateur observée est disponible :
|
||||
|
||||
```text
|
||||
cargo 1.94.1 (29ea6fb6a 2026-03-24)
|
||||
rustc 1.94.1 (e408947bf 2026-03-25)
|
||||
rustfmt 1.8.0-stable (e408947bfd 2026-03-25)
|
||||
clippy 0.1.94 (e408947bfd 2026-03-25)
|
||||
```
|
||||
|
||||
Après l'assertion défectueuse, les commandes Cargo ont été exécutées sur le workspace temporaire et ont réussi :
|
||||
|
||||
```text
|
||||
cargo metadata --format-version 1 --no-deps
|
||||
cargo fmt --all -- --check
|
||||
cargo check --workspace
|
||||
cargo clippy --workspace --all-targets --all-features -- -D warnings
|
||||
```
|
||||
|
||||
`cargo check` et `cargo clippy` ont tous deux terminé avec succès pour `smoke-core-lib v1.2.3`.
|
||||
|
||||
`git diff --check` et `git diff --cached --check` n'ont produit aucun diagnostic. Le scope Git observé avant le présent history est exactement :
|
||||
|
||||
```text
|
||||
M README.md
|
||||
M VERSION
|
||||
A deltas/0.0.4/alpha.4.md
|
||||
M docs/000-README.md
|
||||
M docs/skeletons/000-README.md
|
||||
A docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||
```
|
||||
|
||||
## Défaut exact
|
||||
|
||||
La gate copie `templates/rust-cargo/.cargo/config.toml`, puis remplace le chemin :
|
||||
|
||||
```text
|
||||
../builds/project-name/target
|
||||
```
|
||||
|
||||
par :
|
||||
|
||||
```text
|
||||
target-smoke
|
||||
```
|
||||
|
||||
Les deux valeurs `target-dir` et `build-dir` sont donc adaptées correctement. Cependant, le template contient aussi le commentaire :
|
||||
|
||||
```text
|
||||
# Replace project-name with a unique name before using this configuration.
|
||||
```
|
||||
|
||||
Le script d'instanciation ne remplace pas ce commentaire, puis vérifie volontairement qu'aucun placeholder `project-name` ou `project-core-lib` ne subsiste dans les fichiers copiés. L'assertion échoue donc sur :
|
||||
|
||||
```text
|
||||
/tmp/.../.cargo/config.toml
|
||||
```
|
||||
|
||||
avec :
|
||||
|
||||
```text
|
||||
AssertionError
|
||||
```
|
||||
|
||||
Le workspace généré reste compilable, comme le montrent les commandes Cargo réussies ensuite, mais une commande obligatoire de la gate a échoué. La tranche ne peut donc pas être déclarée `PASS`.
|
||||
|
||||
## Décision
|
||||
|
||||
Aucun REPLAN n'est requis.
|
||||
|
||||
Le défaut appartient uniquement au smoke d'instanciation défini dans la gate de `alpha.4`. Les règles, le skeleton `002` et les cinq templates livrés restent inchangés.
|
||||
|
||||
La correction reste strictement locale :
|
||||
|
||||
```text
|
||||
0.0.4-alpha.4.fix.1
|
||||
```
|
||||
|
||||
Le delta `alpha.4` livré reste un snapshot historique et n'est pas réécrit. Le fix corrige la procédure de smoke en adaptant aussi le commentaire de `.cargo/config.toml`, puis rejoue les contrôles nécessaires.
|
||||
|
||||
## Résultat
|
||||
|
||||
`0.0.4-alpha.4` est enregistré `FAIL`.
|
||||
|
||||
La seule transition autorisée est :
|
||||
|
||||
```text
|
||||
0.0.4-alpha.4.fix.1
|
||||
```
|
||||
85
history/0.0.4/beta.1.fix.1.md
Normal file
85
history/0.0.4/beta.1.fix.1.md
Normal file
@@ -0,0 +1,85 @@
|
||||
<!-- file: history/0.0.4/beta.1.fix.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# History 0.0.4-beta.1.fix.1 — correction de la gate de réconciliation
|
||||
|
||||
## Statut
|
||||
|
||||
PASS
|
||||
|
||||
La gate opérateur de `0.0.4-beta.1.fix.1` exécutée le `2026-09-24` confirme que l'échec de `beta.1` provenait uniquement de la syntaxe de sa gate et que la réconciliation interne prévue est propre après correction.
|
||||
|
||||
Le history `beta.1` reste enregistré `FAIL` et n'est pas réécrit rétroactivement.
|
||||
|
||||
## Baseline et version
|
||||
|
||||
La tranche précédente `0.0.4-beta.1` a été committée et poussée sous le commit observé :
|
||||
|
||||
```text
|
||||
fdaaa35
|
||||
```
|
||||
|
||||
Ce commit contient `history/0.0.4/beta.1.md` avec statut `FAIL`. Le history de `alpha.4.fix.1` reste présent avec statut `PASS`.
|
||||
|
||||
La version contrôlée après application du fix est :
|
||||
|
||||
```text
|
||||
0.0.4-beta.1.fix.1
|
||||
```
|
||||
|
||||
Le delta `deltas/0.0.4/beta.1.fix.1.md` est présent et `history/0.0.4/beta.1.fix.1.md` était absent pendant la gate.
|
||||
|
||||
## Validation opérateur observée
|
||||
|
||||
La suite Python a exécuté `15` tests, tous réussis :
|
||||
|
||||
```text
|
||||
Ran 15 tests in 0.238s
|
||||
|
||||
OK
|
||||
```
|
||||
|
||||
Les trois audits Markdown ont réussi :
|
||||
|
||||
```text
|
||||
Markdown header audit: clean (117 file(s))
|
||||
Markdown table audit: clean (3 table(s), 117 file(s))
|
||||
Markdown link audit: clean (113 local link(s), 117 file(s))
|
||||
```
|
||||
|
||||
L'audit Python corrigé de réconciliation s'est exécuté jusqu'à son terme et a affiché :
|
||||
|
||||
```text
|
||||
Skeleton beta reconciliation fix audit: clean (beta.1 FAIL recorded, 3 skeleton docs, 5 TOML parsed)
|
||||
```
|
||||
|
||||
Il confirme notamment :
|
||||
|
||||
- la chaîne historique `alpha.1 = PASS`, `alpha.2 = PASS`, `alpha.3 = PASS`, `alpha.4 = FAIL`, `alpha.4.fix.1 = PASS`, `beta.1 = FAIL` ;
|
||||
- la présence exclusive des trois documents de la collection skeletons : index, fondation gouvernée et spécialisation Rust/Cargo ;
|
||||
- les owners généraux `200/210/300/400` de la fondation et `500/510` de la spécialisation Rust/Cargo ;
|
||||
- le caractère adaptable et non universel des valeurs `0.1.0`, `2024`, `project-name` et `project-core-lib` ;
|
||||
- les limites documentées des audits Markdown et Rust ;
|
||||
- le maintien du différé Java/Maven/Gradle, Android, Web, JNI et Tauri ;
|
||||
- le parsing réussi des cinq fichiers TOML Rust/Cargo.
|
||||
|
||||
`git diff --check` et `git diff --cached --check` n'ont produit aucun diagnostic. Le scope Git observé avant ce history est exactement :
|
||||
|
||||
```text
|
||||
M VERSION
|
||||
A deltas/0.0.4/beta.1.fix.1.md
|
||||
```
|
||||
|
||||
La transcription du terminal intercale des fragments de heredoc avec les sorties des tests et audits ; les résultats finaux et le statut Git restent néanmoins explicites et aucun échec n'est présent dans cette gate corrigée.
|
||||
|
||||
## Revue de cohérence
|
||||
|
||||
Aucune correction de contenu PGR n'est requise par ce fix. Les règles, skeletons, templates, scripts, tests et documents vivants restent inchangés par rapport à `beta.1`.
|
||||
|
||||
La réconciliation confirme que `220-SKELETONS.md` possède le contrat transversal tandis que les skeletons `001` et `002` composent les owners existants sans les redéfinir. Les domaines différés restent absents sans placeholder anticipé.
|
||||
|
||||
## Transition
|
||||
|
||||
`0.0.4-beta.1.fix.1` est enregistré `PASS`.
|
||||
|
||||
Appliquer ce history, committer et pousser la tranche avant d'appliquer `0.0.4-rc.1`. Le commit futur de ce fix n'est pas attesté par la transcription fournie.
|
||||
97
history/0.0.4/beta.1.md
Normal file
97
history/0.0.4/beta.1.md
Normal file
@@ -0,0 +1,97 @@
|
||||
<!-- file: history/0.0.4/beta.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# History 0.0.4-beta.1 — réconciliation interne des skeletons
|
||||
|
||||
## Statut
|
||||
|
||||
FAIL
|
||||
|
||||
La tranche `0.0.4-beta.1` n'est pas enregistrée `PASS` telle quelle.
|
||||
|
||||
Les tests Python, les trois audits Markdown, les contrôles de présence et le scope Git ont réussi, mais le script Python de réconciliation embarqué dans la gate contient une erreur de syntaxe. Une commande obligatoire ayant échoué, la tranche doit rester `FAIL` même si le défaut appartient uniquement à la gate et non au contenu réconcilié.
|
||||
|
||||
## Baseline et version
|
||||
|
||||
La tranche précédente `0.0.4-alpha.4.fix.1` a été committée et poussée sous le commit observé :
|
||||
|
||||
```text
|
||||
ea80396
|
||||
```
|
||||
|
||||
Ce commit contient `history/0.0.4/alpha.4.fix.1.md` avec statut `PASS` et conserve `history/0.0.4/alpha.4.md` avec statut `FAIL`.
|
||||
|
||||
La version contrôlée après application de `beta.1` est :
|
||||
|
||||
```text
|
||||
0.0.4-beta.1
|
||||
```
|
||||
|
||||
`deltas/0.0.4/beta.1.md` est présent et `history/0.0.4/beta.1.md` était absent pendant la gate.
|
||||
|
||||
## Contrôles réussis observés
|
||||
|
||||
Les contrôles initiaux ont confirmé la présence des deux skeletons concrets et l'absence des skeletons Java/Android différés. Les histories `alpha.4` et `alpha.4.fix.1` ont respectivement été observés en `FAIL` et `PASS`.
|
||||
|
||||
La suite Python globale a exécuté `15` tests, tous réussis :
|
||||
|
||||
```text
|
||||
Ran 15 tests in 0.223s
|
||||
|
||||
OK
|
||||
```
|
||||
|
||||
Les trois audits Markdown ont réussi :
|
||||
|
||||
```text
|
||||
Markdown header audit: clean (115 file(s))
|
||||
Markdown table audit: clean (3 table(s), 115 file(s))
|
||||
Markdown link audit: clean (113 local link(s), 115 file(s))
|
||||
```
|
||||
|
||||
`git diff --check` et `git diff --cached --check` n'ont produit aucun diagnostic. Le scope Git observé avant le présent history est exactement :
|
||||
|
||||
```text
|
||||
M VERSION
|
||||
A deltas/0.0.4/beta.1.md
|
||||
```
|
||||
|
||||
La transcription du terminal contient des fragments de heredoc intercalés avec les sorties des tests ; les résultats finaux ci-dessus restent identifiables.
|
||||
|
||||
## Défaut exact
|
||||
|
||||
Le script Python de réconciliation contient l'assertion suivante :
|
||||
|
||||
```python
|
||||
assert 'Les audits ne modifient ni les fichiers inspectés ni l'arborescence de build.' in rust_audits
|
||||
```
|
||||
|
||||
La chaîne Python est délimitée par des apostrophes simples et contient elle-même l'apostrophe de `l'arborescence`. Le parseur s'arrête donc avant l'exécution des assertions avec :
|
||||
|
||||
```text
|
||||
SyntaxError: unterminated string literal (detected at line 67)
|
||||
```
|
||||
|
||||
Le défaut est purement syntaxique dans la gate `beta.1`. Aucun résultat de cette commande de réconciliation ne peut être considéré comme acquis, même si les contrôles précédents ont réussi.
|
||||
|
||||
## Décision
|
||||
|
||||
Aucun REPLAN n'est requis.
|
||||
|
||||
Le delta `beta.1` et le présent history restent des snapshots historiques et ne doivent pas être réécrits. La correction doit être limitée à une tranche :
|
||||
|
||||
```text
|
||||
0.0.4-beta.1.fix.1
|
||||
```
|
||||
|
||||
Ce fix ne modifie aucun document vivant, skeleton, template, script ou test. Il rejoue la réconciliation avec une chaîne Python correctement délimitée, ainsi que les contrôles nécessaires pour confirmer que le contenu de `beta.1` était cohérent.
|
||||
|
||||
## Résultat
|
||||
|
||||
`0.0.4-beta.1` est enregistré `FAIL`.
|
||||
|
||||
La seule transition autorisée est :
|
||||
|
||||
```text
|
||||
0.0.4-beta.1.fix.1
|
||||
```
|
||||
92
history/0.0.4/rc.1.md
Normal file
92
history/0.0.4/rc.1.md
Normal file
@@ -0,0 +1,92 @@
|
||||
<!-- file: history/0.0.4/rc.1.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# History 0.0.4-rc.1 — gate de release candidate
|
||||
|
||||
## Statut
|
||||
|
||||
PASS
|
||||
|
||||
La gate opérateur de `0.0.4-rc.1` exécutée le `2026-09-24` valide le gel fonctionnel de la release candidate, sa présentation candidate, le prompt de reprise `005` et le smoke d'instanciation Rust/Cargo. Cette preuve porte sur la RC avant son commit ; elle ne constitue ni la promotion stable, ni le tag `v0.0.4`, ni une vérification post-tag.
|
||||
|
||||
## Baseline et scope observés
|
||||
|
||||
La baseline opérateur est le commit `3f8fa6b` de `0.0.4-beta.1.fix.1`, poussé sur `master` avant application du delta RC. L'opérateur a confirmé `VERSION = 0.0.4-rc.1`, la présence dans `HEAD` de `history/0.0.4/beta.1.fix.1.md`, la présence du delta `rc.1` et du prompt `005`, ainsi que l'absence du présent history avant sa livraison.
|
||||
|
||||
Les révisions et marqueurs attendus ont été retrouvés :
|
||||
|
||||
```text
|
||||
CHANGELOG.md version 6
|
||||
CHANGELOG 0.0.4 (candidate)
|
||||
docs/plans/004-V0_0_4_SKELETONS_PLAN.md version 2
|
||||
beta.1.fix.1 PASS consigné dans le plan
|
||||
prompts/005-V0_0_5_START_PROMPT.md baseline pgr-v0.0.4.zip
|
||||
prompts/005-V0_0_5_START_PROMPT.md khadhroony-solana-project
|
||||
prompts/005-V0_0_5_START_PROMPT.md sasedev-games
|
||||
```
|
||||
|
||||
Le prompt `005` reste conditionnel : il demande explicitement les baselines réelles de KSP et `sasedev-games`, interdit d'en déduire version, commit ou contenu, et ne présente le rapport `pgr-0.0.4-publish.001-report.md` comme disponible que s'il a réellement été produit et validé.
|
||||
|
||||
## Tests et audits documentaires
|
||||
|
||||
Les `15` tests Python ciblés ont tous réussi :
|
||||
|
||||
```text
|
||||
Ran 15 tests in 0.212s
|
||||
OK
|
||||
```
|
||||
|
||||
Les trois audits Markdown ont affiché :
|
||||
|
||||
```text
|
||||
Markdown header audit: clean (120 file(s))
|
||||
Markdown table audit: clean (3 table(s), 120 file(s))
|
||||
Markdown link audit: clean (116 local link(s), 120 file(s))
|
||||
```
|
||||
|
||||
L'audit d'intégration RC a affiché :
|
||||
|
||||
```text
|
||||
RC integration audit: clean (7 prior histories, 3 skeleton docs, 5 TOML parsed, prompt 005 ready)
|
||||
```
|
||||
|
||||
Il confirme notamment les statuts historiques précédents (`alpha.4 = FAIL`, `alpha.4.fix.1 = PASS`, `beta.1 = FAIL`, `beta.1.fix.1 = PASS`), les trois documents de la collection skeletons, les owners attendus, les cinq TOML Rust/Cargo lisibles et la disponibilité du prompt `005`.
|
||||
|
||||
## Smoke Rust/Cargo observé
|
||||
|
||||
La toolchain observée est :
|
||||
|
||||
```text
|
||||
cargo 1.94.1 (29ea6fb6a 2026-03-24)
|
||||
rustc 1.94.1 (e408947bf 2026-03-25)
|
||||
rustfmt 1.8.0-stable (e408947bfd 2026-03-25)
|
||||
clippy 0.1.94 (e408947bfd 2026-03-25)
|
||||
```
|
||||
|
||||
L'adaptation temporaire des cinq templates a terminé par :
|
||||
|
||||
```text
|
||||
RC temporary Rust/Cargo template adaptation: clean
|
||||
```
|
||||
|
||||
Le workspace temporaire `smoke-core-lib v1.2.3` a ensuite passé `cargo metadata`, `cargo fmt --all -- --check`, `cargo check --workspace` et `cargo clippy --workspace --all-targets --all-features -- -D warnings`. Les sorties Cargo de `check` et `clippy` se terminent toutes deux par `Finished dev profile` sans diagnostic bloquant.
|
||||
|
||||
Le répertoire temporaire a été supprimé et le trap désarmé après le smoke ; aucun artefact de cette instanciation n'entre dans PGR.
|
||||
|
||||
## Scope Git
|
||||
|
||||
`git diff --check` et `git diff --cached --check` n'ont produit aucun diagnostic. Après ajout des fichiers RC, le statut indexé transmis est exactement :
|
||||
|
||||
```text
|
||||
M CHANGELOG.md
|
||||
M VERSION
|
||||
A deltas/0.0.4/rc.1.md
|
||||
M docs/plans/004-V0_0_4_SKELETONS_PLAN.md
|
||||
A prompts/005-V0_0_5_START_PROMPT.md
|
||||
```
|
||||
|
||||
La revue du contenu confirme que le changelog décrit la release plutôt que ses tranches internes, que les deux `FAIL` historiques restent visibles avec leurs fixes `PASS`, que le prompt `005` ne présume aucune baseline KSP/Games non fournie et qu'aucun nouveau skeleton, profil, template, audit ou domaine technologique n'a été introduit en RC.
|
||||
|
||||
## Transition
|
||||
|
||||
Appliquer ce history puis committer/pousser `0.0.4-rc.1`. Ensuite seulement appliquer le delta stable `rel.001`. La promotion stable reste pré-tag : le tag `v0.0.4`, son archive source Gitea et le rapport post-tag `publish.001` ne pourront être attestés qu'après un `rel.001` PASS, son history, le commit stable et la publication réelle du tag.
|
||||
86
history/0.0.4/rel.001.md
Normal file
86
history/0.0.4/rel.001.md
Normal file
@@ -0,0 +1,86 @@
|
||||
<!-- file: history/0.0.4/rel.001.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# History 0.0.4 rel.001 — clôture stable pré-tag
|
||||
|
||||
## Statut
|
||||
|
||||
PASS
|
||||
|
||||
La gate stable pré-tag `rel.001` exécutée par l'opérateur le `2026-09-24` valide la promotion documentaire de `0.0.4`. Cette preuve porte sur l'état du dépôt avant le commit stable et avant le tag `v0.0.4` ; elle ne valide pas encore l'archive source publiée ensuite par Gitea.
|
||||
|
||||
## Baseline et version
|
||||
|
||||
La baseline opérateur est le commit `c6af96b` de `0.0.4-rc.1`, poussé sur `master` avant application du delta stable. L'opérateur a confirmé `VERSION = 0.0.4`, la présence dans `HEAD` de `history/0.0.4/rc.1.md`, la présence du delta `rel.001` et du prompt `005`, ainsi que l'absence du présent history avant sa livraison.
|
||||
|
||||
Les révisions et marqueurs de clôture attendus ont été retrouvés :
|
||||
|
||||
```text
|
||||
README.md version 11
|
||||
ROADMAP.md version 5
|
||||
CHANGELOG.md version 7
|
||||
docs/000-README.md version 9
|
||||
docs/plans/004-V0_0_4_SKELETONS_PLAN.md version 3
|
||||
ROADMAP 0.0.4 terminé
|
||||
CHANGELOG entrée stable ## 0.0.4
|
||||
plan 004 plan historique, rc.1 PASS
|
||||
```
|
||||
|
||||
La présentation du dépôt décrit désormais `0.0.4` comme la release qui définit le contrat transversal des skeleton specifications, ajoute la fondation gouvernée `001` et la spécialisation Rust/Cargo `002`, tout en maintenant le différé des autres spécialisations technologiques insuffisamment matérialisées.
|
||||
|
||||
## Chaîne historique
|
||||
|
||||
L'audit de la chaîne `0.0.4` a affiché :
|
||||
|
||||
```text
|
||||
Stable history audit: clean (8 prior histories with expected statuses, rel.001 pending)
|
||||
```
|
||||
|
||||
Les statuts antérieurs observés et conservés sont :
|
||||
|
||||
```text
|
||||
alpha.1 PASS
|
||||
alpha.2 PASS
|
||||
alpha.3 PASS
|
||||
alpha.4 FAIL
|
||||
alpha.4.fix.1 PASS
|
||||
beta.1 FAIL
|
||||
beta.1.fix.1 PASS
|
||||
rc.1 PASS
|
||||
```
|
||||
|
||||
Les deux échecs historiques restent donc conservés avec leurs correctifs `PASS`; `rel.001` était le seul delta de `0.0.4` encore sans history au moment de la gate.
|
||||
|
||||
## Audits documentaires
|
||||
|
||||
Les trois audits Markdown ont affiché :
|
||||
|
||||
```text
|
||||
Markdown header audit: clean (122 file(s))
|
||||
Markdown table audit: clean (3 table(s), 122 file(s))
|
||||
Markdown link audit: clean (116 local link(s), 122 file(s))
|
||||
```
|
||||
|
||||
Les `15` tests Python, les cinq TOML Rust/Cargo et le smoke d'instanciation complet avaient été validés dans `rc.1`. Ils n'ont pas été rejoués pendant cette gate stable, conformément au delta `rel.001`, car aucun code, script, test, template ou skeleton technique n'est modifié par la promotion documentaire.
|
||||
|
||||
## Scope Git observé
|
||||
|
||||
`git diff --check` et `git diff --cached --check` n'ont produit aucun diagnostic. Après ajout des fichiers du delta, le statut indexé transmis est exactement :
|
||||
|
||||
```text
|
||||
M CHANGELOG.md
|
||||
M README.md
|
||||
M ROADMAP.md
|
||||
M VERSION
|
||||
A deltas/0.0.4/rel.001.md
|
||||
M docs/000-README.md
|
||||
M docs/plans/004-V0_0_4_SKELETONS_PLAN.md
|
||||
```
|
||||
|
||||
La revue opérateur confirme que le scope fonctionnel gelé en RC n'a pas changé, que README/roadmap/changelog/index/plan décrivent la même stable, que le prompt `005` reste conditionnel à une publication réelle et à des baselines KSP/Games explicitement fournies, et qu'aucune preuve post-tag n'est anticipée.
|
||||
|
||||
## Transition
|
||||
|
||||
Appliquer ce history puis committer et pousser la stable `0.0.4`. Ensuite seulement créer et publier le tag canonique `v0.0.4`, télécharger l'archive source associée depuis Gitea et exécuter une vérification post-tag indépendante.
|
||||
|
||||
Le commit stable, le tag, l'identité de l'archive publiée et le résultat du contrôle post-tag ne sont pas attestés par la transcription reçue. Le rapport `pgr-0.0.4-publish.001-report.md` ne pourra être produit qu'après ces opérations réelles ; le démarrage de `0.0.5` reste bloqué jusqu'à cette preuve post-tag `PASS` et à la fourniture des baselines autoritaires demandées par `prompts/005-V0_0_5_START_PROMPT.md`.
|
||||
44
prompts/004-V0_0_4_START_PROMPT.md
Normal file
44
prompts/004-V0_0_4_START_PROMPT.md
Normal file
@@ -0,0 +1,44 @@
|
||||
<!-- file: prompts/004-V0_0_4_START_PROMPT.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Prompt de démarrage 0.0.4 — spécifications de skeletons
|
||||
|
||||
## Baseline et cible
|
||||
|
||||
Dépôt canonique : `https://git.sasedev.com/Sasedev/pgr`.
|
||||
|
||||
La baseline attendue au démarrage effectif de `0.0.4` est l'archive source téléchargée depuis le tag Gitea `v0.0.3`, dont le nom attendu est `pgr-v0.0.3.zip`. Une archive source peut légitimement ne pas contenir `.git` ; vérifier son contenu et ses artefacts de gouvernance sans lui attribuer une preuve Git qu'elle ne peut contenir.
|
||||
|
||||
Version cible : `0.0.4`. Première tranche attendue : `0.0.4-alpha.1`.
|
||||
|
||||
Si un rapport séparé `pgr-0.0.3-publish.001-report.md` a effectivement été produit et conclut `PASS`, le fournir avec l'archive. S'il est absent ou non validé, le signaler explicitement ; ne jamais présumer la publication ou un résultat PASS. Ce rapport ne fait pas partie du tag et ne remplace pas l'audit de la nouvelle session.
|
||||
|
||||
## Reprise manuelle après publication
|
||||
|
||||
Après vérification réelle de l'archive du tag et du rapport post-tag PASS, remettre spontanément à l'opérateur un message de reprise adapté selon [`docs/templates/003-NEW_SESSION_PROMPT.md`](../docs/templates/003-NEW_SESSION_PROMPT.md). Si les noms attendus ci-dessus sont confirmés et le rapport est PASS, le texte est :
|
||||
|
||||
```text
|
||||
Partir de l'archive pgr-v0.0.3.zip téléchargée depuis le tag Gitea v0.0.3 et du rapport post-tag pgr-0.0.3-publish.001-report.md. Lire et exécuter prompts/004-V0_0_4_START_PROMPT.md. Vérifier l'archive, les règles, la gouvernance, la structure documentaire, les deltas/histories et la cohérence globale avant de préparer 0.0.4-alpha.1.
|
||||
```
|
||||
|
||||
Si le rapport manque ou n'est pas PASS, supprimer sa mention de la phrase et transmettre son état réel séparément. Adapter les noms à ceux des fichiers effectivement téléchargés. Ce texte ne doit être remis qu'après clôture stable et vérification post-tag, jamais comme attestation anticipée au stade RC.
|
||||
|
||||
## Mission
|
||||
|
||||
Définir les premières skeleton specifications Markdown réutilisables et les règles pratiques de composition des profils, templates et choix propres au projet. Un skeleton décrit une procédure de sélection, les fichiers et profils applicables, les décisions à prendre et une validation proportionnée ; il ne génère pas automatiquement un projet et ne fixe pas son architecture pour toujours.
|
||||
|
||||
`alpha.1` MUST vérifier entièrement la stable `v0.0.3`, en particulier les règles `200` à `610`, les cinq modèles Rust/Cargo, les trois audits Markdown, les deux audits de style Rust facultatifs, la chaîne de deltas/histories et les limites annoncées. Elle doit établir quels skeletons répondent déjà à un besoin concret et lesquels exigent encore des templates ou des décisions préalables. Planifier ensuite les tranches proportionnées de `0.0.4` avant toute matérialisation importante.
|
||||
|
||||
## Principes de conception
|
||||
|
||||
- Conserver un propriétaire normatif unique par règle et une copie autonome des règles/configurations pertinentes dans chaque projet instancié.
|
||||
- Respecter la séparation : règles applicables sous `docs/rules/`, fichiers techniques copiables sous `templates/`, mode d'adaptation sous `docs/templates/`, spécifications de skeletons Markdown et audits read-only pour les propriétés réellement contrôlables.
|
||||
- Sélectionner seulement les profils et templates justifiés par le type de projet ; documenter explicitement le nom, la version, les cibles, les dépendances et les exceptions qui dépendent du destinataire.
|
||||
- Ne pas déclarer universelles les valeurs `0.1.0`, `2024`, les seuils Clippy ou les chemins d'exemple des templates Rust/Cargo.
|
||||
- Préserver les décisions d'ordre sémantique des constantes : l'audit correspondant n'est pas une gate globale de tout workspace Rust.
|
||||
- Différer les skeletons Java/Android, Web, JNI, Tauri et autres familles dont les pièces nécessaires ou les propriétaires manquent encore ; un nouveau domaine demande un cadrage justifié.
|
||||
- Garder les audits ciblés et non redondants avec les outils officiels ; les tests prouvent des comportements utiles, sans quota arbitraire de couverture.
|
||||
|
||||
## Workflow
|
||||
|
||||
Suivre `RULES.md`, [`docs/rules/210-WORKFLOW.md`](../docs/rules/210-WORKFLOW.md) et [`docs/rules/400-VALIDATION.md`](../docs/rules/400-VALIDATION.md). La séquence reste delta → gate opérateur → history constaté → application du history → commit → delta suivant. Un changement de session ne crée pas une version nouvelle. Un rapport de publication post-tag est séparé de la validation pré-tag.
|
||||
66
prompts/005-V0_0_5_START_PROMPT.md
Normal file
66
prompts/005-V0_0_5_START_PROMPT.md
Normal file
@@ -0,0 +1,66 @@
|
||||
<!-- file: prompts/005-V0_0_5_START_PROMPT.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Prompt de démarrage 0.0.5 — réconciliation réelle avec KSP et sasedev-games
|
||||
|
||||
## Baseline PGR et cible
|
||||
|
||||
Dépôt canonique PGR : `https://git.sasedev.com/Sasedev/pgr`.
|
||||
|
||||
La baseline PGR attendue au démarrage effectif de `0.0.5` est l'archive source téléchargée depuis le tag Gitea `v0.0.4`, dont le nom attendu est `pgr-v0.0.4.zip`. Une archive source peut légitimement ne pas contenir `.git` ; vérifier son contenu et ses artefacts de gouvernance sans lui attribuer une preuve Git qu'elle ne peut contenir.
|
||||
|
||||
Version cible : `0.0.5`. Première tranche attendue : `0.0.5-alpha.1`.
|
||||
|
||||
Si un rapport séparé `pgr-0.0.4-publish.001-report.md` a effectivement été produit et conclut `PASS`, le fournir avec l'archive. S'il est absent ou non validé, le signaler explicitement ; ne jamais présumer la publication ou un résultat PASS. Ce rapport ne fait pas partie du tag et ne remplace pas l'audit de la nouvelle session.
|
||||
|
||||
## Sources de réconciliation externes
|
||||
|
||||
`0.0.5` doit confronter PGR à des états réels de `khadhroony-solana-project` et `sasedev-games`. Les baselines exactes de ces deux projets doivent donc être fournies explicitement à la session sous forme d'archives, tags ou autres snapshots autoritaires clairement identifiés.
|
||||
|
||||
Ne pas déduire leur version, leur commit ou leur contenu d'une conversation précédente, d'un workspace local non fourni ou d'un souvenir de projet. Si l'une des deux sources manque, l'indiquer et borner l'audit à ce qui est effectivement disponible au lieu de fabriquer une comparaison complète.
|
||||
|
||||
Ces projets sont des corpus de réconciliation. Leurs conventions locales ne deviennent pas automatiquement des règles PGR, et PGR ne doit pas leur imposer rétroactivement une règle sans avoir distingué le besoin commun du besoin spécifique au projet.
|
||||
|
||||
## Reprise manuelle après publication
|
||||
|
||||
Après vérification réelle de l'archive du tag PGR et du rapport post-tag PASS, remettre spontanément à l'opérateur un message de reprise adapté selon [`docs/templates/003-NEW_SESSION_PROMPT.md`](../docs/templates/003-NEW_SESSION_PROMPT.md).
|
||||
|
||||
Si les noms PGR attendus ci-dessus sont confirmés et le rapport est PASS, la base de la phrase est :
|
||||
|
||||
```text
|
||||
Partir de l'archive pgr-v0.0.4.zip téléchargée depuis le tag Gitea v0.0.4 et du rapport post-tag pgr-0.0.4-publish.001-report.md. Lire et exécuter prompts/005-V0_0_5_START_PROMPT.md. Vérifier l'archive PGR et les baselines autoritaires fournies de khadhroony-solana-project et sasedev-games avant de préparer 0.0.5-alpha.1.
|
||||
```
|
||||
|
||||
Si le rapport manque ou n'est pas PASS, retirer sa mention et transmettre son état réel séparément. Adapter également les références KSP/Games aux fichiers ou tags réellement fournis. Ce texte ne doit être remis qu'après clôture stable et vérification post-tag de `0.0.4`, jamais comme attestation anticipée au stade RC.
|
||||
|
||||
## Mission
|
||||
|
||||
Réaliser la première réconciliation explicite de PGR avec deux projets réels qui ont servi de corpus de conception : `khadhroony-solana-project` et `sasedev-games`.
|
||||
|
||||
`alpha.1` MUST commencer par auditer indépendamment la stable `v0.0.4`, ses règles, profils, templates, skeleton specifications, audits et chaîne delta/history. Elle doit ensuite inventorier les règles, conventions, structures et audits réellement présents dans les deux baselines externes fournies, puis classer chaque écart avant toute modification importante.
|
||||
|
||||
La réconciliation doit distinguer au minimum :
|
||||
|
||||
- ce qui est déjà correctement possédé par PGR et seulement appliqué localement ;
|
||||
- ce qui révèle un besoin commun manquant ou insuffisamment spécifié dans PGR ;
|
||||
- ce qui doit rester spécifique à KSP ou à Games ;
|
||||
- ce qui est devenu obsolète, redondant ou contradictoire dans un projet par rapport au modèle PGR actuel ;
|
||||
- ce qui nécessite un nouveau profil, template, skeleton ou audit uniquement si un besoin réel et réutilisable le justifie.
|
||||
|
||||
Fixer ensuite un plan `0.0.5` proportionné. Ne pas transformer la phase d'inventaire en migration massive des projets et ne pas supposer qu'une divergence doit forcément être résolue du côté PGR.
|
||||
|
||||
## Principes de réconciliation
|
||||
|
||||
- Comparer des responsabilités et propriétés concrètes, pas seulement des noms de fichiers ou des structures visuellement similaires.
|
||||
- Conserver un propriétaire normatif unique et éviter de recopier dans PGR une règle déjà possédée ailleurs sous une forme plus générale.
|
||||
- Ne généraliser une convention locale KSP/Games que lorsqu'au moins son besoin et son contrat sont réellement réutilisables.
|
||||
- Préserver les exceptions locales motivées et les contraintes propres à une plateforme, un protocole, une application ou une phase de développement.
|
||||
- Réutiliser les audits PGR existants lorsqu'ils contrôlent déjà la propriété recherchée ; ne pas recréer des scripts composites uniquement parce qu'ils existent dans un projet source.
|
||||
- Vérifier les skeletons `001` et `002` contre des usages réels sans considérer leur adoption intégrale comme obligatoire.
|
||||
- Documenter explicitement les éléments différés si les preuves disponibles ne suffisent pas à créer un owner ou un artefact PGR durable.
|
||||
|
||||
## Workflow
|
||||
|
||||
Suivre `RULES.md`, [`docs/rules/210-WORKFLOW.md`](../docs/rules/210-WORKFLOW.md) et [`docs/rules/400-VALIDATION.md`](../docs/rules/400-VALIDATION.md). La séquence reste delta → gate opérateur → history constaté → application du history → commit → delta suivant.
|
||||
|
||||
Les baselines externes servent à l'analyse et à la preuve. Une modification effective de KSP ou de `sasedev-games`, si elle devient nécessaire, doit être explicitement planifiée et validée dans le scope approprié ; elle ne doit pas être cachée dans un delta PGR.
|
||||
144
scripts/_rust_audit_common.py
Normal file
144
scripts/_rust_audit_common.py
Normal file
@@ -0,0 +1,144 @@
|
||||
# file: scripts/_rust_audit_common.py
|
||||
# version: 1
|
||||
|
||||
"""Small shared lexical and file-selection helpers for read-only Rust audits."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import pathlib
|
||||
|
||||
_IGNORED = frozenset({".git", ".venv", "__pycache__", "target", "builds"})
|
||||
|
||||
|
||||
def selected_files(raw_paths: list[str]) -> tuple[list[pathlib.Path], list[str]]:
|
||||
"""Select explicit Rust files and directories, without following generated trees."""
|
||||
|
||||
files: set[pathlib.Path] = set()
|
||||
errors: list[str] = []
|
||||
for raw in raw_paths:
|
||||
path = pathlib.Path(raw)
|
||||
if path.is_dir():
|
||||
files.update(
|
||||
candidate
|
||||
for candidate in path.rglob("*.rs")
|
||||
if candidate.is_file() and not (set(candidate.parts) & _IGNORED)
|
||||
)
|
||||
elif path.is_file() and path.suffix == ".rs":
|
||||
files.add(path)
|
||||
else:
|
||||
errors.append(f"unsupported or missing Rust path: {path}")
|
||||
return sorted(files), errors
|
||||
|
||||
|
||||
def mask_source(text: str) -> tuple[str, set[int]]:
|
||||
"""Mask comments and literals, preserving offsets and structural punctuation.
|
||||
|
||||
Return line numbers whose first character is inside a multiline literal, so
|
||||
an empty line in a raw string cannot be mistaken for an empty code line.
|
||||
This is a lexical helper, not a full Rust parser or a compiler substitute.
|
||||
"""
|
||||
|
||||
output = list(text)
|
||||
protected: set[int] = set()
|
||||
index = 0
|
||||
line = 1
|
||||
state = "code"
|
||||
block_depth = 0
|
||||
raw_hashes = 0
|
||||
while index < len(text):
|
||||
char = text[index]
|
||||
nxt = text[index + 1] if index + 1 < len(text) else ""
|
||||
if char == "\n":
|
||||
line += 1
|
||||
if state in {"string", "raw_string"}:
|
||||
protected.add(line)
|
||||
if state == "line_comment":
|
||||
state = "code"
|
||||
index += 1
|
||||
continue
|
||||
if state == "code":
|
||||
if char == "/" and nxt in {"/", "*"}:
|
||||
output[index:index + 2] = [" ", " "]
|
||||
state = "line_comment" if nxt == "/" else "block_comment"
|
||||
block_depth = 1 if nxt == "*" else 0
|
||||
index += 2
|
||||
continue
|
||||
if char == '"':
|
||||
output[index] = " "
|
||||
state = "string"
|
||||
index += 1
|
||||
continue
|
||||
if char == "'":
|
||||
# Lifetimes have no nearby closing quote; char literals do.
|
||||
probe = index + 1
|
||||
escaped = False
|
||||
found = False
|
||||
while probe < min(len(text), index + 8) and text[probe] != "\n":
|
||||
if text[probe] == "'" and not escaped:
|
||||
found = True
|
||||
break
|
||||
escaped = text[probe] == "\\" and not escaped
|
||||
probe += 1
|
||||
if found:
|
||||
output[index] = " "
|
||||
state = "char"
|
||||
index += 1
|
||||
continue
|
||||
# Also covers r#"..."#, br#"..."# and cr#"..."#.
|
||||
if char == "r" and (index == 0 or text[index - 1] not in "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"):
|
||||
probe = index + 1
|
||||
while probe < len(text) and text[probe] == "#":
|
||||
probe += 1
|
||||
if probe < len(text) and text[probe] == '"':
|
||||
output[index:probe + 1] = [" "] * (probe + 1 - index)
|
||||
raw_hashes = probe - index - 1
|
||||
state = "raw_string"
|
||||
index = probe + 1
|
||||
continue
|
||||
index += 1
|
||||
continue
|
||||
if state == "line_comment":
|
||||
output[index] = " "
|
||||
elif state == "block_comment":
|
||||
output[index] = " "
|
||||
if char == "/" and nxt == "*":
|
||||
output[index + 1] = " "
|
||||
block_depth += 1
|
||||
index += 2
|
||||
continue
|
||||
if char == "*" and nxt == "/":
|
||||
output[index + 1] = " "
|
||||
block_depth -= 1
|
||||
if block_depth == 0:
|
||||
state = "code"
|
||||
index += 2
|
||||
continue
|
||||
elif state in {"string", "char"}:
|
||||
output[index] = " "
|
||||
if char == "\\" and index + 1 < len(text):
|
||||
if text[index + 1] != "\n":
|
||||
output[index + 1] = " "
|
||||
index += 2
|
||||
continue
|
||||
if char == ('"' if state == "string" else "'"):
|
||||
state = "code"
|
||||
elif state == "raw_string":
|
||||
output[index] = " "
|
||||
if char == '"' and text.startswith("#" * raw_hashes, index + 1):
|
||||
output[index + 1:index + 1 + raw_hashes] = [" "] * raw_hashes
|
||||
index += 1 + raw_hashes
|
||||
state = "code"
|
||||
continue
|
||||
index += 1
|
||||
return "".join(output), protected
|
||||
|
||||
|
||||
def line_depths(masked: str) -> list[int]:
|
||||
"""Return brace depth at the start of each line, excluding literals."""
|
||||
|
||||
depths: list[int] = []
|
||||
depth = 0
|
||||
for line in masked.splitlines():
|
||||
depths.append(depth)
|
||||
depth = max(0, depth + line.count("{") - line.count("}"))
|
||||
return depths
|
||||
96
scripts/audit_markdown_headers.py
Normal file
96
scripts/audit_markdown_headers.py
Normal file
@@ -0,0 +1,96 @@
|
||||
#!/usr/bin/env python3
|
||||
# file: scripts/audit_markdown_headers.py
|
||||
# version: 1
|
||||
|
||||
"""Validate path and positive revision in selected Markdown file headers."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import pathlib
|
||||
import re
|
||||
import sys
|
||||
|
||||
_IGNORED_DIRECTORIES = frozenset({".git", ".idea", ".venv", "__pycache__", "dist", "node_modules", "target"})
|
||||
_VERSION = re.compile(r"<!-- version: [1-9][0-9]* -->")
|
||||
|
||||
|
||||
def _selected_files(raw_paths: list[str], root: pathlib.Path) -> tuple[list[pathlib.Path], list[str]]:
|
||||
files: set[pathlib.Path] = set()
|
||||
errors: list[str] = []
|
||||
|
||||
for raw_path in raw_paths:
|
||||
path = pathlib.Path(raw_path)
|
||||
if path.is_dir() or path.is_file():
|
||||
if not path.resolve().is_relative_to(root):
|
||||
errors.append(f"Markdown header audit: path outside project root: {path}")
|
||||
continue
|
||||
if path.is_dir():
|
||||
candidates = (
|
||||
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":
|
||||
candidates = iter((path,))
|
||||
else:
|
||||
errors.append(f"Markdown header audit: unsupported or missing path: {path}")
|
||||
continue
|
||||
|
||||
for candidate in candidates:
|
||||
canonical = candidate.resolve()
|
||||
if not canonical.is_relative_to(root):
|
||||
errors.append(f"Markdown header audit: path outside project root: {candidate}")
|
||||
else:
|
||||
files.add(canonical)
|
||||
|
||||
return sorted(files), errors
|
||||
|
||||
|
||||
def _audit_file(path: pathlib.Path, root: pathlib.Path) -> list[str]:
|
||||
relative = path.relative_to(root).as_posix()
|
||||
lines = path.read_text(encoding="utf-8").splitlines()
|
||||
errors: list[str] = []
|
||||
expected_file = f"<!-- file: {relative} -->"
|
||||
|
||||
if not lines or lines[0] != expected_file:
|
||||
errors.append(f"{relative}:1: expected `{expected_file}`")
|
||||
if len(lines) < 2 or _VERSION.fullmatch(lines[1]) is None:
|
||||
errors.append(f"{relative}:2: expected positive `<!-- version: N -->`")
|
||||
return errors
|
||||
|
||||
|
||||
def main() -> int:
|
||||
"""Run the read-only Markdown header audit from the project root."""
|
||||
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("paths", nargs="+", help="Markdown files or directories to audit")
|
||||
args = parser.parse_args()
|
||||
|
||||
root = pathlib.Path.cwd().resolve()
|
||||
files, selection_errors = _selected_files(args.paths, root)
|
||||
if selection_errors or not files:
|
||||
for error in selection_errors or ["Markdown header audit: no Markdown files selected"]:
|
||||
print(error, file=sys.stderr)
|
||||
return 2
|
||||
|
||||
errors: list[str] = []
|
||||
for path in files:
|
||||
try:
|
||||
errors.extend(_audit_file(path, root))
|
||||
except (OSError, UnicodeError) as error:
|
||||
print(f"Markdown header audit: cannot read {path}: {error}", file=sys.stderr)
|
||||
return 2
|
||||
|
||||
for error in errors:
|
||||
print(error, file=sys.stderr)
|
||||
if errors:
|
||||
print(f"Markdown header audit: {len(errors)} error(s) across {len(files)} file(s)", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
print(f"Markdown header audit: clean ({len(files)} file(s))")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
83
scripts/audit_rust_blank_lines.py
Normal file
83
scripts/audit_rust_blank_lines.py
Normal file
@@ -0,0 +1,83 @@
|
||||
#!/usr/bin/env python3
|
||||
# file: scripts/audit_rust_blank_lines.py
|
||||
# version: 1
|
||||
|
||||
"""Audit blank-line spacing in explicitly selected Rust sources."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import pathlib
|
||||
import re
|
||||
import sys
|
||||
|
||||
from _rust_audit_common import line_depths, mask_source, selected_files
|
||||
|
||||
_BODY = re.compile(r"^\s*(?:(?:pub(?:\([^)]*\))?|async|const|unsafe|extern|default)\s+)*(fn|struct|enum)\b")
|
||||
|
||||
|
||||
def audit_file(path: pathlib.Path) -> list[str]:
|
||||
"""Check successive empty lines and empty function/struct/enum body lines."""
|
||||
|
||||
text = path.read_text(encoding="utf-8")
|
||||
lines = text.splitlines()
|
||||
masked, protected = mask_source(text)
|
||||
masked_lines = masked.splitlines()
|
||||
depths = line_depths(masked)
|
||||
errors: list[str] = []
|
||||
previous_blank = False
|
||||
pending: tuple[str, int] | None = None
|
||||
active: tuple[str, int] | None = None
|
||||
|
||||
for number, (original, code, depth) in enumerate(zip(lines, masked_lines, depths, strict=True), 1):
|
||||
blank = not original.strip() and number not in protected
|
||||
if blank and previous_blank:
|
||||
errors.append(f"{path}:{number}: consecutive blank Rust source lines")
|
||||
previous_blank = blank
|
||||
|
||||
if active is not None and depth <= active[1]:
|
||||
active = None
|
||||
if active is not None and blank:
|
||||
errors.append(f"{path}:{number}: blank line inside {active[0]} body")
|
||||
|
||||
if active is None and pending is None:
|
||||
match = _BODY.match(code)
|
||||
if match is not None:
|
||||
pending = (match.group(1), depth)
|
||||
if pending is not None:
|
||||
if "{" in code:
|
||||
active = pending
|
||||
pending = None
|
||||
elif ";" in code:
|
||||
pending = None
|
||||
return errors
|
||||
|
||||
|
||||
def main() -> int:
|
||||
"""Run the read-only spacing audit on explicitly selected Rust files."""
|
||||
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("paths", nargs="+", help="Rust files or directories to inspect")
|
||||
args = parser.parse_args()
|
||||
files, errors = selected_files(args.paths)
|
||||
if errors or not files:
|
||||
for error in errors or ["no Rust files selected"]:
|
||||
print(f"Rust blank-line audit: {error}", file=sys.stderr)
|
||||
return 2
|
||||
for path in files:
|
||||
try:
|
||||
errors.extend(audit_file(path))
|
||||
except (OSError, UnicodeError) as error:
|
||||
print(f"Rust blank-line audit: cannot read {path}: {error}", file=sys.stderr)
|
||||
return 2
|
||||
for error in errors:
|
||||
print(error, file=sys.stderr)
|
||||
if errors:
|
||||
print(f"Rust blank-line audit: {len(errors)} error(s) across {len(files)} file(s)", file=sys.stderr)
|
||||
return 1
|
||||
print(f"Rust blank-line audit: clean ({len(files)} file(s))")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
109
scripts/audit_rust_const_blocks.py
Normal file
109
scripts/audit_rust_const_blocks.py
Normal file
@@ -0,0 +1,109 @@
|
||||
#!/usr/bin/env python3
|
||||
# file: scripts/audit_rust_const_blocks.py
|
||||
# version: 1
|
||||
|
||||
"""Audit top-level Rust const blocks for visibility, names and spacing."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import pathlib
|
||||
import re
|
||||
import sys
|
||||
|
||||
from _rust_audit_common import line_depths, mask_source, selected_files
|
||||
|
||||
_CONST = re.compile(r"^\s*(?:(pub|pub\(crate\))\s+)?const\s+([A-Za-z_][A-Za-z0-9_]*)\s*:")
|
||||
|
||||
|
||||
def _natural_key(value: str) -> tuple[tuple[int, object], ...]:
|
||||
parts = re.findall(r"[A-Za-z_]+|[0-9]+", value)
|
||||
return tuple((1, int(part)) if part.isdigit() else (0, part) for part in parts)
|
||||
|
||||
|
||||
def _end_of_const(lines: list[str], start: int) -> int:
|
||||
"""Find the terminating semicolon outside brackets and initializer braces."""
|
||||
|
||||
brackets: list[str] = []
|
||||
closing = {"}": "{", ")": "(", "]": "["}
|
||||
for index in range(start, len(lines)):
|
||||
for char in lines[index]:
|
||||
if char in "{([":
|
||||
brackets.append(char)
|
||||
elif char in "})]" and brackets and brackets[-1] == closing[char]:
|
||||
brackets.pop()
|
||||
elif char == ";" and not brackets:
|
||||
return index
|
||||
return start
|
||||
|
||||
|
||||
def audit_file(path: pathlib.Path) -> list[str]:
|
||||
"""Compare adjacent top-level const declarations in homogeneous blocks."""
|
||||
|
||||
text = path.read_text(encoding="utf-8")
|
||||
lines = text.splitlines()
|
||||
masked, _ = mask_source(text)
|
||||
code_lines = masked.splitlines()
|
||||
depths = line_depths(masked)
|
||||
errors: list[str] = []
|
||||
previous: tuple[int, int, int, str] | None = None # end, line, visibility rank, name
|
||||
index = 0
|
||||
while index < len(lines):
|
||||
code = code_lines[index]
|
||||
if depths[index] != 0:
|
||||
index += 1
|
||||
continue
|
||||
match = _CONST.match(code)
|
||||
if match is not None:
|
||||
visibility, name = match.groups()
|
||||
rank = {"pub": 0, "pub(crate)": 1, None: 2}[visibility]
|
||||
if previous is not None:
|
||||
end, _, last_rank, last_name = previous
|
||||
if rank < last_rank:
|
||||
errors.append(f"{path}:{index + 1}: const visibility must be pub, pub(crate), private")
|
||||
if rank == last_rank and _natural_key(name) < _natural_key(last_name):
|
||||
errors.append(f"{path}:{index + 1}: const names out of alphabetical order: {last_name}, {name}")
|
||||
between = lines[end + 1:index]
|
||||
if all(not candidate.strip() for candidate in between):
|
||||
expected = 0 if rank == last_rank else 1
|
||||
if len(between) != expected:
|
||||
errors.append(f"{path}:{index + 1}: expected {expected} blank line(s) between const declarations")
|
||||
end = _end_of_const(code_lines, index)
|
||||
previous = (end, index + 1, rank, name)
|
||||
index = end + 1
|
||||
continue
|
||||
# Comments, attributes and whitespace attach to the surrounding block.
|
||||
if code.strip() and not lines[index].lstrip().startswith(("//", "/*", "*", "#[")):
|
||||
previous = None
|
||||
index += 1
|
||||
return errors
|
||||
|
||||
|
||||
def main() -> int:
|
||||
"""Run the read-only top-level const-block audit."""
|
||||
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("paths", nargs="+", help="Rust files or directories to inspect")
|
||||
args = parser.parse_args()
|
||||
files, errors = selected_files(args.paths)
|
||||
if errors or not files:
|
||||
for error in errors or ["no Rust files selected"]:
|
||||
print(f"Rust const-block audit: {error}", file=sys.stderr)
|
||||
return 2
|
||||
for path in files:
|
||||
try:
|
||||
errors.extend(audit_file(path))
|
||||
except (OSError, UnicodeError) as error:
|
||||
print(f"Rust const-block audit: cannot read {path}: {error}", file=sys.stderr)
|
||||
return 2
|
||||
for error in errors:
|
||||
print(error, file=sys.stderr)
|
||||
if errors:
|
||||
print(f"Rust const-block audit: {len(errors)} error(s) across {len(files)} file(s)", file=sys.stderr)
|
||||
return 1
|
||||
print(f"Rust const-block audit: clean ({len(files)} file(s))")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
7
templates/rust-cargo/.cargo/config.toml
Normal file
7
templates/rust-cargo/.cargo/config.toml
Normal file
@@ -0,0 +1,7 @@
|
||||
# file: templates/rust-cargo/.cargo/config.toml
|
||||
# version: 1
|
||||
|
||||
# Replace project-name with a unique name before using this configuration.
|
||||
[build]
|
||||
target-dir = "../builds/project-name/target"
|
||||
build-dir = "../builds/project-name/target"
|
||||
41
templates/rust-cargo/Cargo.toml
Normal file
41
templates/rust-cargo/Cargo.toml
Normal file
@@ -0,0 +1,41 @@
|
||||
# file: templates/rust-cargo/Cargo.toml
|
||||
# version: 1
|
||||
|
||||
[workspace]
|
||||
resolver = "3"
|
||||
members = ["crates/project-core-lib"]
|
||||
|
||||
[workspace.package]
|
||||
# Replace this example with the release-unit version before adopting this template.
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
publish = false
|
||||
# Add license, repository, and authors only with the project's real values.
|
||||
|
||||
[workspace.dependencies]
|
||||
# Add dependencies actually shared by multiple crates, with reviewed versions.
|
||||
|
||||
[workspace.lints.rust]
|
||||
missing_docs = "warn"
|
||||
unreachable_pub = "deny"
|
||||
unsafe_code = "forbid"
|
||||
|
||||
[workspace.lints.clippy]
|
||||
unwrap_used = "deny"
|
||||
expect_used = "deny"
|
||||
implicit_return = "deny"
|
||||
needless_return = "allow"
|
||||
useless_vec = "deny"
|
||||
question_mark = "deny"
|
||||
question_mark_used = "deny"
|
||||
needless_match = "allow"
|
||||
manual_ok_err = "allow"
|
||||
manual_unwrap_or = "allow"
|
||||
manual_map = "allow"
|
||||
match_like_matches_macro = "allow"
|
||||
single_match = "allow"
|
||||
manual_unwrap_or_default = "allow"
|
||||
manual_find = "allow"
|
||||
explicit_counter_loop = "allow"
|
||||
get_first = "allow"
|
||||
implicit_saturating_sub = "allow"
|
||||
23
templates/rust-cargo/clippy.toml
Normal file
23
templates/rust-cargo/clippy.toml
Normal file
@@ -0,0 +1,23 @@
|
||||
# file: templates/rust-cargo/clippy.toml
|
||||
# version: 1
|
||||
|
||||
# Baseline shared by the KSP and Games projects; adapt thresholds per project.
|
||||
too-many-arguments-threshold = 16
|
||||
type-complexity-threshold = 250
|
||||
single-char-binding-names-threshold = 3
|
||||
trivial-copy-size-limit = 16
|
||||
pass-by-value-size-limit = 256
|
||||
stack-size-threshold = 512000
|
||||
vec-box-size-threshold = 4096
|
||||
max-fn-params-bools = 2
|
||||
max-include-file-size = 1048576
|
||||
cognitive-complexity-threshold = 25
|
||||
too-large-for-stack = 2048
|
||||
enum-variant-size-threshold = 200
|
||||
large-error-threshold = 128
|
||||
avoid-breaking-exported-api = true
|
||||
allow-unwrap-in-tests = true
|
||||
allow-expect-in-tests = true
|
||||
allow-useless-vec-in-tests = true
|
||||
disallowed-names = ["foo", "bar", "baz", "tmp"]
|
||||
allowed-idents-below-min-chars = ["id"]
|
||||
14
templates/rust-cargo/crates/project-core-lib/Cargo.toml
Normal file
14
templates/rust-cargo/crates/project-core-lib/Cargo.toml
Normal file
@@ -0,0 +1,14 @@
|
||||
# file: templates/rust-cargo/crates/project-core-lib/Cargo.toml
|
||||
# version: 1
|
||||
|
||||
[package]
|
||||
name = "project-core-lib"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
publish.workspace = true
|
||||
|
||||
[dependencies]
|
||||
# Inherit only the workspace dependencies this crate actually uses.
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
23
templates/rust-cargo/rustfmt.toml
Normal file
23
templates/rust-cargo/rustfmt.toml
Normal file
@@ -0,0 +1,23 @@
|
||||
# file: templates/rust-cargo/rustfmt.toml
|
||||
# version: 1
|
||||
|
||||
edition = "2024"
|
||||
newline_style = "Unix"
|
||||
use_small_heuristics = "Default"
|
||||
hard_tabs = false
|
||||
tab_spaces = 4
|
||||
max_width = 160
|
||||
chain_width = 140
|
||||
fn_call_width = 140
|
||||
attr_fn_like_width = 140
|
||||
struct_lit_width = 100
|
||||
struct_variant_width = 100
|
||||
array_width = 140
|
||||
single_line_if_else_max_width = 120
|
||||
single_line_let_else_max_width = 120
|
||||
reorder_imports = true
|
||||
reorder_modules = true
|
||||
match_block_trailing_comma = true
|
||||
use_field_init_shorthand = true
|
||||
use_try_shorthand = false
|
||||
force_explicit_abi = true
|
||||
76
tests/test_markdown_headers.py
Normal file
76
tests/test_markdown_headers.py
Normal file
@@ -0,0 +1,76 @@
|
||||
# file: tests/test_markdown_headers.py
|
||||
# version: 1
|
||||
|
||||
"""Exercise the Markdown header audit's real file and CLI contracts."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import pathlib
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
_SCRIPT = pathlib.Path(__file__).resolve().parents[1] / "scripts/audit_markdown_headers.py"
|
||||
|
||||
|
||||
class MarkdownHeaderAuditTests(unittest.TestCase):
|
||||
def setUp(self) -> None:
|
||||
temporary = tempfile.TemporaryDirectory(prefix="pgr-headers-")
|
||||
self.addCleanup(temporary.cleanup)
|
||||
self.root = pathlib.Path(temporary.name)
|
||||
|
||||
def source(self, name: str, contents: str) -> pathlib.Path:
|
||||
path = self.root / name
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
path.write_text(contents, encoding="utf-8")
|
||||
return path
|
||||
|
||||
def run_audit(self, *paths: str) -> subprocess.CompletedProcess[str]:
|
||||
return subprocess.run(
|
||||
[sys.executable, "-B", str(_SCRIPT), *paths],
|
||||
cwd=self.root, capture_output=True, text=True, check=False,
|
||||
)
|
||||
|
||||
def test_valid_root_and_nested_files_are_deduplicated(self) -> None:
|
||||
self.source("README.md", "<!-- file: README.md -->\n<!-- version: 1 -->\n")
|
||||
self.source("docs/page.md", "<!-- file: docs/page.md -->\n<!-- version: 27 -->\n")
|
||||
result = self.run_audit("README.md", "docs", "docs/page.md")
|
||||
self.assertEqual(result.returncode, 0, result.stderr)
|
||||
self.assertIn("clean (2 file(s))", result.stdout)
|
||||
|
||||
def test_wrong_path_and_nonpositive_revision_report_both_lines(self) -> None:
|
||||
self.source("docs/page.md", "<!-- file: docs/other.md -->\n<!-- version: 0 -->\n")
|
||||
result = self.run_audit("docs/page.md")
|
||||
self.assertEqual(result.returncode, 1)
|
||||
self.assertIn("docs/page.md:1:", result.stderr)
|
||||
self.assertIn("docs/page.md:2:", result.stderr)
|
||||
self.assertIn("2 error(s)", result.stderr)
|
||||
|
||||
def test_leading_zero_revision_is_rejected(self) -> None:
|
||||
self.source("README.md", "<!-- file: README.md -->\n<!-- version: 01 -->\n")
|
||||
result = self.run_audit("README.md")
|
||||
self.assertEqual(result.returncode, 1)
|
||||
self.assertIn("README.md:2:", result.stderr)
|
||||
|
||||
def test_missing_path_is_a_selection_error(self) -> None:
|
||||
result = self.run_audit("missing.md")
|
||||
self.assertEqual(result.returncode, 2)
|
||||
self.assertIn("unsupported or missing path", result.stderr)
|
||||
|
||||
def test_empty_directory_is_a_selection_error(self) -> None:
|
||||
(self.root / "docs").mkdir()
|
||||
result = self.run_audit("docs")
|
||||
self.assertEqual(result.returncode, 2)
|
||||
self.assertIn("no Markdown files selected", result.stderr)
|
||||
|
||||
def test_generated_directory_is_skipped(self) -> None:
|
||||
self.source("docs/visible.md", "<!-- file: docs/visible.md -->\n<!-- version: 1 -->\n")
|
||||
self.source("docs/target/skip.md", "incorrect\n")
|
||||
result = self.run_audit("docs")
|
||||
self.assertEqual(result.returncode, 0, result.stderr)
|
||||
self.assertIn("clean (1 file(s))", result.stdout)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
137
tests/test_rust_audits.py
Normal file
137
tests/test_rust_audits.py
Normal file
@@ -0,0 +1,137 @@
|
||||
# file: tests/test_rust_audits.py
|
||||
# version: 1
|
||||
|
||||
"""Targeted contracts for the two optional Rust style audits."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import pathlib
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
sys.path.insert(0, str(pathlib.Path(__file__).resolve().parents[1] / "scripts"))
|
||||
|
||||
from audit_rust_blank_lines import audit_file as audit_blanks # noqa: E402
|
||||
from audit_rust_const_blocks import audit_file as audit_consts # noqa: E402
|
||||
from _rust_audit_common import selected_files # noqa: E402
|
||||
|
||||
|
||||
class RustAuditTests(unittest.TestCase):
|
||||
def setUp(self) -> None:
|
||||
self.temporary = tempfile.TemporaryDirectory()
|
||||
self.addCleanup(self.temporary.cleanup)
|
||||
self.root = pathlib.Path(self.temporary.name)
|
||||
|
||||
def source(self, text: str) -> pathlib.Path:
|
||||
path = self.root / "source.rs"
|
||||
path.write_text(text, encoding="utf-8")
|
||||
return path
|
||||
|
||||
def test_clean_body_and_const_visibility_groups(self) -> None:
|
||||
path = self.source("""pub const ALPHA: u8 = 1;
|
||||
pub const BETA: u8 = 2;
|
||||
|
||||
pub(crate) const GAMMA: u8 = 3;
|
||||
|
||||
const OMEGA: u8 = 4;
|
||||
|
||||
fn sample() {
|
||||
let value = r#"{\n\n}"#;
|
||||
println!("{value}");
|
||||
}
|
||||
""")
|
||||
self.assertEqual(audit_blanks(path), [])
|
||||
self.assertEqual(audit_consts(path), [])
|
||||
|
||||
def test_blank_body_and_repeated_blank_lines(self) -> None:
|
||||
path = self.source("""fn sample() {
|
||||
let value = 1;
|
||||
|
||||
|
||||
println!("{value}");
|
||||
}
|
||||
""")
|
||||
issues = audit_blanks(path)
|
||||
self.assertTrue(any("consecutive" in issue for issue in issues))
|
||||
self.assertTrue(any("inside fn body" in issue for issue in issues))
|
||||
|
||||
def test_blank_string_and_nested_comment_braces_are_ignored(self) -> None:
|
||||
path = self.source('''fn sample() {
|
||||
let data = r#"{
|
||||
|
||||
|
||||
}"#;
|
||||
/* outer { /* inner } */ outer } */
|
||||
println!("{data}");
|
||||
}
|
||||
''')
|
||||
self.assertEqual(audit_blanks(path), [])
|
||||
|
||||
def test_struct_body_and_tuple_struct(self) -> None:
|
||||
path = self.source("""struct Payload {
|
||||
x: u8,
|
||||
|
||||
y: u8,
|
||||
}
|
||||
|
||||
struct Pair(u8, u8);
|
||||
""")
|
||||
self.assertEqual(len(audit_blanks(path)), 1)
|
||||
self.assertIn("struct body", audit_blanks(path)[0])
|
||||
|
||||
def test_const_order_and_multiline_initializer(self) -> None:
|
||||
path = self.source("""const BETA: [u8; 2] = [
|
||||
1,
|
||||
2,
|
||||
];
|
||||
const ALPHA: u8 = 1;
|
||||
|
||||
pub const GAMMA: u8 = 3;
|
||||
""")
|
||||
issues = audit_consts(path)
|
||||
self.assertTrue(any("alphabetical" in issue for issue in issues))
|
||||
self.assertTrue(any("visibility" in issue for issue in issues))
|
||||
|
||||
def test_const_spacing(self) -> None:
|
||||
path = self.source("""pub const ALPHA: u8 = 1;
|
||||
|
||||
pub const BETA: u8 = 2;
|
||||
pub(crate) const GAMMA: u8 = 3;
|
||||
""")
|
||||
issues = audit_consts(path)
|
||||
self.assertEqual(sum("blank line(s)" in issue for issue in issues), 2)
|
||||
|
||||
def test_const_function_does_not_join_const_block(self) -> None:
|
||||
path = self.source("""const ZETA: u8 = 1;
|
||||
|
||||
const fn compute() -> u8 {
|
||||
1
|
||||
}
|
||||
|
||||
const ALPHA: u8 = 2;
|
||||
""")
|
||||
self.assertEqual(audit_consts(path), [])
|
||||
|
||||
def test_scope_and_missing_path(self) -> None:
|
||||
self.source("fn sample() {}\n")
|
||||
selected, errors = selected_files([str(self.root), str(self.root / "absent.rs")])
|
||||
self.assertEqual(len(selected), 1)
|
||||
self.assertEqual(len(errors), 1)
|
||||
|
||||
def test_cli_status_for_success_violation_and_invalid_selection(self) -> None:
|
||||
path = self.source("const ALPHA: u8 = 1;\nconst BETA: u8 = 2;\n")
|
||||
script = pathlib.Path(__file__).resolve().parents[1] / "scripts" / "audit_rust_const_blocks.py"
|
||||
|
||||
def run(subject: pathlib.Path) -> subprocess.CompletedProcess[str]:
|
||||
return subprocess.run([sys.executable, "-B", str(script), str(subject)], capture_output=True, text=True, check=False)
|
||||
|
||||
self.assertEqual(run(path).returncode, 0)
|
||||
path.write_text("const BETA: u8 = 1;\nconst ALPHA: u8 = 2;\n", encoding="utf-8")
|
||||
self.assertEqual(run(path).returncode, 1)
|
||||
self.assertEqual(run(self.root / "missing.rs").returncode, 2)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user