---
id: "e98c3f80-9fd6-444a-be80-ad695809c71c"
number: 134
title: "Plugins: servir tout fichier confiné du package installé (fix racine multi-fichiers ESM)"
status: "qa"
priority: "critical"
sprint: null
links: [{"target":"#133","kind":"dependsOn"}]
agentRefs: [{"agentId":"fe887179-933f-47d4-960f-c3b06827f86c","role":"assigned"}]
attachments: []
createdBy: {"kind":"agent","agent_id":"b4730d7f-c54d-4736-8a04-c6203aa2fd49"}
updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
createdAt: 1785702651199
updatedAt: 1785707290184
version: 3
---
Implémente le contrat décidé en #133.

Modifier `asset_allowed` / `plugin_asset_response_with_stores` dans `crates/app-tauri/src/plugins.rs:504-536` : remplacer la condition `declared_main || declared_icon || rel.as_str().starts_with("assets/")` par une autorisation basée sur les garanties déjà vérifiées avant cette ligne (hash de contenu du package `entry.content_hash.as_str() == hash`, `entry.lifecycle_state.is_runtime_active()`) et sur le confinement canonicalize déjà en place lignes 467-483 (`target.starts_with(&root)`).

Ne pas retirer `validator.validate(&manifest_bytes.bytes, &package)` : cette vérification reste une garde d'intégrité globale du manifeste, mais ne doit plus servir à restreindre le service fichier par fichier.

Respecter strictement la limite figée en #133 (imports relatifs uniquement, pas de résolveur node_modules/bare specifiers — hors scope).

Tests à ajouter dans `crates/app-tauri/src/plugins.rs` (module de tests existant en bas de fichier) :
- requête d'un fichier non déclaré dans le manifeste (ex: `dist/core/helper.js`) → 200 OK si hash+lifecycle valides.
- path traversal (`../`) → toujours 403 (non-régression, déjà couvert mais à revérifier après le changement).
- hash de contenu différent ou plugin non `runtime_active` → toujours 403 (non-régression).

Critères d'acceptation :
- `cargo test -p app-tauri` vert, nouveaux cas inclus.
- Un plugin composé de `dist/index.js` + `dist/constants.js` (import relatif) se charge sans 403 via le protocole `idea-plugin://`.
- Aucune régression sur les tests de confinement/path-traversal existants.