//! Content-addressed ontology layer (ADR-028).
//!
//! Two-layer separation: this crate owns the **ontology layer** — every
//! ontology a project consumes (its own self-description, plus any
//! shared-domain ontologies it references) is content-addressed via
//! [`OntologyId`], a blake3 hash over the head OpId chain of the
//! ontology's oplog. Cross-project resolution happens via
//! [`fetch::fetch_cell_witness`] which returns only a witness + state
//! root — never the full state of the foreign ontology.
//!
//! Phase 1 is in-process: the registry maps `OntologyId → local_path` and
//! reads the witness from a local oplog (D28). Real transport (P2P sync
//! per ADR-027) is deferred behind a trigger; when it arrives,
//! `fetch_cell_witness` gains an optional `sync_backend` parameter
//! without breaking the local path.

#![forbid(unsafe_code)]
#![warn(missing_docs)]

pub mod classification;
pub mod extract;
pub mod fetch;
pub mod ontology_id;
pub mod publish;
pub mod registry;
pub mod verify;

pub use classification::OntologyType;
pub use extract::{extract_core_to_oplog, write_ontology_refs, ExtractStats};
pub use fetch::{
    fetch_cell_witness, fetch_ontology, CellQuery, CellWitnessResponse, OntologyHandle,
};
pub use ontology_id::{compute_ontology_id, OntologyId};
pub use publish::publish_op;
pub use registry::{OntologyRegistry, RegistryEntry};
pub use verify::verify_cell;

/// Failures emitted by the content-addressed ontology layer.
#[derive(Debug, thiserror::Error)]
pub enum Error {
    /// The requested ontology id is not registered locally.
    #[error("ontology id '{0}' not in local registry")]
    UnknownOntology(String),

    /// The local oplog could not be opened.
    #[error("opening oplog at '{path}': {source}")]
    OpenOplog {
        /// Filesystem path of the oplog that failed to open.
        path: String,
        /// Underlying oplog error.
        #[source]
        source: ontoref_oplog::Error,
    },

    /// Operation could not be appended to the oplog.
    #[error("appending op: {0}")]
    Append(#[from] ontoref_oplog::Error),

    /// The requested cell has never been asserted in the ontology's
    /// commit layer.
    #[error("cell missing: {0}")]
    CellMissing(#[from] ontoref_commit::Error),

    /// Disk IO failure with operation context.
    #[error("io in {context}: {source}")]
    Io {
        /// Short description of what was being attempted.
        context: String,
        /// Underlying IO error.
        #[source]
        source: std::io::Error,
    },

    /// Registry file could not be parsed.
    #[error("parsing registry '{path}': {message}")]
    RegistryParse {
        /// Filesystem path of the registry that failed to parse.
        path: String,
        /// Human-readable parse error.
        message: String,
    },
}

/// Result alias for this crate.
pub type Result<T> = std::result::Result<T, Error>;
