Files
sasedev-knowledge/docs/validation/001-VALIDATION_MATRIX.md
2026-09-29 06:34:10 +02:00

800 lines
47 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!-- file: docs/validation/001-VALIDATION_MATRIX.md -->
<!-- version: 30 -->
# Matrice de validation Knowledge
## Principe
La gate opérateur sélectionne les preuves nécessaires au scope réellement modifié. Une commande n'est pas exécutée uniquement pour augmenter le nombre de checks.
La prévalidation de génération ne vaut pas preuve opérateur.
## Fondation documentaire
Pour une tranche limitée à gouvernance/documentation :
```text
CHECK VERSION attendue
CHECK git diff --check
AUDIT fichiers Git suivis/non ignorés conformes au delta, sans confondre fichiers locaux ignorés et distribution
AUDIT headers file/version des Markdown gouvernés
AUDIT headers file/version des formats texte qui adoptent explicitement cette convention
AUDIT liens Markdown locaux principaux
REVIEW owners PGR / décisions locales / DEFER explicites
REVIEW absence de secret, chemin machine absolu et placeholder non résolu
```
## Politique Eclipse
Les métadonnées Eclipse spécifiques à la machine restent ignorées, notamment `.project`, `.classpath` et les préférences non partagées.
Le fichier suivant constitue l'exception versionnée :
```text
.settings/org.eclipse.core.resources.prefs
```
Il doit contenir :
```text
eclipse.preferences.version=1
encoding/<project>=UTF-8
```
Le `.gitignore` doit contenir :
```text
.settings/*
!.settings/org.eclipse.core.resources.prefs
```
Une gate de distribution ne doit donc pas échouer parce qu'un `.project` ignoré existe dans le workspace local. Elle doit en revanche échouer si `org.eclipse.core.resources.prefs` est ignoré ou absent du contenu suivi.
## Rust/Cargo
Dès qu'un workspace Rust est matérialisé, sélectionner selon le scope :
```text
CHECK cargo metadata --no-deps
FORMAT cargo fmt --all -- --check
CHECK cargo check --workspace
LINT cargo clippy --workspace --all-targets --all-features -- -D warnings
TEST cargo test ciblé ou workspace selon le changement
AUDIT règles structurelles PGR seulement si la preuve n'est pas déjà possédée par Cargo/Rustfmt/Clippy
```
Le profil strict et les éventuelles exceptions doivent être visibles dans les manifests/règles locales.
## Administration et authentification
Aucune route admin/login n'est validée tant qu'elle n'existe pas réellement. Lorsqu'elles seront matérialisées, les gates devront prouver séparément :
- refus d'accès non authentifié aux opérations privilégiées ;
- refus d'accès authentifié sans autorisation suffisante ;
- autorisation vérifiée côté serveur et pas seulement par la navigation frontend ;
- isolation correcte des opérations PGR, HOWTOs et snippets ;
- comportement d'une éventuelle façade admin transverse sans bypass des contrôles locaux.
Les corpus historiques ne constituent pas des preuves de sécurité pour Knowledge.
## Frontend Web
Dès que le frontend est matérialisé :
```text
RESTORE mode reproductible du package manager sélectionné
TYPECHECK script typecheck TypeScript
BUILD production Vite lorsque ses entrées/configuration/outputs changent
STYLES preuve séparée uniquement si le build ne prouve pas déjà la compilation requise
SMOKE navigateur seulement lorsqu'une propriété runtime le justifie
```
La gate frontend reste exécutable indépendamment du backend autant que la topologie réelle le permet. Les templates statiques de référence appartiennent à cette gate : leur rôle est de prouver le design/markup/assets côté Web avant adaptation Maud, pas de prouver le rendu Actix.
Lorsque Vite est sélectionné pour les assets réellement servis par Maud, la gate de production doit également prouver l’émission d’un manifest parsable et la présence des clés d’entrée attendues. Une gate d’intégration Actix/Maud distincte prouve ensuite que ces clés sont résolues sans coder les noms hashés.
Si plusieurs entrées/frontend existent pour PGR, HOWTOs et snippets, la gate doit couvrir chacune des entrées modifiées sans forcer trois builds identiques lorsqu'un package commun possède réellement les assets partagés.
## Serveurs et intégration
Les trois launchers Actix Web/Maud sont validés comme packages exécutables distincts lorsqu'ils sont matérialisés :
```text
knowledge-pgr-server
knowledge-howtos-server
knowledge-snippets-server
```
Leur compilation peut être prouvée par les gates workspace. Un smoke HTTP ciblé est ajouté uniquement lorsqu'une route/runtime réelle est introduite et que compilation/tests ne prouvent pas la propriété visée.
Une gate d'intégration ne remplace pas silencieusement les preuves frontend indépendantes.
## Git et forge
Les contrats Git génériques sont testés sans dépendance à une forge lorsque cela suffit.
Les tests doivent permettre plusieurs `source_id` et ne pas confondre famille de contenu avec provider de forge.
Un test live de remote ou de forge doit être explicitement classé comme externe, séparé des tests unitaires et ne doit pas devenir une condition cachée pour les opérations locales.
## PostgreSQL
Aucune gate PostgreSQL n'est créée avant matérialisation d'une dépendance ou d'un schéma réel.
Lorsqu'elle devient nécessaire, la validation doit distinguer :
- parsing/compilation des migrations ou schémas ;
- tests avec base éphémère/localement contrôlée ;
- accès cohérent depuis les trois applications lorsque le stockage partagé est concerné ;
- éventuels smokes externes ;
- reconstruction d'une projection dérivée à partir d'une révision Git connue ;
- isolation correcte par famille/source sans dupliquer trois bases par simple symétrie.
## Gate de `0.0.1-alpha.1.fix.1`
Le fix reste documentaire. Sa gate doit prouver :
- `VERSION = 0.0.1-alpha.1.fix.1` ;
- le history `alpha.1` `FAIL` déjà committé avant application du fix ;
- les fichiers Git suivis/non ignorés exacts de la fondation, sans compter `.project` ;
- `.gitignore` avec headers `file/version` et exception Eclipse correcte ;
- `.settings/org.eclipse.core.resources.prefs` présent, UTF-8 et non ignoré ;
- l'absence de code fonctionnel ;
- les headers et liens locaux ;
- la topologie documentée à trois serveurs Actix distincts ;
- au moins trois sources Git initiales et une base PostgreSQL logique partagée ;
- l'absence d'override PGR non documenté ;
- la cohérence du plan et de la transition PASS/FAIL.
## Gate de `0.0.1-alpha.2`
La tranche doit prouver :
- `VERSION = 0.0.1-alpha.2` et `[workspace.package].version` identique ;
- `Cargo.lock` versionné et non ignoré ;
- `Cargo.toml`, `rustfmt.toml`, `clippy.toml` et `.cargo/config.toml` sans placeholder PGR ;
- `cargo metadata --format-version 1 --no-deps` ;
- `cargo fmt --all -- --check` ;
- `cargo check --workspace` ;
- `cargo clippy --workspace --all-targets --all-features -- -D warnings` ;
- `cargo test --workspace --all-targets --all-features` ;
- artefacts Cargo hors dépôt sous `../builds/sasedev-knowledge/target/` ;
- seule `knowledge-domain-lib` matérialisée comme première crate, sans création placeholder des trois serveurs ;
- étude auth/admin présente avec distinction entre fonctionnalités câblées, préparatoires et seulement annoncées ;
- surfaces admin locales documentées sans figer `/admin`, `/login` ou un modèle de rôles ;
- hygiène Git et headers documentaires applicables.
## Gate de `0.0.1-alpha.3`
La tranche doit prouver :
- `VERSION = 0.0.1-alpha.3` et `[workspace.package].version` identique ;
- trois packages seulement : `knowledge-domain-lib`, `knowledge-git-api`, `knowledge-sync-api` ;
- `knowledge-git-api` et `knowledge-sync-api` comme crates passives sans dépendance Actix, Gitea, PostgreSQL ou runtime ;
- source/famille de contenu capables de représenter plus de trois sources configurées ;
- `GitRepository` indépendant d'une forge et sans format de hash Git figé ;
- `RepositoryEventSource` produisant un signal non autoritaire lié à un `source_id` ;
- `Cargo.lock` régénéré par Cargo et versionné après ajout des deux packages ;
- `cargo fmt --all -- --check`, `cargo check --workspace` et Clippy strict ;
- tests ciblés des trois crates ;
- audits Rust PGR sélectionnés propres, y compris la façade crate-root ;
- absence de `knowledge-git-lib`, adapter Gitea, schéma PostgreSQL, Actix Web et frontend ;
- hygiène Git et headers documentaires/code applicables.
L'audit `audit_rust_const_blocks.py` n'appartient pas à la gate globale de cette tranche.
## Gate de `0.0.1-alpha.3.fix.1`
Le fix doit prouver :
- `VERSION = 0.0.1-alpha.3.fix.1` et version workspace identique ;
- history `alpha.3` `FAIL` committé avant application du fix ;
- construction valide de `SourceId` depuis son module sans contourner la visibilité du tuple struct ;
- test de régression direct `SourceId::new("pgr")` + tests précédents ;
- audits Rust PGR sélectionnés propres ;
- `cargo check`, Clippy strict et les trois suites ciblées `PASS` ;
- aucune dépendance ou crate fonctionnelle Web/Actix/PostgreSQL/Gitea ajoutée ;
- trajectoire Web documentée : skeleton Web PGR obligatoire en `alpha.4`, templates statiques de référence, rendu runtime Maud, manifest Vite produit côté frontend et intégration Actix/Maud seulement en `alpha.5` ;
- hygiène Git et documentation propres.
## Gate de `0.0.1-alpha.3.fix.2`
Le second fix doit prouver :
- `VERSION = 0.0.1-alpha.3.fix.2` et version workspace identique ;
- history `alpha.3.fix.1` `FAIL` committé avant application du fix ;
- documentation Rust présente sur chacune des quatre variantes publiques `Pgr`, `Howto`, `Snippet` et `ProjectLocal` ;
- aucune réduction de la politique `missing_docs` et aucun `allow(missing_docs)` introduit pour contourner la gate ;
- audits Rust PGR sélectionnés propres ;
- `cargo check --workspace` sans warning `missing_docs` ;
- Clippy workspace strict `-D warnings` `PASS` ;
- les trois suites ciblées `knowledge-domain-lib`, `knowledge-git-api` et `knowledge-sync-api` `PASS` ;
- `Cargo.lock` régénéré/versionné si la version workspace le modifie ;
- aucun changement fonctionnel des contrats domaine/Git/synchronisation ;
- aucun frontend, serveur Actix, schéma PostgreSQL ou adapter de forge ajouté ;
- hygiène Git et documentation propres.
## Gate de `0.0.1-alpha.3.fix.3`
Le troisième fix doit prouver :
- `VERSION = 0.0.1-alpha.3.fix.3` et version workspace identique ;
- history `alpha.3.fix.2` `FAIL` committé avant application du fix ;
- `docs/validation/001-VALIDATION_MATRIX.md` se termine par exactement une fin de ligne, sans ligne vide supplémentaire ;
- `git diff --check` `PASS` avant clôture de tranche ;
- documentation des quatre variantes publiques `ContentFamily` conservée ;
- aucun `allow(missing_docs)` ajouté et politique `missing_docs` inchangée ;
- audits Rust PGR sélectionnés propres ;
- `cargo check --workspace` `PASS` ;
- Clippy workspace strict `-D warnings` `PASS` ;
- les trois suites ciblées `knowledge-domain-lib`, `knowledge-git-api` et `knowledge-sync-api` `PASS` ;
- aucune modification fonctionnelle des contrats domaine/Git/synchronisation ;
- aucun frontend, serveur Actix, schéma PostgreSQL ou adapter de forge ajouté ;
- staging Git propre à la tranche.
## Gate de `0.0.1-alpha.4`
La tranche Web doit prouver :
- `VERSION = 0.0.1-alpha.4` et version workspace Cargo identique ;
- history `alpha.3.fix.3` `PASS` committé avant application d'`alpha.4` ;
- package unique `Web/knowledge-template-lab/` et absence des trois launchers Actix encore différés ;
- npm sélectionné comme package manager ;
- `package-lock.json` généré par npm, versionné et non ignoré ;
- dépendances réelles et versions explicites pour TypeScript, Vite, Sass, Bootstrap, Popper et types nécessaires ;
- `npm ci` `PASS` depuis le lockfile ;
- `npm run typecheck` indépendant `PASS` ;
- `npm run build` `PASS` ;
- cache Vite et `build.outDir` hors dépôt sous `../builds/sasedev-knowledge/` ;
- manifest Vite de production parsable ;
- entrée stable `src/main.ts` présente dans le manifest et associée à un asset JavaScript ;
- au moins un asset CSS associé à l'entrée ou à son graphe de build ;
- page statique de référence incluse dans le build Vite sans route Actix/Maud ;
- aucun chemin `/admin`, `/login` ou hostname de production figé dans le package de laboratoire ;
- aucune crate serveur, dépendance Actix/Maud, migration PostgreSQL ou adapter de forge ajouté ;
- gates Rust existantes toujours propres après le bump de version ;
- `git diff --cached --check` propre et outputs générés absents du staging.
## Gate de `0.0.1-alpha.4.fix.1`
Le premier fix Web doit prouver :
- `VERSION = 0.0.1-alpha.4.fix.1` et version workspace Cargo identique ;
- history `alpha.4` `FAIL` committé avant application du fix ;
- `git diff --check` propre ;
- `compilerOptions.types` contient exactement `vite/client` dans `Web/knowledge-template-lab/tsconfig.json` ;
- aucun shim `*.scss` local ajouté pour contourner les types Vite ;
- `npm ci` `PASS` depuis le `package-lock.json` déjà versionné par `alpha.4` ;
- `npm run typecheck` `PASS` ;
- `npm run build` `PASS` ;
- manifest Vite parsable avec entrée `src/main.ts`, JavaScript et CSS ;
- `npm install-scripts ls` exécuté pour exposer les scripts d'installation non approuvés sans les approuver automatiquement ;
- warnings Sass issus de Bootstrap observables mais non traités comme défaut Knowledge tant que le build reste `PASS` ;
- gates Rust existantes toujours propres après le bump de version ;
- aucun serveur Actix/Maud, route runtime, migration PostgreSQL ou adapter de forge ajouté ;
- staging Git propre et outputs générés absents du dépôt.
## Gate de `0.0.1-alpha.4.fix.2`
Le second fix Web doit prouver :
- `VERSION = 0.0.1-alpha.4.fix.2` et version workspace Cargo identique ;
- history `alpha.4.fix.1` `FAIL` committé avant application du fix ;
- `git diff --check` propre ;
- `@types/node = 24.13.6` présent dans `devDependencies` ;
- `tsconfig.json` contient `types = ["vite/client", "node"]` ;
- `tsconfig.json` conserve `ES2022`, `DOM`, `DOM.Iterable` et ajoute `ESNext.Disposable` ;
- `tsconfig.vite.json` contient `types = ["node"]` et `lib = ["ES2022", "ESNext.Disposable"]` ;
- aucun shim `*.scss` source propre au projet n'est ajouté ;
- l'audit de shims ne parcourt pas `node_modules` ;
- `npm install` met à jour `package-lock.json` avec `@types/node` puis `npm ci` `PASS` ;
- `npm run typecheck` `PASS` ;
- `npm run build` `PASS` ;
- manifest Vite parsable avec entrée `src/main.ts`, JavaScript et CSS ;
- `npm install-scripts ls` garde observable la politique `@parcel/watcher` sans approbation automatique ;
- gates Rust existantes toujours propres après le bump de version ;
- aucun serveur Actix/Maud, loader Rust du manifest, route runtime, migration PostgreSQL ou adapter de forge ajouté ;
- staging Git propre et outputs générés absents du dépôt.
## Gate de `0.0.1-alpha.5`
La composition serveur doit prouver :
- `VERSION = 0.0.1-alpha.5` et version workspace identique ;
- history `alpha.4.fix.2` `PASS` committé avant application ;
- workspace contenant `knowledge-web-lib` et exactement les trois nouveaux launchers attendus ;
- `knowledge-web-lib` comme unique owner Actix/Maud/Vite runtime partagé ;
- launchers dépendant de `knowledge-web-lib` sans dépendance directe Actix/Maud/Serde ;
- Actix Web `4.15.0`, Actix Files `0.7.0`, Maud `0.27.0`, Serde `1.0.229` et Serde JSON `1.0.151` dans le manifest de `knowledge-web-lib` ;
- aucun `panic!`, `unwrap`, `expect` ou `?` ajouté ;
- aucune origin/port Vite ou adresse de bind choisie par le code ;
- mode dev résolvant `@vite/client` puis `src/main.ts` depuis `KNOWLEDGE_VITE_DEV_ORIGIN` ;
- mode production résolvant `src/main.ts` depuis le manifest configuré et servant les fichiers `/assets/*` depuis le build réel ;
- routes runtime limitées à `/` et `/healthz` pour cette tranche ;
- aucune route admin/login, auth, PostgreSQL ou forge ajoutée ;
- `npm ci`, typecheck et build du template lab toujours `PASS` ;
- audits Rust PGR, `cargo check`, Clippy strict et tests ciblés `PASS` ;
- smoke HTTP production `PASS` pour les trois launchers avec ports de test injectés par environnement ;
- `Cargo.lock` mis à jour/versionné et staging propre.
## Convention locale des tests Rust
Knowledge sélectionne la convention PGR optionnelle suivante comme règle locale obligatoire :
```text
crate/
src/
unit_tests/
tests/
```
`unit_tests/` contient les tests unitaires attachés aux modules source par `#[path = "..."]`.
`tests/` contient exclusivement les tests d'intégration Cargo qui consomment l'API publique.
La gate Rust ajoute :
```text
python3 -B scripts/audit_rust_test_layout.py crates
```
Cet audit doit refuser notamment :
- un attribut `#[test]` dans `src/` ;
- un fichier `src/unit_tests.rs` ou `src/tests.rs` ;
- un `mod unit_tests;` classique sous `src/` ;
- un fichier sous `unit_tests/` qui n'est référencé par aucun `#[path = "..."]` d'un source de la crate.
## Gate de `0.0.1-alpha.5.fix.1`
Le fix de layout des tests doit prouver :
- `VERSION = 0.0.1-alpha.5.fix.1` et version workspace identique ;
- history `alpha.5` `FAIL` committé avant application ;
- suppression exacte des quatre anciens `src/unit_tests.rs` via le manifest de suppression ;
- tests unitaires sous `unit_tests/` hors de `src/` pour `knowledge-domain-lib`, `knowledge-git-api`, `knowledge-sync-api` et `knowledge-web-lib` ;
- rattachements `#[cfg(test)]` + `#[path = "..."]` depuis les modules source propriétaires ;
- aucun `#[test]` sous `crates/*/src/` ;
- `tests/` réservé aux futurs tests d'intégration Cargo ;
- `audit_rust_test_layout.py` `PASS` ;
- audits Rust PGR existants toujours `PASS`, y compris export completeness qui suit les modules `#[path]` ;
- `cargo check`, Clippy strict et `cargo test --workspace --all-targets --all-features` `PASS` ;
- baseline Web `npm ci`, typecheck et build `PASS` ;
- smoke HTTP production des trois serveurs `PASS` ;
- aucune modification fonctionnelle Actix/Maud/Vite au-delà du rattachement des tests ;
- `git diff --cached --check` propre.
## Gate de `0.0.1-alpha.5.fix.2`
Le second fix de clôture doit prouver :
- `VERSION = 0.0.1-alpha.5.fix.2` et version workspace identique ;
- history `alpha.5.fix.1` `FAIL` committé avant application ;
- `git diff --check` `PASS` immédiatement après application, avant toute commande de formatage ;
- `cargo fmt --all -- --check` `PASS` sans exécution préalable de `cargo fmt --all`, afin de prouver que le snapshot livré est déjà formaté ;
- les quatre anciens `src/unit_tests.rs` restent absents ;
- les cinq fichiers sous `unit_tests/` restent présents et rattachés par `#[path = "..."]` ;
- `audit_rust_test_layout.py` et les audits Rust PGR existants `PASS` ;
- `cargo check`, Clippy strict et `cargo test --workspace --all-targets --all-features` `PASS` ;
- `npm ci`, `npm run typecheck` et `npm run build` `PASS` ;
- manifest Vite `PASS` ;
- smoke HTTP de `knowledge-pgr-server`, `knowledge-howtos-server` et `knowledge-snippets-server` `PASS` ;
- aucune modification fonctionnelle du runtime Actix/Maud/Vite ;
- `git diff --cached --check` propre.
## Gate de `0.0.1-beta.1`
La réconciliation beta doit prouver :
- `VERSION = 0.0.1-beta.1` et version workspace identique ;
- history `alpha.5.fix.2` `PASS` committé avant application de beta ;
- aucun nouveau package Cargo, package npm ou comportement runtime introduit ;
- workspace Cargo toujours composé exactement de sept packages ;
- `knowledge-web-lib` et les trois launchers documentés comme matérialisés ;
- aucune formulation durable ne décrit encore `knowledge-web-lib` comme candidate ou les launchers comme non matérialisés ;
- owners Web PGR réconciliés avec `alpha.4`/`alpha.5` ;
- `unit_tests/` confirmé comme convention locale et audit associé toujours propre ;
- étude `003-V0_0_1_FOUNDATION_RECONCILIATION.md` présente ;
- roadmap engage uniquement `0.0.2` et ne réserve aucun numéro supplémentaire ;
- prompt `002-V0_0_2_START_PROMPT.md` présent et explicitement bloqué jusqu'au post-tag `0.0.1 PASS` ;
- DEFER PostgreSQL/forge/auth/admin/formats finaux conservés ;
- `CHANGELOG.md` ne contient plus le détail interne du fix rustfmt comme changement utilisateur ;
- audits Markdown headers/tables/links propres ;
- `cargo fmt --check`, audits Rust, `cargo check`, Clippy strict et tests workspace propres ;
- baseline Web `npm ci`, typecheck et build propre ;
- manifest Vite parsable ;
- smoke HTTP des trois launchers propre ;
- `git diff --cached --check` propre.
## Gate de `0.0.1-rc.1`
La release candidate doit prouver :
- `VERSION = 0.0.1-rc.1` et version workspace identique ;
- history `beta.1` `PASS` committé avant application de la RC ;
- aucun diff sous `crates/` ou `Web/` ;
- aucun nouveau package, dépendance, route, contrat métier, étude technique ou scope fonctionnel ;
- quatorze histories antérieurs présents avec leurs statuts réels ;
- `deltas/0.0.1/rc.1.md` présent et `history/0.0.1/rc.1.md` absent pendant la gate ;
- `CHANGELOG.md` conserve `## 0.0.1 (candidate)` et ne contient pas de détail de tranche/fix ;
- `ROADMAP.md` conserve `0.0.1` planifié, engage `0.0.2` et ne réserve pas `0.0.3` ;
- étude de réconciliation `003` et prompt `002` inchangés depuis beta ;
- prompt `002` toujours bloqué jusqu'au tag `v0.0.1` et au rapport post-tag `PASS` ;
- PostgreSQL, forge, auth/admin complète, formats finaux et workflow Git d'écriture restent différés ;
- audits Markdown headers/tables/links propres ;
- hygiène texte globale propre : pas de CR, whitespace terminal ni fichier texte suivi sans newline finale ;
- `cargo fmt --check`, audit de layout des tests, audits Rust, `cargo check`, Clippy strict et tests workspace propres ;
- `npm ci`, typecheck et build Web propres ;
- manifest Vite parsable ;
- smoke HTTP des trois launchers propre ;
- `git diff --cached --check` propre.
La RC `PASS` autorise uniquement la promotion mécanique `0.0.1-rel.1`.
## Gate de `0.0.1-rc.1.fix.1`
Le fix RC doit prouver :
- `VERSION = 0.0.1-rc.1.fix.1` et version workspace identique ;
- history `rc.1` `FAIL` committé avant application ;
- `/Cargo.lock` présent dans `.gitignore` ;
- `Cargo.lock` absent de l'index Git après `git rm --cached`, mais copie locale toujours présente ;
- `git check-ignore -q Cargo.lock` `PASS` ;
- `git ls-files --error-unmatch Cargo.lock` échoue ;
- `package-lock.json` reste suivi et non ignoré ;
- `RULES.md`, profil, architecture et changelog candidat décrivent tous la politique Cargo actuelle comme locale/non versionnée ;
- aucune réécriture des deltas/histories antérieurs pour masquer l'ancienne politique ;
- audit d'intégration corrigé : présence du delta fix contrôlée directement, sans exiger qu'un fichier non suivi apparaisse dans `git diff --name-only` ;
- quinze histories antérieurs présents avec leurs statuts réels, dont `rc.1 = FAIL` ;
- `deltas/0.0.1/rc.1.fix.1.md` présent et history du fix absent pendant la gate ;
- aucun diff sous `crates/` ou `Web/` ;
- audits Markdown et hygiène texte propres ;
- `cargo fmt --check`, audits Rust, `cargo check`, Clippy strict et tests workspace propres ;
- les commandes Cargo peuvent générer/mettre à jour le `Cargo.lock` local sans le remettre dans le staging ;
- `npm ci`, typecheck et build Web propres ;
- manifest Vite parsable ;
- smoke HTTP des trois launchers propre ;
- staging final contenant la suppression Git de `Cargo.lock` mais aucune réintroduction du fichier ;
- `git diff --cached --check` propre.
Le fix `PASS` autorise la reprise de la release candidate vers `0.0.1-rc.2`.
## Gate de `0.0.1-rc.2`
La candidate finale doit prouver :
- `VERSION = 0.0.1-rc.2` et version workspace identique ;
- history `rc.1.fix.1` `PASS` committé avant application ;
- aucun diff sous `crates/` ou `Web/` ;
- `/Cargo.lock` toujours présent dans `.gitignore` ;
- `Cargo.lock` présent localement, ignoré et absent de `git ls-files` ;
- `package-lock.json` toujours suivi et non ignoré ;
- exactement sept packages Cargo ;
- seize histories antérieurs présents avec leurs statuts réels ;
- `deltas/0.0.1/rc.2.md` présent et `history/0.0.1/rc.2.md` absent pendant la gate ;
- `CHANGELOG.md` conserve `## 0.0.1 (candidate)` ;
- `ROADMAP.md` conserve `0.0.1` planifié, `0.0.2` engagé et aucun `0.0.3` ;
- prompt `002` toujours bloqué jusqu'au tag stable `v0.0.1` et au rapport post-tag `PASS` ;
- aucune nouvelle fonctionnalité, dépendance ou décision de produit ;
- audits Markdown headers/tables/links propres ;
- hygiène texte globale propre ;
- `cargo fmt --check`, audit de layout des tests et audits Rust propres ;
- `cargo metadata`, `cargo check`, Clippy strict et tests workspace propres malgré le lockfile non suivi ;
- les commandes Cargo ne réintroduisent pas `Cargo.lock` dans Git ;
- `npm ci`, typecheck et build Web propres ;
- manifest Vite parsable ;
- smoke HTTP des trois launchers propre ;
- staging final sans `Cargo.lock` et `git diff --cached --check` propre.
Un `PASS` de `rc.2` autorise uniquement `0.0.1-rel.1`.
## Gate de `0.0.2-alpha.1`
La première tranche de `0.0.2` est documentaire et de gouvernance. Elle doit prouver :
- `VERSION = 0.0.2-alpha.1` et `[workspace.package].version` identique ;
- baseline Knowledge `v0.0.1` identifiée par son commit, SHA-256 d'archive et rapport `publish.001 PASS` ;
- adoption PGR `v0.1.3` explicite avec commit, SHA-256 d'archive et rapport `publish.001 PASS` ;
- owner `230-ADOPTION` actif uniquement pour la migration du projet existant ;
- preservation des références historiques PGR `v0.1.1` dans les artefacts `0.0.1` ;
- absence d'activation Java/Maven/Gradle/Android et maintien du `DEFER` Tauri ;
- étude comparative Git présente et décision `processus git contrôlé` explicite ;
- `knowledge-git-lib` identifiée comme owner futur de la configuration physique/backend sans création prématurée de la crate ;
- racine d'état Git explicitement hors dépôt source et layout mirror/snapshot documenté ;
- `knowledge-app-lib` seulement comme owner candidat du cas d'usage partagé, sans placeholder ;
- aucun diff sous `crates/` ou `Web/` ;
- aucun history `0.0.2/alpha.1` présent avant la gate ;
- headers, liens Markdown locaux et hygiène texte propres ;
- audits Rust existants propres ;
- Cargo/Clippy/tests workspace propres malgré le bump de version ;
- baseline Web `npm ci`, typecheck et build sans régression ;
- `Cargo.lock` toujours ignoré/non suivi et `package-lock.json` toujours versionné ;
- `git diff --cached --check` propre avant commit.
La disponibilité de l'exécutable `git` et sa version sont relevées comme prérequis du backend futur :
```text
git --version
```
`alpha.1` ne prétend pas encore valider `knowledge-git-lib` puisqu'aucune implémentation fonctionnelle n'existe dans cette tranche. La séquence mirror/refresh/resolve/worktree documentée dans l'étude est une prévalidation de conception, pas une gate produit.
## Gate de `0.0.2-alpha.1.fix.1`
Le fix reste documentaire et ne change aucune décision technique Git. Il doit prouver :
- `VERSION = 0.0.2-alpha.1.fix.1` et `[workspace.package].version` identique ;
- history `history/0.0.2/alpha.1.md` présent avec statut réel `FAIL` et committé avant application du fix ;
- delta historique `deltas/0.0.2/alpha.1.md` inchangé ;
- `docs/plans/002-V0_0_2_GIT_SYNC_PLAN.md` en version documentaire `2` ;
- présence, dans cet ordre, des sections `Statut et sources`, `Mission`, `État acquis et questions ouvertes`, `Scope`, `Hors scope`, `Stratégie de validation`, `Trajectoire prévisionnelle`, `Déclencheurs de REPLAN`, `Clôture et transition`, `Revue d'horizon` ;
- toutes les tranches prévues `alpha.1`, `alpha.2`, `alpha.3`, `alpha.4`, `beta.1`, `rc.1` et `rel.1` déclarées en titres `###` sous `## Trajectoire prévisionnelle` ;
- aucun titre `## alpha.*`, `## beta.*`, `## rc.*` ou `## rel.*` dans le plan ;
- le `FAIL` documentaire d'`alpha.1` et le rôle correctif d'`alpha.1.fix.1` explicitement documentés ;
- scope global et hors-scope de `0.0.2` distincts du forecast tranche par tranche ;
- déclencheurs de REPLAN couvrant au minimum dérive de responsabilités, forge obligatoire, capacités Git supplémentaires, concurrence de l'état, changement substantiel des contrats et accumulation de fixes ;
- revue d'horizon explicitement non réalisée avant `beta.1`, sans version postérieure à `0.0.2` réservée ;
- aucun changement sous `crates/` ou `Web/` ;
- aucune dépendance, crate, route ou comportement Git ajouté par le fix ;
- headers/liens Markdown, hygiène texte et audits Rust existants propres ;
- Cargo/Clippy/tests workspace et baseline Web toujours propres malgré le bump de version ;
- `Cargo.lock` reste ignoré/non suivi et `package-lock.json` reste versionné ;
- `git diff --cached --check` propre avant commit.
Le `PASS` du fix ferme `alpha.1` et autorise uniquement la préparation de `0.0.2-alpha.2`.
## Gate de `0.0.2-alpha.2`
La première tranche fonctionnelle Git doit prouver :
- `VERSION = 0.0.2-alpha.2` et `[workspace.package].version` identique ;
- history `alpha.1.fix.1` `PASS` committé avant application ;
- huit packages Cargo exactement, avec `knowledge-git-lib` comme nouvelle crate `-lib` réelle ;
- `knowledge-git-api` et `knowledge-sync-api` toujours passives et inchangées ;
- `knowledge-git-lib` dépendant uniquement des contrats/domaines réellement nécessaires, sans Actix, forge, PostgreSQL, scheduler ou runtime async ;
- racine d'état obligatoire et explicite, avec sous-répertoires `hooks-disabled/`, `repositories/` et `snapshots/` ;
- dérivation de `source-key` ne réutilisant ni `SourceId` brut ni URL remote comme chemin ;
- source locale utilisant `git clone --mirror --no-local -- ...` ;
- source remote utilisant `git clone --mirror -- ...` sans `--no-local` ;
- runner process interne utilisant `std::process::Command` directement, sans shell ;
- prompts Git interactifs désactivés et variables Git capables de rediriger implicitement repository/worktree retirées ;
- hooks Git désactivés via un répertoire contrôlé ;
- erreurs de processus publiques ne contenant ni URL source, ni arguments, ni stderr, ni credentials ;
- inspection d'un mirror existant sans suppression/recréation silencieuse ;
- tests unitaires ciblant configuration, layout, arguments, redaction et erreurs ;
- aucun refresh, résolution de révision ou snapshot fonctionnel anticipé avant `alpha.3` ;
- aucun adapter Gitea/GitHub/GitLab, PostgreSQL, scheduler ou `knowledge-app-lib` ajouté ;
- `cargo fmt --all -- --check`, audits Rust, `cargo metadata`, `cargo check`, Clippy strict et tests ciblés/workspace propres ;
- baseline Web inchangée et absence de diff sous `Web/` ;
- `Cargo.lock` toujours ignoré/non suivi ;
- `git diff --cached --check` propre avant commit.
Le `PASS` d'`alpha.2` autorise uniquement la préparation de `0.0.2-alpha.3`, consacrée au refresh réel, à la résolution et au snapshot sur repositories Git temporaires.
## Gate de `0.0.2-alpha.2.fix.1`
Le fix reste strictement dans le scope `alpha.2` et doit prouver :
- `VERSION = 0.0.2-alpha.2.fix.1` et `[workspace.package].version` identique ;
- history `history/0.0.2/alpha.2.md` présent avec statut réel `FAIL` et committé avant application du fix ;
- delta historique `deltas/0.0.2/alpha.2.md` inchangé ;
- suppression du défaut `git diff --check` sur la matrice de validation ;
- audit Markdown limité au contenu gouverné et ignorant notamment `.git`, `node_modules`, `target` et autres arbres générés ;
- correction de la construction interne de `GitSourceKey` sans rendre son champ tuple public ;
- formatage rustfmt propre des fichiers de `knowledge-git-lib` ;
- huit packages Cargo exactement et dépendances de `knowledge-git-lib` inchangées ;
- absence de `refresh`, résolution de révision, worktree/snapshot, forge, PostgreSQL, scheduler ou `knowledge-app-lib` ;
- audits Rust, `cargo metadata`, `cargo check`, Clippy strict, tests ciblés `knowledge-git-lib` et tests workspace propres ;
- `Web/`, `knowledge-git-api` et `knowledge-sync-api` sans diff ;
- `Cargo.lock` toujours ignoré/non suivi ;
- `git diff --cached --check` propre avant commit.
Le `PASS` du fix ferme `alpha.2` et autorise uniquement la préparation de `0.0.2-alpha.3`.
## Gate de `0.0.2-alpha.2.fix.2`
Le second fix reste strictement dans le scope `alpha.2` et doit prouver :
- `VERSION = 0.0.2-alpha.2.fix.2` et `[workspace.package].version` identique ;
- history `history/0.0.2/alpha.2.fix.1.md` présent avec statut réel `FAIL` et committé avant application du fix ;
- deltas historiques `alpha.2.md` et `alpha.2.fix.1.md` inchangés ;
- correction limitée à la violation `clippy::implicit_return` observée dans `unit_tests/backend.rs` ;
- retour explicite dans la closure de validation du `source-key` ;
- aucune modification fonctionnelle du backend Git, de ses erreurs publiques ou de son API ;
- huit packages Cargo exactement et dépendances de `knowledge-git-lib` inchangées ;
- absence de `refresh`, résolution de révision, worktree/snapshot, forge, PostgreSQL, scheduler ou `knowledge-app-lib` ;
- `git diff --check`, audits structurels, `cargo fmt`, `cargo metadata`, `cargo check`, Clippy strict, tests ciblés `knowledge-git-lib` et tests workspace propres ;
- `Web/`, `knowledge-git-api` et `knowledge-sync-api` sans diff ;
- `Cargo.lock` toujours ignoré/non suivi ;
- `git diff --cached --check` propre avant commit.
Le `PASS` de `alpha.2.fix.2` ferme `alpha.2` et autorise uniquement la préparation de `0.0.2-alpha.3`.
## Gate de `0.0.2-alpha.3`
La tranche de lecture Git réelle doit prouver :
- `VERSION = 0.0.2-alpha.3` et `[workspace.package].version` identique ;
- history `history/0.0.2/alpha.2.fix.2.md` présent avec statut `PASS` et committé avant application ;
- huit packages Cargo exactement ;
- `knowledge-git-lib` dépend désormais de `knowledge-domain-lib` et `knowledge-git-api`, sans autre dépendance ;
- `knowledge-git-api` étendu uniquement avec le contrat `GitSnapshot` / `prepare_snapshot` nécessaire à la lecture ;
- `GitBackend` implémente `knowledge_git_api::GitRepository` et possède l'enregistrement explicite des configurations physiques de source ;
- doublons de `SourceId` refusés et source non configurée signalée sans exposer sa localisation ;
- refresh du mirror par `git --git-dir <mirror> remote update --prune` ;
- résolution par `rev-parse --verify --end-of-options <reference>^{commit}` ;
- révision backend validée comme identité hexadécimale non vide avant usage dans un chemin, sans longueur SHA figée ;
- snapshot créé par `worktree add --detach -- <path> <revision>` sous `snapshots/<source-key>/<revision>` ;
- snapshot existant réutilisé seulement si son `HEAD` correspond exactement à la révision et si `status --porcelain=v1 --untracked-files=all` est vide ;
- snapshot divergent ou sale refusé sans suppression silencieuse ;
- tests avec vrais repositories Git temporaires prouvant initialisation/refresh/résolution/snapshot, réutilisation idempotente, changement de commit, référence invalide et snapshot sale ;
- aucune API de forge, dépendance réseau Rust, PostgreSQL, scheduler, `knowledge-app-lib` ou écriture/push Git ajoutée ;
- `cargo fmt --all -- --check`, audits Rust, `cargo metadata`, `cargo check`, Clippy strict, tests ciblés et tests workspace propres ;
- `Web/` et `knowledge-sync-api` sans diff ;
- `Cargo.lock` toujours ignoré/non suivi ;
- `git diff --cached --check` propre avant commit.
La gate opérateur réelle d'`alpha.3` est `FAIL` : les preuves Git fonctionnelles passent, mais `git diff --check`, `cargo fmt --check` et Clippy strict ne sont pas tous propres. La transition autorisée est uniquement `alpha.3.fix.1`.
## Gate de `0.0.2-alpha.3.fix.1`
Le fix ferme les défauts techniques d'`alpha.3` et enregistre le REPLAN sans élargir son comportement Git. Il doit prouver :
- `VERSION = 0.0.2-alpha.3.fix.1` et `[workspace.package].version` identique ;
- history `history/0.0.2/alpha.3.md` présent avec statut réel `FAIL` et committé avant application du fix ;
- delta historique `deltas/0.0.2/alpha.3.md` inchangé ;
- suppression du défaut `git diff --check` sur la matrice de validation ;
- formatage rustfmt propre du test `knowledge-git-api` signalé par la gate ;
- documentation de crate explicite dans `crates/knowledge-git-lib/tests/git_read_path.rs` afin de satisfaire `missing_docs` ;
- comportement Git d'`alpha.3` inchangé : refresh, résolution, snapshot et tests réels restent identiques ;
- plan `0.0.2` replanifié avec `alpha.4` dédiée à l'autonomie normative/structure interne des crates et ancien scope de synchronisation déplacé en `alpha.5` ;
- PGR `v0.1.3` documenté comme provenance d'adoption figée et non comme dépendance normative vivante ;
- règle locale interdisant la consultation automatique de PGR à chaque version/session/tranche, sauf réévaluation PGR explicitement engagée ;
- aucune matérialisation prématurée des règles PGR détaillées ni refactor massif de crates dans ce fix : ce travail appartient à `alpha.4` ;
- `cargo fmt --all -- --check`, audits Rust, `cargo metadata`, `cargo check`, Clippy strict, tests ciblés `knowledge-git-api`/`knowledge-git-lib`, test d'intégration `git_read_path` et tests workspace propres ;
- `Web/` et `knowledge-sync-api` sans diff ;
- `Cargo.lock` toujours ignoré/non suivi ;
- `git diff --cached --check` propre avant commit.
Le `PASS` de `alpha.3.fix.1` ferme `alpha.3` et autorise uniquement la préparation de `0.0.2-alpha.4`.
## Gate de `0.0.2-alpha.4`
La tranche d'autonomie normative et de structure interne doit prouver :
- `VERSION = 0.0.2-alpha.4` et version workspace identique ;
- history `history/0.0.2/alpha.3.fix.1.md` présent avec statut `PASS` et committé avant application ;
- owners locaux `200`, `210`, `300`, `400`, `510` et `530-WEB_FRONTEND` présents, indexés et suffisamment complets pour retrouver localement lifecycle/versioning, fixes/REPLAN, delta/history/handoff, rôles documentaires et catégories de preuve ;
- mapping d'adoption `003-PGR_ADOPTION_MAP.md` présent, PGR `v0.1.3` seulement comme provenance et aucune consultation PGR automatique requise ;
- templates locaux de nouvelle session, release plan, handoff opérateur et crate bibliothèque présents ;
- audits Markdown headers/liens/tables possédés localement et propres ;
- audit `audit_rust_crate_root_facades.py` propre sur toutes les crates bibliothèque ;
- `knowledge-git-api/src/lib.rs` limité à documentation/module declarations/réexports/test attachment, avec définitions déplacées vers `reference`, `repository`, `revision`, `snapshot` ;
- `knowledge-sync-api/src/lib.rs` limité à façade, avec définitions déplacées vers `event_source` et `signal` ;
- API publique crate-root inchangée pour `GitReference`, `GitRevision`, `GitSnapshot`, `GitRepository`, `RepositorySyncCause`, `RepositorySyncSignal`, `RepositoryEventSource` ;
- `knowledge-domain-lib`, `knowledge-git-lib` et `knowledge-web-lib` déjà conformes à la façade crate-root sans refactor artificiel ;
- comportement Git `alpha.3` inchangé et tests réels toujours propres ;
- `cargo fmt --all -- --check`, audits Rust, `cargo metadata`, `cargo check`, Clippy strict, tests ciblés `knowledge-git-api`/`knowledge-sync-api`/`knowledge-git-lib` et tests workspace propres ;
- `Web/` sans diff et aucun `knowledge-app-lib`, adapter forge ou store PostgreSQL ajouté ;
- `Cargo.lock` ignoré/non suivi ;
- `git diff --cached --check` propre avant commit.
Le `PASS` d'`alpha.4` ferme l'adoption PGR `v0.1.3` comme migration ponctuelle et autorise uniquement la préparation de `0.0.2-alpha.5`.
## Gate de `0.0.2-alpha.4.fix.1`
Le correctif doit prouver :
- `VERSION = 0.0.2-alpha.4.fix.1` et version workspace identique ;
- history `history/0.0.2/alpha.4.md` présent avec statut `FAIL` et committé avant application ;
- `GitReference::new` construit le tuple struct privé avec `Self(...)` depuis `reference.rs` ;
- `GitRevision::new` construit le tuple struct privé avec `Self(...)` depuis `revision.rs` ;
- aucune ouverture de visibilité des champs tuple et aucune construction via `crate::GitReference(...)`, `crate::GitRevision(...)` ou chemin de module propriétaire ;
- API publique crate-root inchangée et audit `audit_rust_crate_root_facades.py` toujours propre ;
- owners locaux, mapping d'adoption, templates et audits d'autonomie d'`alpha.4` inchangés et toujours valides ;
- `cargo fmt --all -- --check`, `cargo check --workspace` et Clippy strict `PASS` ;
- tests ciblés `knowledge-git-api`, `knowledge-sync-api`, `knowledge-git-lib` et tests workspace `PASS` ;
- comportement Git `alpha.3` inchangé ;
- `Web/`, `knowledge-git-lib/src` et les modules `knowledge-sync-api` sans diff ;
- `Cargo.lock` ignoré/non suivi et `git diff --cached --check` propre.
Le `PASS` de `alpha.4.fix.1` ferme `alpha.4`, termine l'adoption PGR `v0.1.3` comme migration ponctuelle et autorise uniquement la préparation de `0.0.2-alpha.5`.
## Ordre canonique des validations Rust à partir de `0.0.2-alpha.5`
Toute gate qui audite du code Rust applique d'abord le formatter :
```bash
cargo fmt --all
cargo fmt --all -- --check
```
Les audits Rust sont exécutés seulement après ces deux commandes. Viennent ensuite `cargo metadata`/`cargo check`, Clippy et les tests requis par le scope. Les audits Markdown peuvent être placés avant ou après cette séquence puisqu'ils ne lisent pas la forme du code Rust.
## Gate de `0.0.2-alpha.5`
La tranche de cas d'usage de synchronisation doit prouver :
- `VERSION = 0.0.2-alpha.5` et version workspace identique ;
- history `history/0.0.2/alpha.4.fix.1.md` présent avec statut `PASS` et committé avant application ;
- neuf packages Cargo exactement, avec `knowledge-app-lib` comme nouvel owner application réel ;
- `knowledge-app-lib` dépendant seulement de `knowledge-git-api` et `knowledge-sync-api` en production ;
- `src/lib.rs` de `knowledge-app-lib` conforme au contrat de façade crate-root ;
- cas d'usage public enchaînant refresh, résolution, comparaison de `previous_revision` puis snapshot seulement si changement ;
- résultat explicite `Changed` / `Unchanged` exposant toujours la révision observée et le snapshot uniquement en cas de changement ;
- absence de persistance implicite de la dernière révision ;
- cause `Periodic` prouvée sur le même chemin que la synchronisation explicite, sans scheduler concret ;
- aucune dépendance forge, PostgreSQL, Actix, worker réseau ou écriture Git dans `knowledge-app-lib` ;
- `cargo fmt --all` exécuté avant tout audit Rust ;
- `cargo fmt --all -- --check` exécuté immédiatement après le formatage et avant tout audit Rust ;
- audits Rust locaux propres, y compris façade crate-root et complétude d'exports ;
- `cargo metadata`, `cargo check --workspace`, Clippy strict, tests ciblés `knowledge-app-lib`/Git et tests workspace propres ;
- `Web/` sans diff et `Cargo.lock` ignoré/non suivi ;
- `git diff --cached --check` propre avant commit.
Le `PASS` d'`alpha.5` ferme le scope fonctionnel alpha de `0.0.2` et autorise uniquement la préparation de `beta.1` de réconciliation et revue d'horizon.
## Gate de `0.0.2-beta.1`
La réconciliation beta doit prouver :
- `VERSION = 0.0.2-beta.1` et version workspace identique ;
- history `history/0.0.2/alpha.5.md` présent avec statut `PASS` et committé avant application ;
- aucun nouveau package Cargo, package npm, contrat runtime ou comportement Git introduit ;
- workspace Cargo composé exactement de neuf packages ;
- étude `005-V0_0_2_GIT_SYNC_RECONCILIATION.md` présente et cohérente avec l'implémentation ;
- `knowledge-git-lib` documentée comme backend Git générique réel et `knowledge-app-lib` comme owner du cas d'usage partagé ;
- références historiques aux alphas Web de fondation qualifiées `0.0.1-*` lorsqu'elles seraient ambiguës ;
- `DEFER` PostgreSQL/forge/auth/admin/formats finaux/écriture Git/scheduler/submodules-LFS/rétention snapshots/multi-processus conservés ;
- revue d'horizon réalisée sans engager ni numéroter de release après `0.0.2` ;
- `CHANGELOG.md` contient une section `0.0.2 (candidate)` utile et sans catalogue de fixes internes ;
- `cargo fmt --all` puis `cargo fmt --all -- --check` exécutés avant tout audit Rust ;
- audits Markdown et Rust locaux propres ;
- `cargo metadata`, `cargo check --workspace`, Clippy strict et tests workspace propres ;
- baseline Web `npm ci`, `npm run typecheck` et `npm run build` propre ;
- manifest Vite généré parsable avec l'entrée stable `src/main.ts` ;
- aucun diff sous `crates/` ou `Web/` ;
- `Cargo.lock` présent localement, ignoré et non suivi ;
- hygiène texte et `git diff --cached --check` propres.
Un `PASS` de `beta.1` autorise uniquement `0.0.2-rc.1`. Aucun prompt de release suivante n'est créé tant que la revue d'horizon ne l'a pas engagée.
## Gate de `0.0.2-beta.1.fix.1`
Le fix de clôture beta doit prouver :
- `VERSION = 0.0.2-beta.1.fix.1` et version workspace identique ;
- history `history/0.0.2/beta.1.md` présent avec statut `PARTIAL` et committé avant application ;
- aucun nouveau package Cargo, package npm, contrat runtime ou comportement Git ;
- aucun diff sous `crates/` ou `Web/` avant le formatage ;
- revue d'horizon et étude `005` inchangées dans leur conclusion : aucune release après `0.0.2` engagée ;
- `cargo fmt --all` puis `cargo fmt --all -- --check` exécutés avant tout audit Rust ;
- audits Markdown et Rust locaux propres ;
- `cargo metadata`, `cargo check --workspace`, Clippy strict et tests workspace propres ;
- baseline Web `npm ci`, `npm run typecheck` et `npm run build` propre ;
- manifest Vite généré parsable avec l'entrée stable `src/main.ts` ;
- smoke HTTP de `knowledge-pgr-server`, `knowledge-howtos-server` et `knowledge-snippets-server` `PASS`, vérifiant `/healthz`, `/`, les références du manifest et le service effectif des assets générés ;
- `Cargo.lock` présent localement, ignoré et non suivi ;
- hygiène texte et `git diff --cached --check` propres.
`beta.1.fix.1` est `FAIL` malgré les smokes HTTP `PASS` : son audit Python de stabilisation échoue sur un quoting invalide et `git diff --cached --check` détecte une ligne vide supplémentaire à EOF. La transition autorisée est uniquement `beta.1.fix.2`.
## Gate de `0.0.2-beta.1.fix.2`
Le fix de clôture beta doit prouver :
- `VERSION = 0.0.2-beta.1.fix.2` et version workspace identique ;
- history `history/0.0.2/beta.1.fix.1.md` présent avec statut `FAIL` et committé avant application ;
- aucun diff sous `crates/` ou `Web/` ;
- aucune nouvelle fonctionnalité, package Cargo/npm, dépendance ou contrat runtime ;
- audit Python de stabilisation corrigé et exécutable, sans chaîne littérale mal quotée ;
- fichiers texte gouvernés terminés par exactement un LF, sans ligne vide supplémentaire à EOF ;
- audits Markdown locaux propres ;
- preuves runtime acquises en `beta.1.fix.1` conservées dans son history : Cargo/Clippy/tests, baseline Web et trois smokes HTTP `PASS` ;
- `Cargo.lock` présent localement, ignoré et non suivi ;
- `git diff --check` puis `git diff --cached --check` propres ;
- gate interactive ne modifiant pas le shell opérateur avec `set -euo pipefail`.
Le `PASS` de `beta.1.fix.2`, combiné aux preuves runtime `PASS` conservées dans `history/0.0.2/beta.1.fix.1.md`, ferme la stabilisation beta et autorise uniquement `0.0.2-rc.1`.