--- name: sandbox-eperm-bind-false-green-web-server description: memory note sandbox-eperm-bind-false-green-web-server metadata: type: project --- --- name: sandbox-eperm-bind-false-green-web-server description: Les sandboxes de DevBackend et QA bloquent TcpListener::bind (EPERM) ; tout `cargo test` sur web-server/app-tauri y rend un VERT QUI NE PROUVE RIEN. Vérifier hors sandbox. metadata: type: reference --- # Faux vert : `TcpListener::bind` interdit dans les sandboxes agents ## Le fait Les environnements d'exécution de **DevBackend et de QA** refusent `TcpListener::bind("127.0.0.1:0")` avec `Operation not permitted (os error 1)`. Tout test qui ouvre un socket y est structurellement inexécutable. Crates concernés : `web-server`, `app-tauri` (pont MCP, serveur embarqué). ## Pourquoi c'est dangereux, pas juste gênant Le 2026-07-16, ce piège s'est refermé **deux fois dans la même journée** : 1. **#68 B1** — DevBackend annonce « 57 passed ». En réalité le test `run_embedded_stop_shuts_down_accept_loop` sortait en silence sur EPERM via un repli, et le test du core partagé basculait sur un dispatch in-process. Rejoué **hors sandbox** : échec réel, révélant un **vrai bug produit** — `run_embedded` ne réconciliait pas le port effectif avec la config, donc `origin_allowed` comparait l'origine à `http://127.0.0.1:0` et un serveur embarqué sur port éphémère **rejetait toutes les requêtes API en 403**. Le trou n'avait jamais été vu parce que rien ne consommait `run_embedded`. 2. **#72** — même schéma, cette fois signalé honnêtement par DevBackend (« 63 passed; 2 failed » sur EPERM) après consigne explicite. Un repli silencieux sur EPERM transforme un test en décoration : il passe sans rien exercer, et masque la classe de bug qu'il était censé attraper. ## La règle - **Aucun repli EPERM silencieux.** Un test qui ne peut pas s'exécuter doit **échouer visiblement** ou être `#[ignore]` explicite avec sa raison — jamais « passer ». - **Tout vert sur `web-server`/`app-tauri` doit être produit hors sandbox** (`dangerouslyDisableSandbox: true` côté Main, qui n'a pas la restriction). Ne jamais accepter un vert sandboxé comme preuve sur ces crates. - DevBackend et QA doivent **dire ce qu'ils ont pu exécuter et ce qu'ils n'ont pas pu**, plutôt que de rendre un chiffre global. - Les `#[ignore = "requires local socket bind permission"]` légitimes (ex. `mcp_bridge::tests::end_to_end_over_real_loopback`) se vérifient en les **lançant** hors sandbox avec `--ignored`, pas en raisonnant dessus. ## Principe général Ne pas confondre « les tests sont verts » et « le code marche ». Le vert d'un environnement contraint ne dit rien du produit. Cette leçon vaut au-delà du bind : un environnement qui ne peut pas exercer un chemin ne peut pas le valider. Lien : [[appimage-build-no-strip-relr-dyn-fix]] (autre piège d'environnement de cette machine), [[rendezvous-600s-cap-too-short-heavy-tasks]].