Skip to main content

ferrify_domain/
provenance.rs

1//! Provenance labels for inputs observed during a Ferrify run.
2//!
3//! The central question here is not only "what did Ferrify read?" but also
4//! "what role is that input allowed to play?" [`InputRole`] captures that
5//! distinction so repository policy, operator goals, source code, evidence, and
6//! untrusted text do not collapse into a single undifferentiated blob.
7
8use serde::{Deserialize, Serialize};
9
10use crate::TrustLevel;
11
12/// The operational role an input plays in Ferrify.
13#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
14pub enum InputRole {
15    /// The direct task intent from the operator.
16    Goal,
17    /// Repository or platform policy that can constrain execution.
18    Policy,
19    /// Source code or manifests from the workspace.
20    Code,
21    /// Verification output and other execution evidence.
22    Evidence,
23    /// Text from tools or external sources that must not change authority.
24    UntrustedText,
25}
26
27impl InputRole {
28    /// Returns whether this role is allowed to influence authority decisions.
29    #[must_use]
30    pub fn can_define_authority(self) -> bool {
31        matches!(self, Self::Goal | Self::Policy)
32    }
33}
34
35/// A lightweight provenance record for an input observed during a run.
36#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
37pub struct ClassifiedInput {
38    /// The operational role attached to the input.
39    pub role: InputRole,
40    /// Where the input came from.
41    pub source: String,
42    /// A concise summary of how the input is used.
43    pub summary: String,
44    /// The trust level attached to the input source.
45    pub trust_level: TrustLevel,
46}
47
48#[cfg(test)]
49mod tests {
50    use super::InputRole;
51
52    #[test]
53    fn only_goal_and_policy_define_authority() {
54        assert!(InputRole::Goal.can_define_authority());
55        assert!(InputRole::Policy.can_define_authority());
56        assert!(!InputRole::Code.can_define_authority());
57        assert!(!InputRole::Evidence.can_define_authority());
58        assert!(!InputRole::UntrustedText.can_define_authority());
59    }
60}