feat(orchestrator): modèle de désignation d'orchestrateur + sink de diagnostic
Introduit le modèle AgentManifest { version, entries, orchestrator } et la
garde d'écriture directe may_write_directly(..., &OrchestratorDesignation) :
seul l'orchestrateur désigné peut écrire directement, les autres passent par
le rendez-vous médié. Câble la désignation à travers domain → application →
infrastructure → app-tauri (context_guard, service, lifecycle, ports).
Ajoute crates/application/src/diag.rs : sink de diagnostic best-effort, sans
dépendance, qui miroite les traces du rendez-vous inter-agents de
l'orchestrateur vers un fichier de log persistant (utile au lancement via
AppImage où stderr est jeté), avec la même discipline « zéro dépendance,
ne casse jamais le rendez-vous ».
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -122,6 +122,8 @@ pub struct CodexExecSession {
|
||||
command: String,
|
||||
/// Répertoire de travail (run dir isolé §14.1).
|
||||
cwd: String,
|
||||
/// Project/workspace roots that must be writable in Codex's CLI sandbox.
|
||||
writable_roots: Vec<String>,
|
||||
/// Id de conversation **du moteur** Codex, capté au premier tour, `None` avant.
|
||||
conversation_id: Mutex<Option<String>>,
|
||||
/// Plan de sandbox OS **par lancement** (lot LP4-4), porté dans chaque
|
||||
@ -143,6 +145,7 @@ impl CodexExecSession {
|
||||
command: impl Into<String>,
|
||||
cwd: impl Into<String>,
|
||||
seed_conversation_id: Option<String>,
|
||||
writable_roots: Vec<String>,
|
||||
sandbox: Option<SandboxPlan>,
|
||||
sandbox_enforcer: Option<Arc<dyn SandboxEnforcer>>,
|
||||
) -> Self {
|
||||
@ -150,6 +153,7 @@ impl CodexExecSession {
|
||||
id,
|
||||
command: command.into(),
|
||||
cwd: cwd.into(),
|
||||
writable_roots,
|
||||
conversation_id: Mutex::new(seed_conversation_id),
|
||||
sandbox,
|
||||
sandbox_enforcer,
|
||||
@ -160,18 +164,18 @@ impl CodexExecSession {
|
||||
///
|
||||
/// Format RÉEL vérifié 2026-06-10 (codex 0.137.0) :
|
||||
/// - Conversation neuve : `codex exec --json --skip-git-repo-check
|
||||
/// --sandbox workspace-write <prompt>`.
|
||||
/// --sandbox workspace-write --add-dir <project-root> <prompt>`.
|
||||
/// - Reprise (id connu) : `codex exec resume <thread_id> --json
|
||||
/// --skip-git-repo-check --sandbox workspace-write <prompt>`.
|
||||
/// --skip-git-repo-check --sandbox workspace-write --add-dir <project-root>
|
||||
/// <prompt>`.
|
||||
///
|
||||
/// **Autonomie d'écriture (D3)** : `--sandbox workspace-write` autorise l'agent à
|
||||
/// écrire dans son workspace. `codex exec` est déjà non-interactif (aucun prompt
|
||||
/// d'approbation possible), donc on ne passe **pas** `--ask-for-approval` : ce flag
|
||||
/// appartient à la commande interactive `codex`, pas à la sous-commande `exec` qui
|
||||
/// sort sur `error: unexpected argument '--ask-for-approval' found`. Défaut
|
||||
/// raisonnable, aligné sur l'autonomie projet (CLAUDE.md §12) ; à terme **piloté par
|
||||
/// les permissions de l'agent** (`.ideai/permissions.json` + sandbox OS) — non
|
||||
/// implémenté ici.
|
||||
/// sort sur `error: unexpected argument '--ask-for-approval' found`. Comme l'agent
|
||||
/// tourne depuis son run dir isolé, `--add-dir` expose explicitement le project root
|
||||
/// à la sandbox Codex pour que les écritures Git touchent le vrai workspace.
|
||||
fn build_spawn_line(&self, prompt: &str) -> SpawnLine {
|
||||
let mut args = vec!["exec".to_owned()];
|
||||
if let Some(id) = self.conversation_id.lock().expect("mutex sain").as_ref() {
|
||||
@ -182,6 +186,10 @@ impl CodexExecSession {
|
||||
args.push("--skip-git-repo-check".to_owned());
|
||||
args.push("--sandbox".to_owned());
|
||||
args.push("workspace-write".to_owned());
|
||||
for root in self.writable_roots.iter().filter(|root| !root.is_empty()) {
|
||||
args.push("--add-dir".to_owned());
|
||||
args.push(root.clone());
|
||||
}
|
||||
args.push(prompt.to_owned());
|
||||
SpawnLine {
|
||||
command: self.command.clone(),
|
||||
|
||||
Reference in New Issue
Block a user