Files
pgr/deltas/0.1.1/rc.1.md
2026-09-27 12:08:21 +02:00

12 KiB

Delta 0.1.1-rc.1 — gel du scope et gate de release candidate

Baseline et version

Baseline attendue : commit opérateur de 0.1.1-beta.1, réalisé après application de history/0.1.1/beta.1.md avec statut PASS.

Le hash de ce commit n'est pas anticipé.

Version avant application :

0.1.1-beta.1

Version après application :

0.1.1-rc.1

Objet et gel

La RC gèle le scope fonctionnel de 0.1.1 sur :

  • les quatre owners indépendants 530 — TypeScript, 540 — JavaScript package ecosystem, 550 — Vite et 560 — CSS / Sass ;
  • la baseline TypeScript/package avec strict, noEmit, script typecheck, politique de lockfile par rôle et déclarations de types externes conditionnelles ;
  • Vite comme build tool/dev server recommandé mais non obligatoire, avec ownership explicite des caches, outputs, assets et limites d'exposition du dev server ;
  • CSS comme baseline valide et Sass recommandé lorsqu'il apporte une valeur réelle, avec préférence @use / @forward, consommation des entrypoints publics et séparation source/généré ;
  • la validation frontend 005 indépendante du host ;
  • le skeleton Web 003 composable sans vite.config.ts, main.scss, package manager, framework CSS ou layout universels ;
  • la preuve beta.1 que les cinq prérequis Web du futur réexamen Tauri sont couverts, sans lever le DEFER avant 0.1.4.

Le changelog reçoit une entrée candidate 0.1.1 orientée utilisateurs. Le prompt 008-V0_1_2_START_PROMPT.md est préparé pour la prochaine cible engagée Java/Maven/Gradle avec frontière Android explicite.

Aucune nouvelle fonctionnalité normative n'entre dans cette RC. Les profils, skeletons, templates techniques et contrats de validation Web sont vérifiés mais non modifiés.

Scope

REPLACE :

VERSION
CHANGELOG.md
docs/000-README.md
docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md

ADD :

deltas/0.1.1/rc.1.md
prompts/008-V0_1_2_START_PROMPT.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 :

test "$(cat VERSION)" = '0.1.1-rc.1'
git cat-file -e HEAD:history/0.1.1/beta.1.md
test -f history/0.1.1/beta.1.md
test -f deltas/0.1.1/rc.1.md
test -f prompts/008-V0_1_2_START_PROMPT.md
test ! -e history/0.1.1/rc.1.md

grep -A2 '^## Statut$' history/0.1.1/beta.1.md | grep -Fx 'PASS'
grep -Fx '<!-- version: 12 -->' CHANGELOG.md
grep -Fx '## 0.1.1 (candidate)' CHANGELOG.md
grep -Fx '<!-- version: 30 -->' docs/000-README.md
grep -Fx '<!-- version: 10 -->' docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md
grep -Fx '<!-- version: 11 -->' ROADMAP.md
grep -Fx '<!-- version: 1 -->' prompts/008-V0_1_2_START_PROMPT.md

Contrôle d'intégration de la RC :

python3 -B - <<'PYGATE'
from pathlib import Path
import json
import re
import shutil
import tempfile

expected = {
    "alpha.1.md": "PASS",
    "alpha.2.md": "FAIL",
    "alpha.2.fix.1.md": "PASS",
    "alpha.3.md": "PASS",
    "alpha.3.fix.1.md": "FAIL",
    "alpha.3.fix.2.md": "PASS",
    "alpha.4.md": "PASS",
    "alpha.5.md": "PASS",
    "beta.1.md": "PASS",
}

histories = {path.name for path in Path("history/0.1.1").glob("*.md")}
assert histories == set(expected), histories
for name, status in expected.items():
    text = Path("history/0.1.1", 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.1").glob("*.md")}
assert deltas == set(expected) | {"rc.1.md"}, deltas

changelog = Path("CHANGELOG.md").read_text(encoding="utf-8")
assert "## 0.1.1 (candidate)" in changelog
section = changelog.split("## 0.1.1 (candidate)", 1)[1].split("## 0.1.0", 1)[0]
for phrase in (
    "quatre owners indépendants",
    "TypeScript",
    "@types/*",
    "package JavaScript",
    "Vite",
    "CSS comme baseline valide",
    "Sass",
    "validation frontend indépendante du host",
    "DEFER",
    "0.1.4",
):
    assert phrase in section, phrase
for forbidden in (
    "alpha.2",
    "alpha.3",
    "alpha.4",
    "alpha.5",
    "beta.1",
    "rc.1",
):
    assert forbidden not in section, forbidden

plan = Path("docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md").read_text(encoding="utf-8")
for phrase in (
    "### beta.1 — réconciliation et preuve de préparation Tauri\n\nStatut opérateur : **PASS**.",
    "### rc.1 — release candidate\n\nStatut opérateur : **à valider**.",
    "prompts/008-V0_1_2_START_PROMPT.md",
    "Aucune nouvelle fonctionnalité normative ne doit apparaître en RC.",
):
    assert phrase in plan, phrase

prompt = Path("prompts/008-V0_1_2_START_PROMPT.md").read_text(encoding="utf-8")
for phrase in (
    "archive source téléchargée depuis le tag Gitea `v0.1.1`",
    "pgr-0.1.1-publish.001-report.md",
    "0.1.2-alpha.1",
    "ad6e44a1332eb7d6069cf1189d9433f0fbb8fac19c5aac9f4641ac45c1c556e8",
    "520-JAVA_MAVEN_GRADLE.md",
    "610-ANDROID.md",
    "ADOPT / KEEP-LOCAL / OVERRIDE / DEFER",
    "Gradle système versus Wrapper",
    "Maven",
    "Frontière Android obligatoire",
    "réservé à `0.1.4`",
):
    assert phrase in prompt, phrase

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 "skeleton Tauri jusqu'au réexamen 0.1.4" in roadmap

for path, version in (
    ("docs/rules/530-TYPESCRIPT.md", 3),
    ("docs/rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md", 3),
    ("docs/rules/550-VITE.md", 2),
    ("docs/rules/560-CSS_SASS.md", 2),
    ("docs/rules/710-TAURI.md", 6),
    ("docs/skeletons/003-WEB_FRONTEND.md", 1),
    ("docs/validation/005-WEB_FRONTEND_VALIDATION.md", 1),
    ("docs/studies/002-TAURI_SKELETON_DECISION.md", 2),
):
    lines = Path(path).read_text(encoding="utf-8").splitlines()
    assert lines[1] == f"<!-- version: {version} -->", (path, lines[1])

study = Path("docs/studies/002-TAURI_SKELETON_DECISION.md").read_text(encoding="utf-8")
for phrase in (
    "DEFER",
    "Condition 1 — TypeScript et conventions Web contrôlées",
    "Condition 2 — Vite et ownership des commandes/dev server/build outputs",
    "Condition 3 — Sass/CSS et statut des artefacts générés",
    "Condition 4 — validation frontend indépendante de la validation Tauri",
    "Condition 5 — framework CSS classé comme décision de skeleton/projet",
    "réexamen autorisé            0.1.4",
):
    assert phrase in study, phrase

package_source = Path("templates/web-typescript/package.json")
tsconfig_source = Path("templates/web-typescript/tsconfig.json")
with tempfile.TemporaryDirectory(prefix="pgr-rc1-web-") as temp_name:
    temp = Path(temp_name)
    shutil.copy2(package_source, temp / "package.json")
    shutil.copy2(tsconfig_source, temp / "tsconfig.json")
    package = json.loads((temp / "package.json").read_text(encoding="utf-8"))
    tsconfig = json.loads((temp / "tsconfig.json").read_text(encoding="utf-8"))
    assert package == {
        "name": "project-web",
        "private": True,
        "scripts": {"typecheck": "tsc --noEmit"},
    }
    assert tsconfig["compilerOptions"] == {
        "strict": True,
        "noEmit": True,
        "noUnusedLocals": True,
        "noUnusedParameters": True,
        "noFallthroughCasesInSwitch": True,
    }
    assert not (temp / "vite.config.ts").exists()
    assert not (temp / "main.scss").exists()
    assert not (temp / "src-tauri").exists()

assert not Path("templates/web-vite/vite.config.ts").exists()
assert not Path("templates/web-css/main.scss").exists()

index = Path("docs/000-README.md").read_text(encoding="utf-8")
assert "../prompts/008-V0_1_2_START_PROMPT.md" in index

print("0.1.1 rc.1 integration audit: clean (9 prior histories, frozen Web foundation, candidate changelog and prompt 008 verified)")
PYGATE

Rejouer ensuite les preuves PGR :

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

Vérifier également l'hygiène texte/JSON sans prétendre remplacer les toolchains frontend :

python3 -B - <<'PYHYGIENE'
from pathlib import Path
import json

json.loads(Path("templates/web-typescript/package.json").read_text(encoding="utf-8"))
json.loads(Path("templates/web-typescript/tsconfig.json").read_text(encoding="utf-8"))

roots = (
    Path("VERSION"),
    Path("README.md"),
    Path("RULES.md"),
    Path("ROADMAP.md"),
    Path("CHANGELOG.md"),
    Path("docs"),
    Path("deltas"),
    Path("history"),
    Path("prompts"),
    Path("templates"),
)
files = []
for root in roots:
    if root.is_file():
        files.append(root)
    elif root.is_dir():
        files.extend(path for path in root.rglob("*") if path.is_file())

for path in files:
    try:
        data = path.read_bytes()
        text = data.decode("utf-8")
    except UnicodeDecodeError:
        continue
    assert b"\r" not in data, path
    assert text.endswith("\n"), path
    for number, line in enumerate(text.splitlines(), 1):
        assert line == line.rstrip(" \t"), (path, number)

print("0.1.1 rc.1 text/JSON hygiene: clean")
PYHYGIENE

git diff --check

git add VERSION CHANGELOG.md docs/000-README.md \
    docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md \
    prompts/008-V0_1_2_START_PROMPT.md \
    deltas/0.1.1/rc.1.md

git diff --cached --check
git status --short

Le scope indexé attendu avant ajout du history de rc.1 est exactement :

M  CHANGELOG.md
M  VERSION
A  deltas/0.1.1/rc.1.md
M  docs/000-README.md
M  docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md
A  prompts/008-V0_1_2_START_PROMPT.md

Revue opérateur complémentaire

Confirmer que :

  • le scope normatif Web est gelé ;
  • aucun owner 530/540/550/560, skeleton, template technique ou contrat de validation n'est modifié par la RC ;
  • le changelog candidat décrit les capacités utiles de 0.1.1 sans recopier les tranches internes ;
  • TypeScript, Vite et Sass restent des recommandations conditionnelles et non des obligations universelles ;
  • le prompt 008 réévalue le profil 520 avant de créer de nouveaux artefacts Java/Gradle ;
  • le prompt 008 ne transforme pas les choix Android de Games en règles Java/Gradle générales ;
  • Maven reste dans l'owner 520, mais aucun nouvel artefact Maven n'est anticipé sans corpus réel ;
  • le skeleton Tauri reste DEFER et son réexamen reste réservé à 0.1.4 ;
  • 0.1.8 n'est pas réservé ;
  • aucun résultat tsc, Vite ou Sass n'est revendiqué alors que PGR ne contient pas de frontend concret ni de dépendances installées pour cette RC.

Transition

PASS

Produire history/0.1.1/rc.1.md, l'appliquer puis committer/pousser rc.1. Continuer avec 0.1.1-rel.1 pour la promotion mécanique vers la stable, la clôture roadmap/plan/changelog et la gate pré-tag.

FAIL

Consigner le diagnostic réel dans history/0.1.1/rc.1.md. Corriger uniquement la release candidate dans rc.1.fix.N tant qu'aucun défaut normatif plus large ne justifie un REPLAN. Ne pas préparer rel.1 tant que la RC n'a pas obtenu PASS.