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:
2026-06-15 20:39:18 +02:00
parent 46492506e1
commit 27597eb64e
41 changed files with 6513 additions and 269 deletions

View File

@ -84,6 +84,67 @@ export interface GatewayError {
message: string;
}
// ---------------------------------------------------------------------------
// Permissions (LP1)
// ---------------------------------------------------------------------------
/** Agent capability governed by IdeA permissions. */
export type Capability = "read" | "write" | "delete" | "executeBash";
/** Permission rule verdict. */
export type PermissionEffect = "allow" | "deny";
/** Fallback stance when no permission rule matches. */
export type PermissionPosture = "ask" | "allow" | "deny";
/** Glob path scope, relative to the project root. */
export type PathScope = string[];
/** Shell command matcher. */
export type CommandMatcher =
| { kind: "exact"; value: string }
| { kind: "prefix"; value: string }
| { kind: "glob"; value: string };
/** Per-command bash verdict. */
export interface CommandRule {
matcher: CommandMatcher;
effect: PermissionEffect;
}
/** One permission rule. */
export interface PermissionRule {
capability: Capability;
effect: PermissionEffect;
paths?: PathScope;
commands?: CommandRule[];
}
/** Permission policy bundle. */
export interface PermissionSet {
rules: PermissionRule[];
fallback: PermissionPosture;
}
/** One sparse agent override in `.ideai/permissions.json`. */
export interface AgentPermissionOverride {
agentId: string;
permissions: PermissionSet;
}
/** Full project permission document. */
export interface ProjectPermissions {
version: number;
projectDefaults?: PermissionSet;
agents?: AgentPermissionOverride[];
}
/** Effective project+agent policy. */
export interface EffectivePermissions {
rules: PermissionRule[];
fallback: PermissionPosture;
}
// ---------------------------------------------------------------------------
// Layout (L4) — mirror of the domain `LayoutTree` (ARCHITECTURE §3, §7).
// ---------------------------------------------------------------------------