0.1.0-rc.1

This commit is contained in:
2026-09-26 23:26:23 +02:00
parent 5393257d93
commit d5e1fc4300
5 changed files with 471 additions and 6 deletions

View File

@@ -1,5 +1,5 @@
<!-- file: CHANGELOG.md -->
<!-- version: 9 -->
<!-- version: 10 -->
# Changelog Project Governance Rules
@@ -7,6 +7,15 @@ 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.1.0 (candidate)
- établit la première baseline PGR réellement réutilisable pour initialiser de nouveaux projets et adopter progressivement des projets existants, avec une fondation de gouvernance, des skeleton specifications composables et une validation proportionnée ;
- stabilise le socle Rust/Cargo réutilisable : cinq templates techniques, composition `001 + 002`, dry-run `NEW` avec Cargo/rustfmt/Clippy et chemin `ADOPTION` non destructif ;
- formalise l'adoption de projets existants avec baseline autoritaire, migration progressive et décisions `ADOPT / KEEP-LOCAL / OVERRIDE / DEFER`, sans réécriture rétroactive de l'historique ;
- corrige la convention de clôture stable vers `rel.N` sans zéro de padding et garantit que la première clôture qui obtient réellement `PASS` produit le commit produit `X.Y.Z` avant le tag `vX.Y.Z` ;
- rend obligatoire le handoff automatique des commandes opérateur entre history, commit/push, delta suivant et publication stable, avec distinction entre objet tag, commit déréférencé et rapport `publish.*` post-tag ;
- matérialise la revue d'horizon suivante : frontend Web, Java/Gradle, Android, Tauri conditionnel, adoption Games puis KSP et audits Rust/Clippy statiques Python-only, tout en laissant WASM, serveur Rust et deployment/operations sans réservation prématurée.
## 0.0.5
- consolide le lifecycle inter-release de PGR : prompts de reprise versionnés, contrats locaux de fichiers/familles, responsabilités de fermeture et revue d'horizon sans création artificielle de releases futures ;

View File

@@ -1 +1 @@
0.1.0-beta.1
0.1.0-rc.1

333
deltas/0.1.0/rc.1.md Normal file
View File

@@ -0,0 +1,333 @@
<!-- file: deltas/0.1.0/rc.1.md -->
<!-- version: 1 -->
# Delta 0.1.0-rc.1 — gel du scope et gate de release candidate
## Baseline et version
Baseline attendue : commit opérateur de `0.1.0-beta.1`, réalisé après application de `history/0.1.0/beta.1.md` avec statut `PASS`.
Le hash de ce commit n'est pas anticipé.
Version avant application :
```text
0.1.0-beta.1
```
Version après application :
```text
0.1.0-rc.1
```
## Objet et gel
La RC gèle le scope fonctionnel de `0.1.0` sur :
- la fondation de gouvernance et les skeleton specifications réutilisables ;
- le socle Rust/Cargo, ses cinq templates techniques et les dry-runs `NEW` / `ADOPTION` ;
- le contrat d'adoption de projets existants `ADOPT / KEEP-LOCAL / OVERRIDE / DEFER` ;
- la convention de clôture stable `rel.N` sans zéro de padding et l'identité du premier commit stable `X.Y.Z` ;
- le handoff automatique des commandes opérateur, du commit/push au tag et à la preuve `publish.*` ;
- la revue d'horizon validée et le prompt `007` vers `0.1.1`.
Le changelog reçoit une entrée candidate `0.1.0` orientée utilisateurs. `ROADMAP.md`, `RULES.md`, les owners, profils, templates techniques, skeletons et scripts d'audit sont vérifiés mais non modifiés.
Aucun scope Web, Java/Gradle, Android, Tauri, WASM, serveur Rust, Games/KSP ou deployment/operations n'entre fonctionnellement dans cette RC au-delà des décisions de trajectoire déjà validées.
## Scope
REPLACE :
```text
VERSION
CHANGELOG.md
docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md
```
ADD :
```text
deltas/0.1.0/rc.1.md
```
DELETE : aucun.
Le history `beta.1` est livré séparément et MUST être appliqué/committé avant ce delta.
## Gate opérateur de release candidate
Après application du history `PASS` de `beta.1`, commit/push de `beta.1`, puis application du présent delta :
```bash
test "$(cat VERSION)" = '0.1.0-rc.1'
git cat-file -e HEAD:history/0.1.0/beta.1.md
test -f history/0.1.0/beta.1.md
test -f deltas/0.1.0/rc.1.md
test -f prompts/007-V0_1_1_START_PROMPT.md
test ! -e history/0.1.0/rc.1.md
grep -A2 '^## Statut$' history/0.1.0/beta.1.md | grep -Fx 'PASS'
grep -Fx '<!-- version: 10 -->' CHANGELOG.md
grep -Fx '## 0.1.0 (candidate)' CHANGELOG.md
grep -Fx '<!-- version: 9 -->' docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md
grep -Fx '<!-- version: 9 -->' ROADMAP.md
grep -Fx '<!-- version: 1 -->' prompts/007-V0_1_1_START_PROMPT.md
```
Contrôle d'intégration de la RC :
```bash
python3 -B - <<'PYGATE'
from pathlib import Path
import re
expected = {
"alpha.1.md": "PASS",
"alpha.2.md": "FAIL",
"alpha.2.fix.1.md": "PASS",
"alpha.3.md": "FAIL",
"alpha.3.fix.1.md": "PASS",
"alpha.4.md": "PASS",
"alpha.5.md": "PASS",
"beta.1.md": "PASS",
}
histories = {path.name for path in Path("history/0.1.0").glob("*.md")}
assert histories == set(expected), histories
for name, status in expected.items():
text = Path("history/0.1.0", 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.1.0").glob("*.md")}
assert deltas == set(expected) | {"rc.1.md"}, deltas
changelog = Path("CHANGELOG.md").read_text(encoding="utf-8")
assert "## 0.1.0 (candidate)" in changelog
section = changelog.split("## 0.1.0 (candidate)", 1)[1].split("## 0.0.5", 1)[0]
for phrase in (
"première baseline PGR réellement réutilisable",
"ADOPT / KEEP-LOCAL / OVERRIDE / DEFER",
"rel.N",
"publish.*",
"frontend Web",
):
assert phrase in section, phrase
for forbidden in ("alpha.2", "alpha.3", "beta.1", "rc.1"):
assert forbidden not in section, forbidden
workflow = Path("docs/rules/210-WORKFLOW.md").read_text(encoding="utf-8")
for phrase in (
"La famille `rel.N` utilise la représentation sans zéro de padding",
"première de ces tranches qui obtient réellement `PASS` est incluse dans le commit stable `X.Y.Z`",
"Le rapport `publish.*` est produit seulement à partir des artefacts et preuves réellement disponibles après publication.",
"../templates/006-OPERATOR_COMMAND_HANDOFF.md",
):
assert phrase in workflow, phrase
adoption = Path("docs/rules/230-ADOPTION.md").read_text(encoding="utf-8")
for phrase in ("ADOPT", "KEEP-LOCAL", "OVERRIDE", "DEFER", "Préservation de l’historique"):
assert phrase in adoption, phrase
rust_dryrun = Path("docs/validation/004-RUST_CARGO_BASELINE_DRY_RUN.md").read_text(encoding="utf-8")
assert "NEW nouveau projet" in rust_dryrun
assert "ADOPTION projet existant" in rust_dryrun
roadmap = Path("ROADMAP.md").read_text(encoding="utf-8")
for version in ("0.1.1", "0.1.2", "0.1.3", "0.1.4", "0.1.5", "0.1.6", "0.1.7"):
assert f"- `( ) {version}`" in roadmap, version
assert "- `( ) 0.1.8`" not in roadmap
assert "WASM" in roadmap
assert "serveur Web Rust / Actix Web ou alternative" in roadmap
assert "deployment & operations" in roadmap
prompt = Path("prompts/007-V0_1_1_START_PROMPT.md").read_text(encoding="utf-8")
for phrase in (
"archive source téléchargée depuis le tag Gitea `v0.1.0`",
"pgr-0.1.0-publish.001-report.md",
"0.1.1-alpha.1",
"games-v0.3.6.zip",
"TypeScript",
"Vite",
"Sass/CSS",
"Le skeleton Tauri reste `DEFER` pendant cette release.",
):
assert phrase in prompt, phrase
plan = Path("docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md").read_text(encoding="utf-8")
assert "### beta.1 — réconciliation finale et revue d'horizon\n\nStatut opérateur : **PASS**." in plan
assert "### rc.1 — release candidate\n\nStatut opérateur : **à valider**." in plan
assert "État : **validée `PASS` par la gate opérateur de `beta.1`**." in plan
print("0.1.0 rc.1 integration audit: clean (8 prior histories, frozen reusable baseline, candidate changelog, horizon and prompt 007 verified)")
PYGATE
```
Rejouer également les deux chemins Rust/Cargo avec la toolchain réelle :
```bash
python3 -B - <<'PYRUST'
from pathlib import Path
import hashlib
import shutil
import subprocess
import tempfile
import tomllib
cargo = shutil.which("cargo")
if cargo is None:
raise SystemExit("BLOCKED: cargo is required for the 0.1.0 RC Rust/Cargo release gate")
commands = (
[cargo, "metadata", "--format-version", "1", "--no-deps"],
[cargo, "fmt", "--all", "--", "--check"],
[cargo, "check", "--workspace"],
[cargo, "clippy", "--workspace", "--all-targets", "--all-features", "--", "-D", "warnings"],
)
source = Path("templates/rust-cargo")
with tempfile.TemporaryDirectory(prefix="pgr-rc1-new-") as temporary:
root = Path(temporary)
(root / ".cargo").mkdir(parents=True)
(root / "crates/pgr-rc-core-lib/src").mkdir(parents=True)
shutil.copy2(source / "Cargo.toml", root / "Cargo.toml")
shutil.copy2(source / "clippy.toml", root / "clippy.toml")
shutil.copy2(source / "rustfmt.toml", root / "rustfmt.toml")
shutil.copy2(source / ".cargo/config.toml", root / ".cargo/config.toml")
shutil.copy2(source / "crates/project-core-lib/Cargo.toml", root / "crates/pgr-rc-core-lib/Cargo.toml")
workspace = (root / "Cargo.toml").read_text(encoding="utf-8")
workspace = workspace.replace("crates/project-core-lib", "crates/pgr-rc-core-lib")
workspace = workspace.replace('version = "0.1.0"', 'version = "9.9.9"')
(root / "Cargo.toml").write_text(workspace, encoding="utf-8")
member = (root / "crates/pgr-rc-core-lib/Cargo.toml").read_text(encoding="utf-8")
member = member.replace("project-core-lib", "pgr-rc-core-lib")
(root / "crates/pgr-rc-core-lib/Cargo.toml").write_text(member, encoding="utf-8")
config = (root / ".cargo/config.toml").read_text(encoding="utf-8")
config = config.replace("project-name", "pgr-rc1-new")
(root / ".cargo/config.toml").write_text(config, encoding="utf-8")
(root / "crates/pgr-rc-core-lib/src/lib.rs").write_text(
"//! Minimal source used only by the PGR RC dry-run.\n\n"
"/// Returns the RC marker.\n"
"#[must_use]\n"
"pub const fn rc_marker() -> u32 {\n"
" return 1;\n"
"}\n",
encoding="utf-8",
)
for path in (
root / "Cargo.toml",
root / "clippy.toml",
root / "rustfmt.toml",
root / ".cargo/config.toml",
root / "crates/pgr-rc-core-lib/Cargo.toml",
):
with path.open("rb") as handle:
tomllib.load(handle)
text = path.read_text(encoding="utf-8")
assert "project-name" not in text
assert "project-core-lib" not in text
for command in commands:
subprocess.run(command, cwd=root, check=True)
with tempfile.TemporaryDirectory(prefix="pgr-rc1-adoption-") as temporary:
root = Path(temporary)
(root / "crates/legacy-core-lib/src").mkdir(parents=True)
(root / "Cargo.toml").write_text(
'[workspace]\nresolver = "3"\nmembers = ["crates/legacy-core-lib"]\n\n'
'[workspace.package]\nversion = "2.3.4"\nedition = "2024"\npublish = false\n',
encoding="utf-8",
)
(root / "rustfmt.toml").write_text('edition = "2024"\nmax_width = 120\n', encoding="utf-8")
(root / "crates/legacy-core-lib/Cargo.toml").write_text(
'[package]\nname = "legacy-core-lib"\nversion.workspace = true\nedition.workspace = true\npublish.workspace = true\n',
encoding="utf-8",
)
(root / "crates/legacy-core-lib/src/lib.rs").write_text(
"//! Existing synthetic library.\n\n"
"/// Returns the existing marker.\n"
"#[must_use]\n"
"pub const fn existing_marker() -> u32 {\n"
" 7\n"
"}\n",
encoding="utf-8",
)
protected = (root / "Cargo.toml", root / "rustfmt.toml", root / "crates/legacy-core-lib/Cargo.toml")
before = {path: hashlib.sha256(path.read_bytes()).hexdigest() for path in protected}
decisions = {
"510-RUST_CARGO": "ADOPT",
"rustfmt.max_width=120": "KEEP-LOCAL",
"PGR external artifact configuration": "DEFER",
"strict crate-root export audit": "DEFER",
}
assert set(decisions.values()) <= {"ADOPT", "KEEP-LOCAL", "OVERRIDE", "DEFER"}
for command in commands:
subprocess.run(command, cwd=root, check=True)
after = {path: hashlib.sha256(path.read_bytes()).hexdigest() for path in protected}
assert before == after
assert "max_width = 120" in (root / "rustfmt.toml").read_text(encoding="utf-8")
print("0.1.0 rc.1 Rust/Cargo release dry-runs: clean (NEW and ADOPTION accepted by Cargo/rustfmt/Clippy)")
PYRUST
```
Puis la suite PGR complète :
```bash
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
git diff --check
git add VERSION CHANGELOG.md \
docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md \
deltas/0.1.0/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.1.0/rc.1.md
M docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md
```
## Revue opérateur complémentaire
Confirmer que :
- le changelog décrit les capacités de `0.1.0` et non ses tranches internes ;
- aucune règle/profil/template/skeleton/audit fonctionnel nouveau n'entre dans la RC ;
- `ROADMAP.md` conserve `0.1.0` en cours jusqu'à la promotion stable ;
- `0.1.1..0.1.7` restent la trajectoire engagée et les domaines non numérotés restent réellement différés ;
- le prompt `007` exige bien l'archive taggée `v0.1.0` et le rapport `publish.001` seulement lorsqu'il existe réellement avec statut `PASS` ;
- la RC n'est ni le commit stable `0.1.0`, ni le tag `v0.1.0`, ni la vérification post-tag.
## Transition
### PASS
Produire séparément `history/0.1.0/rc.1.md`, l'appliquer puis committer/pousser `0.1.0-rc.1` avant le delta stable `rel.1`.
### FAIL
Consigner l'échec réel dans `history/0.1.0/rc.1.md` puis corriger uniquement le scope gelé dans `rc.1.fix.1`, sauf REPLAN si la candidate révèle un défaut fonctionnel plus large.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md -->
<!-- version: 8 -->
<!-- version: 9 -->
# Plan 0.1.0 — première baseline PGR réutilisable
@@ -226,7 +226,9 @@ Les `48/48` tests PGR et les trois audits Markdown sont restés propres. Games e
### beta.1 — réconciliation finale et revue d'horizon
Statut opérateur : **à valider**.
Statut opérateur : **PASS**.
La gate opérateur a confirmé la revue d'horizon, la roadmap `0.1.1` à `0.1.7`, le maintien des domaines différés sans numéro, le prompt `007` et les `48/48` tests PGR avec les trois audits Markdown propres.
La revue d'horizon est matérialisée dans `003-V0_1_0_HORIZON_REVIEW.md`. Elle engage une séquence par domaines cohérents :
@@ -244,7 +246,9 @@ WASM, serveur Rust et deployment restent non numérotés. Le prompt `007-V0_1_1_
### rc.1 — release candidate
Geler le scope, produire l'entrée candidate de `CHANGELOG.md`, exécuter le release gate complet applicable, vérifier le prompt/handoff suivant et confirmer que les changements `rel.N`/commandes opérateur sont exercés par les artefacts de la release elle-même.
Statut opérateur : **à valider**.
Le scope est gelé. La RC produit l'entrée candidate de `CHANGELOG.md`, rejoue la gate d'intégration complète, reconfirme les deux dry-runs Rust/Cargo, vérifie le contrat d'adoption, la convention `rel.N`, le handoff opérateur, la roadmap et le prompt `007`. Aucun owner ni domaine technique nouveau n'entre dans la RC.
### rel.1 — promotion stable
@@ -288,7 +292,7 @@ REPLAN est requis si :
## Revue d'horizon
État : **matérialisée en `beta.1`, à valider par la gate opérateur**.
État : **validée `PASS` par la gate opérateur de `beta.1`**.
Décision proposée par la revue :

119
history/0.1.0/rc.1.md Normal file
View File

@@ -0,0 +1,119 @@
<!-- file: history/0.1.0/rc.1.md -->
<!-- version: 1 -->
# History 0.1.0-rc.1 — release candidate
## Statut
PASS
La gate opérateur de `0.1.0-rc.1` exécutée le `2026-09-26` a réussi. Elle confirme le scope gelé de la première baseline PGR réutilisable, l'intégrité des histories antérieurs, le `CHANGELOG` candidat, la trajectoire `0.1.x`, le prompt `007` et les deux dry-runs Rust/Cargo avec la toolchain réelle.
## Baseline opérateur
La tranche `0.1.0-beta.1` a été clôturée avec son history `PASS`, puis committée et poussée avant application de `rc.1` :
```text
commit 5393257
message 0.1.0-beta.1
push origin/master PASS
```
Après application du delta `rc.1`, les contrôles initiaux ont confirmé :
```text
VERSION 0.1.0-rc.1
history/0.1.0/beta.1.md présent dans HEAD et le workspace
deltas/0.1.0/rc.1.md présent
prompts/007-V0_1_1_START_PROMPT.md présent
history/0.1.0/rc.1.md absent pendant la gate
CHANGELOG.md version 10
docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md version 9
ROADMAP.md version 9
prompts/007-V0_1_1_START_PROMPT.md version 1
```
Le history `beta.1` a été retrouvé avec statut `PASS` et le `CHANGELOG` contient l'entrée `## 0.1.0 (candidate)`.
## Gate d'intégration
Le contrôle d'intégration a affiché :
```text
0.1.0 rc.1 integration audit: clean (8 prior histories, frozen reusable baseline, candidate changelog, horizon and prompt 007 verified)
```
Il a vérifié les huit histories antérieurs avec leurs statuts réels :
```text
alpha.1 PASS
alpha.2 FAIL
alpha.2.fix.1 PASS
alpha.3 FAIL
alpha.3.fix.1 PASS
alpha.4 PASS
alpha.5 PASS
beta.1 PASS
```
La gate reconfirme également le contrat `ADOPT / KEEP-LOCAL / OVERRIDE / DEFER`, la convention `rel.N` sans padding, le commit stable final `X.Y.Z`, le handoff `publish.*`, la roadmap `0.1.1` à `0.1.7`, l'absence de `0.1.8` et la préparation du prompt `007`.
## Dry-runs Rust/Cargo de release
La toolchain Cargo réelle a exercé les deux chemins de la baseline :
```text
NEW cargo metadata / fmt / check / clippy -D warnings PASS
ADOPTION cargo metadata / fmt / check / clippy -D warnings PASS
```
Résultat observé :
```text
0.1.0 rc.1 Rust/Cargo release dry-runs: clean (NEW and ADOPTION accepted by Cargo/rustfmt/Clippy)
```
Le chemin `ADOPTION` conserve le principe de non-écrasement des choix locaux protégés.
## Tests et audits PGR
La suite Python globale a exécuté `48` tests, tous réussis :
```text
Ran 48 tests in 0.702s
OK
```
Les audits documentaires sont propres :
```text
Markdown header audit: clean (195 file(s))
Markdown table audit: clean (8 table(s), 195 file(s))
Markdown link audit: clean (193 local link(s), 195 file(s))
```
## Contrôles Git
`git diff --check` et `git diff --cached --check` n'ont produit aucun diagnostic. Le statut indexé transmis avant ajout du présent history est exactement :
```text
M CHANGELOG.md
M VERSION
A deltas/0.1.0/rc.1.md
M docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md
```
Le scope correspond exactement au delta annoncé. Aucun owner, profil, template, skeleton ou script technique n'a été modifié pendant la RC.
## Décision
`0.1.0-rc.1` est `PASS`. Aucun fix ni REPLAN n'est requis.
La tranche suivante est la promotion stable pré-tag :
```text
0.1.0-rel.1
```
`rel.1` est la première utilisation réelle de la convention sans padding. Si sa gate obtient `PASS`, son history sera inclus dans le commit stable nommé `0.1.0`, avant création et publication du tag `v0.1.0`.