corpora-core 0.1.0

Core domain types, immutable graph, and event bus for the corpora docs validator.
Documentation
//! The one impure dependency the rule pack needs: resolving VCS revisions. The trait lives
//! in core so rules can depend on it; the git-backed implementation is in `corpora-engine`
//! (it does IO). Inject a [`NullOracle`] in tests to keep rules pure-testable.

use crate::model::Rev;

/// Why an oracle can or can't verify revisions — lets Gate B distinguish an intentional
/// no-op (`Disabled`) and a repo-less corpus (`NoRepo`, skip) from a real misconfiguration
/// (`Unavailable`, e.g. git missing), rather than failing open silently for all three.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum OracleStatus {
    /// No verification backend at all (e.g. [`NullOracle`]); gates skip silently.
    Disabled,
    /// Backend present but unusable (e.g. the `git` binary is missing) — a misconfiguration.
    Unavailable,
    /// Backend present, but there's no repository here — nothing to verify against.
    NoRepo,
    /// Ready to resolve revisions.
    Ready,
}

pub trait RevisionOracle {
    /// Whether — and why — this oracle can verify revisions right now.
    fn status(&self) -> OracleStatus;
    /// Resolve a revision (sha / ref) to a canonical commit, or `None` if it doesn't exist.
    fn resolve(&self, r: &Rev) -> Option<Rev>;
}

/// No-VCS oracle: a deliberate no-op. Gates that need revision context skip silently.
pub struct NullOracle;

impl RevisionOracle for NullOracle {
    fn status(&self) -> OracleStatus {
        OracleStatus::Disabled
    }

    fn resolve(&self, _r: &Rev) -> Option<Rev> {
        None
    }
}