Skip to main content

rskit_skill/
verification.rs

1//! Manifest verification contracts and built-in verification policies.
2
3use std::path::Path;
4
5use crate::{Manifest, SkillError};
6
7/// Verification result.
8#[derive(Debug, Clone, PartialEq, Eq)]
9#[non_exhaustive]
10pub enum VerificationOutcome {
11    /// Verification passed.
12    Verified,
13    /// Verification emitted warnings and registration may continue.
14    Warning(Vec<String>),
15    /// Verification denied registration.
16    Denied(String),
17}
18
19/// Verifier for manifest signatures.
20pub trait Verifier: Send + Sync {
21    /// Verify a manifest at load time.
22    fn verify(&self, manifest: &Manifest, root: &Path) -> Result<VerificationOutcome, SkillError>;
23}
24
25/// Default warn-only verifier.
26#[derive(Debug, Default, Clone, Copy)]
27pub struct WarnOnlyVerifier;
28
29impl Verifier for WarnOnlyVerifier {
30    fn verify(&self, manifest: &Manifest, _root: &Path) -> Result<VerificationOutcome, SkillError> {
31        if manifest.signature.is_some() {
32            Ok(VerificationOutcome::Verified)
33        } else {
34            Ok(VerificationOutcome::Warning(vec![
35                "unsigned skill manifest".to_string(),
36            ]))
37        }
38    }
39}
40
41/// `DenyVerifier` is the canonical operator-deny verifier: it rejects every manifest unconditionally.
42/// Use it as a safe default until a real signature verifier (e.g., Sigstore/cosign) adapter is wired in.
43#[derive(Debug, Default, Clone, Copy)]
44pub struct DenyVerifier;
45
46impl Verifier for DenyVerifier {
47    fn verify(
48        &self,
49        _manifest: &Manifest,
50        _root: &Path,
51    ) -> Result<VerificationOutcome, SkillError> {
52        Ok(VerificationOutcome::Denied(
53            "deny verifier: signatures rejected".to_string(),
54        ))
55    }
56}