cordance-core 0.1.0

Cordance core types, schemas, and ports. No I/O.
Documentation
//! Cordance core: types, schemas, ports. No I/O.
//!
//! Doctrine alignment:
//! - `modularity-and-ports-adapters.md`: ports here, adapters elsewhere.
//! - `event-contracts.md`: every emitted artifact has a versioned `schema` tag.
//! - `single-source-of-truth.md`: serde structs are the single source of truth
//!   for on-disk shapes; the JSON schemas in `/contracts/` are generated from
//!   these structs and round-trip-tested.

#![forbid(unsafe_code)]
#![deny(clippy::unwrap_used, clippy::expect_used)]
#![cfg_attr(test, allow(clippy::expect_used, clippy::unwrap_used))]

pub mod advise;
pub mod evidence;
pub mod fence;
pub mod fs;
pub mod harness_target;
pub mod lock;
pub mod pack;
pub mod paths;
pub mod receipt;
pub mod source;

pub use advise::{AdviseFinding, AdviseReport, Severity};
pub use evidence::{EvidenceEntry, EvidenceMap, EvidenceSource, OutputEvidence};
pub use fence::{
    find_regions, replace_region, replace_regions, sanitise_fenced_value, FenceError,
    FenceMarker, FencedRegion,
};
// Round-6 codereview-3 / Round-7 codereview-3: re-export the symlink-refusal
// helpers and error type at the crate root so downstream callers can write
// `use cordance_core::SymlinkRefusal` instead of the longer
// `cordance_core::fs::SymlinkRefusal`. The error type is what
// `safe_write`/`safe_write_with_mkdir` wrap inside `std::io::Error::other`,
// and callers typed-downcast against it; the inconsistent re-export shape
// was an ergonomic trap that pushed `cordance-emit`'s integration test into
// string-scraping the error message instead of typed matching.
pub use fs::{safe_write, safe_write_with_mkdir, SymlinkRefusal};
pub use harness_target::{
    AccessMode, AuthoritySurfaces, AxiomProjectHarnessTargetV1, ClaimCeiling, HarnessBlock,
    HarnessClassification, HarnessInvariantError, HarnessOperations, ProjectBlock,
};
pub use lock::{DriftReport, OutputDriftEntry, SourceDriftEntry, SourceLock, SourceLockEntry};
pub use pack::{CordancePack, PackOutput, PackTargets, ProjectIdentity};
pub use receipt::{
    AuthorityBoundary, CortexReceiptV1Candidate, ReceiptBody, ReceiptInvariantError,
    SourceAnchor, TruthCeiling,
};
pub use source::{SourceClass, SourceRecord, SurfaceCategory};

/// Schema versions emitted by this crate. Never mutate; add a new constant.
pub mod schema {
    pub const CORDANCE_PACK_V1: &str = "cordance-pack.v1";
    pub const CORDANCE_SOURCE_LOCK_V1: &str = "cordance-source-lock.v1";
    pub const CORDANCE_ADVISE_REPORT_V1: &str = "cordance-advise-report.v1";
    pub const CORDANCE_CORTEX_RECEIPT_V1_CANDIDATE: &str =
        "cordance-cortex-receipt-v1-candidate";
    pub const CORDANCE_EVIDENCE_MAP_V1: &str = "cordance-evidence-map.v1";
    pub const AXIOM_PROJECT_HARNESS_TARGET_V1: &str = "pai-axiom-project-harness-target.v1";
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn schema_constants_present() {
        // Verify the constants have the expected name prefix (not vacuous).
        assert!(schema::CORDANCE_PACK_V1.starts_with("cordance-"));
        assert!(schema::CORDANCE_CORTEX_RECEIPT_V1_CANDIDATE.starts_with("cordance-"));
    }
}