Files
IdeA/.ideai/tickets/99/carnet.md
Blomios 5955ea37a2 chore(tickets): synchronise l'état ticketing courant
Met à jour les carnets/issues existants et ajoute les tickets #108,
#109, #111, #112 créés durant le cycle. État runtime sans rapport
avec le lot de code #82, isolé dans son propre commit.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-29 15:57:37 +02:00

8.0 KiB

issueRef, version, updatedBy, updatedAt
issueRef version updatedBy updatedAt
#99 4
kind
user
1785271085627

Carnet #99 — Cadrage (prêt pour le cycle)

Cadrage établi par Main après investigation code + vérification empirique des binaires installés (codex-cli 0.145.0, Claude Code 2.1.220). Les faits CLI ci-dessous sont capitalisés et vérifiés ; ils conditionnent toute l'architecture. Architect doit valider les ports/VO et les questions ouvertes (§6) avant l'implémentation.


1. État des lieux vérifié — comparaison des 3 moteurs

Moteur Modèle contrôlé par IdeA ? Mécanisme Source
OpenCode Oui model écrit à la racine du opencode.json isolé (OPENCODE_CONFIG), lu par la session structured lifecycle.rs:2686-2689, 2786-2788
Codex Non aucun --model, codex_config_toml n'écrit pas model → défaut du binaire codex.rs:215-239, lifecycle.rs:2941-2955
Claude Non aucun --model, claude_settings_seed n'écrit pas model → défaut du binaire claude.rs:273-284, infrastructure/permission/claude.rs:59

PTY et headless sont deux processus OS séparés pour un même agent (allow_structured_alongside_pty: true, lifecycle.rs:1512-1517) ; ils partagent le même CODEX_HOME/cwd mais aucun état modèle n'est synchronisé entre eux côté IdeA. Le /model de la TUI ne sort jamais du process TUI (pass-through brut, terminal/usecases.rs:140).

2. Faits CLI vérifiés (capitalisation) — la clé qui débloque tout

Codex 0.145.0 — model est une clé config.toml documentée

  • L'exemple littéral du --help est -c model="o3". config.toml est chargé depuis $CODEX_HOME/config.toml.
  • Honorée par codex (TUI) ET codex exec (headless) — même mécanisme de base (--ignore-user-config confirme qu'il est chargé par défaut).
  • Bonus : codex exec accepte aussi -m, --model <MODEL> (seconde porte d'injection).
  • → Écrire model = "..." dans le $CODEX_HOME/config.toml isolé fixe le défaut pour les DEUX canaux.

Claude 2.1.220 — model est gérable via settings + flag

  • --model <model> fonctionne en interactif et -p/--print (headless).
  • --settings <file-or-json> + la hiérarchie ./.claude/settings.local.json (project-local) supportent une clé model.
  • → Écrire "model": "..." dans le .claude/settings.local.json du run dir fixe le défaut pour les DEUX canaux (cwd = run dir, lu par PTY et headless).

Conclusion d'architecture

Les trois moteurs convergent vers le même pattern : écrire le modèle du profil dans le fichier de config isolé du run dir. Le fichier partagé = point de vérité unique pour headless + TUI au lancement. L'exigence produit « modèle par défaut = modèle headless = modèle exposé TUI au lancement » est satisfaite par construction, sans sync à coder.

3. Points d'intégration IdeA précis (avec chemins)

Moteur Renderer à modifier Fichier produit Ownership Isolation
Codex codex_config_toml (application/agent/lifecycle.rs:2941-2955) $CODEX_HOME/config.toml MergeToml (préservé aux régénérations) CODEX_HOME={runDir}/.codex déjà isolé (lifecycle.rs:2361)
Claude claude_settings_seed (infrastructure/src/permission/claude.rs:59) {runDir}/.claude/settings.local.json Replace (régénéré du profil à chaque lancement) cwd=run dir ; pas d'iso home mais project-local override user → le modèle IdeA gagne

Champ existant à consommer ou déprécier : AgentProfile.model: Option<String> (domain/src/profile.rs:1008) — actuellement code mort. Référence OpenCode à répliquer : OpenCodeProviderConfig { provider_id, model, api_key_ref } (domain/src/profile.rs:372-391)

  • SaveOpenCodeProviderProfile (application/agent/usecases.rs).

4. Architecture proposée — découpage en lots

  • A. Domaine — Nouveaux VO miroir d'OpenCodeProviderConfig : CodexProviderConfig { provider, model, api_key_ref } et ClaudeProviderConfig { provider, model, api_key_ref }. Rendre les backends mutuellement exclusifs par moteur (cf. opencode_backend_is_consistent, domain/src/profile.rs:363-364,1224). Décision Architect : nouveau VO vs réutiliser AgentProfile.model (voir §6).
  • B. Renderers de configcodex_config_toml écrit model (+ model_provider si requis par la sémantique codex) ; claude_settings_seed écrit la clé model.
  • C. Use cases / persistanceSaveCodexProviderProfile / SaveClaudeProviderProfile miroirs de SaveOpenCodeProviderProfile, même SecretRef pour la clé scellée.
  • D. UI / wizard — duplication de profils Codex/Claude comme OpenCode (catalogue providers, sélection modèle, clé scellée). Réutiliser provider_catalogue + picker existants.
  • E. QA — assert headless + TUI utilisent le modèle du profil (voir §5).

5. Invariants (à respecter, à tester)

  • Source de vérité unique : le modèle vient du profil AI, écrit dans le fichier de config isolé du run dir, lu par headless et TUI au lancement.
  • Isolation préservée : Codex via CODEX_HOME (rien ne change) ; Claude via project-local override (rien ne change). Pas d'accès au home global pour le modèle.
  • /model en cours de session TUI ne corrompt pas le headless (acceptable : ne concerne que le process PTY en cours ; le prochain lancement réapplique le défaut du profil).
  • Non-régression OpenCode : rendu opencode.json byte-identique (rien ne touche ce chemin).
  • Non-régression permissions : codex_config_toml et claude_settings_seed continuent d'écrire mcp/sandbox/trust/approval comme aujourd'hui (le model s'ajoute).

6. Questions ouvertes pour Architect (à trancher avant DevBackend)

  1. VO : créer CodexProviderConfig/ClaudeProviderConfig (homogène à OpenCode) ou consommer le champ existant AgentProfile.model (code mort) ? Recommandation Main : nouveaux VO pour rester isomorphe à OpenCode (provider + clé scellée), déprécier AgentProfile.model.
  2. Codex model_provider : la config codex distingue model et model_provider. Faut-il exposer les deux au profil, ou model seul suffit (provider implicite) ?
  3. Claude : clé model dans settings.local.json suffit, ou faut-il gérer aussi la clé API Anthropic du profil (SecretRef) pour que le modèle soit réellement joignable ?
  4. Catalogue providers : quels providers exposer pour Codex (lié OpenAI) et Claude (Anthropic) ? Réutiliser provider_catalogue.rs ou catalogue dédié par moteur ?
  5. Sémantique TUI : confirmer qu'aucune CLI n'écrase config.toml/settings au démarrage (risque équivalent au « gate refresh » du ticket #98 côté OpenCode).

7. Périmètre QA — 2 couches (cf. méthodologie #98)

  • Couche 1 (unitaire pure) : le rendu codex_config_toml contient la clé model attendue ; claude_settings_seed contient "model" attendue ; non-régression byte-identique du reste (mcp/sandbox/trust/approval) ; exclusion mutuelle des backends.
  • Couche 2 (intégration gated) : spawn réel codex exec et claude -p sur un profil avec modèle X → assert le modèle actif est X (pas le défaut binaire). Vérifier côté TUI aussi (modèle exposé au lancement). Gate §6.5 à lever.

8. Hors périmètre (exclu de ce ticket)

  • Override runtime du modèle à l'appel (idea_ask_agent porterait un modèle) — autre lot.
  • Providers distants SSH/WSL (ne concerne que le spawn local).
  • Détail de la provider_catalogue au-delà de la réutilisation (fast-follow).

Contexte de mise à jour

  • Cadrage Main après vérification empirique CLI (codex 0.145.0, claude 2.1.220).
  • Lié à #98 (relatesTo) — même famille « modèle au spawn ».
  • Prochaine étape cycle : Architect (valide ports/VO + tranche §6) → Git (branche) → DevBackend (lots A-C) + DevFrontend (lot D) → QA (2 couches) → Git (commit).