Files
IdeA/.ideai/memory/sandbox-eperm-bind-false-green-web-server.md
Blomios a13a6c1801 chore(ideai): carnet de #68, passage en QA et note du faux vert sandbox
Dernier état `.ideai/` du sprint serveur embarqué, séparé du code applicatif
conformément aux précédents `f965f64` / `7fbaa8e` / `5ee25d1`.

- #68 passé en `qa`, pas en `closed` : mergé dans `develop` (`b30c9c7`) et vert,
  mais RIEN n'a été cliqué dans l'app réelle. « Mergé » ne veut pas dire
  « validé » — même distinction que pour #69 et son lot 3.
- Carnet de #68 : périmètre livré, réserve « aucune validation live », et la
  dette identifiée (ordre de `preview_settings` qui verrouille la liste des
  candidats LAN, warning `missingTrustedProxy` inatteignable).
- Mémoire projet : note `sandbox-eperm-bind-false-green-web-server`. Elle
  capitalise le piège qui s'est refermé DEUX FOIS le 2026-07-16 : les sandboxes
  de DevBackend et QA refusent `TcpListener::bind`, donc tout `cargo test` sur
  `web-server`/`app-tauri` y rend un vert qui ne prouve rien. La première fois,
  ce faux vert masquait un vrai bug produit — un serveur embarqué sur port
  éphémère rejetait toutes les requêtes API en 403. La règle qui en sort : aucun
  repli EPERM silencieux, et tout vert sur ces crates doit être produit hors
  sandbox.
- Journal des tâches de fond : complétions enregistrées.

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

2.9 KiB

name, description, metadata
name description metadata
sandbox-eperm-bind-false-green-web-server memory note sandbox-eperm-bind-false-green-web-server
type
project

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 produitrun_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.