Skip to main content

termivar_scanner/
contracts.rs

1//! Stable data and execution contracts shared by scanner components.
2//!
3//! ## Runtime scope
4//!
5//! - **Build:** non-default `legacy-scanner` feature.
6//! - **Execution:** Surface A contract used by the historical `ScanRunner`.
7//! - **Default `termivar scan`:** no.
8//! - **Support:** legacy alpha.
9//!
10//! See `docs/internals/runtime-map.md`.
11
12use crate::{context::ScanContext, error::Result};
13use async_trait::async_trait;
14pub use termivar_core::ScanFinding;
15
16/// Minimal execution contract understood by the scan runner.
17///
18/// Implementations contain detection logic only. Scheduling, cancellation,
19/// event publication, and aggregation remain runner responsibilities.
20///
21/// Implementations must structurally own any child work they start. Dropping
22/// the future returned by [`ScanPhase::execute`] must stop its child requests
23/// and shared-state mutations; detached tasks violate this contract. The
24/// runner structurally owns and can drop only the outer `execute` future. Its
25/// panic boundary likewise covers only panics that unwind while polling that
26/// future, not detached work or `panic = "abort"` builds.
27///
28/// # Examples
29///
30/// ```
31/// use async_trait::async_trait;
32/// use termivar_scanner::{Result, ScanContext, ScanFinding, ScanPhase};
33///
34/// struct HeaderPhase;
35///
36/// #[async_trait]
37/// impl ScanPhase for HeaderPhase {
38///     fn phase_number(&self) -> u8 { 10 }
39///     fn name(&self) -> &'static str { "header-check" }
40///
41///     async fn execute(&self, _ctx: &ScanContext) -> Result<Vec<ScanFinding>> {
42///         Ok(Vec::new())
43///     }
44/// }
45/// ```
46#[async_trait]
47pub trait ScanPhase: Send + Sync {
48    /// Phase number used to order the pipeline.
49    fn phase_number(&self) -> u8;
50
51    /// Human-readable phase name used in logs and events.
52    fn name(&self) -> &'static str;
53
54    /// Execute phase logic and return structured findings.
55    async fn execute(&self, ctx: &ScanContext) -> Result<Vec<ScanFinding>>;
56}