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
42/// manifest unconditionally. Use it as a safe default until a real signature
43/// verifier (e.g., Sigstore/cosign) adapter is wired in.
44#[derive(Debug, Default, Clone, Copy)]
45pub struct DenyVerifier;
46
47impl Verifier for DenyVerifier {
48    fn verify(
49        &self,
50        _manifest: &Manifest,
51        _root: &Path,
52    ) -> Result<VerificationOutcome, SkillError> {
53        Ok(VerificationOutcome::Denied(
54            "deny verifier: signatures rejected".to_string(),
55        ))
56    }
57}