chore(tickets): versionne le store de tickets et de sprints du projet

`.ideai/tickets/` et `.ideai/sprints/` sont le registre durable du projet (les
tickets sont déjà référencés par les messages de commit : #14, #21..#25, #28),
au même titre que `.ideai/memory/`. Ils entrent donc dans le dépôt.

À l'inverse, `.ideai/background-tasks/` (snapshots de rendez-vous headless) et
`.ideai/proposals/` (amendements de contexte en attente d'arbitrage) restent de
l'état d'exécution transitoire, de la même classe que `live-state.json` et
`.ideai/requests/` : ils doivent être ignorés (patch `.gitignore` à venir).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-08 08:38:33 +02:00
parent 56757c7e1b
commit 2fa226e413
72 changed files with 1439 additions and 0 deletions

View File

@ -0,0 +1,39 @@
---
id: "c3e1fbcc-cedc-48a5-a00e-b22ea8dc90de"
number: 33
title: "[Dette] Fallthrough silencieux du routage structuré (lifecycle.rs:1705)"
status: "open"
priority: "high"
sprint: null
links: [{"target":"#32","kind":"relatesTo"},{"target":"#14","kind":"relatesTo"}]
agentRefs: []
createdBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
createdAt: 1783492190391
updatedAt: 1783492190391
version: 1
---
Cause racine structurelle identifiée par Architect lors du cadrage de #32.
`LaunchAgent::execute` (crates/application/src/agent/lifecycle.rs:1705) route vers la session structurée avec :
```rust
if let (Some(factory), Some(structured), true) = (
self.session_factory.as_ref(), self.structured.as_ref(),
profile.structured_adapter.is_some(),
)
```
Ce `if let` **confond deux situations distinctes** :
- « profil structuré, mais factory non câblée » (cas de l'UI : `state.rs:1466` construit le `LaunchAgent` sans `.with_structured(...)`) ;
- « profil non structuré » (vrai profil PTY historique).
Dans les deux cas on tombe silencieusement, sans erreur ni branche explicite, sur `lifecycle.rs:1746` `self.pty.spawn(spec)`.
C'est ce fallthrough qui a produit le bug #32 : un profil `openAiCompatible` (aucun binaire) atteignait `CommandBuilder::new("openai-compatible")`. Claude et Codex tombent dans le **même** fallthrough ; ça ne passe inaperçu que parce qu'un binaire `claude`/`codex` existe dans le PATH.
Le fix de #32 neutralise le cas transport-backed, mais **le piège reste armé** pour le prochain adapter.
**Attendu** : remplacer le `if let` par un `match` explicite qui distingue les deux cas, et décider du comportement quand un profil structuré rencontre une factory non câblée (erreur explicite plutôt que dégradation muette vers le PTY).
Hors périmètre de #32 (déposé comme bug). Cadrage Architect requis avant implémentation.