[Bug — medium] Une base d’audit corrompue bloque même l’installation d’un paquet officiel #88

Closed
opened 2026-09-17 12:09:32 +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é : medium. auroscope -S tree échoue sur l’état d’audit avant même de demander à Paru si tree est officiel. Une panne SQLite sans rapport avec les dépôts officiels rend donc le chemin natif indisponible. Contournement : commande native Paru ou --repo explicite.

Reproduction exécutée : fichier d’état temporaire contenant not a database, Paru simulé prêt à répondre REPO TARGET extra tree puis à réussir l’installation. Résultat :

status=1
stderr="auroscope: open state: file is not a database\n"
calls=""

Attendu : classifier puis installer le paquet officiel avec le statut et les flux de Paru, sans dépendre de SQLite. La base corrompue doit continuer à faire échouer la branche AUR, sans contournement d’audit.

Cause et emplacement

orchestrator.run, review.go:40–67 prépare CloneDir et ouvre/migre SQLite avant la résolution, alors que son retour natif officiel se trouve après. Le même couplage ajoute des écritures inutiles lorsqu’aucune cible AUR n’existe.

Piste minimale et simplification concrète

Déplacer la préparation de CloneDir et l’ouverture/fermeture de l’état après la classification et le retour officiel (et après le cas sans cible). On retire au chemin officiel la responsabilité de gérer les ressources d’audit ; on réduit ses conditions d’échec sans ajouter de couche ni modifier les responsabilités de Paru.

Acceptation :

  • installation officielle explicite et sélection officielle réussies avec une base d’audit corrompue ou un chemin d’audit inutilisable ; pas de création de base ni de clones ;
  • refus AUR inchangé lorsque son état est inutilisable ;
  • mêmes arguments officiels, flux, terminal et statuts natifs ; aucun appel LLM ;
  • aucune « réparation » automatique destructive du fichier SQLite.

Déduplication : #60/#61 portaient sur la traversée des artefacts de build, non sur l’ouverture SQLite avant classification ; #52/#53 sur la recherche. Aucun ticket ouvert correspondant. Mathieu : évaluer/prioriser ; pas d’exécution autorisée par ce ticket de revue.

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 TestReviewProbeOfficialInstallIndependentOfAuditState -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 ("bytes"; "io"; "os"; "path/filepath"; "strings"; "testing")
func TestReviewProbeOfficialInstallIndependentOfAuditState(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\"\nif test \"$1\" = -P; then printf 'REPO TARGET extra tree\\n'; fi\nexit 0\n")
 state:=filepath.Join(dir,"state.sqlite3"); if err:=os.WriteFile(state,[]byte("not a database\n"),0600);err!=nil{t.Fatal(err)}
 var stderr bytes.Buffer
 status:=run([]string{"-S","tree"},runConfig{paruPath:p,statePath:state,cloneDir:filepath.Join(dir,"clones"),stdin:strings.NewReader(""),stdout:io.Discard,stderr:&stderr})
 callsData,_:=os.ReadFile(calls);t.Logf("status=%d stderr=%q calls=%q",status,stderr.String(),callsData)
 if status!=0||!strings.Contains(string(callsData),"-S tree"){t.Error("official install blocked by audit state")}
}

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é : medium.** `auroscope -S tree` échoue sur l’état d’audit avant même de demander à Paru si `tree` est officiel. Une panne SQLite sans rapport avec les dépôts officiels rend donc le chemin natif indisponible. Contournement : commande native Paru ou `--repo` explicite. Reproduction exécutée : fichier d’état temporaire contenant `not a database`, Paru simulé prêt à répondre `REPO TARGET extra tree` puis à réussir l’installation. Résultat : ```text status=1 stderr="auroscope: open state: file is not a database\n" calls="" ``` Attendu : classifier puis installer le paquet officiel avec le statut et les flux de Paru, sans dépendre de SQLite. La base corrompue doit continuer à faire échouer la branche AUR, sans contournement d’audit. ## Cause et emplacement [`orchestrator.run`, review.go:40–67](https://git.2027a.net/2027a/auroscope/src/commit/30b53a270c3e28024a74762fc94c5ddb6f541f38/internal/app/review.go#L40-L67) prépare CloneDir et ouvre/migre SQLite avant la résolution, alors que son retour natif officiel se trouve après. Le même couplage ajoute des écritures inutiles lorsqu’aucune cible AUR n’existe. ## Piste minimale et simplification concrète Déplacer la préparation de CloneDir et l’ouverture/fermeture de l’état après la classification et le retour officiel (et après le cas sans cible). On retire au chemin officiel la responsabilité de gérer les ressources d’audit ; on réduit ses conditions d’échec sans ajouter de couche ni modifier les responsabilités de Paru. Acceptation : - installation officielle explicite et sélection officielle réussies avec une base d’audit corrompue ou un chemin d’audit inutilisable ; pas de création de base ni de clones ; - refus AUR inchangé lorsque son état est inutilisable ; - mêmes arguments officiels, flux, terminal et statuts natifs ; aucun appel LLM ; - aucune « réparation » automatique destructive du fichier SQLite. Déduplication : #60/#61 portaient sur la traversée des artefacts de build, non sur l’ouverture SQLite avant classification ; #52/#53 sur la recherche. Aucun ticket ouvert correspondant. Mathieu : évaluer/prioriser ; pas d’exécution autorisée par ce ticket de revue. ## 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 TestReviewProbeOfficialInstallIndependentOfAuditState -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 ("bytes"; "io"; "os"; "path/filepath"; "strings"; "testing") func TestReviewProbeOfficialInstallIndependentOfAuditState(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\"\nif test \"$1\" = -P; then printf 'REPO TARGET extra tree\\n'; fi\nexit 0\n") state:=filepath.Join(dir,"state.sqlite3"); if err:=os.WriteFile(state,[]byte("not a database\n"),0600);err!=nil{t.Fatal(err)} var stderr bytes.Buffer status:=run([]string{"-S","tree"},runConfig{paruPath:p,statePath:state,cloneDir:filepath.Join(dir,"clones"),stdin:strings.NewReader(""),stdout:io.Discard,stderr:&stderr}) callsData,_:=os.ReadFile(calls);t.Logf("status=%d stderr=%q calls=%q",status,stderr.String(),callsData) if status!=0||!strings.Contains(string(callsData),"-S tree"){t.Error("official install blocked by audit state")} } ``` </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#88
No description provided.