fix(#108): restreint Code Mode Codex au namespace MCP IdeA et documente les tools au démarrage

Codex Code Mode pouvait appeler n'importe quel outil MCP directement,
contournant la médiation d'approbation. On force
[features.code_mode].direct_only_tool_namespaces = ["mcp__idea"] sur
chaque surface qui écrit le config.toml Codex (permission projector,
lifecycle, migration run-dir, assistant de ticket), et on ajoute
initialize.instructions côté serveur MCP pour orienter Codex vers le
bon outil idea_* dès la connexion, sans dépendre de la recherche
sémantique différée.

QA : domain 283/0, application 126/0 + agent_lifecycle 73/0 +
change_agent_profile 19/0 + ticket_assistant 5/0, infrastructure 339/0
dont mcp_server 37/0, backend 68/0 (7 ignored). Les échecs web-server
observés sur cargo test --workspace (Too many open files, cookies)
sont une contamination de ressources inter-tests ; les deux tests
concernés repassent isolément.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-29 22:51:38 +02:00
parent af6b76935c
commit d0b65a92bd
9 changed files with 228 additions and 32 deletions

View File

@ -10,6 +10,15 @@ use crate::error::DomainError;
use crate::ids::{LocalModelServerId, ProfileId};
use crate::permission::ProjectorKey;
/// Codex feature table managed by IdeA to restrict Code Mode direct tool calls
/// to the local IdeA MCP namespace.
pub const CODEX_CODE_MODE_FEATURES_TABLE: &str = "features.code_mode";
/// TOML block injected in Codex `config.toml` so Code Mode can call IdeA MCP
/// tools directly while every other namespace stays mediated by Codex.
pub const CODEX_CODE_MODE_FEATURES_TOML: &str =
"[features.code_mode]\ndirect_only_tool_namespaces = [\"mcp__idea\"]\n";
/// Strategy for injecting an agent's `.md` context into the launched CLI.
///
/// Invariants:
@ -803,7 +812,7 @@ impl McpServerWiring {
let transport = self.transport_label();
let tool_timeout_sec = Self::IDEA_TOOL_TIMEOUT_SEC;
format!(
"[mcp_servers.idea]\ncommand = {command}\nargs = [{args}]\ntransport = \"{transport}\"\ndefault_tools_approval_mode = \"approve\"\ntool_timeout_sec = {tool_timeout_sec}\n"
"[mcp_servers.idea]\ncommand = {command}\nargs = [{args}]\ntransport = \"{transport}\"\ndefault_tools_approval_mode = \"approve\"\ntool_timeout_sec = {tool_timeout_sec}\n\n{CODEX_CODE_MODE_FEATURES_TOML}"
)
}
}
@ -2129,6 +2138,10 @@ mod mcp_tests {
toml.contains("tool_timeout_sec = 86400"),
"IdeA MCP tools must outlive Codex's short default tool timeout; got: {toml}"
);
assert!(
toml.contains("[features.code_mode]\ndirect_only_tool_namespaces = [\"mcp__idea\"]"),
"Code Mode direct tools must be restricted to IdeA MCP; got: {toml}"
);
}
// -- §21 : rate_limit_pattern (détection de limite par motif, niveau 2) ------