# Delta 0.0.2-alpha.3.fix.1 — conformité alpha.3 et REPLAN d'autonomie Knowledge ## Base requise Partir de `0.0.2-alpha.3` après application de son history réel `FAIL`, commit et push : ```text deltas/0.0.2/alpha.3.md présent et historique history/0.0.2/alpha.3.md FAIL ``` Les deltas, histories et prompts antérieurs ne doivent pas être réécrits. La version devient : ```text 0.0.2-alpha.3.fix.1 ``` ## Causes du fix La gate opérateur d'`alpha.3` a confirmé le comportement Git réel mais a relevé trois défauts bloquants : 1. `docs/validation/001-VALIDATION_MATRIX.md` possède une ligne vide terminale rejetée par `git diff --check` ; 2. `crates/knowledge-git-api/unit_tests/lib.rs` n'est pas au format exact attendu par rustfmt ; 3. `crates/knowledge-git-lib/tests/git_read_path.rs` ne possède pas de documentation de crate et échoue sous `-D missing-docs` lors de Clippy. La revue a aussi déclenché un REPLAN explicite : avant d'ajouter l'orchestration `Changed` / `Unchanged`, Knowledge doit terminer son autonomie normative après l'adoption PGR et auditer l'organisation interne de ses crates. ## Scope technique du fix Le correctif technique est volontairement minimal : - retirer la ligne vide terminale fautive de la matrice ; - appliquer le formatage rustfmt attendu au test de `knowledge-git-api` ; - ajouter une documentation de crate au test d'intégration `git_read_path` ; - conserver inchangés le backend Git, ses erreurs, son API publique et les deux scénarios d'intégration réels. Le comportement prouvé en `alpha.3` reste donc : mirror -> refresh -> résolution -> snapshot/worktree détaché -> validation/réutilisation. ## REPLAN de `0.0.2` Le plan `docs/plans/002-V0_0_2_GIT_SYNC_PLAN.md` passe en version documentaire `7` et adopte la trajectoire suivante : ```text alpha.3 refresh / resolve / snapshot FAIL initial -> fix.1 alpha.4 autonomie normative + structure crates alpha.5 cas d'usage Changed / Unchanged beta.1 réconciliation + revue d'horizon rc.1 candidate stable rel.1 fermeture stable ``` L'ancienne tranche `alpha.4` de synchronisation devient `alpha.5` sans changement de mission fonctionnelle. ## Autonomie PGR enregistrée `RULES.md` et le profil projet distinguent désormais explicitement : ```text PGR v0.1.3 = provenance de l'adoption engagée pendant 0.0.2 Knowledge = baseline normative locale après matérialisation ``` Les règles sont : - ne pas charger/rechercher automatiquement PGR au début de chaque version, session ou tranche ; - ne pas faire dépendre un futur prompt de démarrage Knowledge d'une « stable PGR courante » ; - consulter une nouvelle version PGR uniquement lorsqu'une réévaluation/adoption PGR est explicitement inscrite au scope ; - lors d'une telle réévaluation, comparer la baseline locale puis classifier `ADOPT / KEEP-LOCAL / OVERRIDE / DEFER` ; - matérialiser/adopter localement uniquement les règles, templates/configurations et audits réellement nécessaires ; - ne pas recopier mécaniquement l'arborescence PGR lorsqu'un owner Knowledge plus adapté suffit. Le prompt `prompts/002-V0_0_2_START_PROMPT.md` reste historique et inchangé : sa consultation de PGR appartenait précisément à l'adoption explicitement engagée au démarrage de `0.0.2`. ## Scope futur `alpha.4` `alpha.4` doit : - inventorier les owners/contrats PGR `v0.1.3` réellement retenus par Knowledge ; - produire le mapping durable de leurs décisions et owners locaux ; - vérifier que gouvernance, workflow, documentation, validation, Rust/Cargo et Web nécessaires sont compréhensibles depuis Knowledge seul ; - adapter/matérialiser les règles, templates/configurations et audits manquants ; - supprimer toute dépendance documentaire obligatoire vers PGR pour le développement courant ; - auditer toutes les crates pour garder `lib.rs` comme façade/documentation/réexports et déplacer les définitions dans des modules possédant une responsabilité claire lorsque cela est justifié ; - examiner en priorité `knowledge-git-api` et `knowledge-sync-api` ; - ne pas imposer un générique `api.rs` si des modules `reference`, `revision`, `snapshot`, `repository`, `signal`, etc. expriment mieux l'ownership ; - ne pas découper artificiellement une petite crate sans bénéfice réel. Cette tranche sera livrée séparément après `PASS` du présent fix. ## Hors scope du fix `alpha.3.fix.1` ne doit pas : - créer `docs/rules/` ou copier des owners PGR détaillés ; - refactorer maintenant `knowledge-git-api` ou `knowledge-sync-api` en modules supplémentaires ; - modifier `crates/knowledge-git-api/src/`, `crates/knowledge-git-lib/src/` ou `crates/knowledge-sync-api/` ; - modifier le comportement Git d'`alpha.3` ; - introduire `knowledge-app-lib`, scheduler, PostgreSQL ou adapter de forge ; - modifier `Web/` ; - préparer `alpha.4` avant `PASS` opérateur du fix. ## Gate opérateur Exécuter depuis la racine du workspace après application du delta : ```bash test "$(cat VERSION)" = '0.0.2-alpha.3.fix.1' grep -F 'version = "0.0.2-alpha.3.fix.1"' Cargo.toml grep -A2 '^## Statut$' history/0.0.2/alpha.3.md | grep -Fx 'FAIL' git diff --check python3 - <<'PY' from pathlib import Path import re import tomllib root = tomllib.loads(Path("Cargo.toml").read_text(encoding="utf-8")) assert len(root["workspace"]["members"]) == 8 plan_path = Path("docs/plans/002-V0_0_2_GIT_SYNC_PLAN.md") plan = plan_path.read_text(encoding="utf-8") plan_lines = plan.splitlines() assert plan_lines[1] == "" trajectory_start = plan_lines.index("## Trajectoire prévisionnelle") replan_start = plan_lines.index("## Déclencheurs de REPLAN") trajectory = plan_lines[trajectory_start + 1:replan_start] for heading in ( "### alpha.3 — refresh, résolution et snapshot réel", "### alpha.4 — autonomie normative et structure interne des crates", "### alpha.5 — cas d'usage de synchronisation", "### beta.1 — réconciliation et revue d'horizon", "### rc.1 — candidate stable", "### rel.1 — fermeture stable", ): assert heading in trajectory, heading for phrase in ( "Statut opérateur initial : **FAIL**.", "`v0.1.3` constitue une provenance d'adoption", "une réévaluation PGR explicitement engagée", "aucune consultation PGR automatique", ): assert phrase in plan, phrase assert "une nouvelle stable PGR modifie un owner" not in plan rules = Path("RULES.md").read_text(encoding="utf-8") for phrase in ( "## Provenance PGR et autonomie normative", "source d'adoption", "n'est pas une dépendance normative vivante", "ni un référentiel à charger automatiquement", "Une future version de PGR n'a aucun effet automatique sur Knowledge", ): assert phrase in rules, phrase assert "baseline PGR courante" not in rules profile = Path("docs/architecture/001-PROJECT_PROFILE.md").read_text(encoding="utf-8") assert "source d'adoption" in profile assert "provenance d'adoption figée" in profile assert "ne consulte pas automatiquement le PGR courant" in profile git_api_test = Path("crates/knowledge-git-api/unit_tests/lib.rs").read_text(encoding="utf-8") assert 'assert_eq!(snapshot_result, Ok(crate::GitSnapshot::new(revision, std::path::PathBuf::from("/controlled/snapshot"))));' in git_api_test integration = Path("crates/knowledge-git-lib/tests/git_read_path.rs").read_text(encoding="utf-8") assert "//! Integration tests for the real generic Git read path using local temporary repositories." in integration for phrase in ( "real_local_repository_refreshes_resolves_and_materializes_revision_snapshots", "invalid_reference_and_dirty_existing_snapshot_are_rejected", ): assert phrase in integration, phrase for path in Path(".").rglob("*.md"): if any(part in {".git", "node_modules", "target", "builds"} for part in path.parts): continue lines = path.read_text(encoding="utf-8").splitlines() assert lines[0] == f"", path assert re.fullmatch(r"", lines[1]), path print("Knowledge 0.0.2-alpha.3.fix.1 structural/replan audit: clean") PY 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_export_completeness.py --root . --summary-only cargo fmt --all -- --check cargo metadata --format-version 1 --no-deps > /tmp/sasedev-knowledge-0.0.2-alpha.3.fix.1-metadata.json cargo check --workspace cargo clippy --workspace --all-targets --all-features -- -D warnings cargo test -p knowledge-git-api --all-targets --all-features cargo test -p knowledge-git-lib --all-targets --all-features cargo test -p knowledge-git-lib --test git_read_path cargo test --workspace --all-targets --all-features python3 - <<'PY' import json from pathlib import Path metadata = json.loads(Path("/tmp/sasedev-knowledge-0.0.2-alpha.3.fix.1-metadata.json").read_text(encoding="utf-8")) packages = {package["name"] for package in metadata["packages"]} expected = { "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 packages == expected, packages assert len(metadata["workspace_members"]) == 8, metadata["workspace_members"] print("Knowledge 0.0.2-alpha.3.fix.1 Cargo metadata audit: clean") PY 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 -z "$(git diff --name-only -- Web)" test -z "$(git diff --name-only -- crates/knowledge-sync-api)" test -z "$(git diff --name-only -- crates/knowledge-git-api/src)" test -z "$(git diff --name-only -- crates/knowledge-git-lib/src)" test -z "$(git diff --name-only -- prompts)" test ! -e docs/rules test ! -e crates/knowledge-app-lib test ! -e crates/knowledge-forge-gitea-lib test ! -e crates/knowledge-store-postgres-lib git add -A git diff --cached --check git status --short ``` ## Transition Si la gate est `PASS` : ```text history alpha.3.fix.1 = PASS -> commit/push alpha.3.fix.1 -> préparer alpha.4 uniquement ensuite ``` Si la gate est `FAIL`, produire un nouveau fix ciblé ou REPLAN uniquement si le résultat révèle un problème structurel nouveau.