diff --git a/Cargo.toml b/Cargo.toml index a4fc022..52e0c7e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ # file: Cargo.toml -# version: 19 +# version: 20 [workspace] resolver = "3" @@ -15,7 +15,7 @@ members = [ ] [workspace.package] -version = "0.0.2-alpha.2" +version = "0.0.2-alpha.2.fix.1" edition = "2024" publish = false repository = "https://git.sasedev.com/Sasedev/sasedev-knowledge" diff --git a/VERSION b/VERSION index f063100..d441dc6 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.0.2-alpha.2 +0.0.2-alpha.2.fix.1 diff --git a/crates/knowledge-git-lib/src/backend.rs b/crates/knowledge-git-lib/src/backend.rs index e596e83..31cc94d 100644 --- a/crates/knowledge-git-lib/src/backend.rs +++ b/crates/knowledge-git-lib/src/backend.rs @@ -1,5 +1,5 @@ // file: crates/knowledge-git-lib/src/backend.rs -// version: 1 +// version: 2 //! Physical source configuration, generated-state layout and controlled Git process runner. @@ -17,10 +17,7 @@ impl crate::GitBackendConfig { } /// Build a backend configuration with an explicit Git executable path. - pub fn with_git_executable( - state_root: std::path::PathBuf, - git_executable: std::path::PathBuf, - ) -> Result { + pub fn with_git_executable(state_root: std::path::PathBuf, git_executable: std::path::PathBuf) -> Result { if state_root.as_os_str().is_empty() { return Err(crate::GitBackendError::EmptyStateRoot); } @@ -75,18 +72,11 @@ pub struct GitSourceConfig { impl crate::GitSourceConfig { /// Build a local Git source configuration. - pub fn local( - source_id: knowledge_domain_lib::SourceId, - path: std::path::PathBuf, - ) -> Result { + pub fn local(source_id: knowledge_domain_lib::SourceId, path: std::path::PathBuf) -> Result { if path.as_os_str().is_empty() { return Err(crate::GitBackendError::EmptySourceLocation); } - return Ok(crate::GitSourceConfig { - location: path.into_os_string(), - source_id, - source_kind: crate::GitSourceKind::Local, - }); + return Ok(crate::GitSourceConfig { location: path.into_os_string(), source_id, source_kind: crate::GitSourceKind::Local }); } /// Build a remote Git source configuration without interpreting provider-specific syntax. @@ -94,11 +84,7 @@ impl crate::GitSourceConfig { if location.trim().is_empty() { return Err(crate::GitBackendError::EmptySourceLocation); } - return Ok(crate::GitSourceConfig { - location: std::ffi::OsString::from(location), - source_id, - source_kind: crate::GitSourceKind::Remote, - }); + return Ok(crate::GitSourceConfig { location: std::ffi::OsString::from(location), source_id, source_kind: crate::GitSourceKind::Remote }); } /// Return the logical source identifier associated with this physical source. @@ -123,7 +109,7 @@ impl crate::GitSourceKey { for byte in source_id.as_str().as_bytes() { value.push_str(format!("{:02x}", *byte).as_str()); } - return crate::GitSourceKey(value); + return Self(value); } /// Return the path-safe key text. @@ -204,16 +190,11 @@ impl GitCommandRunner for SystemGitRunner { let output = match output_result { Ok(value) => value, Err(_) => { - return Err(crate::GitBackendError::GitUnavailable { - operation: specification.operation, - }); - } + return Err(crate::GitBackendError::GitUnavailable { operation: specification.operation }); + }, }; if !output.status.success() { - return Err(crate::GitBackendError::GitCommandFailed { - operation: specification.operation, - exit_code: output.status.code(), - }); + return Err(crate::GitBackendError::GitCommandFailed { operation: specification.operation, exit_code: output.status.code() }); } return Ok(GitCommandOutput { stdout: output.stdout }); } @@ -228,10 +209,7 @@ pub struct GitBackend { impl crate::GitBackend { /// Create a backend using the configured real Git executable. pub fn new(config: crate::GitBackendConfig) -> crate::GitBackend { - return crate::GitBackend { - config, - runner: Box::new(SystemGitRunner), - }; + return crate::GitBackend { config, runner: Box::new(SystemGitRunner) }; } #[cfg(test)] @@ -260,12 +238,8 @@ impl crate::GitBackend { let inspection_result = self.inspect_bare_repository(&repository_path); match inspection_result { Ok(()) => { - return Ok(Some(crate::GitMirror { - repository_path, - source_key, - status: crate::GitMirrorStatus::Existing, - })); - } + return Ok(Some(crate::GitMirror { repository_path, source_key, status: crate::GitMirrorStatus::Existing })); + }, Err(error) => return Err(error), } } @@ -283,12 +257,8 @@ impl crate::GitBackend { let inspection_result = self.inspect_bare_repository(&repository_path); match inspection_result { Ok(()) => { - return Ok(crate::GitMirror { - repository_path, - source_key, - status: crate::GitMirrorStatus::Existing, - }); - } + return Ok(crate::GitMirror { repository_path, source_key, status: crate::GitMirrorStatus::Existing }); + }, Err(error) => return Err(error), } } @@ -300,12 +270,8 @@ impl crate::GitBackend { let inspection_result = self.inspect_bare_repository(&repository_path); match inspection_result { Ok(()) => { - return Ok(crate::GitMirror { - repository_path, - source_key, - status: crate::GitMirrorStatus::Created, - }); - } + return Ok(crate::GitMirror { repository_path, source_key, status: crate::GitMirrorStatus::Created }); + }, Err(error) => return Err(error), } } @@ -362,10 +328,8 @@ impl crate::GitBackend { let stdout = match stdout_result { Ok(value) => value.trim(), Err(_) => { - return Err(crate::GitBackendError::UnexpectedGitOutput { - operation: crate::GitOperation::InspectMirror, - }); - } + return Err(crate::GitBackendError::UnexpectedGitOutput { operation: crate::GitOperation::InspectMirror }); + }, }; if stdout != "true" { return Err(crate::GitBackendError::InvalidMirror); diff --git a/crates/knowledge-git-lib/src/error.rs b/crates/knowledge-git-lib/src/error.rs index 353c595..3f338a8 100644 --- a/crates/knowledge-git-lib/src/error.rs +++ b/crates/knowledge-git-lib/src/error.rs @@ -1,5 +1,5 @@ // file: crates/knowledge-git-lib/src/error.rs -// version: 1 +// version: 2 //! Recoverable errors for controlled Git process execution. @@ -66,11 +66,11 @@ impl std::fmt::Display for crate::GitBackendError { crate::GitBackendError::GitUnavailable { operation } => return write!(formatter, "git is unavailable while attempting to {operation}"), crate::GitBackendError::GitCommandFailed { operation, exit_code } => { return write!(formatter, "git failed while attempting to {operation}; exit code {exit_code:?}"); - } + }, crate::GitBackendError::InvalidMirror => return formatter.write_str("controlled git repository is not a valid bare mirror"), crate::GitBackendError::UnexpectedGitOutput { operation } => { return write!(formatter, "git returned unexpected output while attempting to {operation}"); - } + }, } } } diff --git a/crates/knowledge-git-lib/src/lib.rs b/crates/knowledge-git-lib/src/lib.rs index 373091e..834690a 100644 --- a/crates/knowledge-git-lib/src/lib.rs +++ b/crates/knowledge-git-lib/src/lib.rs @@ -1,5 +1,5 @@ // file: crates/knowledge-git-lib/src/lib.rs -// version: 1 +// version: 2 //! Controlled Git process backend for Knowledge content sources. //! @@ -17,10 +17,10 @@ pub use self::backend::GitBackendConfig; pub use self::backend::GitMirror; /// Result of ensuring that a controlled mirror exists. pub use self::backend::GitMirrorStatus; -/// Path-safe storage key derived from a logical Knowledge source identifier. -pub use self::backend::GitSourceKey; /// Physical Git source configuration associated with one logical source identifier. pub use self::backend::GitSourceConfig; +/// Path-safe storage key derived from a logical Knowledge source identifier. +pub use self::backend::GitSourceKey; /// Coarse physical source kind used by the backend. pub use self::backend::GitSourceKind; /// Recoverable error returned by the controlled Git backend. diff --git a/crates/knowledge-git-lib/unit_tests/backend.rs b/crates/knowledge-git-lib/unit_tests/backend.rs index 5927350..bfd759e 100644 --- a/crates/knowledge-git-lib/unit_tests/backend.rs +++ b/crates/knowledge-git-lib/unit_tests/backend.rs @@ -1,5 +1,5 @@ // file: crates/knowledge-git-lib/unit_tests/backend.rs -// version: 1 +// version: 2 #[derive(Clone)] struct RecordingRunner { @@ -41,9 +41,7 @@ impl super::GitCommandRunner for RecordingRunner { return Err(error); } if specification.operation == crate::GitOperation::InspectMirror { - return Ok(super::GitCommandOutput { - stdout: self.inspection_stdout.clone(), - }); + return Ok(super::GitCommandOutput { stdout: self.inspection_stdout.clone() }); } return Ok(super::GitCommandOutput { stdout: Vec::new() }); } @@ -180,10 +178,7 @@ fn process_errors_do_not_expose_remote_location_or_credentials() { Ok(value) => value, Err(_) => return, }; - let runner = RecordingRunner::failing(crate::GitBackendError::GitCommandFailed { - operation: crate::GitOperation::CloneMirror, - exit_code: Some(128), - }); + let runner = RecordingRunner::failing(crate::GitBackendError::GitCommandFailed { operation: crate::GitOperation::CloneMirror, exit_code: Some(128) }); let backend = crate::GitBackend::with_runner(config, Box::new(runner)); let source_id_result = source_id("snippets"); assert!(source_id_result.is_some()); @@ -206,13 +201,7 @@ fn process_errors_do_not_expose_remote_location_or_credentials() { let display = error.to_string(); assert!(!display.contains("secret")); assert!(!display.contains("example.invalid")); - assert_eq!( - error, - crate::GitBackendError::GitCommandFailed { - operation: crate::GitOperation::CloneMirror, - exit_code: Some(128), - } - ); + assert_eq!(error, crate::GitBackendError::GitCommandFailed { operation: crate::GitOperation::CloneMirror, exit_code: Some(128) }); let _ = std::fs::remove_dir_all(root); return; } diff --git a/deltas/0.0.2/alpha.2.fix.1.md b/deltas/0.0.2/alpha.2.fix.1.md new file mode 100644 index 0000000..8cdd6ba --- /dev/null +++ b/deltas/0.0.2/alpha.2.fix.1.md @@ -0,0 +1,280 @@ + + + +# Delta 0.0.2-alpha.2.fix.1 — correction de gate, formatage et construction interne + +## Base requise + +Partir de `0.0.2-alpha.2` après application et commit du history réel : + +```text +deltas/0.0.2/alpha.2.md présent et historique +history/0.0.2/alpha.2.md FAIL +``` + +Le delta `alpha.2` historique ne doit pas être réécrit. + +La version devient : + +```text +0.0.2-alpha.2.fix.1 +``` + +## Objet + +Corriger uniquement les défauts révélés par la gate opérateur d'`alpha.2` : + +- supprimer la ligne vide terminale détectée par `git diff --check` dans la matrice de validation ; +- empêcher l'audit Markdown embarqué de traiter `node_modules` ou d'autres arbres générés comme contenu gouverné ; +- appliquer le formatage attendu par `cargo fmt` aux quatre fichiers Rust signalés ; +- construire `GitSourceKey` depuis son module propriétaire au lieu de tenter d'utiliser son constructeur tuple privé via le réexport `crate::GitSourceKey` ; +- conserver le champ tuple privé et ne pas élargir l'API publique ; +- documenter le `FAIL` d'`alpha.2` et la portée strictement corrective de ce fix. + +Le fix n'ajoute aucune capacité Git. `refresh`, résolution vers commit et snapshot/worktree restent réservés à `alpha.3`. + +## Scope + +REPLACE : + +```text +VERSION +Cargo.toml +crates/knowledge-git-lib/src/backend.rs +crates/knowledge-git-lib/src/error.rs +crates/knowledge-git-lib/src/lib.rs +crates/knowledge-git-lib/unit_tests/backend.rs +docs/plans/002-V0_0_2_GIT_SYNC_PLAN.md +docs/validation/001-VALIDATION_MATRIX.md +``` + +ADD : + +```text +deltas/0.0.2/alpha.2.fix.1.md +``` + +DELETE : aucun. + +Le history `history/0.0.2/alpha.2.md` appartient à la base requise mais n'est pas inclus dans ce delta. + +Aucun fichier sous `Web/`, `crates/knowledge-git-api/` ou `crates/knowledge-sync-api/` n'est modifié. + +## Corrections attendues + +### Hygiène documentaire + +`docs/validation/001-VALIDATION_MATRIX.md` doit terminer par une seule fin de ligne, sans ligne vide additionnelle produisant un warning `git diff --check`. + +La gate du fix contrôle les Markdown du workspace mais ignore explicitement les arbres générés/non gouvernés : + +```text +.git +node_modules +target +builds +``` + +La présence d'un README provenant d'une dépendance npm ne doit donc plus faire échouer la gouvernance documentaire du projet. + +### Rustfmt + +Les fichiers signalés par la gate initiale sont remis dans la forme attendue par `rustfmt.toml` : + +```text +crates/knowledge-git-lib/src/backend.rs +crates/knowledge-git-lib/src/error.rs +crates/knowledge-git-lib/src/lib.rs +crates/knowledge-git-lib/unit_tests/backend.rs +``` + +Aucun changement fonctionnel autre que la correction de visibilité ci-dessous n'est introduit. + +### Construction de `GitSourceKey` + +`GitSourceKey` conserve son champ tuple privé : + +```text +pub struct GitSourceKey(String); +``` + +Sa méthode `from_source_id`, définie dans le module `backend`, construit le type avec `Self(value)` depuis son propre `impl`. Le réexport public reste destiné à nommer le type, pas à contourner la visibilité de son champ interne. + +## Gate opérateur + +Après application du history `alpha.2`, commit/push de cet état, puis application du présent delta : + +```bash +test "$(cat VERSION)" = '0.0.2-alpha.2.fix.1' +grep -F 'version = "0.0.2-alpha.2.fix.1"' Cargo.toml +grep -A2 '^## Statut$' history/0.0.2/alpha.2.md | grep -Fx 'FAIL' + +git diff --check + +python3 - <<'PY' +from pathlib import Path +import re +import tomllib + +required = ( + "crates/knowledge-git-lib/Cargo.toml", + "crates/knowledge-git-lib/src/backend.rs", + "crates/knowledge-git-lib/src/error.rs", + "crates/knowledge-git-lib/src/lib.rs", + "crates/knowledge-git-lib/unit_tests/backend.rs", + "deltas/0.0.2/alpha.2.md", + "deltas/0.0.2/alpha.2.fix.1.md", + "history/0.0.2/alpha.2.md", +) +for value in required: + assert Path(value).is_file(), value + +root = tomllib.loads(Path("Cargo.toml").read_text(encoding="utf-8")) +manifest = tomllib.loads(Path("crates/knowledge-git-lib/Cargo.toml").read_text(encoding="utf-8")) +assert "crates/knowledge-git-lib" in root["workspace"]["members"] +assert set(manifest["dependencies"]) == {"knowledge-domain-lib"}, manifest["dependencies"] + +backend = Path("crates/knowledge-git-lib/src/backend.rs").read_text(encoding="utf-8") +error = Path("crates/knowledge-git-lib/src/error.rs").read_text(encoding="utf-8") +assert "return Self(value);" in backend +assert "return crate::GitSourceKey(value);" not in backend +assert "return crate::backend::GitSourceKey(value);" not in backend +assert "pub struct GitSourceKey(String);" in backend + +for phrase in ( + "std::process::Command::new", + 'command.env("GIT_TERMINAL_PROMPT", "0")', + 'command.env_remove("GIT_DIR")', + 'command.env_remove("GIT_WORK_TREE")', + 'command.env_remove("GIT_INDEX_FILE")', + 'command.env_remove("GIT_OBJECT_DIRECTORY")', + 'command.env_remove("GIT_ALTERNATE_OBJECT_DIRECTORIES")', + 'command.env("GIT_CONFIG_KEY_0", "core.hooksPath")', + 'std::ffi::OsString::from("--mirror")', + 'std::ffi::OsString::from("--no-local")', + 'std::ffi::OsString::from("--")', + 'std::ffi::OsString::from("--is-bare-repository")', +): + assert phrase in backend, phrase + +for forbidden in ( + 'Command::new("sh")', + 'Command::new("bash")', + 'Command::new("cmd")', + 'Command::new("powershell")', + "stderr: String", + "arguments: Vec", + "refresh(", + "resolve_revision(", + "worktree add", + "knowledge-app-lib", +): + assert forbidden not in backend + error, forbidden + +for path in Path("crates/knowledge-git-lib").rglob("*.rs"): + text = path.read_text(encoding="utf-8") + for forbidden in ("unwrap()", "expect(", "panic!("): + assert forbidden not in text, (path, forbidden) + +ignored_parts = {".git", "node_modules", "target", "builds"} +checked_markdown = 0 +for path in Path(".").rglob("*.md"): + if any(part in ignored_parts 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 + checked_markdown += 1 +assert checked_markdown > 0 + +print(f"Knowledge 0.0.2-alpha.2.fix.1 structural audit: clean ({checked_markdown} Markdown file(s))") +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.2.fix.1-metadata.json +cargo check --workspace +cargo clippy --workspace --all-targets --all-features -- -D warnings +cargo test -p knowledge-git-lib --all-targets --all-features +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.2.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.2.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-git-api crates/knowledge-sync-api)" +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 +``` + +## Résultats attendus + +La gate doit notamment produire : + +```text +Knowledge 0.0.2-alpha.2.fix.1 structural audit: clean (... Markdown file(s)) +Rust test-layout audit: clean (8 crate(s)) +Rust export completeness audit: 0 candidate(s) across 8 package(s) +Knowledge 0.0.2-alpha.2.fix.1 Cargo metadata audit: clean +``` + +`cargo fmt --all -- --check` doit être silencieux et `cargo check`, Clippy et les deux suites de tests doivent tous terminer avec succès. + +La suite ciblée `knowledge-git-lib` doit exécuter `7` tests unitaires `PASS`, sauf modification explicitement justifiée du nombre de tests dans un fix ultérieur. + +## Revue opérateur complémentaire + +Vérifier que : + +- la correction de visibilité n'a pas rendu public l'état interne de `GitSourceKey` ; +- l'audit Markdown ne dépend plus de l'absence physique de `node_modules` ; +- aucun comportement de `refresh`, résolution ou snapshot n'est apparu dans le fix ; +- aucune nouvelle dépendance Cargo n'a été introduite ; +- le fix ne change pas l'architecture validée d'`alpha.2`. + +## Transition + +### PASS + +Produire `history/0.0.2/alpha.2.fix.1.md`, appliquer ce history, committer/pousser le fix, puis seulement préparer `0.0.2-alpha.3`. + +### FAIL / PARTIAL / BLOCKED + +Conserver le résultat réel dans `history/0.0.2/alpha.2.fix.1.md` et rester dans le scope `alpha.2` avec `alpha.2.fix.2` si nécessaire, sauf déclencheur de REPLAN explicitement satisfait. diff --git a/docs/plans/002-V0_0_2_GIT_SYNC_PLAN.md b/docs/plans/002-V0_0_2_GIT_SYNC_PLAN.md index 4118b92..3b2e4a9 100644 --- a/docs/plans/002-V0_0_2_GIT_SYNC_PLAN.md +++ b/docs/plans/002-V0_0_2_GIT_SYNC_PLAN.md @@ -1,5 +1,5 @@ - + # Plan 0.0.2 — Git générique et synchronisation de lecture @@ -139,7 +139,9 @@ La gate opérateur de `alpha.1.fix.1` est **PASS**. ### alpha.2 — contrats minimaux et backend process -Statut opérateur : **à valider**. +Statut opérateur initial : **FAIL**. + +`alpha.2.fix.1` corrige exclusivement l'hygiène de fin de fichier, la portée de la gate Markdown, le formatage rustfmt et la construction interne de `GitSourceKey`. Il n'ajoute aucune capacité Git et ne modifie ni les dépendances ni les frontières de la tranche. Le delta matérialise le premier backend réel sans encore prétendre couvrir tout le cycle de synchronisation. Les choix concrets de la tranche sont : configuration publique `GitBackendConfig`/`GitSourceConfig`, runner process strictement interne, erreurs publiques redacted par construction et `source-key` hexadécimale déterministe dérivée du `SourceId`. diff --git a/docs/validation/001-VALIDATION_MATRIX.md b/docs/validation/001-VALIDATION_MATRIX.md index fe69f32..19bdae6 100644 --- a/docs/validation/001-VALIDATION_MATRIX.md +++ b/docs/validation/001-VALIDATION_MATRIX.md @@ -1,5 +1,5 @@ - + # Matrice de validation Knowledge @@ -572,3 +572,22 @@ La première tranche fonctionnelle Git doit prouver : 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`. diff --git a/history/0.0.2/alpha.2.fix.1.md b/history/0.0.2/alpha.2.fix.1.md new file mode 100644 index 0000000..b601fec --- /dev/null +++ b/history/0.0.2/alpha.2.fix.1.md @@ -0,0 +1,193 @@ + + + +# History 0.0.2-alpha.2.fix.1 — correction de gate, formatage et construction interne + +## Statut + +FAIL + +La gate opérateur de `0.0.2-alpha.2.fix.1` exécutée le `2026-09-28` corrige les défauts initiaux d'`alpha.2`, mais reste bloquée par une violation Clippy unique dans un test de `knowledge-git-lib`. + +## Baseline opérateur + +`alpha.2` `FAIL` a été historisé, committé et poussé avant application du fix : + +```text +history/0.0.2/alpha.2.md FAIL +commit bdbd6a5 +message 0.0.2-alpha.2 +branch master +push origin/master PASS +workspace après push propre +``` + +Le push observé a avancé `origin/master` de `84c01eb` à `bdbd6a5`. + +## Version et prérequis + +Les contrôles passent : + +```text +VERSION 0.0.2-alpha.2.fix.1 +Cargo workspace version 0.0.2-alpha.2.fix.1 +history alpha.2 FAIL +``` + +`git diff --check` est propre. + +## Audit structurel et documentaire + +L'audit corrigé passe : + +```text +Knowledge 0.0.2-alpha.2.fix.1 structural audit: clean (61 Markdown file(s)) +``` + +Il confirme notamment : + +- la présence des artefacts attendus de `knowledge-git-lib` ; +- huit membres workspace avec dépendances minimales inchangées ; +- `GitSourceKey` construit via `Self(value)` tout en conservant son champ tuple privé ; +- le runner process sans shell, les protections d'environnement Git et les arguments `--mirror` / `--no-local` ; +- l'absence de `refresh`, `resolve_revision`, worktree/snapshot et `knowledge-app-lib` ; +- l'exclusion de `.git`, `node_modules`, `target` et `builds` de l'audit Markdown gouverné. + +Les audits Rust structurels passent : + +```text +Rust test-layout audit: clean (8 crate(s)) +Rust blank-line audit: clean (22 file(s)) +Rust item-spacing audit: clean (22 file(s)) +Rust module-order audit: clean (22 file(s)) +Rust trait-import-block audit: clean (22 file(s)) +Rust re-export-block audit: clean (22 file(s)) +Rust export completeness audit: 0 candidate(s) across 8 package(s) +``` + +## Formatage et compilation + +Les contrôles suivants passent : + +```text +cargo fmt --all -- --check PASS +cargo metadata --format-version 1 --no-deps PASS +cargo check --workspace PASS +``` + +La compilation du workspace est donc restaurée par rapport à `alpha.2`. + +## Clippy + +La gate reste `FAIL` sur : + +```text +cargo clippy --workspace --all-targets --all-features -- -D warnings +``` + +Erreur observée : + +```text +crates/knowledge-git-lib/unit_tests/backend.rs:85 +missing `return` statement +clippy::implicit_return +``` + +La closure passée à `Iterator::all` retourne implicitement son expression booléenne : + +```text +|character| character.is_ascii_alphanumeric() || character == '-' +``` + +La configuration workspace interdit explicitement `clippy::implicit_return`. Le correctif attendu est uniquement de rendre ce retour explicite dans la closure. + +## Tests + +Malgré l'échec Clippy, les tests ciblés passent : + +```text +cargo test -p knowledge-git-lib --all-targets --all-features +7 passed; 0 failed +``` + +Tests observés : + +```text +backend_configuration_requires_non_empty_paths PASS +local_source_clone_uses_mirror_no_local_and_argument_separator PASS +invalid_existing_mirror_is_rejected_without_deleting_it PASS +existing_mirror_is_inspected_without_clone PASS +source_key_never_interpolates_raw_source_identifier_as_a_path PASS +process_errors_do_not_expose_remote_location_or_credentials PASS +remote_source_clone_does_not_add_no_local PASS +``` + +Les tests workspace passent également : + +```text +knowledge-domain-lib : 3 PASS +knowledge-git-api : 1 PASS +knowledge-git-lib : 7 PASS +knowledge-sync-api : 1 PASS +knowledge-web-lib : 4 PASS +launchers : 0 test chacun +``` + +## Métadonnées, lockfile et frontières + +L'audit Cargo passe : + +```text +Knowledge 0.0.2-alpha.2.fix.1 Cargo metadata audit: clean +``` + +Les contrôles de frontière passent : + +```text +Web/ sans diff +crates/knowledge-git-api sans diff +crates/knowledge-sync-api sans diff +crates/knowledge-app-lib absent +crates/knowledge-forge-gitea-lib absent +crates/knowledge-store-postgres-lib absent +Cargo.lock présent localement, ignoré et non suivi +``` + +Après staging, `git diff --cached --check` passe. Le staging observé avant ajout du présent history est : + +```text +M Cargo.toml +M VERSION +M crates/knowledge-git-lib/src/backend.rs +M crates/knowledge-git-lib/src/error.rs +M crates/knowledge-git-lib/src/lib.rs +M crates/knowledge-git-lib/unit_tests/backend.rs +A deltas/0.0.2/alpha.2.fix.1.md +M docs/plans/002-V0_0_2_GIT_SYNC_PLAN.md +M docs/validation/001-VALIDATION_MATRIX.md +``` + +## Diagnostic + +`alpha.2.fix.1` reste dans le scope prévu et restaure l'hygiène, le formatage et la compilation. Aucun déclencheur de REPLAN n'est atteint. + +Le nouveau fix doit uniquement : + +- rendre explicite le retour de la closure signalée par Clippy dans `unit_tests/backend.rs` ; +- conserver l'API, les dépendances et le comportement Git inchangés ; +- rejouer la gate complète d'`alpha.2` afin de confirmer qu'aucun autre warning Clippy n'est masqué. + +## Décision + +`0.0.2-alpha.2.fix.1` est `FAIL`. + +La transition autorisée est : + +```text +appliquer ce history +-> git add / diff --cached --check / status +-> commit exact "0.0.2-alpha.2.fix.1" +-> push origin master +-> vérifier le workspace propre +-> appliquer seulement ensuite 0.0.2-alpha.2.fix.2 +```