Skip to main content

ferrify_domain/
policy.rs

1//! Policy, trust, and capability types.
2//!
3//! Ferrify treats policy as first-class data. The types in this module describe
4//! where a rule came from, what level of trust an input carries, which
5//! capabilities a stage may request, and which verification/reporting
6//! constraints survive into the final run.
7
8use std::collections::{BTreeMap, BTreeSet};
9
10use serde::{Deserialize, Serialize};
11
12use crate::{RepoPath, VerificationKind};
13
14/// The precedence layer that introduced a policy fragment.
15#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
16pub enum PolicyLayer {
17    /// Hardcoded platform invariants.
18    Core,
19    /// Organization-wide policy.
20    Org,
21    /// Repository-level policy.
22    Repo,
23    /// Path-scoped policy.
24    Path,
25    /// Mode-specific policy.
26    Mode,
27    /// Task-local constraints.
28    Task,
29}
30
31/// The trust classification attached to inputs and observations.
32#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
33pub enum TrustLevel {
34    /// Built-in platform guidance.
35    System,
36    /// Repository policy files.
37    RepoPolicy,
38    /// Source code and manifests from the workspace.
39    RepoCode,
40    /// The direct user request for the active task.
41    UserTask,
42    /// Tool output captured during execution.
43    ToolOutput,
44    /// External text such as issue descriptions or web pages.
45    ExternalText,
46}
47
48impl TrustLevel {
49    /// Returns whether this trust level is allowed to define or widen policy.
50    #[must_use]
51    pub fn can_define_policy(self) -> bool {
52        matches!(self, Self::System | Self::RepoPolicy | Self::UserTask)
53    }
54}
55
56/// A capability that can be granted, denied, or approval-gated.
57#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
58pub enum Capability {
59    /// Read files within the workspace.
60    ReadWorkspace,
61    /// Edit files within the workspace.
62    EditWorkspace,
63    /// Run verification commands such as `cargo check`.
64    RunChecks,
65    /// Run ad hoc commands outside the verification plan.
66    RunArbitraryCommand,
67    /// Delete files from the workspace.
68    DeleteFiles,
69    /// Reach the network.
70    NetworkAccess,
71    /// Call an MCP server by identifier.
72    UseMcpServer(String),
73    /// Transition between execution modes.
74    SwitchMode,
75}
76
77/// The approval policy attached to a capability.
78#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
79pub enum ApprovalRule {
80    /// The capability can be used without approval.
81    Allow,
82    /// The capability requires explicit approval.
83    Ask,
84    /// The capability requires approval when the action is risky.
85    AskIfRisky,
86    /// The capability is not allowed.
87    Deny,
88}
89
90/// A repository-relative path restriction.
91#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
92pub struct PathPattern(pub RepoPath);
93
94/// The repository stance on dependency changes.
95#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
96pub enum DependencyPolicy {
97    /// Dependency additions are denied unless a policy layer approves them.
98    Frozen,
99    /// Dependency additions are allowed with explicit approval.
100    #[default]
101    AllowApproved,
102    /// Dependency additions are broadly allowed.
103    Flexible,
104}
105
106/// Reporting rules that constrain what the runtime may claim.
107#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
108pub struct ReportingPolicy {
109    /// Whether the runtime may claim a fix without test evidence.
110    pub may_claim_fix_without_tests: bool,
111}
112
113/// Minimum verification requirements imposed by policy.
114#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
115pub struct ValidationMinimums {
116    /// Verification steps that must run before the report is complete.
117    #[serde(default)]
118    pub must_run: BTreeSet<VerificationKind>,
119}
120
121/// The fully resolved policy used by a run.
122#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
123pub struct EffectivePolicy {
124    /// Capabilities the current mode is allowed to attempt.
125    pub allowed_capabilities: BTreeSet<Capability>,
126    /// Approval rules attached to individual capabilities.
127    pub approval_rules: BTreeMap<Capability, ApprovalRule>,
128    /// Workspace paths that must remain untouched.
129    pub forbidden_paths: Vec<PathPattern>,
130    /// Dependency modification policy.
131    pub dependency_policy: DependencyPolicy,
132    /// Reporting constraints for the final report.
133    pub reporting_policy: ReportingPolicy,
134    /// Verification minimums enforced by policy.
135    pub validation_minimums: ValidationMinimums,
136}