[maintainability] La documentation indique que le fallback s'exécute dans /workspace, alors que l'implémentation utilise /workspaces/workspace par défaut. Cette divergence rend les commandes et instructions d'utilisation incorrectes pour les consommateurs du fallback ; alignez la documentation et le code.
[performance] Le tag d'une image construite n'est enregistré dans Container::owned_image qu'après la création, le démarrage et l'upload du workspace. Si le réseau, la création/le démarrage du container ou l'upload échoue avant cette ligne, l'image construite reste dans le daemon sans possibilité de nettoyage, ce qui laisse des images potentiellement volumineuses à chaque sandbox échouée. Nettoyez l'image dans chaque chemin d'erreur après le build, ou encapsulez sa propriété dans un garde-fou jusqu'à la création de Container.
[bug] L'image par défaut debian:stable-slim ne crée pas le répertoire /workspaces/workspace, qui est pourtant le chemin retourné par workspace_folder() lorsque cette valeur est absente. up() tente ensuite d'y téléverser le workspace et configure ce chemin comme répertoire de travail ; le fallback échouera donc probablement dès le démarrage ou l'upload. Il faut créer ce répertoire avant l'upload, ou choisir un chemin garanti d'exister comme /tmp/workspace.
[performance] La collecte de la sortie d'un exec accumule toute la sortie dans deux String sans limite. La limitation à 32 KiB dans l'agent intervient seulement après le retour de cette fonction ; un read_file sur un gros fichier ou un grep très bavard peut donc consommer une quantité arbitraire de mémoire avant d'être tronqué. Il faut borner la sortie pendant la lecture, ou interrompre l'exec dès que la limite est atteinte.
[security] La vérification normalized.starts_with(workspace) compare des chaînes et ne respecte pas les frontières de composants. Avec un workspace /workspaces/repo, un chemin comme ../repo-secrets devient /workspaces/repo-secrets et passe ce test, ce qui permet aux outils de lire un répertoire voisin dans le container. Utiliser une comparaison de chemins basée sur les composants, par exemple strip_prefix(workspace).is_ok() après normalisation.
[performance] Si remove_container échoue, le ? quitte immédiatement la méthode et le réseau ainsi que l'image ne sont jamais supprimés. Après un daemon indisponible, un container déjà supprimé ou une erreur transitoire, chaque sandbox peut donc laisser des ressources persistantes. Effectuer le nettoyage du réseau et de l'image même lorsque la suppression du container échoue, puis retourner l'erreur.
Le nettoyage s'arrête immédiatement si remove_container échoue, et les suppressions du réseau et de l'image ne sont alors jamais tentées. Une course, un conteneur déjà supprimé ou une erreur transitoire peut donc laisser systématiquement le réseau et l'image derrière lui. Il faut tenter les trois nettoyages indépendamment, puis agréger ou retourner l'erreur pertinente.
La vérification ne protège pas réellement la frontière du dépôt lorsque workspaceFolder vient du dépôt non fiable. Une valeur comme / ou /tmp passe la normalisation et permet aux outils de lire n'importe quel chemin du conteneur, contrairement au contrat annoncé (« confined to the repository workspace »). Il faut imposer un workspace absolu dédié et vérifier qu'il s'agit bien du répertoire de dépôt, plutôt que de faire confiance à workspaceFolder fourni par la PR.
Le flux de build n'est considéré en échec que lorsque error_detail.message est renseigné. L'API Docker peut aussi fournir l'erreur dans le champ error de BuildInfo; dans ce cas la méthode retourne Ok(()) alors que l'image n'a pas été construite. Il faut traiter les deux champs et préserver le message d'erreur le plus utile.
La valeur de DOCKER_HOST est seulement stockée dans endpoint pour les logs : Docker::connect_with_defaults() ne l'utilise pas. Ainsi, la configuration documentée pour Podman ou pour un socket Docker non standard est ignorée et le runtime tente toujours sa connexion par défaut. Il faut construire le client Bollard avec l'endpoint lu dans l'environnement, ou supprimer cette configuration trompeuse.
Le schéma ne prend en charge que dockerfile et args, puis DevContainer::build utilise systématiquement le répertoire du Dockerfile comme contexte. La spécification devcontainer.json permet pourtant de définir build.context (souvent la racine du dépôt) ; les Dockerfile qui font COPY . ... ou qui utilisent un contexte distinct échoueront ou ne verront pas les fichiers attendus. Il faut modéliser et résoudre le contexte de build, avec une validation empêchant qu'il sorte du dépôt.
La suppression de .dockerignore fait que le contexte envoyé lors de buildah bud contient désormais notamment .git, les répertoires de build et le fichier .env local. Même si le Containerfile ne le copie pas explicitement, ce contexte est transmis au moteur de build et peut contenir des secrets ou devenir inutilement volumineux. Il faut conserver un .dockerignore excluant au minimum .git, .env*, target et les fichiers locaux.
Le chemin build.dockerfile fourni par une pull request est concaténé sans normalisation ni vérification qu'il reste dans le dépôt. Une valeur comme ../../... peut faire choisir un Dockerfile situé hors du clone ; comme son parent devient ensuite le contexte envoyé au daemon, cela peut empaqueter des fichiers d'autres sandboxes ou du système dans le contexte de build. Résolvez le chemin puis imposez qu'il soit situé sous la racine du dépôt avant de l'utiliser.
endpoint lit DOCKER_HOST, mais le client Bollard est créé avec connect_with_defaults() sans utiliser cette valeur. Ainsi, le daemon configuré via DOCKER_HOST (notamment le socket Podman rootless documenté) risque d'être ignoré, tandis que les logs indiquent un endpoint différent de celui réellement utilisé. Il faut construire le client à partir de l'endpoint résolu, ou vérifier que l'API utilisée prend effectivement en charge DOCKER_HOST.
La vérification de confinement dépend entièrement de workspace, qui est contrôlé par le devcontainer.json de la pull request. Une PR peut définir workspaceFolder à /, après quoi starts_with(workspace) autorise pratiquement tout le système de fichiers du container et les outils peuvent lire des fichiers hors dépôt. Le workspace doit être validé et forcé sous un répertoire dédié au dépôt, indépendamment de la configuration non fiable.