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>
8.0 KiB
issueRef, version, updatedBy, updatedAt
| issueRef | version | updatedBy | updatedAt | ||
|---|---|---|---|---|---|
| #99 | 4 |
|
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
--helpest-c model="o3".config.tomlest chargé depuis$CODEX_HOME/config.toml. - Honorée par
codex(TUI) ETcodex exec(headless) — même mécanisme de base (--ignore-user-configconfirme qu'il est chargé par défaut). - Bonus :
codex execaccepte aussi-m, --model <MODEL>(seconde porte d'injection). - → Écrire
model = "..."dans le$CODEX_HOME/config.tomlisolé 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.jsondu 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 }etClaudeProviderConfig { 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éutiliserAgentProfile.model(voir §6). - B. Renderers de config —
codex_config_tomlécritmodel(+model_providersi requis par la sémantique codex) ;claude_settings_seedécrit la clémodel. - C. Use cases / persistance —
SaveCodexProviderProfile/SaveClaudeProviderProfilemiroirs deSaveOpenCodeProviderProfile, 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. /modelen 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.jsonbyte-identique (rien ne touche ce chemin). - Non-régression permissions :
codex_config_tomletclaude_settings_seedcontinuent d'écriremcp/sandbox/trust/approvalcomme aujourd'hui (lemodels'ajoute).
6. Questions ouvertes pour Architect (à trancher avant DevBackend)
- VO : créer
CodexProviderConfig/ClaudeProviderConfig(homogène à OpenCode) ou consommer le champ existantAgentProfile.model(code mort) ? Recommandation Main : nouveaux VO pour rester isomorphe à OpenCode (provider + clé scellée), déprécierAgentProfile.model. - Codex
model_provider: la config codex distinguemodeletmodel_provider. Faut-il exposer les deux au profil, oumodelseul suffit (provider implicite) ? - Claude : clé
modeldanssettings.local.jsonsuffit, ou faut-il gérer aussi la clé API Anthropic du profil (SecretRef) pour que le modèle soit réellement joignable ? - Catalogue providers : quels providers exposer pour Codex (lié OpenAI) et Claude
(Anthropic) ? Réutiliser
provider_catalogue.rsou catalogue dédié par moteur ? - Sémantique TUI : confirmer qu'aucune CLI n'écrase
config.toml/settingsau 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_tomlcontient la clémodelattendue ;claude_settings_seedcontient"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 execetclaude -psur 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_agentporterait un modèle) — autre lot. - Providers distants SSH/WSL (ne concerne que le spawn local).
- Détail de la
provider_catalogueau-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).