[Bug — high] Une prévisualisation -Syu --print lance une vraie mise à jour officielle #86

Closed
opened 2026-09-17 12:09:31 +00:00 by hermes · 0 comments
Member

Ticket de revue indépendante, pour évaluation ultérieure uniquement. Mathieu n’a demandé ni implémentation, ni déclenchement de boucle, ni PR. Aucun correctif apporté.

Référence : branche main, commit 30b53a270c3e28024a74762fc94c5ddb6f541f38 ; branche distante relue juste avant publication. Le contrôle de fraîcheur du paquet 0.1.0.r23.gee99222 passe : ses entrées de code sont identiques à celles examinées.

Défaut et impact

Gravité : high. Une commande de consultation devient une opération susceptible de modifier le système. auroscope -Syu --print, auroscope -Sup et auroscope --sync --sysupgrade --print lancent tous paru -Syu --repo, sans --print. La confirmation native peut encore limiter l’impact : le test ne prétend pas qu’une installation s’est produite ni qu’une confirmation a été contournée.

Attendu : conserver la sémantique de prévisualisation, sans transaction d’installation ni audit. Observé : première invocation réelle du sous-processus simulé = -Syu --repo pour les trois entrées. Le faux Paru s’arrête volontairement avec 17 à ce point ; ce statut est conservé.

Cause et emplacement

run.go:68–85 traite isSystemUpgrade avant le classificateur des commandes non constructrices. La reconstruction en -Syu --repo efface toutes les options. commandMayBuildAUR connaît pourtant --print/p, mais n’est jamais consulté dans ces cas.

Piste minimale et acceptation

  • Faire passer les variantes de consultation avant l’orchestration de mise à jour, en conservant leurs arguments natifs. Une petite classification partagée suffit ; pas de nouveau framework CLI.
  • Tester les trois formes ci-dessus, --print-format et le statut natif ; aucune invocation d’installation, de Codex ou de préparation AUR.
  • Conserver le vrai -Syu : phase officielle puis revue AUR ; ne pas corriger en désactivant l’audit des mises à jour constructrices.
  • Examiner les autres options perdues par cette même reconstruction, sans les déclarer corrigées par ce seul test.

Déduplication : tickets/PR parcourus avec pagination, aucun ouvert lors de la revue ; #84/#85 portent sur une liste AUR vide, pas sur la prévisualisation. À corriger avant de se fier aux commandes de prévisualisation. Mathieu : évaluer et prioriser ; un mandat ultérieur pourra autoriser le correctif.

Reproduction automatisée isolée

Le test ci-dessous réutilise les helpers existants de internal/app. Il a été exécuté avec un overlay Go, sans modifier le checkout : go test -overlay /chemin/overlay.json ./internal/app -run TestReviewProbeUpgradePrintMustNotInstall -v -count=1. L’overlay associe le chemin absolu internal/app/review_probe_test.go du checkout au fichier temporaire contenant ce test. Ce test exprime le comportement attendu et échoue actuellement. Aucun vrai Paru/Pacman, fournisseur LLM ou contenu de paquet n’est exécuté.

Test Go reproductible
package app
import ("io"; "path/filepath"; "strings"; "testing")
func TestReviewProbeUpgradePrintMustNotInstall(t *testing.T) {
 for _, args := range [][]string{{"-Syu", "--print"}, {"-Sup"}, {"--sync", "--sysupgrade", "--print"}} {
  t.Run(strings.Join(args,"_"),func(t *testing.T){
   dir:=t.TempDir(); calls:=filepath.Join(dir,"calls"); t.Setenv("CALLS",calls)
   p:=writeExecutable(t,dir,"paru", "#!/bin/sh\nprintf '%s\\n' \"$*\" >> \"$CALLS\"\nexit 17\n")
   status:=run(args,runConfig{paruPath:p,stdin:strings.NewReader(""),stdout:io.Discard,stderr:io.Discard})
   got:=strings.TrimSpace(readString(t,calls)); t.Logf("input=%q status=%d first Paru invocation=%q",args,status,got)
   if got!=strings.Join(args," "){t.Errorf("non-building command rewritten as %q",got)}
  })
 }
}

Ticket de revue indépendante, **pour évaluation ultérieure uniquement**. Mathieu n’a demandé ni implémentation, ni déclenchement de boucle, ni PR. Aucun correctif apporté. Référence : branche `main`, commit `30b53a270c3e28024a74762fc94c5ddb6f541f38` ; branche distante relue juste avant publication. Le contrôle de fraîcheur du paquet `0.1.0.r23.gee99222` passe : ses entrées de code sont identiques à celles examinées. ## Défaut et impact **Gravité : high.** Une commande de consultation devient une opération susceptible de modifier le système. `auroscope -Syu --print`, `auroscope -Sup` et `auroscope --sync --sysupgrade --print` lancent tous `paru -Syu --repo`, sans `--print`. La confirmation native peut encore limiter l’impact : le test ne prétend pas qu’une installation s’est produite ni qu’une confirmation a été contournée. Attendu : conserver la sémantique de prévisualisation, sans transaction d’installation ni audit. Observé : première invocation réelle du sous-processus simulé = `-Syu --repo` pour les trois entrées. Le faux Paru s’arrête volontairement avec 17 à ce point ; ce statut est conservé. ## Cause et emplacement [`run.go:68–85`](https://git.2027a.net/2027a/auroscope/src/commit/30b53a270c3e28024a74762fc94c5ddb6f541f38/internal/app/run.go#L68-L85) traite `isSystemUpgrade` avant le classificateur des commandes non constructrices. La reconstruction en `-Syu --repo` efface toutes les options. [`commandMayBuildAUR`](https://git.2027a.net/2027a/auroscope/src/commit/30b53a270c3e28024a74762fc94c5ddb6f541f38/internal/app/run.go#L223-L260) connaît pourtant `--print`/`p`, mais n’est jamais consulté dans ces cas. ## Piste minimale et acceptation - Faire passer les variantes de consultation avant l’orchestration de mise à jour, en conservant leurs arguments natifs. Une petite classification partagée suffit ; pas de nouveau framework CLI. - Tester les trois formes ci-dessus, `--print-format` et le statut natif ; aucune invocation d’installation, de Codex ou de préparation AUR. - Conserver le vrai `-Syu` : phase officielle puis revue AUR ; ne pas corriger en désactivant l’audit des mises à jour constructrices. - Examiner les autres options perdues par cette même reconstruction, sans les déclarer corrigées par ce seul test. Déduplication : tickets/PR parcourus avec pagination, aucun ouvert lors de la revue ; #84/#85 portent sur une liste AUR vide, pas sur la prévisualisation. À corriger avant de se fier aux commandes de prévisualisation. Mathieu : évaluer et prioriser ; un mandat ultérieur pourra autoriser le correctif. ## Reproduction automatisée isolée Le test ci-dessous réutilise les helpers existants de `internal/app`. Il a été exécuté avec un overlay Go, sans modifier le checkout : `go test -overlay /chemin/overlay.json ./internal/app -run TestReviewProbeUpgradePrintMustNotInstall -v -count=1`. L’overlay associe le chemin absolu `internal/app/review_probe_test.go` du checkout au fichier temporaire contenant ce test. Ce test exprime le comportement attendu et **échoue actuellement**. Aucun vrai Paru/Pacman, fournisseur LLM ou contenu de paquet n’est exécuté. <details><summary>Test Go reproductible</summary> ```go package app import ("io"; "path/filepath"; "strings"; "testing") func TestReviewProbeUpgradePrintMustNotInstall(t *testing.T) { for _, args := range [][]string{{"-Syu", "--print"}, {"-Sup"}, {"--sync", "--sysupgrade", "--print"}} { t.Run(strings.Join(args,"_"),func(t *testing.T){ dir:=t.TempDir(); calls:=filepath.Join(dir,"calls"); t.Setenv("CALLS",calls) p:=writeExecutable(t,dir,"paru", "#!/bin/sh\nprintf '%s\\n' \"$*\" >> \"$CALLS\"\nexit 17\n") status:=run(args,runConfig{paruPath:p,stdin:strings.NewReader(""),stdout:io.Discard,stderr:io.Discard}) got:=strings.TrimSpace(readString(t,calls)); t.Logf("input=%q status=%d first Paru invocation=%q",args,status,got) if got!=strings.Join(args," "){t.Errorf("non-building command rewritten as %q",got)} }) } } ``` </details>
Sign in to join this conversation.
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
2027a/auroscope#86
No description provided.