//! The target-classification port. //! //! A [`TargetClassifier`] inspects a target's artifacts (and optionally their //! ingested working directories) and proposes one or more [`ClassifierVerdict`]s //! — a target type, a confidence, and the facts the decision rested on. Concrete //! classifiers live in the agent (language/build-system fingerprinting, a //! firmware detector backed by tramiton, etc.); a registry merges and ranks //! their verdicts. This mirrors the [`crate::traits::Scanner`] port so the two //! read the same way. use std::collections::HashMap; use std::path::PathBuf; use crate::error::CoreError; use crate::models::{Artifact, DetectedFact, TargetType}; /// Everything a classifier needs to reason about a target. pub struct ClassificationInput<'a> { /// The artifacts declared for the target. pub artifacts: &'a [Artifact], /// Ingested working paths, keyed by [`Artifact::id`]. Absent for artifacts /// with no on-disk form (e.g. a live URL). pub working_paths: &'a HashMap, /// Free-form description of the target, if provided. pub description: Option<&'a str>, } /// A single classifier's proposal for a target. pub struct ClassifierVerdict { /// The proposed target type. pub target_type: TargetType, /// Confidence in `[0.0, 1.0]`. pub confidence: f32, /// Facts that informed the proposal. pub facts: Vec, /// Human-readable explanation. pub rationale: String, } /// A source of target-type classification. #[allow(async_fn_in_trait)] pub trait TargetClassifier: Send + Sync { /// Stable identifier for this classifier (recorded in `detected_by`). fn name(&self) -> &str; /// Propose zero or more ranked verdicts for the given input. async fn classify( &self, input: &ClassificationInput<'_>, ) -> Result, CoreError>; }