feat(backend): domaine + catalogue et store durable des permissions tools MCP (#82 lot B1)

Introduit le domaine mcp_tool_permissions (règles de permission par tool
MCP) et étend le port de store correspondant. Le catalogue read/write des
tools MCP (orchestrator/mcp/tools.rs) s'appuie désormais sur ces règles, et
un store durable (mcp_tool_permission.rs) persiste les permissions au-delà
d'une session.

Lot B1 du ticket #82 : pose le socle domaine/store, l'enforcement suit en
B2 sur la même branche.

QA vert.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-18 22:45:32 +02:00
parent 32408b5232
commit 5175589aa5
8 changed files with 721 additions and 11 deletions

View File

@ -43,6 +43,7 @@ use crate::issue::{
Issue, IssueCarnet, IssueIndexEntry, IssueListFilter, IssueNumber, IssueRef, IssueVersion,
};
use crate::markdown::MarkdownDoc;
use crate::mcp_tool_permissions::ProjectMcpToolPermissions;
use crate::memory::{Memory, MemoryIndexEntry, MemoryLink, MemorySlug};
use crate::model_server::{
HfModelRef, LocalModelServerConfig, ModelPath, ModelServerEndpoint, ModelServerStatus,
@ -1791,6 +1792,33 @@ pub trait PermissionStore: Send + Sync {
) -> Result<(), StoreError>;
}
/// Reads/writes a project's `.ideai/mcp-tool-permissions.json`.
///
/// This is intentionally distinct from [`PermissionStore`]: it governs IdeA MCP
/// application tools, not filesystem/process/sandbox capabilities.
#[async_trait]
pub trait McpToolPermissionStore: Send + Sync {
/// Loads the project's MCP tool permission document. Missing file returns the
/// default empty document.
///
/// # Errors
/// [`StoreError`] on I/O, deserialisation, or validation failure.
async fn load_mcp_tool_permissions(
&self,
project: &Project,
) -> Result<ProjectMcpToolPermissions, StoreError>;
/// Saves the project's MCP tool permission document.
///
/// # Errors
/// [`StoreError`] on I/O, serialisation, or validation failure.
async fn save_mcp_tool_permissions(
&self,
project: &Project,
permissions: &ProjectMcpToolPermissions,
) -> Result<(), StoreError>;
}
/// Persistence port for first-class background tasks.
#[async_trait]
pub trait BackgroundTaskStore: Send + Sync {