feat(permissions): voie projection CLI (LP0→LP3) + checkpoint Codex/input
Jalon vert regroupant deux chantiers entrelacés dans le working tree, indissociables au niveau fichier mais tous deux verts (cargo test --workspace + tests frontend permissions au vert). Permissions — voie « projection CLI » (advisory), complète : - LP0 domaine pur : modèle PermissionSet/EffectivePermissions, resolve deny-wins + postures Allow<Ask<Deny (crates/domain/src/permission.rs). - LP1 store : FsPermissionStore (.ideai/permissions.json). - LP2 use cases : Get/Update project, Update agent override, Resolve. - LP3 projecteurs Claude/Codex (settings.local.json / config.toml), câblage launch-path + PermissionProjectorRegistry, nettoyage des fichiers Replace orphelins au swap de profil (LP3-4), composition root + commandes Tauri, UI PermissionsPanel (projet + override agent). - ports.rs : PermissionStore + FileSystem::remove_file (cleanup au swap). Reste ouvert (hors scope, marqué dans le code) : LP4 enforcement OS airtight (Landlock fichiers) + résumé de permissions injecté. Inclut aussi le chantier Codex/input/sessions structurées en cours (McpConfigStrategy, StructuredAdapter, gestion d'input) partageant les mêmes fichiers (lifecycle.rs, commands.rs, dto.rs, state.rs). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
46
crates/infrastructure/src/permission/mod.rs
Normal file
46
crates/infrastructure/src/permission/mod.rs
Normal file
@ -0,0 +1,46 @@
|
||||
//! Per-CLI **permission projectors** (lot LP3-2).
|
||||
//!
|
||||
//! Concrete implementations of the domain port
|
||||
//! [`domain::permission::PermissionProjector`]: they translate the resolved
|
||||
//! [`domain::permission::EffectivePermissions`] into a CLI-specific
|
||||
//! [`domain::permission::PermissionProjection`] — a **plan** (files + args + env),
|
||||
//! never an action. Writing/merging the plan into the agent run dir is the launch
|
||||
//! path's job (lot LP3-3); the projectors here stay **pure** (no `FileSystem`, no
|
||||
//! I/O), exactly like the domain trait demands.
|
||||
//!
|
||||
//! This is an **extraction**: the translation rules (postures → allow/deny/ask
|
||||
//! lists for Claude, posture → sandbox/approval modes for Codex) are moved here
|
||||
//! verbatim from `application/src/agent/lifecycle.rs`, only reshaped to return a
|
||||
//! `PermissionProjection`. The rules themselves are unchanged.
|
||||
|
||||
mod claude;
|
||||
mod codex;
|
||||
|
||||
pub use claude::ClaudePermissionProjector;
|
||||
pub use codex::CodexPermissionProjector;
|
||||
|
||||
/// Minimal JSON string escaper for embedding a filesystem path / permission entry
|
||||
/// in a settings document (handles the characters that actually occur in paths:
|
||||
/// backslash, quote, control chars). Extracted verbatim from `lifecycle.rs`.
|
||||
pub(crate) fn json_escape(s: &str) -> String {
|
||||
let mut out = String::with_capacity(s.len());
|
||||
for c in s.chars() {
|
||||
match c {
|
||||
'"' => out.push_str("\\\""),
|
||||
'\\' => out.push_str("\\\\"),
|
||||
'\n' => out.push_str("\\n"),
|
||||
'\r' => out.push_str("\\r"),
|
||||
'\t' => out.push_str("\\t"),
|
||||
c if (c as u32) < 0x20 => out.push_str(&format!("\\u{:04x}", c as u32)),
|
||||
c => out.push(c),
|
||||
}
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
/// Escapes `s` as a TOML basic string (quotes included). The escape set required
|
||||
/// by a TOML basic string coincides with JSON's for the characters that concern
|
||||
/// us (paths, mode keywords). Extracted verbatim from `lifecycle.rs`.
|
||||
pub(crate) fn toml_string(s: &str) -> String {
|
||||
format!("\"{}\"", json_escape(s))
|
||||
}
|
||||
Reference in New Issue
Block a user