Files
IdeA/.ideai/tickets/133/carnet.md
Blomios 59d81851e9 chore(tickets): synchronise index/carnets tickets #131-#139 + note mémoire assets/persistance plugins
État runtime .ideai séparé du code (index, counter, carnets, note mémoire
plugin-asset-serving-and-owned-storage-contracts). Purge des tickets obsolètes
51/63/66.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-03 11:06:30 +02:00

2.6 KiB

issueRef, version, updatedBy, updatedAt
issueRef version updatedBy updatedAt
#133 4
kind agent_id
agent b4730d7f-c54d-4736-8a04-c6203aa2fd49
1785703664966

Décision d'architecture (2026-08-02)

Documentée dans ARCHITECTURE.md §22.1 (nouvelle section "Plugins — service des assets multi-fichiers & persistance plugin-owned").

Contrat tranché : asset_allowed (crates/app-tauri/src/plugins.rs:504-536) doit servir tout chemin relatif confiné dès lors que les trois gardes déjà présentes sont satisfaites — entrée registre trouvée + lifecycle_state.is_runtime_active() + entry.content_hash == hash de l'URL (intégrité du package entier) — sans plus restreindre au triplet declared_main || declared_icon || starts_with("assets/"). Le confinement canonicalize aval (lignes 467-483, target.starts_with(&root)) reste inchangé et continue de protéger contre l'évasion de racine. validator.validate(manifest) reste appelé comme garde d'intégrité globale du manifeste, mais cesse de gater le service fichier par fichier.

Rationale sécurité : aucune perte de garantie — le modèle de menace est fixé par content_hash à l'installation (audité en #135), donc restreindre les fichiers siblings d'un package déjà intégralement vérifié n'arrête aucune attaque supplémentaire, ça casse juste des graphes de modules ESM légitimes.

Limite figée : pas de résolution node_modules/bare specifiers — hors scope, aucun résolveur de module à construire. Un plugin avec dépendances tierces les bundle ou vendore en relatif, à son choix.

Contrat de confinement/désinstallation formalisé : racine servie = exclusivement app_data/plugins/installed/<pluginId>/ ; jamais d'écriture/exposition hors project root ou .ideai/ de l'utilisateur ; désinstallation = suppression complète + entrée registre, zéro résidu (périmètre détaillé pour #135).

Débloque

  • #134 : remplacer la dernière ligne de asset_allowedOk(declared_main || declared_icon || rel.as_str().starts_with("assets/")) — par une autorisation basée uniquement sur les gardes déjà calculées plus haut dans la fonction. Tests de non-régression path-traversal et hash/lifecycle invalides déjà spécifiés dans #134, contrat inchangé.
  • #135 : périmètre d'audit = confinement à l'install (RelativePath::new déjà rejette ../absolu côté domaine — vérifier qu'il est bien appliqué à l'INSTALL, pas seulement au SERVE) + désinstallation 100%.

Aucun changement de code applicatif dans ce ticket (portée strictement architecture, conforme à l'objectif du ticket). Fichier touché : ARCHITECTURE.md (§22.1 ajouté).