ci: --locked in check-rust and the release builds, cargo-xwin pinned, cargo metadata --locked in /release (#449) #469

Open
maximus wants to merge 3 commits from issue-449-cargo-locked into issue-453-i18n-keys-guard
Owner

Resolves #449
Generated autonomously by /autopilot run of 2026-10-18

Résumé

Maillon 2 sur 8 de la pile planned-2026-10-16-lot-v018, basé sur issue-453-i18n-keys-guard (PR #468).

La CI et le build de release compilaient sans --locked : un Cargo.lock désaccordé de Cargo.toml était réécrit dans le checkout du job sans aucun échec, et les deux gardes, l'audit et les binaires livrés partaient alors du lock réécrit, pas du commité. Désormais :

  • check-rust.yml : cargo check --manifest-path src-tauri/Cargo.toml --all-targets --locked et cargo test --manifest-path src-tauri/Cargo.toml --all-targets --locked. Le commentaire de la garde windows-sys qui disait « the committed one unless cargo had to update it » est réécrit : le lock lu est le commité.
  • release.yml : npx tauri build --bundles deb,rpm -- --locked et npx tauri build --runner cargo-xwin --target x86_64-pc-windows-msvc -- --locked. cargo-xwin est épinglé (cargo install --locked cargo-xwin --version 0.23.1) et l'étape affiche cargo-xwin --version. 0.23.1 est la dernière stable de crates.io au 2026-10-18 (max_stable_version, publiée le 2026-08-13) et la version qu'a installée, sans épinglage, la release v0.17.2 (run 570 : Installed package cargo-xwin v0.23.1) : l'épinglage ne change pas l'outil.
  • Skill /release, étape 2 : cargo metadata --manifest-path src-tauri/Cargo.toml --format-version 1 --locked > /dev/null juste après l'édition du lock, avant la garde windows-sys, avec le message de refus réel de cargo ; étape 0 : --locked sur cargo check et cargo test (décision MEDIUM ci-dessous) ; ligne au journal du skill, updated: à 2026-10-18.
  • ADR 0023 (phrase « il lit le lock tel que cargo check l'a laissé » réécrite), CLAUDE.md (section CI/CD, avec la raison du miroir non aligné), REVIEW.md (tableau et bloc des « Commandes de vérification » avec --locked, phrase « #449 l'ajoute » retirée, et règle de la zone Release qui disait cargo-xwin installé sans version épinglée), docs/architecture.md (paragraphe check-rust.yml, paragraphe « Lock commité, cargo-xwin épinglé » dans release.yml).
  • Miroir .github/workflows/ intact (décision de Max). Aucune entrée de CHANGELOG : rien de visible pour l'utilisateur.

Le cargo update d'une PR et l'édition à la main de /release restent possibles : --locked n'interdit que la réécriture implicite pendant la CI et le build (le premier commite le lock qu'il écrit, la seconde est vérifiée par cargo metadata --locked).

Fichiers

Fichier Changement
.forgejo/workflows/check-rust.yml --locked sur cargo check et cargo test, commentaires (#449)
.forgejo/workflows/release.yml -- --locked sur les deux npx tauri build, cargo-xwin 0.23.1 épinglé, cargo-xwin --version
.claude/skills/release/SKILL.md étape 2 cargo metadata --locked, étape 0 --locked, journal, updated:
docs/adr/0023-windows-sys-pinning.md phrase sur le lock lu par la garde
CLAUDE.md section CI/CD
REVIEW.md « Commandes de vérification » et zone « Release et mise à jour » (hors « Niveaux »)
docs/architecture.md section CI/CD (check-rust.yml, release.yml)

Aucun déclencheur, aucune référence à secrets, aucun workflow ajouté ; src-tauri/ inchangé (git diff origin/main -- src-tauri/Cargo.toml vide).

Preuves

Désaccord utilisé partout : urlencoding = "2" → urlencoding = "=2.1.2" dans src-tauri/Cargo.toml. Le lock porte 2.1.3 et simpl-result est le seul dépendant de urlencoding : la borne déplacée se résout, seul le lock est en désaccord. Chaque essai local a été fait après les commits, puis git checkout -- src-tauri/Cargo.toml src-tauri/Cargo.lock et git status --short vide. Local : cargo 1.94.1, @tauri-apps/cli 2.10.0, cargo-xwin 0.23.1.

# Commande, sur le manifeste désaccordé Code Sortie
L1 cargo check --manifest-path src-tauri/Cargo.toml --all-targets --locked 101 error: cannot update the lock file …/src-tauri/Cargo.lock because --locked was passed to prevent this ; lock intact
L2 cargo test --manifest-path src-tauri/Cargo.toml --all-targets --locked 101 même message ; lock intact
L3 npx tauri build --bundles deb -- --locked 1 beforeBuildCommand passe, puis le même message de cargo et failed to build app ; lock intact
L4 npx tauri build --runner cargo-xwin --target x86_64-pc-windows-msvc -- --locked 1 même message de cargo et failed to build app ; lock intact
L5 cargo metadata --manifest-path src-tauri/Cargo.toml --format-version 1 --locked (étape 2 du skill) 101 même message ; 0 sur le lock réel
M1 mutation : la commande d'avant, cargo check --manifest-path src-tauri/Cargo.toml --all-targets 0 Locking 1 package, Downgrading urlencoding v2.1.3 -> v2.1.2, Finished, et Cargo.lock réécrit : le défaut de l'issue, que L1 refuse
M2 mutation : npx tauri build --bundles deb sans -- --locked, cargo espion qui remplace cargo build par la résolution qu'il ferait 1 (espion) la CLI appelle cargo build --bins --features tauri/custom-protocol --release, sans --locked ; la résolution passe (rc 0) et Cargo.lock est réécrit
M3 mutation : npx tauri build --runner cargo-xwin --target x86_64-pc-windows-msvc sans -- --locked, même espion 1 (espion) cargo-xwin appelle cargo build --features tauri/custom-protocol --target x86_64-pc-windows-msvc --release --bins, sans --locked ; Cargo.lock réécrit. Ni la CLI ni cargo-xwin n'ajoutent --locked d'eux-mêmes : seul -- --locked le porte
P1 épinglage : cargo install --locked cargo-xwin --version 0.23.99 --root /tmp/… (version inexistante, racine jetable) 101 could not find cargo-xwin in registry crates-io with version =0.23.99 : la version sans opérateur est lue comme =, sans repli sur une autre ; rien d'installé, cargo-xwin local toujours en 0.23.1
CI run 572, check-rust par workflow_dispatch sur la branche jetable failure à cargo check, citation ci-dessous

Relais des arguments jusqu'à cargo build (le journal de release n'imprime jamais la ligne de cargo, d'où cette preuve) :

  • npx tauri build -v --runner cargo-xwin … imprime :
    Running [tauri_cli] Command `cargo-xwin build --locked --bins --features tauri/custom-protocol --release --target x86_64-pc-windows-msvc`
    
  • Un cargo espion placé en tête du PATH (il journalise ses arguments puis lance le vrai cargo) a enregistré, pour L4 : six cargo metadata --no-deps --format-version 1, puis cargo build --features tauri/custom-protocol --target x86_64-pc-windows-msvc --locked --release --bins, dans l'ordre propre à cargo-xwin : c'est bien cargo-xwin qui passe --locked à cargo build. Pour L3 : les mêmes cargo metadata --no-deps, puis cargo build --locked --bins --features tauri/custom-protocol --release. Aucun autre appel à cargo ne résout les dépendances : --no-deps ne touche pas au lock, si bien que ni la CLI de Tauri ni cargo-xwin ne réécrivent le lock avant le build.
  • Le relais par cargo-xwin est donc prouvé, et non « à confirmer au prochain tag » comme le prévoyait le plan : cargo-xwin 0.23.1 était déjà installé sur le Lenovo, avec un cache CRT/SDK complet (licence acceptée par Max le 2026-10-17). Rien n'a été installé, mis à jour ni téléchargé.

Preuve CI (run 572)

Branche throwaway-449-lock-mismatch = tête de cette branche (14badbe) plus un commit (23d8190) qui porte le manifeste désaccordé ; check-rust lancé par POST …/actions/workflows/check-rust.yml/dispatches (204), aucune PR ouverte. Run 572 (https://git.lacompagniemaximus.com/maximus/Simpl-Resultat/actions/runs/572), cargo 1.99.1, en échec à l'étape cargo check :

2026-10-18T21:36:26.2136426Z     Updating crates.io index
2026-10-18T21:36:28.9577703Z error: cannot update the lock file /workspace/maximus/Simpl-Resultat/src-tauri/Cargo.lock because --locked was passed to prevent this
2026-10-18T21:36:28.9578263Z help: to generate the lock file without accessing the network, remove the --locked flag and use --offline instead.
2026-10-18T21:36:29.0190212Z ⚙️ [runner]: exitcode '101': failure
2026-10-18T21:36:29.2633467Z Skipping step 'Rust cache' due to 'success() || env.CACHE_ON_FAILURE == 'true''

C'est la seule commande cargo exécutée après la restauration du cache : la garde suivante n'a rien imprimé, « Install cargo-audit » a été sautée, et le post-step du cache n'a rien sauvegardé (cache partagé intact). Branche supprimée ensuite (git push origin --delete, ls-remote vide, API 404).

Vert

  • Local, sur le lock réel : cargo check --manifest-path src-tauri/Cargo.toml --all-targets --locked exit 0 ; cargo test --manifest-path src-tauri/Cargo.toml --all-targets --locked : 267 passed, 1 ignored ; cargo metadata … --locked exit 0.
  • La CI de cette PR lance check-rust (le diff touche check-rust.yml) avec --locked sur le lock réel : c'est le critère « check-rust vert avec --locked sur le lock actuel ». L'orchestrateur la surveille, je ne l'ai pas attendue. check-frontend tourne aussi (release.yml et .claude/**).
  • Indice pour le build de release : le journal du run 570 (v0.17.2) n'a aucune ligne Locking ni Downgrading dans les deux builds Tauri, et aucun fichier Cargo n'a changé depuis le tag : le lock commité y a servi tel quel, --locked n'y aurait pas échoué. La preuve reste le prochain tag (ci-dessous).

Tests

  • vitest : 138 fichiers, 2305 tests verts dans le worktree (sonde rc=1 : src/zz_tmp_probe.test.ts rouge, supprimé) ; npm run build vert.
  • Rust : cargo test --locked 267 passed, 1 ignored (aucun code Rust touché).
  • python3 scripts/review-levels.py --check : ok, 37 motifs (section « Niveaux » de REVIEW.md non touchée).
  • YAML des deux workflows relu par PyYAML : commandes et déclencheurs attendus ; scripts/build-latest-json.test.mjs, qui exécute l'étape « Publish » de release.yml, passe (étape non touchée).

Décisions

  • [HIGH] cargo-xwin épinglé à 0.23.1 (dernière stable, version de la v0.17.2), écrit sans opérateur : cargo help install dit qu'une version sans opérateur « will install exactly that version; it is not treated as a caret requirement ».
  • [HIGH] REVIEW.md, zone « Release et mise à jour » : la règle disait cargo-xwin « installé à chaque tag sans version épinglée », fait rendu faux par cette PR, donc réécrit (règle de REVIEW.md sur les faits cités) ; la ligne release.yml du tableau nomme l'épinglage et -- --locked.
  • [HIGH] ADR 0023 : seule la phrase périmée change, #449 cité dans le texte, sans bloc d'amendement (la décision ne change pas).
  • [MEDIUM] Étape 0 de /release aussi en --locked, au-delà de l'étape 2 demandée : sans lui, un lock que cargo réécrirait pendant le pré-vol, dans l'arbre de Max, partirait sans relecture dans le commit de release (Cargo.lock fait partie des sept fichiers commités), et le cargo metadata --locked de l'étape 2 passerait sur ce lock réécrit, devenu cohérent. Écarté : laisser l'étape 0 telle quelle (diff plus petit, mais le trou reste sur le seul chemin sans PR).
  • [MEDIUM] Relais par cargo-xwin éprouvé en local au lieu de « à confirmer au prochain tag » (voir Preuves) ; écarté : reporter au tag, qui aurait été le premier run à l'exercer, clé de signature dans le job.
  • [MEDIUM] Désaccord par une borne déplacée (urlencoding) ; écartés : la version de l'app changée d'un seul côté (valable, mais lie la preuve au bump de release) et une dépendance ajoutée (plus de bruit).

Vérifications manuelles dues (prochaine release)

  • Run release.yml du prochain tag vert sur les deux cibles avec -- --locked. Dans le journal (route web, codes ANSI retirés), l'étape « Install Windows cross-compile dependencies » doit montrer l'installation de 0.23.1 puis la sortie de cargo-xwin --version, et chaque build Tauri sa ligne Finished (Linux puis Windows), sans aucune ligne cannot update the lock file :
    Installed package `cargo-xwin v0.23.1` (executable `cargo-xwin`)
    cargo-xwin 0.23.1
    Finished `release` profile [optimized] target(s) in …
    
    Comme le journal n'imprime pas la ligne de cargo, ce vert plus les preuves L3, L4 et l'espion ci-dessus constituent la preuve (critère post-merge de l'issue).
  • Étape 2 de /release au prochain tag : cargo metadata --manifest-path src-tauri/Cargo.toml --format-version 1 --locked > /dev/null à exit 0 sur le lock édité à la main, avant la garde windows-sys ; étape 0 avec cargo check --locked && cargo test --locked.
  • Étape 10 de /release (cycle réel de mise à jour, docs/qa-update-cycle.md) due à la prochaine release, puisque cette PR touche release.yml (règle de REVIEW.md, zone « Release et mise à jour ») : Linux et Windows, clé Base+, depuis une installation à la version précédente. Aucun écart n'est attendu (même lock, cargo-xwin 0.23.1 comme pour la v0.17.2), mais seul ce cycle le prouve. Il est déjà dû pour #455 et #447.

Pour le relecteur

  • Niveau haut : .forgejo/workflows/release.yml et .claude/skills/release/** (Release et mise à jour, toujours), et deux étapes de verdict de check-rust.yml modifiées (CI et gardes).
  • Recouvrement avec #461 (en triage), point 2 « cargo-xwin et toolchain non épinglés dans release.yml » : cette PR ne couvre que la moitié cargo-xwin. La toolchain Rust reste sur stable sans épinglage (rustup), ce que CLAUDE.md, REVIEW.md et docs/architecture.md disent.
  • L'épinglage fige le binaire, pas ses dépendances de build au-delà du Cargo.lock publié de cargo-xwin (cargo install --locked) : c'était déjà le cas avant.
  • La branche jetable du run 572 est supprimée ; son commit 23d8190 reste visible dans l'historique du run.

🤖 Generated with Claude Code

Resolves #449 Generated autonomously by /autopilot run of 2026-10-18 ## Résumé Maillon 2 sur 8 de la pile `planned-2026-10-16-lot-v018`, basé sur `issue-453-i18n-keys-guard` (PR #468). La CI et le build de release compilaient sans `--locked` : un `Cargo.lock` désaccordé de `Cargo.toml` était réécrit dans le checkout du job sans aucun échec, et les deux gardes, l'audit et les binaires livrés partaient alors du lock réécrit, pas du commité. Désormais : - `check-rust.yml` : `cargo check --manifest-path src-tauri/Cargo.toml --all-targets --locked` et `cargo test --manifest-path src-tauri/Cargo.toml --all-targets --locked`. Le commentaire de la garde `windows-sys` qui disait « the committed one unless cargo had to update it » est réécrit : le lock lu est le commité. - `release.yml` : `npx tauri build --bundles deb,rpm -- --locked` et `npx tauri build --runner cargo-xwin --target x86_64-pc-windows-msvc -- --locked`. cargo-xwin est épinglé (`cargo install --locked cargo-xwin --version 0.23.1`) et l'étape affiche `cargo-xwin --version`. 0.23.1 est la dernière stable de crates.io au 2026-10-18 (`max_stable_version`, publiée le 2026-08-13) et la version qu'a installée, sans épinglage, la release v0.17.2 (run 570 : `Installed package cargo-xwin v0.23.1`) : l'épinglage ne change pas l'outil. - Skill `/release`, étape 2 : `cargo metadata --manifest-path src-tauri/Cargo.toml --format-version 1 --locked > /dev/null` juste après l'édition du lock, avant la garde `windows-sys`, avec le message de refus réel de cargo ; étape 0 : `--locked` sur `cargo check` et `cargo test` (décision MEDIUM ci-dessous) ; ligne au journal du skill, `updated:` à 2026-10-18. - ADR 0023 (phrase « il lit le lock tel que `cargo check` l'a laissé » réécrite), `CLAUDE.md` (section CI/CD, avec la raison du miroir non aligné), `REVIEW.md` (tableau et bloc des « Commandes de vérification » avec `--locked`, phrase « #449 l'ajoute » retirée, et règle de la zone Release qui disait cargo-xwin installé sans version épinglée), `docs/architecture.md` (paragraphe `check-rust.yml`, paragraphe « Lock commité, cargo-xwin épinglé » dans `release.yml`). - Miroir `.github/workflows/` intact (décision de Max). Aucune entrée de CHANGELOG : rien de visible pour l'utilisateur. Le `cargo update` d'une PR et l'édition à la main de `/release` restent possibles : `--locked` n'interdit que la réécriture implicite pendant la CI et le build (le premier commite le lock qu'il écrit, la seconde est vérifiée par `cargo metadata --locked`). ## Fichiers | Fichier | Changement | |---|---| | `.forgejo/workflows/check-rust.yml` | `--locked` sur `cargo check` et `cargo test`, commentaires (#449) | | `.forgejo/workflows/release.yml` | `-- --locked` sur les deux `npx tauri build`, cargo-xwin 0.23.1 épinglé, `cargo-xwin --version` | | `.claude/skills/release/SKILL.md` | étape 2 `cargo metadata --locked`, étape 0 `--locked`, journal, `updated:` | | `docs/adr/0023-windows-sys-pinning.md` | phrase sur le lock lu par la garde | | `CLAUDE.md` | section CI/CD | | `REVIEW.md` | « Commandes de vérification » et zone « Release et mise à jour » (hors « Niveaux ») | | `docs/architecture.md` | section CI/CD (`check-rust.yml`, `release.yml`) | Aucun déclencheur, aucune référence à `secrets`, aucun workflow ajouté ; `src-tauri/` inchangé (`git diff origin/main -- src-tauri/Cargo.toml` vide). ## Preuves Désaccord utilisé partout : `urlencoding = "2"` → `urlencoding = "=2.1.2"` dans `src-tauri/Cargo.toml`. Le lock porte 2.1.3 et `simpl-result` est le seul dépendant de `urlencoding` : la borne déplacée se résout, seul le lock est en désaccord. Chaque essai local a été fait après les commits, puis `git checkout -- src-tauri/Cargo.toml src-tauri/Cargo.lock` et `git status --short` vide. Local : cargo 1.94.1, `@tauri-apps/cli` 2.10.0, cargo-xwin 0.23.1. | # | Commande, sur le manifeste désaccordé | Code | Sortie | |---|---|---|---| | L1 | `cargo check --manifest-path src-tauri/Cargo.toml --all-targets --locked` | 101 | `error: cannot update the lock file …/src-tauri/Cargo.lock because --locked was passed to prevent this` ; lock intact | | L2 | `cargo test --manifest-path src-tauri/Cargo.toml --all-targets --locked` | 101 | même message ; lock intact | | L3 | `npx tauri build --bundles deb -- --locked` | 1 | `beforeBuildCommand` passe, puis le même message de cargo et `failed to build app` ; lock intact | | L4 | `npx tauri build --runner cargo-xwin --target x86_64-pc-windows-msvc -- --locked` | 1 | même message de cargo et `failed to build app` ; lock intact | | L5 | `cargo metadata --manifest-path src-tauri/Cargo.toml --format-version 1 --locked` (étape 2 du skill) | 101 | même message ; 0 sur le lock réel | | M1 | mutation : la commande d'avant, `cargo check --manifest-path src-tauri/Cargo.toml --all-targets` | 0 | `Locking 1 package`, `Downgrading urlencoding v2.1.3 -> v2.1.2`, `Finished`, et `Cargo.lock` réécrit : le défaut de l'issue, que L1 refuse | | M2 | mutation : `npx tauri build --bundles deb` sans `-- --locked`, `cargo` espion qui remplace `cargo build` par la résolution qu'il ferait | 1 (espion) | la CLI appelle `cargo build --bins --features tauri/custom-protocol --release`, sans `--locked` ; la résolution passe (rc 0) et `Cargo.lock` est réécrit | | M3 | mutation : `npx tauri build --runner cargo-xwin --target x86_64-pc-windows-msvc` sans `-- --locked`, même espion | 1 (espion) | cargo-xwin appelle `cargo build --features tauri/custom-protocol --target x86_64-pc-windows-msvc --release --bins`, sans `--locked` ; `Cargo.lock` réécrit. Ni la CLI ni cargo-xwin n'ajoutent `--locked` d'eux-mêmes : seul `-- --locked` le porte | | P1 | épinglage : `cargo install --locked cargo-xwin --version 0.23.99 --root /tmp/…` (version inexistante, racine jetable) | 101 | `could not find cargo-xwin in registry crates-io with version =0.23.99` : la version sans opérateur est lue comme `=`, sans repli sur une autre ; rien d'installé, cargo-xwin local toujours en 0.23.1 | | CI | run 572, `check-rust` par `workflow_dispatch` sur la branche jetable | failure | à `cargo check`, citation ci-dessous | **Relais des arguments jusqu'à `cargo build`** (le journal de release n'imprime jamais la ligne de cargo, d'où cette preuve) : - `npx tauri build -v --runner cargo-xwin …` imprime : ``` Running [tauri_cli] Command `cargo-xwin build --locked --bins --features tauri/custom-protocol --release --target x86_64-pc-windows-msvc` ``` - Un `cargo` espion placé en tête du `PATH` (il journalise ses arguments puis lance le vrai cargo) a enregistré, pour L4 : six `cargo metadata --no-deps --format-version 1`, puis `cargo build --features tauri/custom-protocol --target x86_64-pc-windows-msvc --locked --release --bins`, dans l'ordre propre à cargo-xwin : c'est bien cargo-xwin qui passe `--locked` à `cargo build`. Pour L3 : les mêmes `cargo metadata --no-deps`, puis `cargo build --locked --bins --features tauri/custom-protocol --release`. Aucun autre appel à cargo ne résout les dépendances : `--no-deps` ne touche pas au lock, si bien que ni la CLI de Tauri ni cargo-xwin ne réécrivent le lock avant le build. - Le relais par cargo-xwin est donc **prouvé**, et non « à confirmer au prochain tag » comme le prévoyait le plan : cargo-xwin 0.23.1 était déjà installé sur le Lenovo, avec un cache CRT/SDK complet (licence acceptée par Max le 2026-10-17). Rien n'a été installé, mis à jour ni téléchargé. ### Preuve CI (run 572) Branche `throwaway-449-lock-mismatch` = tête de cette branche (`14badbe`) plus un commit (`23d8190`) qui porte le manifeste désaccordé ; `check-rust` lancé par `POST …/actions/workflows/check-rust.yml/dispatches` (204), aucune PR ouverte. Run 572 (`https://git.lacompagniemaximus.com/maximus/Simpl-Resultat/actions/runs/572`), cargo 1.99.1, en échec à l'étape `cargo check` : ``` 2026-10-18T21:36:26.2136426Z Updating crates.io index 2026-10-18T21:36:28.9577703Z error: cannot update the lock file /workspace/maximus/Simpl-Resultat/src-tauri/Cargo.lock because --locked was passed to prevent this 2026-10-18T21:36:28.9578263Z help: to generate the lock file without accessing the network, remove the --locked flag and use --offline instead. 2026-10-18T21:36:29.0190212Z ⚙️ [runner]: exitcode '101': failure 2026-10-18T21:36:29.2633467Z Skipping step 'Rust cache' due to 'success() || env.CACHE_ON_FAILURE == 'true'' ``` C'est la seule commande cargo exécutée après la restauration du cache : la garde suivante n'a rien imprimé, « Install cargo-audit » a été sautée, et le post-step du cache n'a rien sauvegardé (cache partagé intact). Branche supprimée ensuite (`git push origin --delete`, `ls-remote` vide, API 404). ### Vert - Local, sur le lock réel : `cargo check --manifest-path src-tauri/Cargo.toml --all-targets --locked` exit 0 ; `cargo test --manifest-path src-tauri/Cargo.toml --all-targets --locked` : 267 passed, 1 ignored ; `cargo metadata … --locked` exit 0. - La CI de cette PR lance `check-rust` (le diff touche `check-rust.yml`) avec `--locked` sur le lock réel : c'est le critère « `check-rust` vert avec `--locked` sur le lock actuel ». L'orchestrateur la surveille, je ne l'ai pas attendue. `check-frontend` tourne aussi (`release.yml` et `.claude/**`). - Indice pour le build de release : le journal du run 570 (v0.17.2) n'a aucune ligne `Locking` ni `Downgrading` dans les deux builds Tauri, et aucun fichier Cargo n'a changé depuis le tag : le lock commité y a servi tel quel, `--locked` n'y aurait pas échoué. La preuve reste le prochain tag (ci-dessous). ## Tests - vitest : 138 fichiers, 2305 tests verts dans le worktree (sonde rc=1 : `src/zz_tmp_probe.test.ts` rouge, supprimé) ; `npm run build` vert. - Rust : `cargo test --locked` 267 passed, 1 ignored (aucun code Rust touché). - `python3 scripts/review-levels.py --check` : ok, 37 motifs (section « Niveaux » de `REVIEW.md` non touchée). - YAML des deux workflows relu par PyYAML : commandes et déclencheurs attendus ; `scripts/build-latest-json.test.mjs`, qui exécute l'étape « Publish » de `release.yml`, passe (étape non touchée). ## Décisions - [HIGH] cargo-xwin épinglé à 0.23.1 (dernière stable, version de la v0.17.2), écrit sans opérateur : `cargo help install` dit qu'une version sans opérateur « will install exactly that version; it is not treated as a caret requirement ». - [HIGH] `REVIEW.md`, zone « Release et mise à jour » : la règle disait cargo-xwin « installé à chaque tag sans version épinglée », fait rendu faux par cette PR, donc réécrit (règle de `REVIEW.md` sur les faits cités) ; la ligne `release.yml` du tableau nomme l'épinglage et `-- --locked`. - [HIGH] ADR 0023 : seule la phrase périmée change, #449 cité dans le texte, sans bloc d'amendement (la décision ne change pas). - [MEDIUM] Étape 0 de `/release` aussi en `--locked`, au-delà de l'étape 2 demandée : sans lui, un lock que cargo réécrirait pendant le pré-vol, dans l'arbre de Max, partirait sans relecture dans le commit de release (`Cargo.lock` fait partie des sept fichiers commités), et le `cargo metadata --locked` de l'étape 2 passerait sur ce lock réécrit, devenu cohérent. Écarté : laisser l'étape 0 telle quelle (diff plus petit, mais le trou reste sur le seul chemin sans PR). - [MEDIUM] Relais par cargo-xwin éprouvé en local au lieu de « à confirmer au prochain tag » (voir Preuves) ; écarté : reporter au tag, qui aurait été le premier run à l'exercer, clé de signature dans le job. - [MEDIUM] Désaccord par une borne déplacée (`urlencoding`) ; écartés : la version de l'app changée d'un seul côté (valable, mais lie la preuve au bump de release) et une dépendance ajoutée (plus de bruit). ## Vérifications manuelles dues (prochaine release) - Run `release.yml` du prochain tag vert sur les deux cibles avec `-- --locked`. Dans le journal (route web, codes ANSI retirés), l'étape « Install Windows cross-compile dependencies » doit montrer l'installation de 0.23.1 puis la sortie de `cargo-xwin --version`, et chaque build Tauri sa ligne `Finished` (Linux puis Windows), sans aucune ligne `cannot update the lock file` : ``` Installed package `cargo-xwin v0.23.1` (executable `cargo-xwin`) cargo-xwin 0.23.1 Finished `release` profile [optimized] target(s) in … ``` Comme le journal n'imprime pas la ligne de cargo, ce vert plus les preuves L3, L4 et l'espion ci-dessus constituent la preuve (critère post-merge de l'issue). - Étape 2 de `/release` au prochain tag : `cargo metadata --manifest-path src-tauri/Cargo.toml --format-version 1 --locked > /dev/null` à exit 0 sur le lock édité à la main, avant la garde `windows-sys` ; étape 0 avec `cargo check --locked && cargo test --locked`. - Étape 10 de `/release` (cycle réel de mise à jour, `docs/qa-update-cycle.md`) due à la prochaine release, puisque cette PR touche `release.yml` (règle de `REVIEW.md`, zone « Release et mise à jour ») : Linux et Windows, clé Base+, depuis une installation à la version précédente. Aucun écart n'est attendu (même lock, cargo-xwin 0.23.1 comme pour la v0.17.2), mais seul ce cycle le prouve. Il est déjà dû pour #455 et #447. ## Pour le relecteur - Niveau haut : `.forgejo/workflows/release.yml` et `.claude/skills/release/**` (Release et mise à jour, toujours), et deux étapes de verdict de `check-rust.yml` modifiées (CI et gardes). - Recouvrement avec #461 (en triage), point 2 « cargo-xwin et toolchain non épinglés dans `release.yml` » : cette PR ne couvre que la moitié cargo-xwin. La toolchain Rust reste sur `stable` sans épinglage (`rustup`), ce que `CLAUDE.md`, `REVIEW.md` et `docs/architecture.md` disent. - L'épinglage fige le binaire, pas ses dépendances de build au-delà du `Cargo.lock` publié de cargo-xwin (`cargo install --locked`) : c'était déjà le cas avant. - La branche jetable du run 572 est supprimée ; son commit `23d8190` reste visible dans l'historique du run. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
maximus added 3 commits 2026-10-18 21:42:28 +00:00
check-rust.yml ran cargo check and cargo test without --locked: a
Cargo.lock out of step with Cargo.toml was rewritten in the job's
checkout, and the suppression guard, the windows-sys guard and cargo
audit then read the rewritten lockfile instead of the committed one.
Both now pass --locked, and the windows-sys guard comment says the
lockfile it reads is the committed one.

release.yml built the shipped binaries the same way. Both npx tauri
build calls now end with `-- --locked`, which the Tauri CLI hands to its
runner (cargo, or cargo-xwin for Windows, which passes it to cargo
build).

cargo-xwin, the runner of the Windows build, runs with the updater
signing key in its environment and was installed at whatever version
crates.io served on the day of the tag. It is pinned at 0.23.1, the
version the v0.17.2 release installed (run 570), and its version is
printed in the job log.

Refs #449

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Release skill, step 2: right after the hand edit of Cargo.lock and
  before the windows-sys guard, `cargo metadata --format-version 1
  --locked` must exit 0, since the tag builds with -- --locked and the
  release commit goes to main without a pull request. Step 0 runs cargo
  check and cargo test with --locked, like CI, so the pre-flight cannot
  fold a lockfile rewrite into the release commit.
- ADR 0023: the windows-sys guard reads the committed lockfile, cargo
  check having already refused one it would have had to rewrite.
- CLAUDE.md, REVIEW.md and docs/architecture.md: CI commands with
  --locked, release builds on the committed lockfile, cargo-xwin pinned
  (REVIEW.md said it was installed unpinned), the stale REVIEW.md
  sentence about #449 removed, and why the dormant .github mirror is
  not aligned.

Resolves #449

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
docs: record the proven --locked relay of both release runners (#449)
All checks were successful
PR Check — Frontend / frontend (pull_request) Successful in 1m57s
PR Check — Rust / rust (pull_request) Successful in 9m58s
db625d02ef
- Release skill, step 2: quote the refusal cargo actually prints, the
  same under cargo 1.94.1 and 1.99.1 (`cannot update the lock file ...
  because --locked was passed to prevent this`, code 101).
- docs/architecture.md: the relay of --locked is proven for both runners
  on a lockfile out of step with Cargo.toml: cargo-xwin 0.23.1 runs
  `cargo build ... --locked ...`, and the other cargo calls of the Tauri
  CLI and cargo-xwin are `cargo metadata --no-deps`, which never touch
  the lockfile.

Resolves #449

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
maximus added the
autopilot:pending-human
label 2026-10-18 21:42:49 +00:00
Author
Owner

Niveau : haut — .forgejo/workflows/release.yml (Release et mise à jour)
Dossier de décision requis : /pr-brief 469 avant le merge.

Verdict : APPROVE

Auto-revue de l'auteur (worker /autopilot), pas une revue indépendante. Checklist du skill pr-review à la profondeur du niveau haut, appliquée au diff complet de la PR contre sa base issue-453-i18n-keys-guard (GET /pulls/469.diff, 7 fichiers, 52 lignes ajoutées), avec REVIEW.md lu sur main. Une boucle de correction : un constat de la passe des zones, corrigé dans le corps de la PR (voir Constats). Tête relue : db625d02efc015ab8ef0ca28d84bbed79f5a7036.

Niveau (Step 0bis)

Fichier Niveau Ligne du tableau
.forgejo/workflows/release.yml haut release.yml, « toujours » (Release et mise à jour)
.claude/skills/release/SKILL.md haut .claude/skills/release/**, « toujours » (Release et mise à jour)
.forgejo/workflows/check-rust.yml haut étapes de verdict cargo check et cargo test modifiées (CI et gardes). La ligne .forgejo/workflows/** ne joue pas : ni fichier ajouté, ni référence à secrets, ni pull_request_target
CLAUDE.md, REVIEW.md (hors « Niveaux »), docs/adr/0023-windows-sys-pinning.md, docs/architecture.md normal liste « Restent au moins normaux »

Résumé

--locked sur cargo check et cargo test de check-rust.yml, -- --locked sur les deux npx tauri build de release.yml, cargo-xwin épinglé à 0.23.1 avec cargo-xwin --version au journal, cargo metadata --locked à l'étape 2 de /release (et --locked à l'étape 0), docs alignées. Le diff fait ce que disent l'issue, son plan d'exécution et sa note du 2026-10-18 ; il ne rend vert rien de ce qui était rouge : les deux étapes de verdict deviennent plus strictes.

Mutations et sondes

Désaccord commun : urlencoding = "2" → "=2.1.2" (lock en 2.1.3, simpl-result seul dépendant). Chaque essai après les commits, arbre restauré par git checkout et git status --short vide ensuite.

Règle Essai Résultat
cargo check --locked (CI) L1 local ; run 572 en CI (branche jetable, workflow_dispatch) 101 en local ; run 572 en échec à cargo check, cargo 1.99.1 : cannot update the lock file … because --locked was passed to prevent this, cache non sauvegardé
idem, mutation M1 : la commande d'avant, sans --locked 0, Downgrading urlencoding v2.1.3 -> v2.1.2, lock réécrit : le défaut de l'issue
cargo test --locked (CI) L2 local 101, même message (le run 572 s'arrête avant, à cargo check)
-- --locked, build Linux L3 + cargo espion 1 ; la CLI lance cargo build --locked --bins --features tauri/custom-protocol --release, refus de cargo
idem, mutation M2 : sans -- --locked, espion qui remplace cargo build par sa résolution cargo build --bins --features tauri/custom-protocol --release, lock réécrit
-- --locked, build Windows L4 + -v + espion 1 ; cargo-xwin build --locked … puis, côté cargo-xwin, cargo build --features tauri/custom-protocol --target x86_64-pc-windows-msvc --locked --release --bins, refus de cargo
idem, mutation M3 : sans -- --locked cargo build … --release --bins sans --locked, lock réécrit. Ni la CLI ni cargo-xwin n'ajoutent --locked d'eux-mêmes
autres appels à cargo pendant tauri build espion, deux chemins six cargo metadata --no-deps --format-version 1, qui ne résolvent rien : aucun appel ne réécrit le lock avant le build
épinglage cargo-xwin P1 : cargo install --locked cargo-xwin --version 0.23.99 --root /tmp/… 101, with version =0.23.99 : version sans opérateur lue comme exacte, pas de repli ; rien d'installé, cargo-xwin local inchangé (0.23.1)
cargo-xwin --version binaire local cargo-xwin 0.23.1
étape 2 de /release L5 : cargo metadata … --locked 101 sur le désaccord, 0 sur le lock réel

Vert local sur le lock réel : cargo check … --all-targets --locked 0, cargo test … --all-targets --locked 267 passed et 1 ignored ; vitest 138 fichiers et 2305 tests (sonde rc=1) ; npm run build 0 ; scripts/review-levels.py --check ok. Indice pour la release : le journal du run 570 (v0.17.2, même lock) n'a aucune ligne Locking ni Downgrading.

Passe sécurité (bloquante)

  • §1 secrets : aucune valeur de clé ou de jeton, aucune URL avec identifiants dans les 52 lignes ajoutées ; TAURI_SIGNING_PRIVATE_KEY n'y figure que par son nom, dans des commentaires et la doc. Aucun .env, aucun changement de mode, aucun fichier ajouté, renommé ou supprimé.
  • §3 motifs dangereux : pas de code applicatif. Lignes shell ajoutées : cargo install --locked cargo-xwin --version 0.23.1, cargo-xwin --version et les deux npx tauri build … -- --locked. Aucune expression de workflow (${{) ajoutée, même en commentaire, et rien d'interpolé.
  • §4 configuration : sans objet (ni CORS, ni port, ni TODO de sécurité).
  • §2 dépendances : sans objet, aucun manifeste ni lock dans le diff (git diff origin/main -- src-tauri/Cargo.toml vide).
  • Zones de REVIEW.md :
    • Release et mise à jour : clé de signature toujours dans les deux étapes de build, rien de nouveau ne tourne avec elle ; cargo-xwin désormais figé, à la version qu'avait installée la v0.17.2, donc sans code nouveau. Règle « la PR signale l'étape 10 » : constat, corrigé (voir plus bas).
    • CI et gardes : aucun déclencheur, aucune référence à secrets, aucun workflow ajouté, aucun branches:, aucun continue-on-error ni || true.
    • Dépendances : aucune version déplacée.
    • Règles de revue : les faits que REVIEW.md cite et que la PR change sont mis à jour (tableau, bloc local, cargo-xwin « sans version épinglée »).
    • i18n et documentation : aucune chaîne visible ; pas de CHANGELOG (rien de visible pour l'utilisateur) ; CLAUDE.md, ADR 0023 et architecture.md à jour.

Constats

  1. Corrigé : REVIEW.md, zone « Release et mise à jour », dit qu'une release qui touche release.yml exige le cycle réel de mise à jour (étape 10 de /release) et que la PR le signale. Le corps de la PR ne le faisait pas. Ajouté sous « Vérifications manuelles dues (prochaine release) » (PATCH du corps, relu identique à l'octet), avec les mutations M2, M3 et la sonde P1 dans le tableau des preuves.

Aucun constat ouvert.

Critères d'acceptation

  • cargo check et cargo test de check-rust.yml avec --locked ; commentaire de la garde et ADR 0023 réécrits.
  • Les deux builds de release.yml portent -- --locked.
  • Preuve locale citée (L1, L3) ; relais cargo-xwin prouvé (L4, espion), pas seulement « à confirmer ».
  • Preuve CI : run 572, cité.
  • check-rust vert avec --locked sur le lock actuel : run de cette PR, en attente au moment de ce commentaire (vert en local).
  • Étape 2 de /release : cargo metadata --locked.
  • CLAUDE.md à jour ; miroir .github/workflows/ intact.
  • cargo update en PR et édition à la main de /release toujours possibles.

Suggestions (non bloquantes)

  1. Le journal de release ne montrera toujours pas la ligne de cargo. npx tauri build -v l'imprimerait (Running [tauri_cli] Command …), mais le mode verbeux, avec la clé de signature dans l'environnement, n'a pas été audité : non proposé ici.
  2. Effet voulu à connaître : un cargo stable plus récent qui voudrait réécrire le lock (format, résolution) fera désormais rougir check-rust et le build du tag au lieu de passer en silence. La réparation est une PR qui commite le nouveau lock. Le lock est en version = 4, accepté tel quel par cargo 1.99.1 au run 570.
  3. #461, point 2 : cette PR n'épingle que cargo-xwin, la toolchain Rust reste sur stable.
Niveau : haut — `.forgejo/workflows/release.yml` (Release et mise à jour) Dossier de décision requis : /pr-brief 469 avant le merge. Verdict : APPROVE **Auto-revue de l'auteur (worker `/autopilot`), pas une revue indépendante.** Checklist du skill `pr-review` à la profondeur du niveau haut, appliquée au diff complet de la PR contre sa base `issue-453-i18n-keys-guard` (`GET /pulls/469.diff`, 7 fichiers, 52 lignes ajoutées), avec `REVIEW.md` lu sur `main`. Une boucle de correction : un constat de la passe des zones, corrigé dans le corps de la PR (voir Constats). Tête relue : `db625d02efc015ab8ef0ca28d84bbed79f5a7036`. ## Niveau (Step 0bis) | Fichier | Niveau | Ligne du tableau | |---|---|---| | `.forgejo/workflows/release.yml` | haut | `release.yml`, « toujours » (Release et mise à jour) | | `.claude/skills/release/SKILL.md` | haut | `.claude/skills/release/**`, « toujours » (Release et mise à jour) | | `.forgejo/workflows/check-rust.yml` | haut | étapes de verdict `cargo check` et `cargo test` modifiées (CI et gardes). La ligne `.forgejo/workflows/**` ne joue pas : ni fichier ajouté, ni référence à `secrets`, ni `pull_request_target` | | `CLAUDE.md`, `REVIEW.md` (hors « Niveaux »), `docs/adr/0023-windows-sys-pinning.md`, `docs/architecture.md` | normal | liste « Restent au moins normaux » | ## Résumé `--locked` sur `cargo check` et `cargo test` de `check-rust.yml`, `-- --locked` sur les deux `npx tauri build` de `release.yml`, cargo-xwin épinglé à 0.23.1 avec `cargo-xwin --version` au journal, `cargo metadata --locked` à l'étape 2 de `/release` (et `--locked` à l'étape 0), docs alignées. Le diff fait ce que disent l'issue, son plan d'exécution et sa note du 2026-10-18 ; il ne rend vert rien de ce qui était rouge : les deux étapes de verdict deviennent plus strictes. ## Mutations et sondes Désaccord commun : `urlencoding = "2"` → `"=2.1.2"` (lock en 2.1.3, `simpl-result` seul dépendant). Chaque essai après les commits, arbre restauré par `git checkout` et `git status --short` vide ensuite. | Règle | Essai | Résultat | |---|---|---| | `cargo check --locked` (CI) | L1 local ; run 572 en CI (branche jetable, `workflow_dispatch`) | 101 en local ; run 572 en échec à `cargo check`, cargo 1.99.1 : `cannot update the lock file … because --locked was passed to prevent this`, cache non sauvegardé | | idem, mutation | M1 : la commande d'avant, sans `--locked` | 0, `Downgrading urlencoding v2.1.3 -> v2.1.2`, lock réécrit : le défaut de l'issue | | `cargo test --locked` (CI) | L2 local | 101, même message (le run 572 s'arrête avant, à `cargo check`) | | `-- --locked`, build Linux | L3 + `cargo` espion | 1 ; la CLI lance `cargo build --locked --bins --features tauri/custom-protocol --release`, refus de cargo | | idem, mutation | M2 : sans `-- --locked`, espion qui remplace `cargo build` par sa résolution | `cargo build --bins --features tauri/custom-protocol --release`, lock réécrit | | `-- --locked`, build Windows | L4 + `-v` + espion | 1 ; `cargo-xwin build --locked …` puis, côté cargo-xwin, `cargo build --features tauri/custom-protocol --target x86_64-pc-windows-msvc --locked --release --bins`, refus de cargo | | idem, mutation | M3 : sans `-- --locked` | `cargo build … --release --bins` sans `--locked`, lock réécrit. Ni la CLI ni cargo-xwin n'ajoutent `--locked` d'eux-mêmes | | autres appels à cargo pendant `tauri build` | espion, deux chemins | six `cargo metadata --no-deps --format-version 1`, qui ne résolvent rien : aucun appel ne réécrit le lock avant le build | | épinglage cargo-xwin | P1 : `cargo install --locked cargo-xwin --version 0.23.99 --root /tmp/…` | 101, `with version =0.23.99` : version sans opérateur lue comme exacte, pas de repli ; rien d'installé, cargo-xwin local inchangé (0.23.1) | | `cargo-xwin --version` | binaire local | `cargo-xwin 0.23.1` | | étape 2 de `/release` | L5 : `cargo metadata … --locked` | 101 sur le désaccord, 0 sur le lock réel | Vert local sur le lock réel : `cargo check … --all-targets --locked` 0, `cargo test … --all-targets --locked` 267 passed et 1 ignored ; vitest 138 fichiers et 2305 tests (sonde rc=1) ; `npm run build` 0 ; `scripts/review-levels.py --check` ok. Indice pour la release : le journal du run 570 (v0.17.2, même lock) n'a aucune ligne `Locking` ni `Downgrading`. ## Passe sécurité (bloquante) - §1 secrets : aucune valeur de clé ou de jeton, aucune URL avec identifiants dans les 52 lignes ajoutées ; `TAURI_SIGNING_PRIVATE_KEY` n'y figure que par son nom, dans des commentaires et la doc. Aucun `.env`, aucun changement de mode, aucun fichier ajouté, renommé ou supprimé. - §3 motifs dangereux : pas de code applicatif. Lignes shell ajoutées : `cargo install --locked cargo-xwin --version 0.23.1`, `cargo-xwin --version` et les deux `npx tauri build … -- --locked`. Aucune expression de workflow (`${{`) ajoutée, même en commentaire, et rien d'interpolé. - §4 configuration : sans objet (ni CORS, ni port, ni TODO de sécurité). - §2 dépendances : sans objet, aucun manifeste ni lock dans le diff (`git diff origin/main -- src-tauri/Cargo.toml` vide). - Zones de `REVIEW.md` : - Release et mise à jour : clé de signature toujours dans les deux étapes de build, rien de nouveau ne tourne avec elle ; cargo-xwin désormais figé, à la version qu'avait installée la v0.17.2, donc sans code nouveau. Règle « la PR signale l'étape 10 » : constat, corrigé (voir plus bas). - CI et gardes : aucun déclencheur, aucune référence à `secrets`, aucun workflow ajouté, aucun `branches:`, aucun `continue-on-error` ni `|| true`. - Dépendances : aucune version déplacée. - Règles de revue : les faits que `REVIEW.md` cite et que la PR change sont mis à jour (tableau, bloc local, cargo-xwin « sans version épinglée »). - i18n et documentation : aucune chaîne visible ; pas de CHANGELOG (rien de visible pour l'utilisateur) ; `CLAUDE.md`, ADR 0023 et `architecture.md` à jour. ## Constats 1. **Corrigé** : `REVIEW.md`, zone « Release et mise à jour », dit qu'une release qui touche `release.yml` exige le cycle réel de mise à jour (étape 10 de `/release`) et que la PR le signale. Le corps de la PR ne le faisait pas. Ajouté sous « Vérifications manuelles dues (prochaine release) » (PATCH du corps, relu identique à l'octet), avec les mutations M2, M3 et la sonde P1 dans le tableau des preuves. Aucun constat ouvert. ## Critères d'acceptation - [x] `cargo check` et `cargo test` de `check-rust.yml` avec `--locked` ; commentaire de la garde et ADR 0023 réécrits. - [x] Les deux builds de `release.yml` portent `-- --locked`. - [x] Preuve locale citée (L1, L3) ; relais cargo-xwin **prouvé** (L4, espion), pas seulement « à confirmer ». - [x] Preuve CI : run 572, cité. - [ ] `check-rust` vert avec `--locked` sur le lock actuel : run de cette PR, en attente au moment de ce commentaire (vert en local). - [x] Étape 2 de `/release` : `cargo metadata --locked`. - [x] `CLAUDE.md` à jour ; miroir `.github/workflows/` intact. - [x] `cargo update` en PR et édition à la main de `/release` toujours possibles. ## Suggestions (non bloquantes) 1. Le journal de release ne montrera toujours pas la ligne de cargo. `npx tauri build -v` l'imprimerait (`Running [tauri_cli] Command …`), mais le mode verbeux, avec la clé de signature dans l'environnement, n'a pas été audité : non proposé ici. 2. Effet voulu à connaître : un cargo `stable` plus récent qui voudrait réécrire le lock (format, résolution) fera désormais rougir `check-rust` et le build du tag au lieu de passer en silence. La réparation est une PR qui commite le nouveau lock. Le lock est en `version = 4`, accepté tel quel par cargo 1.99.1 au run 570. 3. #461, point 2 : cette PR n'épingle que cargo-xwin, la toolchain Rust reste sur `stable`.
Author
Owner

CI lue par l'orchestrateur du run /autopilot du 2026-10-18 sur la tête db625d0 : les deux contrôles sont verts.

  • check-frontend (run 573) : 138 fichiers et 2305 tests verts, dont scripts/build-latest-json.test.mjs (36 tests), qui exécute l'étape « Publish » de release.yml.
  • check-rust (run 574) :
    • rustc 1.99.1 ; démarrage à froid (No cache found.), puis Cache saved successfully ;
    • cargo check terminé, puis les deux gardes : canari webkit2gtk trouvé, et windows-sys pinning: 9 checks, exit 0 ;
    • cargo test : 267 passés, 1 ignoré ;
    • cargo audit informatif : 663 crates, aucune vulnérabilité, 18 avertissements autorisés.
  • Limite de ce journal : le runner n'y écrit pas les lignes de commande des étapes, donc --locked n'y apparaît pas en clair. Sa présence vient du fichier de workflow de la PR, et elle est démontrée par le run rouge ci-dessous, lancé avec ce même fichier.
  • Preuve rouge vérifiée de façon indépendante : le run 572 (workflow_dispatch sur throwaway-449-lock-mismatch, 23d8190) échoue à cargo check avec error: cannot update the lock file … because --locked was passed to prevent this, code de sortie 101. La branche jetable n'existe plus sur le dépôt.
CI lue par l'orchestrateur du run `/autopilot` du 2026-10-18 sur la tête `db625d0` : les deux contrôles sont **verts**. - `check-frontend` (run 573) : 138 fichiers et 2305 tests verts, dont `scripts/build-latest-json.test.mjs` (36 tests), qui exécute l'étape « Publish » de `release.yml`. - `check-rust` (run 574) : - rustc 1.99.1 ; démarrage à froid (`No cache found.`), puis `Cache saved successfully` ; - `cargo check` terminé, puis les deux gardes : canari `webkit2gtk` trouvé, et `windows-sys pinning: 9 checks, exit 0` ; - `cargo test` : 267 passés, 1 ignoré ; - `cargo audit` informatif : 663 crates, aucune vulnérabilité, 18 avertissements autorisés. - **Limite de ce journal** : le runner n'y écrit pas les lignes de commande des étapes, donc `--locked` n'y apparaît pas en clair. Sa présence vient du fichier de workflow de la PR, et elle est démontrée par le run rouge ci-dessous, lancé avec ce même fichier. - Preuve rouge vérifiée de façon indépendante : le run 572 (`workflow_dispatch` sur `throwaway-449-lock-mismatch`, `23d8190`) échoue à `cargo check` avec `error: cannot update the lock file … because --locked was passed to prevent this`, code de sortie 101. La branche jetable n'existe plus sur le dépôt.
Author
Owner

Niveau : haut — .forgejo/workflows/release.yml (Release et mise à jour) ; aussi .claude/skills/release/SKILL.md (Release et mise à jour) et les étapes de verdict cargo check et cargo test de check-rust.yml (CI et gardes)
Dossier de décision requis : /pr-brief 469 avant le merge.

Verdict : APPROVE

Revue indépendante, distincte de l'auto-revue du worker (commentaire 25148). --locked arrive à cargo build par les deux runners de la release et fait échouer check-rust sur un lock désaccordé, sans jamais le réécrire ; l'épinglage fige cargo-xwin à la version que la v0.17.2 avait installée. Tout est rejoué ci-dessous sur une copie hors dépôt de la tête db625d0, avec un désaccord différent de celui de l'auteur. La passe sécurité ne relève rien.

Rejoué (texte exact des étapes, extrait par PyYAML, lancé sous bash --noprofile --norc -e -o pipefail)

Désaccord : version de l'app montée dans src-tauri/Cargo.toml seul (0.17.2 → 0.17.3), l'oubli que l'étape 2 de /release doit attraper. L'auteur avait déplacé la borne d'urlencoding.

# Texte exécuté Résultat
R1 étape cargo check (tête) 101, cannot update the lock file … because --locked was passed to prevent this, lock intact
R2 étape cargo test (tête) 101, même message, lock intact
M1 mutation : étape cargo check de la base lock réécrit (version = "0.17.3" dans le bloc simpl-result) sans aucune ligne Locking dans la sortie, puis compilation (arrêtée à 45 s)
R3 étape « Build Tauri » (tête), vrai cargo derrière un espion qui journalise chaque appel et son appelant node (CLI) : 6 × cargo metadata --no-deps --format-version 1, puis cargo build --locked --bins --features tauri/custom-protocol --release ; échec sur le message de cargo puis failed to build app, lock intact
R4 étape « Build Tauri Windows » (tête), cargo-xwin 0.23.1 réel node : les mêmes 6 metadata --no-deps ; cargo-xwin : cargo build --features tauri/custom-protocol --target x86_64-pc-windows-msvc --locked --release --bins ; même échec, lock intact
M2, M3 mutation : les deux étapes de la base, l'espion remplaçant cargo build par la résolution qu'il ferait aucun --locked dans l'appel ; lock réécrit dans les deux cas
R5 commande de l'étape 2 du skill, extraite du SKILL.md lock réel : 0 ; Cargo.toml monté seul : 101, lock intact ; bloc simpl-result corrigé à la main : 0, lock non réécrit ; arête urlencoding retirée du bloc (« strophe abîmée ») : 101
M4 mutation : la même commande sans --locked, Cargo.toml monté seul 0 et lock réécrit : le contrôle passerait en régénérant ce que le skill interdit de régénérer
R6 cargo-xwin --version sous les options du runner cargo-xwin 0.23.1, code 0 : la ligne ajoutée ne fait pas tomber l'étape
R7 cargo install --locked cargo-xwin --version 0.23.99 --root /tmp/… 101, with version =0.23.99 : version exacte, sans repli ; rien d'installé

Vérifié aussi :

  • crates.io : max_stable_version et newest_version à 0.23.1 (2026-08-13), non retirée ; run 570 (v0.17.2) : Installed package cargo-xwin v0.23.1.
  • Run 572 : commit 23d8190 = 14badbe plus la seule ligne urlencoding = "=2.1.2" ; échec à cargo check (101), cache non sauvegardé. De 14badbe à la tête, seuls SKILL.md et architecture.md changent : la preuve CI vaut pour les workflows relus.
  • CI de la tête db625d0 : check-frontend run 573 vert (138 fichiers, 2305 tests, dont les 36 de build-latest-json.test.mjs) ; check-rust run 574 vert (267 tests, garde des suppressions 2/2, windows-sys 9/9, audit sur 663 crates sans vulnérabilité, 18 avertissements autorisés).
  • Workflows : déclencheurs, env:, uses:, if: et nombre d'étapes identiques à la base, seuls des run: changent ; python3 scripts/review-levels.py --check ok (37 motifs), section « Niveaux » non touchée.
  • Doc : CLAUDE.md, REVIEW.md, ADR 0023 et architecture.md décrivent ce que font les workflows ; plus aucune mention de cargo-xwin non épinglé ni d'une CI sans --locked. Miroir : aucun miroir de poussée sur Forgejo, qui ignore .github/workflows/ quand .forgejo/workflows/ existe : « rien n'y tourne » tient.

Passe sécurité : sans constat

  • §1 (secrets) : aucune valeur, aucun jeton, aucune URL à identifiants dans les 51 lignes ajoutées ; TAURI_SIGNING_PRIVATE_KEY n'y apparaît que comme nom, en commentaire ou en doc.
  • §3 et §4 : aucun motif dangereux, aucune expression de workflow dans les run: ajoutés, aucun continue-on-error, || true, écriture de $GITHUB_ENV ou $GITHUB_PATH, aucun TODO de sécurité.
  • §2 : aucun manifeste ni lock modifié ; l'épinglage réduit ce qui s'exécute avec la clé de signature.
  • Zones de REVIEW.md : Release (clé dans l'environnement des deux builds inchangée, cargo-xwin --version tourne dans une étape sans la clé, cycle réel signalé pour la prochaine release) ; CI et gardes (aucun workflow ajouté, aucune référence à secrets, pas de pull_request_target ; --locked ne peut que faire rougir ce qui passait, voir R1, R2 et M1).

Suggestions (non bloquantes)

  1. Fermeture de #449. La timeline porte un closes de cette PR (Resolves #449 dans le corps et dans deux des trois commits) : #449 se fermera au merge, avant sa « Vérification post-merge (au prochain tag) ». Pour #447 et #455, la PR était en Refs et l'issue fermée à la main. Reformuler deux commits d'une pile de huit coûte plus que ça ne rapporte : au /merge-stack, reporter ce contrôle dans la puce « Vérifications dues à la release suivante » de STATE.md (le plan du lot prévoit ce report au /merge-stack), ou rouvrir #449 en status:blocked jusqu'au tag, comme #421.
  2. Le relais dépend de deux versions. -- --locked n'arrive à cargo build que par @tauri-apps/cli 2.10.0 (lock npm) et cargo-xwin 0.23.1, et le journal du tag ne le montre jamais. Le commentaire de l'épinglage dit « Bump it on purpose, after reading what the new version changes » : y ajouter le rejeu de la preuve du relais (espion, lock désaccordé), et la même consigne pour une montée de @tauri-apps/cli dans architecture.md ou dans la zone Release de REVIEW.md.
  3. Précision de doc. D'après l'appelant journalisé par l'espion, les six cargo metadata --no-deps viennent tous de la CLI de Tauri (node) ; cargo-xwin ne lance que cargo build. « les autres appels à cargo de la CLI et de cargo-xwin » (architecture.md, message de db625d0) n'est pas faux, mais prête à cargo-xwin des appels qu'il ne fait pas.
  4. L'indice du run 570 est plus faible que le corps ne le dit. M1 montre que cargo réécrit sans un mot la version de simpl-result dans le lock : l'absence de ligne Locking dans un journal ne prouve rien pour l'oubli que vise l'étape 2 de /release. Sans effet sur la v0.17.2 (son lock avait passé cargo metadata --locked avant le tag), et un argument de plus pour --locked.
  5. Pour STATE.md. Hors paths-ignore, cette PR ne touche que .claude/skills/release/SKILL.md et release.yml : le run 573 prouve que cette paire déclenche check-frontend, ce que l'entrée #419 de STATE.md laissait « à prouver ». Chacun seul reste non prouvé.

Actions faites

  • Copie hors dépôt /tmp/pr469-copy (git archive de db625d0, npm ci), espion cargo, journaux des runs 570 à 574 et textes extraits : supprimés en fin de revue. Dépôt local intact (git status vide, sur main), rien d'installé (/tmp/pr469-xroot jamais créé).
  • Label de #449 : status:review → status:approved.
Niveau : haut — `.forgejo/workflows/release.yml` (Release et mise à jour) ; aussi `.claude/skills/release/SKILL.md` (Release et mise à jour) et les étapes de verdict `cargo check` et `cargo test` de `check-rust.yml` (CI et gardes) Dossier de décision requis : /pr-brief 469 avant le merge. ## Verdict : APPROVE Revue indépendante, distincte de l'auto-revue du worker (commentaire 25148). `--locked` arrive à `cargo build` par les deux runners de la release et fait échouer `check-rust` sur un lock désaccordé, sans jamais le réécrire ; l'épinglage fige cargo-xwin à la version que la v0.17.2 avait installée. Tout est rejoué ci-dessous sur une copie hors dépôt de la tête `db625d0`, avec un désaccord différent de celui de l'auteur. La passe sécurité ne relève rien. ### Rejoué (texte exact des étapes, extrait par PyYAML, lancé sous `bash --noprofile --norc -e -o pipefail`) Désaccord : version de l'app montée dans `src-tauri/Cargo.toml` seul (0.17.2 → 0.17.3), l'oubli que l'étape 2 de `/release` doit attraper. L'auteur avait déplacé la borne d'`urlencoding`. | # | Texte exécuté | Résultat | |---|---|---| | R1 | étape `cargo check` (tête) | 101, `cannot update the lock file … because --locked was passed to prevent this`, lock intact | | R2 | étape `cargo test` (tête) | 101, même message, lock intact | | M1 | mutation : étape `cargo check` de la base | lock réécrit (`version = "0.17.3"` dans le bloc `simpl-result`) sans **aucune** ligne `Locking` dans la sortie, puis compilation (arrêtée à 45 s) | | R3 | étape « Build Tauri » (tête), vrai cargo derrière un espion qui journalise chaque appel et son appelant | `node` (CLI) : 6 × `cargo metadata --no-deps --format-version 1`, puis `cargo build --locked --bins --features tauri/custom-protocol --release` ; échec sur le message de cargo puis `failed to build app`, lock intact | | R4 | étape « Build Tauri Windows » (tête), cargo-xwin 0.23.1 réel | `node` : les mêmes 6 `metadata --no-deps` ; `cargo-xwin` : `cargo build --features tauri/custom-protocol --target x86_64-pc-windows-msvc --locked --release --bins` ; même échec, lock intact | | M2, M3 | mutation : les deux étapes de la base, l'espion remplaçant `cargo build` par la résolution qu'il ferait | aucun `--locked` dans l'appel ; lock réécrit dans les deux cas | | R5 | commande de l'étape 2 du skill, extraite du `SKILL.md` | lock réel : 0 ; `Cargo.toml` monté seul : 101, lock intact ; bloc `simpl-result` corrigé à la main : 0, lock non réécrit ; arête `urlencoding` retirée du bloc (« strophe abîmée ») : 101 | | M4 | mutation : la même commande sans `--locked`, `Cargo.toml` monté seul | 0 et lock réécrit : le contrôle passerait en régénérant ce que le skill interdit de régénérer | | R6 | `cargo-xwin --version` sous les options du runner | `cargo-xwin 0.23.1`, code 0 : la ligne ajoutée ne fait pas tomber l'étape | | R7 | `cargo install --locked cargo-xwin --version 0.23.99 --root /tmp/…` | 101, `with version =0.23.99` : version exacte, sans repli ; rien d'installé | Vérifié aussi : - crates.io : `max_stable_version` et `newest_version` à 0.23.1 (2026-08-13), non retirée ; run 570 (v0.17.2) : `Installed package cargo-xwin v0.23.1`. - Run 572 : commit `23d8190` = `14badbe` plus la seule ligne `urlencoding = "=2.1.2"` ; échec à `cargo check` (101), cache non sauvegardé. De `14badbe` à la tête, seuls `SKILL.md` et `architecture.md` changent : la preuve CI vaut pour les workflows relus. - CI de la tête `db625d0` : `check-frontend` run 573 vert (138 fichiers, 2305 tests, dont les 36 de `build-latest-json.test.mjs`) ; `check-rust` run 574 vert (267 tests, garde des suppressions 2/2, `windows-sys` 9/9, audit sur 663 crates sans vulnérabilité, 18 avertissements autorisés). - Workflows : déclencheurs, `env:`, `uses:`, `if:` et nombre d'étapes identiques à la base, seuls des `run:` changent ; `python3 scripts/review-levels.py --check` ok (37 motifs), section « Niveaux » non touchée. - Doc : `CLAUDE.md`, `REVIEW.md`, ADR 0023 et `architecture.md` décrivent ce que font les workflows ; plus aucune mention de cargo-xwin non épinglé ni d'une CI sans `--locked`. Miroir : aucun miroir de poussée sur Forgejo, qui ignore `.github/workflows/` quand `.forgejo/workflows/` existe : « rien n'y tourne » tient. ### Passe sécurité : sans constat - §1 (secrets) : aucune valeur, aucun jeton, aucune URL à identifiants dans les 51 lignes ajoutées ; `TAURI_SIGNING_PRIVATE_KEY` n'y apparaît que comme nom, en commentaire ou en doc. - §3 et §4 : aucun motif dangereux, aucune expression de workflow dans les `run:` ajoutés, aucun `continue-on-error`, `|| true`, écriture de `$GITHUB_ENV` ou `$GITHUB_PATH`, aucun TODO de sécurité. - §2 : aucun manifeste ni lock modifié ; l'épinglage réduit ce qui s'exécute avec la clé de signature. - Zones de `REVIEW.md` : Release (clé dans l'environnement des deux builds inchangée, `cargo-xwin --version` tourne dans une étape sans la clé, cycle réel signalé pour la prochaine release) ; CI et gardes (aucun workflow ajouté, aucune référence à `secrets`, pas de `pull_request_target` ; `--locked` ne peut que faire rougir ce qui passait, voir R1, R2 et M1). ### Suggestions (non bloquantes) 1. **Fermeture de #449.** La timeline porte un `closes` de cette PR (`Resolves #449` dans le corps et dans deux des trois commits) : #449 se fermera au merge, avant sa « Vérification post-merge (au prochain tag) ». Pour #447 et #455, la PR était en `Refs` et l'issue fermée à la main. Reformuler deux commits d'une pile de huit coûte plus que ça ne rapporte : au `/merge-stack`, reporter ce contrôle dans la puce « Vérifications dues à la release suivante » de `STATE.md` (le plan du lot prévoit ce report au `/merge-stack`), ou rouvrir #449 en `status:blocked` jusqu'au tag, comme #421. 2. **Le relais dépend de deux versions.** `-- --locked` n'arrive à `cargo build` que par `@tauri-apps/cli` 2.10.0 (lock npm) et cargo-xwin 0.23.1, et le journal du tag ne le montre jamais. Le commentaire de l'épinglage dit « Bump it on purpose, after reading what the new version changes » : y ajouter le rejeu de la preuve du relais (espion, lock désaccordé), et la même consigne pour une montée de `@tauri-apps/cli` dans `architecture.md` ou dans la zone Release de `REVIEW.md`. 3. **Précision de doc.** D'après l'appelant journalisé par l'espion, les six `cargo metadata --no-deps` viennent tous de la CLI de Tauri (`node`) ; cargo-xwin ne lance que `cargo build`. « les autres appels à cargo de la CLI et de cargo-xwin » (`architecture.md`, message de `db625d0`) n'est pas faux, mais prête à cargo-xwin des appels qu'il ne fait pas. 4. **L'indice du run 570 est plus faible que le corps ne le dit.** M1 montre que cargo réécrit sans un mot la version de `simpl-result` dans le lock : l'absence de ligne `Locking` dans un journal ne prouve rien pour l'oubli que vise l'étape 2 de `/release`. Sans effet sur la v0.17.2 (son lock avait passé `cargo metadata --locked` avant le tag), et un argument de plus pour `--locked`. 5. **Pour `STATE.md`.** Hors `paths-ignore`, cette PR ne touche que `.claude/skills/release/SKILL.md` et `release.yml` : le run 573 prouve que cette paire déclenche `check-frontend`, ce que l'entrée #419 de `STATE.md` laissait « à prouver ». Chacun seul reste non prouvé. ### Actions faites - Copie hors dépôt `/tmp/pr469-copy` (`git archive` de `db625d0`, `npm ci`), espion `cargo`, journaux des runs 570 à 574 et textes extraits : supprimés en fin de revue. Dépôt local intact (`git status` vide, sur `main`), rien d'installé (`/tmp/pr469-xroot` jamais créé). - Label de #449 : `status:review` → `status:approved`.
All checks were successful
PR Check — Frontend / frontend (pull_request) Successful in 1m57s
PR Check — Rust / rust (pull_request) Successful in 9m58s
This pull request can be merged automatically.
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin issue-449-cargo-locked:issue-449-cargo-locked
git checkout issue-449-cargo-locked

Merge

Merge the changes and update on Forgejo.
git checkout issue-453-i18n-keys-guard
git merge --no-ff issue-449-cargo-locked
git checkout issue-453-i18n-keys-guard
git merge --ff-only issue-449-cargo-locked
git checkout issue-449-cargo-locked
git rebase issue-453-i18n-keys-guard
git checkout issue-453-i18n-keys-guard
git merge --no-ff issue-449-cargo-locked
git checkout issue-453-i18n-keys-guard
git merge --squash issue-449-cargo-locked
git checkout issue-453-i18n-keys-guard
git merge --ff-only issue-449-cargo-locked
git checkout issue-453-i18n-keys-guard
git merge issue-449-cargo-locked
git push origin issue-453-i18n-keys-guard
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: maximus/Simpl-Resultat#469
No description provided.