289 lines
10 KiB
Markdown
289 lines
10 KiB
Markdown
<!-- file: deltas/0.1.3/rel.1.md -->
|
||
<!-- version: 1 -->
|
||
|
||
# Delta 0.1.3 rel.1 — promotion stable pré-tag
|
||
|
||
## Baseline et version
|
||
|
||
Baseline : `0.1.3-rc.1`, avec `history/0.1.3/rc.1.md` appliqué et committé. Ce delta MUST NOT être appliqué avant ce commit.
|
||
|
||
Version avant application :
|
||
|
||
```text
|
||
0.1.3-rc.1
|
||
```
|
||
|
||
Version après application :
|
||
|
||
```text
|
||
0.1.3
|
||
```
|
||
|
||
`rel.1` identifie la clôture opérationnelle ; il ne fait pas partie de la version SemVer du produit.
|
||
|
||
## Objet
|
||
|
||
Promouvoir mécaniquement la RC validée vers la stable `0.1.3` sans rouvrir le scope fonctionnel.
|
||
|
||
La tranche finalise uniquement la présentation et les métadonnées de release : version stable, roadmap terminée, changelog sans marqueur `candidate`, README/index en état stable et plan `009` historique. Aucun owner Android/Java/Gradle/Tauri, template, skeleton, validation, étude technique ou script d'audit n'est modifié.
|
||
|
||
La validation de cette tranche est **pré-tag**. Le tag `v0.1.3`, son archive source Gitea et le rapport `pgr-0.1.3-publish.001-report.md` ne sont pas déclarés existants par ce delta. Ils suivent uniquement un history `rel.1` `PASS`, le commit stable `0.1.3` et la publication réelle du tag.
|
||
|
||
## Scope
|
||
|
||
REPLACE :
|
||
|
||
```text
|
||
VERSION
|
||
README.md
|
||
ROADMAP.md
|
||
CHANGELOG.md
|
||
docs/000-README.md
|
||
docs/plans/009-V0_1_3_ANDROID_REEVALUATION_PLAN.md
|
||
```
|
||
|
||
ADD :
|
||
|
||
```text
|
||
deltas/0.1.3/rel.1.md
|
||
```
|
||
|
||
DELETE : aucun.
|
||
|
||
Le history `rc.1` est livré séparément. Le history `rel.1` sera produit uniquement après la gate opérateur.
|
||
|
||
## Validation opérateur pré-tag
|
||
|
||
Après application sur le commit contenant `history/0.1.3/rc.1.md` :
|
||
|
||
```bash
|
||
test "$(cat VERSION)" = '0.1.3'
|
||
git cat-file -e HEAD:history/0.1.3/rc.1.md
|
||
test -f history/0.1.3/rc.1.md
|
||
test -f deltas/0.1.3/rel.1.md
|
||
test -f prompts/010-V0_1_4_START_PROMPT.md
|
||
test ! -e history/0.1.3/rel.1.md
|
||
|
||
grep -A2 '^## Statut$' history/0.1.3/rc.1.md | grep -Fx 'PASS'
|
||
grep -Fx '<!-- version: 25 -->' README.md
|
||
grep -Fx '<!-- version: 15 -->' ROADMAP.md
|
||
grep -Fx '<!-- version: 17 -->' CHANGELOG.md
|
||
grep -Fx '<!-- version: 40 -->' docs/000-README.md
|
||
grep -Fx '<!-- version: 6 -->' docs/plans/009-V0_1_3_ANDROID_REEVALUATION_PLAN.md
|
||
grep -F -- '- `(x) 0.1.3`' ROADMAP.md
|
||
grep -Fx '## 0.1.3' CHANGELOG.md
|
||
grep -F 'avec `0.1.3` d’un profil Android réévalué contre Games' README.md
|
||
grep -F 'plan historique de la stable `0.1.3`' docs/000-README.md
|
||
|
||
python3 -B - <<'PYGATE'
|
||
from pathlib import Path
|
||
import re
|
||
|
||
expected = {
|
||
"alpha.1.md": "PASS",
|
||
"alpha.2.md": "PASS",
|
||
"alpha.3.md": "PASS",
|
||
"beta.1.md": "PASS",
|
||
"rc.1.md": "PASS",
|
||
}
|
||
|
||
for name, status in expected.items():
|
||
delta = Path("deltas/0.1.3", name)
|
||
history = Path("history/0.1.3", 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 = {path.name for path in Path("deltas/0.1.3").glob("*.md")} - {
|
||
path.name for path in Path("history/0.1.3").glob("*.md")
|
||
}
|
||
assert pending == {"rel.1.md"}, pending
|
||
|
||
roadmap = Path("ROADMAP.md").read_text(encoding="utf-8")
|
||
assert "- `(x) 0.1.3`" in roadmap
|
||
for version in ("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
|
||
|
||
changelog = Path("CHANGELOG.md").read_text(encoding="utf-8")
|
||
assert "## 0.1.3" in changelog.splitlines()
|
||
assert "## 0.1.3 (candidate)" not in changelog
|
||
section = changelog.split("## 0.1.3", 1)[1].split("## 0.1.2", 1)[0]
|
||
for phrase in (
|
||
"profil Android",
|
||
"compileSdk",
|
||
"targetSdk",
|
||
"minSdk",
|
||
"namespace",
|
||
"applicationId",
|
||
"NDK",
|
||
"Android Lint",
|
||
"tests instrumentés",
|
||
"APK/AAB",
|
||
"16 KB",
|
||
"0.1.4",
|
||
"0.1.5",
|
||
):
|
||
assert phrase in section, phrase
|
||
for forbidden in ("alpha.1", "alpha.2", "alpha.3", "beta.1", "rc.1", "rel.1"):
|
||
assert forbidden not in section, forbidden
|
||
|
||
readme = Path("README.md").read_text(encoding="utf-8")
|
||
assert "avec `0.1.3` d’un profil Android réévalué contre Games" in readme
|
||
assert "plan historique de la stable Android `0.1.3`" in readme
|
||
|
||
index = Path("docs/000-README.md").read_text(encoding="utf-8")
|
||
assert "plan historique de la stable `0.1.3`" in index
|
||
assert "à exécuter uniquement après publication et vérification post-tag de `v0.1.3`" in index
|
||
|
||
plan = Path("docs/plans/009-V0_1_3_ANDROID_REEVALUATION_PLAN.md").read_text(encoding="utf-8")
|
||
assert "Plan 0.1.3 — réévaluation pratique Android" in plan
|
||
assert "### rc.1 — release candidate\n\nStatut opérateur : **PASS**." in plan
|
||
assert "history/0.1.3/rel.1.md" in plan
|
||
assert "pgr-0.1.3-publish.001-report.md" in plan
|
||
assert "commit `0.1.3` avant le tag `v0.1.3`" in plan
|
||
assert "plan historique de la stable `0.1.3`" in plan
|
||
|
||
prompt = Path("prompts/010-V0_1_4_START_PROMPT.md").read_text(encoding="utf-8")
|
||
for phrase in (
|
||
"tag Gitea `v0.1.3`",
|
||
"pgr-0.1.3-publish.001-report.md",
|
||
"0.1.4-alpha.1",
|
||
"002-TAURI_SKELETON_DECISION.md",
|
||
"710-TAURI.md",
|
||
"003-WEB_FRONTEND",
|
||
"ADOPT / KEEP-LOCAL / OVERRIDE / DEFER",
|
||
"adoption Games `0.1.5`",
|
||
"adoption KSP `0.1.6`",
|
||
):
|
||
assert phrase in prompt, phrase
|
||
|
||
for path, version in (
|
||
("docs/rules/400-VALIDATION.md", 1),
|
||
("docs/rules/520-JAVA.md", 4),
|
||
("docs/rules/522-GRADLE.md", 1),
|
||
("docs/rules/600-PLATFORMS.md", 1),
|
||
("docs/rules/610-ANDROID.md", 5),
|
||
("docs/rules/710-TAURI.md", 6),
|
||
("docs/studies/002-TAURI_SKELETON_DECISION.md", 2),
|
||
("docs/skeletons/003-WEB_FRONTEND.md", 1),
|
||
("docs/validation/005-WEB_FRONTEND_VALIDATION.md", 1),
|
||
):
|
||
lines = Path(path).read_text(encoding="utf-8").splitlines()
|
||
assert lines[1] == f"<!-- version: {version} -->", (path, lines[1])
|
||
|
||
android = Path("docs/rules/610-ANDROID.md").read_text(encoding="utf-8")
|
||
for phrase in (
|
||
"Android ne sélectionne pas à lui seul le langage applicatif du projet.",
|
||
"Le choix de `minSdk` MUST être justifié par le contrat produit",
|
||
"PGR ne fixe ni version NDK ni liste universelle d'ABI.",
|
||
"PGR MUST NOT supposer qu'un build Gradle ordinaire exécute Lint automatiquement.",
|
||
"Un AAB n'est pas directement une preuve d'installation ou d'exécution sur device.",
|
||
"## Pages mémoire 16 KB et packaging natif",
|
||
"PGR MUST NOT imposer une version AGP/NDK globale uniquement pour cette raison.",
|
||
):
|
||
assert phrase in android, phrase
|
||
for forbidden in (
|
||
"targetSdk MUST être 36",
|
||
"minSdk MUST être 21",
|
||
"NDK MUST être r28",
|
||
"MUST supporter arm64-v8a, armeabi-v7a, x86_64 et x86",
|
||
"Gradle MUST être 9.7.1",
|
||
"AGP MUST être 9.4.0",
|
||
"JDK MUST être 25",
|
||
):
|
||
assert forbidden not in android, forbidden
|
||
|
||
for forbidden_path in (
|
||
"docs/validation/006-ANDROID_VALIDATION.md",
|
||
"docs/skeletons/004-ANDROID.md",
|
||
"docs/rules/620-JNI.md",
|
||
"docs/skeletons/004-TAURI.md",
|
||
):
|
||
assert not Path(forbidden_path).exists(), forbidden_path
|
||
|
||
workflow = Path("docs/rules/210-WORKFLOW.md").read_text(encoding="utf-8")
|
||
assert "history rel.1 FAIL / PARTIAL / BLOCKED" in workflow
|
||
assert "premier history rel.N[/fix.M] PASS qui établit réellement la stable" in workflow
|
||
assert "commit X.Y.Z" in workflow
|
||
|
||
print("0.1.3 rel.1 stable gate audit: clean (5 prior histories, rel.1 pending, stable Android presentation and post-tag Tauri handoff coherent)")
|
||
PYGATE
|
||
|
||
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 - <<'PYHYGIENE'
|
||
from pathlib import Path
|
||
import json
|
||
import tomllib
|
||
|
||
for path in sorted(Path("templates/rust-cargo").rglob("*.toml")):
|
||
tomllib.loads(path.read_text(encoding="utf-8"))
|
||
|
||
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.3 rel.1 text/template hygiene: clean")
|
||
PYHYGIENE
|
||
|
||
git diff --check
|
||
git add VERSION README.md ROADMAP.md CHANGELOG.md docs/000-README.md \
|
||
docs/plans/009-V0_1_3_ANDROID_REEVALUATION_PLAN.md \
|
||
deltas/0.1.3/rel.1.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.1.3/rel.1.md
|
||
M docs/000-README.md
|
||
M docs/plans/009-V0_1_3_ANDROID_REEVALUATION_PLAN.md
|
||
```
|
||
|
||
La RC a déjà reconfirmé le profil Android gelé, les frontières Tauri/Games/KSP, le contrat du prompt `010` et l'absence d'artefacts Android supplémentaires. Comme `rel.1` ne modifie aucun artefact technique, la promotion stable rejoue les tests PGR, les audits documentaires et l'hygiène des templates sans simuler une toolchain Android absente du dépôt.
|
||
|
||
## Revue opérateur complémentaire
|
||
|
||
Confirmer que :
|
||
|
||
- `0.1.3` est bien présenté comme stable partout où la RC était auparavant candidate ;
|
||
- aucun changement fonctionnel Android n'est entré dans `rel.1` ;
|
||
- `0.1.4` reste le réexamen Tauri, sans création anticipée du skeleton ;
|
||
- `0.1.5` et `0.1.6` restent respectivement les adoptions Games et KSP ;
|
||
- le tag et le rapport post-tag ne sont pas anticipés dans le dépôt pré-tag.
|