diff --git a/Cargo.toml b/Cargo.toml index 9e6d76d..2f8afb2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ # file: Cargo.toml -# version: 36 +# version: 37 [workspace] resolver = "3" @@ -16,7 +16,7 @@ members = [ ] [workspace.package] -version = "0.0.3-beta.1" +version = "0.0.3-rc.1" edition = "2024" publish = false repository = "https://git.sasedev.com/Sasedev/sasedev-knowledge" diff --git a/README.md b/README.md index 92e5af0..67713be 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ - + # SaseDev Knowledge @@ -13,7 +13,7 @@ La version courante est définie par [`VERSION`](VERSION). `0.0.1` est la première stable de fondation de SaseDev Knowledge. `0.0.2` est la stable du chemin Git générique de lecture, de l'autonomie normative locale et du cas d'usage partagé de synchronisation `Changed` / `Unchanged`. -`0.0.3-beta.1` réconcilie maintenant le chemin Git générique complet avant la release candidate : lecture/snapshot, création d'un commit candidat isolé, puis push compare-and-exchange protégé par `--force-with-lease` contre l'état distant explicitement attendu. Une branche peut être créée uniquement lorsque son absence est attendue ; toute divergence devient un conflit récupérable sans écrasement silencieux. La beta n'ajoute pas de fonctionnalité Git : elle stabilise l'état acquis, prépare le changelog candidat et réévalue la trajectoire produit au-delà de `0.0.3`. +`0.0.3-rc.1` est la release candidate du chemin Git générique complet : lecture/snapshot, création d'un commit candidat isolé, puis push compare-and-exchange protégé par `--force-with-lease` contre l'état distant explicitement attendu. Une branche peut être créée uniquement lorsque son absence est attendue ; toute divergence devient un conflit récupérable sans écrasement silencieux. Le scope est gelé : la RC n'introduit aucune nouvelle fonctionnalité et rejoue les preuves Rust, Git, Web et runtime avant promotion stable. `knowledge-git-lib` implémente `knowledge-git-api::GitRepository` pour des sources physiques enregistrées : mirror contrôlé, refresh avec pruning, résolution d'une référence vers un commit et snapshot/worktree détaché adressé par révision. La création locale du candidat d'`alpha.3` reste séparée de cette sémantique de lecture. Les règles nécessaires au développement courant sont désormais possédées localement sous `docs/rules/`, et les futurs prompts Knowledge ne chargent pas PGR sauf réévaluation explicitement engagée. `knowledge-app-lib` compose maintenant refresh, résolution, comparaison avec la révision précédente et préparation de snapshot en un résultat explicite `Changed` / `Unchanged`, sans persister la dernière révision ni matérialiser de scheduler. diff --git a/VERSION b/VERSION index 4c98a1d..2b724e1 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.0.3-beta.1 +0.0.3-rc.1 diff --git a/deltas/0.0.3/rc.1.md b/deltas/0.0.3/rc.1.md new file mode 100644 index 0000000..2bd7f87 --- /dev/null +++ b/deltas/0.0.3/rc.1.md @@ -0,0 +1,253 @@ + + + +# Delta 0.0.3-rc.1 — release candidate + +## Base requise + +État `0.0.3-beta.1` committé et poussé après application du history : + +```text +history/0.0.3/beta.1.md = PASS +``` + +La version devient : + +```text +0.0.3-rc.1 +``` + +## Objet + +Geler le scope de `0.0.3` et exécuter sa gate complète de release candidate. + +Aucune nouvelle fonctionnalité, dépendance, crate, route, comportement Git, décision PostgreSQL/Web ou modification de l'horizon produit n'est introduite. + +## Scope + +La RC remplace uniquement : + +```text +VERSION +Cargo.toml +README.md +docs/plans/003-V0_0_3_GIT_WRITE_PLAN.md +docs/validation/001-VALIDATION_MATRIX.md +``` + +et ajoute : + +```text +deltas/0.0.3/rc.1.md +``` + +Aucun fichier n'est supprimé. `crates/`, `Web/`, `CHANGELOG.md`, `ROADMAP.md`, `docs/architecture/`, `docs/studies/`, `docs/rules/` et `prompts/` sont gelés. + +## Histories attendus avant RC + +La gate doit retrouver exactement les huit histories antérieurs suivants : + +```text +alpha.1 PARTIAL +alpha.1.fix.1 PARTIAL +alpha.1.fix.2 PASS +alpha.2 PASS +alpha.3 FAIL +alpha.3.fix.1 PASS +alpha.4 PASS +beta.1 PASS +``` + +Pendant la gate, `rc.1.md` doit être le seul delta `0.0.3` sans history correspondant. + +## Présentation candidate + +La RC conserve : + +```text +CHANGELOG.md -> ## 0.0.3 (candidate) +ROADMAP.md -> 0.0.3 encore engagée + horizon 0.0.4..0.0.10 +prompt 004 -> handoff 0.0.4 présent, sans commit/SHA futur inventé +``` + +La présentation stable appartient à `rel.1`, pas à la RC. + +## Gate opérateur + +Exécuter directement dans le shell interactif. Ne pas activer `set -e`, `set -u` ou `set -o pipefail` globalement. + +```bash +test "$(cat VERSION)" = '0.0.3-rc.1' +grep -F 'version = "0.0.3-rc.1"' Cargo.toml +grep -A2 '^## Statut$' history/0.0.3/beta.1.md | grep -Fx 'PASS' + +git diff --check + +python3 -B scripts/audit_markdown_headers.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts deltas history +python3 -B scripts/audit_markdown_links.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts deltas history +python3 -B scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts deltas history + +cargo fmt --all +cargo fmt --all -- --check + +python3 -B scripts/audit_rust_test_layout.py crates +python3 -B scripts/audit_rust_blank_lines.py crates +python3 -B scripts/audit_rust_item_spacing.py crates +python3 -B scripts/audit_rust_module_order.py crates +python3 -B scripts/audit_rust_trait_import_blocks.py crates +python3 -B scripts/audit_rust_reexport_blocks.py crates +python3 -B scripts/audit_rust_crate_root_facades.py crates +python3 -B scripts/audit_rust_export_completeness.py --root . --summary-only + +cargo metadata --format-version 1 --no-deps > /tmp/sasedev-knowledge-0.0.3-rc.1-metadata.json +cargo check --workspace +cargo clippy --workspace --all-targets --all-features -- -D warnings +cargo test -p knowledge-git-lib --test git_read_path +cargo test -p knowledge-git-lib --test git_write_candidate +cargo test -p knowledge-git-lib --test git_write_push +cargo test --workspace --all-targets --all-features + +(cd Web/knowledge-template-lab && npm ci) +(cd Web/knowledge-template-lab && npm run typecheck) +(cd Web/knowledge-template-lab && npm run build) + +python3 -c 'import json; from pathlib import Path; p=Path("../builds/sasedev-knowledge/web/template-lab/.vite/manifest.json"); m=json.loads(p.read_text(encoding="utf-8")); e=m["src/main.ts"]; assert e.get("file"); assert e.get("css"); print("Knowledge 0.0.3-rc.1 Vite manifest audit: clean")' +``` + +## Contrôles d'intégrité courts + +```bash +grep -A2 '^## Statut$' history/0.0.3/alpha.1.md | grep -Fx 'PARTIAL' +grep -A2 '^## Statut$' history/0.0.3/alpha.1.fix.1.md | grep -Fx 'PARTIAL' +grep -A2 '^## Statut$' history/0.0.3/alpha.1.fix.2.md | grep -Fx 'PASS' +grep -A2 '^## Statut$' history/0.0.3/alpha.2.md | grep -Fx 'PASS' +grep -A2 '^## Statut$' history/0.0.3/alpha.3.md | grep -Fx 'FAIL' +grep -A2 '^## Statut$' history/0.0.3/alpha.3.fix.1.md | grep -Fx 'PASS' +grep -A2 '^## Statut$' history/0.0.3/alpha.4.md | grep -Fx 'PASS' +grep -A2 '^## Statut$' history/0.0.3/beta.1.md | grep -Fx 'PASS' + +test "$(find history/0.0.3 -maxdepth 1 -type f -name '*.md' | wc -l)" -eq 8 +test "$(find deltas/0.0.3 -maxdepth 1 -type f -name '*.md' | wc -l)" -eq 9 + +test ! -e history/0.0.3/rc.1.md + +grep -F '## 0.0.3 (candidate)' CHANGELOG.md +grep -F -- '- `( ) 0.0.3` — écriture Git contrôlée et push gardé' ROADMAP.md +grep -F -- '- `(h) 0.0.4` — fondation PostgreSQL partagée' ROADMAP.md +grep -F -- '- `(h) 0.0.10` — gestion, proposition, revue et publication' ROADMAP.md + +test -f prompts/004-V0_0_4_START_PROMPT.md +! grep -Eq '[0-9a-f]{40}|[0-9a-f]{64}' prompts/004-V0_0_4_START_PROMPT.md + +test ! -e crates/knowledge-store-postgres-lib +test ! -e crates/knowledge-forge-gitea-lib +test ! -e migrations +``` + +Vérifier le workspace Cargo sans bloc multi-lignes : + +```bash +python3 -c 'import json; from pathlib import Path; m=json.loads(Path("/tmp/sasedev-knowledge-0.0.3-rc.1-metadata.json").read_text()); expected={"knowledge-app-lib","knowledge-domain-lib","knowledge-git-api","knowledge-git-lib","knowledge-sync-api","knowledge-web-lib","knowledge-pgr-server","knowledge-howtos-server","knowledge-snippets-server"}; assert {p["name"] for p in m["packages"]} == expected; assert len(m["workspace_members"]) == 9; print("Knowledge 0.0.3-rc.1 workspace audit: clean")' +``` + +Vérifier l'hygiène texte : + +```bash +python3 -c 'from pathlib import Path; roots=[Path("README.md"),Path("RULES.md"),Path("ROADMAP.md"),Path("CHANGELOG.md"),Path("docs"),Path("prompts"),Path("deltas"),Path("history")]; paths=[p for r in roots for p in ([r] if r.is_file() else r.rglob("*")) if p.is_file()]; bad=[str(p) for p in paths if (lambda b: b"\r" in b or not b.endswith(b"\n") or b.endswith(b"\n\n") or any(line != line.rstrip(" \t") for line in b.decode("utf-8").splitlines()))(p.read_bytes())]; print(f"Knowledge 0.0.3-rc.1 text hygiene: clean ({len(paths)} file(s))") if not bad else (_ for _ in ()).throw(AssertionError(bad))' +``` + +## Smokes HTTP de production + +Construire les trois launchers : + +```bash +cargo build -p knowledge-pgr-server -p knowledge-howtos-server -p knowledge-snippets-server +``` + +Préparer le chemin du manifest et la liste des assets : + +```bash +export KNOWLEDGE_RC_MANIFEST="$(realpath ../builds/sasedev-knowledge/web/template-lab/.vite/manifest.json)" +python3 -c 'import json,os; m=json.load(open(os.environ["KNOWLEDGE_RC_MANIFEST"],encoding="utf-8")); e=m["src/main.ts"]; print("/"+e["file"].lstrip("/")); print(*["/"+x.lstrip("/") for x in e.get("css",[])],sep="\n")' > /tmp/sasedev-knowledge-0.0.3-rc.1-assets.txt +cat /tmp/sasedev-knowledge-0.0.3-rc.1-assets.txt +``` + +### PGR + +```bash +env -u KNOWLEDGE_VITE_DEV_ORIGIN KNOWLEDGE_VITE_MANIFEST_PATH="$KNOWLEDGE_RC_MANIFEST" KNOWLEDGE_PGR_BIND_ADDRESS=127.0.0.1:18181 ../builds/sasedev-knowledge/target/debug/knowledge-pgr-server > /tmp/knowledge-pgr-rc.1.log 2>&1 & echo $! > /tmp/knowledge-pgr-rc.1.pid +sleep 1 +python3 -c 'import urllib.request; r=urllib.request.urlopen("http://127.0.0.1:18181/healthz",timeout=2); assert r.status==200 and r.read().decode()=="ok"; print("pgr healthz PASS")' +python3 -c 'import urllib.request; r=urllib.request.urlopen("http://127.0.0.1:18181/",timeout=2); assert r.status==200; open("/tmp/knowledge-pgr-rc.1.html","wb").write(r.read())' +while IFS= read -r asset; do grep -F "$asset" /tmp/knowledge-pgr-rc.1.html >/dev/null && python3 -c 'import sys,urllib.request; r=urllib.request.urlopen("http://127.0.0.1:18181"+sys.argv[1],timeout=2); assert r.status==200' "$asset" || exit 1; done < /tmp/sasedev-knowledge-0.0.3-rc.1-assets.txt +kill "$(cat /tmp/knowledge-pgr-rc.1.pid)" +wait "$(cat /tmp/knowledge-pgr-rc.1.pid)" 2>/dev/null || true +echo 'knowledge-pgr-server smoke PASS' +``` + +### HOWTOs + +```bash +env -u KNOWLEDGE_VITE_DEV_ORIGIN KNOWLEDGE_VITE_MANIFEST_PATH="$KNOWLEDGE_RC_MANIFEST" KNOWLEDGE_HOWTOS_BIND_ADDRESS=127.0.0.1:18182 ../builds/sasedev-knowledge/target/debug/knowledge-howtos-server > /tmp/knowledge-howtos-rc.1.log 2>&1 & echo $! > /tmp/knowledge-howtos-rc.1.pid +sleep 1 +python3 -c 'import urllib.request; r=urllib.request.urlopen("http://127.0.0.1:18182/healthz",timeout=2); assert r.status==200 and r.read().decode()=="ok"; print("howtos healthz PASS")' +python3 -c 'import urllib.request; r=urllib.request.urlopen("http://127.0.0.1:18182/",timeout=2); assert r.status==200; open("/tmp/knowledge-howtos-rc.1.html","wb").write(r.read())' +while IFS= read -r asset; do grep -F "$asset" /tmp/knowledge-howtos-rc.1.html >/dev/null && python3 -c 'import sys,urllib.request; r=urllib.request.urlopen("http://127.0.0.1:18182"+sys.argv[1],timeout=2); assert r.status==200' "$asset" || exit 1; done < /tmp/sasedev-knowledge-0.0.3-rc.1-assets.txt +kill "$(cat /tmp/knowledge-howtos-rc.1.pid)" +wait "$(cat /tmp/knowledge-howtos-rc.1.pid)" 2>/dev/null || true +echo 'knowledge-howtos-server smoke PASS' +``` + +### Snippets + +```bash +env -u KNOWLEDGE_VITE_DEV_ORIGIN KNOWLEDGE_VITE_MANIFEST_PATH="$KNOWLEDGE_RC_MANIFEST" KNOWLEDGE_SNIPPETS_BIND_ADDRESS=127.0.0.1:18183 ../builds/sasedev-knowledge/target/debug/knowledge-snippets-server > /tmp/knowledge-snippets-rc.1.log 2>&1 & echo $! > /tmp/knowledge-snippets-rc.1.pid +sleep 1 +python3 -c 'import urllib.request; r=urllib.request.urlopen("http://127.0.0.1:18183/healthz",timeout=2); assert r.status==200 and r.read().decode()=="ok"; print("snippets healthz PASS")' +python3 -c 'import urllib.request; r=urllib.request.urlopen("http://127.0.0.1:18183/",timeout=2); assert r.status==200; open("/tmp/knowledge-snippets-rc.1.html","wb").write(r.read())' +while IFS= read -r asset; do grep -F "$asset" /tmp/knowledge-snippets-rc.1.html >/dev/null && python3 -c 'import sys,urllib.request; r=urllib.request.urlopen("http://127.0.0.1:18183"+sys.argv[1],timeout=2); assert r.status==200' "$asset" || exit 1; done < /tmp/sasedev-knowledge-0.0.3-rc.1-assets.txt +kill "$(cat /tmp/knowledge-snippets-rc.1.pid)" +wait "$(cat /tmp/knowledge-snippets-rc.1.pid)" 2>/dev/null || true +echo 'knowledge-snippets-server smoke PASS' +``` + +## Scope gelé et staging + +```bash +test -z "$(git diff --name-only -- crates Web CHANGELOG.md ROADMAP.md docs/architecture docs/studies docs/rules prompts)" + +test -f Cargo.lock +git check-ignore -q Cargo.lock + +if git ls-files --error-unmatch Cargo.lock >/dev/null 2>&1; then + echo 'Cargo.lock must remain untracked for Knowledge' >&2 + exit 1 +fi + +test -f Web/knowledge-template-lab/package-lock.json + +git add -A +git diff --cached --check +git status --short +``` + +Le staging final attendu avant history est limité à : + +```text +M Cargo.toml +M README.md +M VERSION +A deltas/0.0.3/rc.1.md +M docs/plans/003-V0_0_3_GIT_WRITE_PLAN.md +M docs/validation/001-VALIDATION_MATRIX.md +``` + +## Transition + +### PASS + +Produire `history/0.0.3/rc.1.md`, l'appliquer, commit/push `0.0.3-rc.1`, puis préparer `0.0.3-rel.1` comme promotion mécanique stable pré-tag. + +### FAIL + +Produire le history avec le résultat exact puis une tranche `rc.1.fix.1` strictement bornée à la régression observée. Ne pas promouvoir la stable tant que la RC n'est pas `PASS`. diff --git a/docs/plans/003-V0_0_3_GIT_WRITE_PLAN.md b/docs/plans/003-V0_0_3_GIT_WRITE_PLAN.md index ffc824d..63f48a5 100644 --- a/docs/plans/003-V0_0_3_GIT_WRITE_PLAN.md +++ b/docs/plans/003-V0_0_3_GIT_WRITE_PLAN.md @@ -1,5 +1,5 @@ - + # Plan 0.0.3 — écriture Git contrôlée et push gardé @@ -19,7 +19,7 @@ Knowledge start prompt prompts/003-V0_0_3_START_PROMPT.md PGR `v0.1.3` reste une provenance historique de l'adoption fermée pendant `0.0.2`. Aucune version PGR plus récente n'est une source de cette release et aucune réévaluation PGR n'est engagée. -`0.0.3-alpha.1` et `alpha.1.fix.1` sont conservées `PARTIAL` avec leurs preuves réelles. `alpha.1.fix.2` a complété la gate documentaire et technique en `PASS`. `alpha.2` a matérialisé le contrat d'écriture provider-neutral en `PASS`. `alpha.3` reste historisée `FAIL` pour son défaut de test `E0369`; `alpha.3.fix.1` a corrigé uniquement cette assertion en `PASS`. `alpha.4` a fermé le scope fonctionnel alpha en `PASS` avec push gardé, création de branche sous attente d'absence et conflit concurrent sans écrasement. `beta.1` réconcilie maintenant l'état acquis, prépare le changelog candidat, rejoue la non-régression de stabilisation et effectue la revue d'horizon produit. +`0.0.3-alpha.1` et `alpha.1.fix.1` sont conservées `PARTIAL` avec leurs preuves réelles. `alpha.1.fix.2` a complété la gate documentaire et technique en `PASS`. `alpha.2` a matérialisé le contrat d'écriture provider-neutral en `PASS`. `alpha.3` reste historisée `FAIL` pour son défaut de test `E0369`; `alpha.3.fix.1` a corrigé uniquement cette assertion en `PASS`. `alpha.4` a fermé le scope fonctionnel alpha en `PASS` avec push gardé, création de branche sous attente d'absence et conflit concurrent sans écrasement. `beta.1` a réconcilié l'état acquis, préparé le changelog candidat, rejoué la non-régression Rust/Web et effectué la revue d'horizon produit en `PASS`. `rc.1` gèle maintenant ce scope et rejoue la gate complète avant promotion stable. ## Mission @@ -255,7 +255,7 @@ La release est fermable lorsque : - les règles/architecture décrivent l'état effectivement obtenu ; - beta et RC ont fermé les non-régressions prévues. -Le `PARTIAL` de `alpha.1` a autorisé `0.0.3-alpha.1.fix.1`. Le premier fix est resté `PARTIAL`, puis `alpha.1.fix.2` a fermé la preuve en `PASS`. `alpha.2` a matérialisé le contrat d'écriture provider-neutral en `PASS`. `alpha.3` est conservée `FAIL` à cause de l'assertion de test `E0369`; `alpha.3.fix.1` a corrigé uniquement le test en `PASS`. `alpha.4` a ensuite fermé le scope fonctionnel alpha en `PASS`. La beta doit maintenant stabiliser et réconcilier cet état sans nouveau code produit. +Le `PARTIAL` de `alpha.1` a autorisé `0.0.3-alpha.1.fix.1`. Le premier fix est resté `PARTIAL`, puis `alpha.1.fix.2` a fermé la preuve en `PASS`. `alpha.2` a matérialisé le contrat d'écriture provider-neutral en `PASS`. `alpha.3` est conservée `FAIL` à cause de l'assertion de test `E0369`; `alpha.3.fix.1` a corrigé uniquement le test en `PASS`. `alpha.4` a ensuite fermé le scope fonctionnel alpha en `PASS`. `beta.1` a stabilisé et réconcilié cet état en `PASS`, sans nouveau code produit. La RC doit désormais uniquement confirmer la candidate stable par la gate complète. ## Revue d'horizon diff --git a/docs/validation/001-VALIDATION_MATRIX.md b/docs/validation/001-VALIDATION_MATRIX.md index ae3e1b1..7073b8f 100644 --- a/docs/validation/001-VALIDATION_MATRIX.md +++ b/docs/validation/001-VALIDATION_MATRIX.md @@ -1,5 +1,5 @@ - + # Matrice de validation Knowledge @@ -198,6 +198,24 @@ La tranche de réconciliation/stabilisation doit prouver : Un `PASS` autorise uniquement `0.0.3-rc.1`. Toute régression produit exige un fix beta borné ou un retour de phase ; la beta ne doit pas masquer un défaut sous une réécriture documentaire. +## Gate de `0.0.3-rc.1` + +La release candidate doit prouver : + +- `VERSION = 0.0.3-rc.1` et version workspace identique ; +- history `history/0.0.3/beta.1.md` présent avec statut `PASS` et committé avant application ; +- scope produit gelé : aucun diff sous `crates/`, `Web/`, `CHANGELOG.md`, `ROADMAP.md`, `docs/architecture/`, `docs/studies/`, `docs/rules/` ou `prompts/` ; +- tous les histories antérieurs de `0.0.3` présents avec leurs statuts réels et `rc.1.md` seul delta sans history correspondant ; +- `CHANGELOG.md` toujours en `## 0.0.3 (candidate)` et `ROADMAP.md` conservant `0.0.3` engagée avec l'horizon validé en beta ; +- handoff `prompts/004-V0_0_4_START_PROMPT.md` présent et toujours sans commit/SHA futur inventé ; +- `cargo fmt --all`, audits Rust, metadata/check, Clippy strict, tests Git ciblés et tests workspace passent ; +- baseline Web `npm ci`, typecheck, build Vite et manifest de production passent ; +- les trois launchers passent un smoke HTTP de production sur `/healthz`, `/` et le service effectif des assets référencés par le manifest ; +- PostgreSQL, migrations, forge, rebase/merge automatique, auth/admin et workflow produit différés restent absents ; +- `Cargo.lock` local reste ignoré/non suivi, package-lock Web versionné et staging final propre. + +Un `PASS` autorise uniquement `0.0.3-rel.1`. Toute régression fonctionnelle exige un fix RC borné ou un retour de phase approprié ; aucune fonctionnalité ne peut être ajoutée en RC. + ## PostgreSQL Aucune gate PostgreSQL n'est créée avant matérialisation d'une dépendance ou d'un schéma réel. diff --git a/history/0.0.3/rc.1.md b/history/0.0.3/rc.1.md new file mode 100644 index 0000000..dd701a8 --- /dev/null +++ b/history/0.0.3/rc.1.md @@ -0,0 +1,63 @@ + + + +# History 0.0.3-rc.1 — release candidate + +## Statut + +FAIL + +## Résultat observé + +La gate opérateur de `0.0.3-rc.1` a été exécutée le `2026-09-29` après commit/push de `0.0.3-beta.1`. + +Toutes les preuves produit et runtime exécutées sont `PASS` : + +- version `0.0.3-rc.1` et history `beta.1 = PASS` ; +- audits Markdown propres sur `118` fichiers, `82` liens locaux et `4` tables ; +- `cargo fmt --all` puis `cargo fmt --all -- --check` ; +- audits Rust structurels propres sur `36` fichiers et `9` crates ; +- complétude d'exports : `0 candidate(s)` ; +- `cargo metadata`, `cargo check --workspace` et Clippy strict ; +- `git_read_path` : `2 PASS` ; +- `git_write_candidate` : `2 PASS` ; +- `git_write_push` : `2 PASS`, incluant le conflit concurrent sans écrasement ; +- tests workspace : tous `PASS` ; +- `npm ci`, typecheck et build Vite `PASS`, manifest de production valide ; +- workspace Cargo : `9` packages attendus ; +- smokes HTTP production PGR, HOWTOs et snippets : `/healthz`, `/` et assets manifest servis, tous `PASS` ; +- scope RC gelé, politique `Cargo.lock` et staging final conformes. + +Les avertissements Sass/Bootstrap observés pendant le build restent des dépréciations non bloquantes ; le build termine avec succès. + +## Échec de gate + +Une seule commande de contrôle d'intégrité a échoué : + +```text +grep -A2 '^## Statut$' history/0.0.3/alpha.1.md | grep -Fx 'PARTIAL' +``` + +`history/0.0.3/alpha.1.md` contient historiquement le statut Markdown : + +```text +`PARTIAL` +``` + +Le sens du history est donc correct. L'échec provient de l'assertion RC qui exigeait la représentation lexicale non formatée `PARTIAL` au lieu de normaliser l'éventuel balisage inline Markdown. + +Les autres histories utilisent la forme non balisée et ont passé les contrôles attendus. + +## Décision + +`0.0.3-rc.1` est conservée `FAIL` parce qu'une commande appartenant à sa gate a réellement échoué. + +L'ancien history `alpha.1` ne doit pas être réécrit : il constitue une preuve historique déjà committée. + +La correction utilise `0.0.3-rc.1.fix.1` et reste limitée à : + +- corriger la règle de vérification des statuts historiques pour accepter leur représentation Markdown existante ; +- conserver sans changement les statuts historiques eux-mêmes ; +- rejouer les contrôles nécessaires au fix avant toute promotion `rel.1`. + +Aucun défaut produit Git, Web ou runtime n'a été observé pendant `rc.1`.