--- name: b8-in-app-trigger-run-in-background description: Arbitrage de l'écart de périmètre #1 — la surface agent MCP idea_run_in_background ferme la boucle B8, contrat et lots figés. metadata: type: reference --- # B8 — Déclencheur in-app (FIGÉ Architecture, 2026-07-03) Suite de [[b8-command-runner-pty-framing]] et [[b8-arbitration-outcomes]]. Constat : le consommateur B8 (runner PTY → sink → inbox → wake) est livré (8cac147) mais SANS producteur — `spawn_background_command` (commands.rs:2586) n'est appelé par personne. #1 n'a donc aucun déclencheur réel. ## Décision - **Retenu : outil MCP agent `idea_run_in_background`** (surface principale, fermante). Chemin humain UI (bouton panel F2) = secondaire optionnel, `wake_policy=RecordOnly`. **Promotion auto d'une commande PTY longue : REJETÉE** (pas d'owner/intention, heuristique fragile, change la sémantique de write_terminal). - Pourquoi (a) : toute la machinerie (WakeOwner, inbox, AgentWakePort) est agent-centrée ; seul un agent déclarant explicitement une tâche de fond exerce la boucle bout-en-bout. ## Contrat `idea_run_in_background` Params : label(req), command(req), args[], cwd?(déf=project root), deadline_ms?. **owner = identité handshake du demandeur (non paramètre, non usurpable, rejet si absente)** ; project = contexte du demandeur ; record_only NON exposé côté agent → **WakeOwner forcé**. Retour SYNCHRONE {taskId,state} ; le résultat arrive plus tard en InboxItem::BackgroundCompletion (fire-and-forget-avec-tracking, distinct d'idea_ask_agent synchrone). ## Frontière — ZÉRO nouveau port/adapter - Domaine : variante `OrchestratorCommand::RunInBackground` (domain/orchestrator.rs). - Adapter MCP : décl outil + map_tool_call (mcp/tools.rs), comme idea_ask_agent. - Exécution : handler route vers use case EXISTANT application::SpawnBackgroundCommand (déjà en composition root state.rs), owner=requester, WakeOwner. Suivre le MÊME dispatch qu'AskAgent pour atteindre la couche app ; ne pas ré-router par commande Tauri front. ## Lots - BE-1 : variante enum + outil + mapping + tests mapping. - BE-2 : handler RunInBackground → SpawnBackgroundCommand (rejet si demandeur absent). - FE-1 (secondaire) : formulaire création dans panel F2 → spawn_background_command record_only. - QA T1 : agent appelle idea_run_in_background(`sh -c 'sleep 8; echo done'`), finit son tour → owner ré-invoqué avec exit+résumé. T3 cancel/retry sur ce taskId (retry session-scoped, pas reboot — dette ticket B). ## Branche Tient sur feature/background-tasks-first-class (additif, réutilise la boucle figée). Rien à préparer côté Git.