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>
129 lines
8.0 KiB
Markdown
129 lines
8.0 KiB
Markdown
---
|
|
issueRef: "#99"
|
|
version: 4
|
|
updatedBy: {"kind":"user"}
|
|
updatedAt: 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 config** — `codex_config_toml` écrit `model` (+ `model_provider` si requis
|
|
par la sémantique codex) ; `claude_settings_seed` écrit la clé `model`.
|
|
- **C. Use cases / persistance** — `SaveCodexProviderProfile` / `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).
|