From b7c16717be1baa3c9486047bb610e2ff90f9ef05 Mon Sep 17 00:00:00 2001 From: Oleh Martsokha Date: Mon, 27 Jul 2026 22:11:32 +0200 Subject: [PATCH] Re-export schema types from nvisy-engine Fold nvisy_schema's modules into nvisy-engine's public surface so SDK consumers depending only on nvisy-engine can name every type its public API accepts or returns: - Widen schema's `entity`, `modality`, and `primitive` modules to cover the full elide-core slice callers reach through Entity, RecognizedGroup variants, and Scope. - Add `FormatRegistry` at engine's root (leaks through Engine::formats). - Drop elide-bento's root re-exports of BentoNer/BentoOcr; update the two engine consumers to use the module paths. - Unify module-level doc summaries across schema + engine so the rendered first line is a consistent noun phrase. Override the `policy` re-export's docstring so it no longer picks up the target crate's H1. - Convert all remaining inline rustdoc `[text](path)` links to reference form. Co-Authored-By: Claude Opus 4.7 --- crates/elide-bento/src/lib.rs | 5 ---- crates/elide-bento/src/ner/mod.rs | 4 ++- crates/elide-bento/src/ocr/mod.rs | 3 +- .../nvisy-engine/src/analyzer/enricher/ocr.rs | 2 +- .../src/analyzer/recognizer/ner.rs | 2 +- .../src/analyzer/recognizer/pattern.rs | 6 ++-- crates/nvisy-engine/src/lib.rs | 10 +++++-- crates/nvisy-engine/src/pipeline/analyzed.rs | 5 ++-- .../nvisy-engine/src/provider/llm/prompt.rs | 6 ++-- crates/nvisy-policy/src/action/mod.rs | 10 +++---- crates/nvisy-policy/src/rule.rs | 28 ++++++++++--------- crates/nvisy-schema/src/annotation.rs | 3 +- crates/nvisy-schema/src/entity.rs | 18 +++++++----- crates/nvisy-schema/src/lib.rs | 3 ++ crates/nvisy-schema/src/modality.rs | 15 +++++++--- crates/nvisy-schema/src/plan/label.rs | 21 +++++++------- crates/nvisy-schema/src/plan/mod.rs | 16 +++++------ crates/nvisy-schema/src/primitive.rs | 13 +++++---- 18 files changed, 97 insertions(+), 73 deletions(-) diff --git a/crates/elide-bento/src/lib.rs b/crates/elide-bento/src/lib.rs index ad4151ba3..4686c404a 100644 --- a/crates/elide-bento/src/lib.rs +++ b/crates/elide-bento/src/lib.rs @@ -11,8 +11,3 @@ pub mod ner; #[cfg(feature = "ocr")] #[cfg_attr(docsrs, doc(cfg(feature = "ocr")))] pub mod ocr; - -#[cfg(feature = "ner")] -pub use self::ner::BentoNer; -#[cfg(feature = "ocr")] -pub use self::ocr::BentoOcr; diff --git a/crates/elide-bento/src/ner/mod.rs b/crates/elide-bento/src/ner/mod.rs index f7d8545b5..3fb6cc090 100644 --- a/crates/elide-bento/src/ner/mod.rs +++ b/crates/elide-bento/src/ner/mod.rs @@ -1,4 +1,4 @@ -//! [`BentoNer`]: an [`elide_ner::backend::NerBackend`] backed by the +//! [`BentoNer`]: an [`NerBackend`] backed by the //! `nvisy-inference-ner` BentoML service. //! //! Wire contract: `POST /recognize` accepts a batched list of @@ -11,6 +11,8 @@ //! Wire types live in the private `request` (outgoing) and //! `response` (incoming) submodules; only the public //! [`BentoNer`] backend is part of this crate's API. +//! +//! [`NerBackend`]: elide_ner::backend::NerBackend mod request; mod response; diff --git a/crates/elide-bento/src/ocr/mod.rs b/crates/elide-bento/src/ocr/mod.rs index 641f37ef3..a22416743 100644 --- a/crates/elide-bento/src/ocr/mod.rs +++ b/crates/elide-bento/src/ocr/mod.rs @@ -1,4 +1,4 @@ -//! [`BentoOcr`]: an [`elide_ocr::OcrBackend`] backed by the +//! [`BentoOcr`]: an [`OcrBackend`] backed by the //! `nvisy-inference-ocr` BentoML service. //! //! Wire contract: `POST /recognize` accepts a batched list of @@ -15,6 +15,7 @@ //! `response` (incoming) submodules; only the public //! [`BentoOcr`] backend is part of this crate's API. //! +//! [`OcrBackend`]: elide_ocr::OcrBackend //! [`LayoutBlock`]: elide_core::modality::image::LayoutBlock //! [`LayoutWord`]: elide_core::modality::image::LayoutWord diff --git a/crates/nvisy-engine/src/analyzer/enricher/ocr.rs b/crates/nvisy-engine/src/analyzer/enricher/ocr.rs index 39292b3f0..251c1781d 100644 --- a/crates/nvisy-engine/src/analyzer/enricher/ocr.rs +++ b/crates/nvisy-engine/src/analyzer/enricher/ocr.rs @@ -9,7 +9,7 @@ use elide::detection::Analyzer; #[cfg(feature = "test-utils")] use elide::enrichment::ocr::MockBackend as MockOcrBackend; use elide::enrichment::ocr::OcrEnricher; -use elide_bento::BentoOcr; +use elide_bento::ocr::BentoOcr; use elide_core::modality::image::Image; use elide_core::{Error, ErrorKind}; use nvisy_schema::plan::{OcrBackendParams, OcrEnricherParams}; diff --git a/crates/nvisy-engine/src/analyzer/recognizer/ner.rs b/crates/nvisy-engine/src/analyzer/recognizer/ner.rs index caafedca9..147358727 100644 --- a/crates/nvisy-engine/src/analyzer/recognizer/ner.rs +++ b/crates/nvisy-engine/src/analyzer/recognizer/ner.rs @@ -12,7 +12,7 @@ use elide::detection::Analyzer; use elide::recognition::ner::NerRecognizer; -use elide_bento::BentoNer; +use elide_bento::ner::BentoNer; use elide_core::modality::TextRecognizable; use elide_core::recognition::Recognizer; use elide_core::{Error, ErrorKind}; diff --git a/crates/nvisy-engine/src/analyzer/recognizer/pattern.rs b/crates/nvisy-engine/src/analyzer/recognizer/pattern.rs index 7124e1bbb..20a6e9f9b 100644 --- a/crates/nvisy-engine/src/analyzer/recognizer/pattern.rs +++ b/crates/nvisy-engine/src/analyzer/recognizer/pattern.rs @@ -15,8 +15,10 @@ //! [`elide_pattern::Dictionary`] / [`Term`]. //! //! [`PatternGuardrails`] bounds runaway compile cost from any of -//! those slots. See [`guardrails`](super::guardrails) for the -//! per-request budget shape. +//! those slots. See [`guardrails`] for the per-request budget +//! shape. +//! +//! [`guardrails`]: super::guardrails use std::collections::HashMap; diff --git a/crates/nvisy-engine/src/lib.rs b/crates/nvisy-engine/src/lib.rs index d3cb5c335..c23a95d43 100644 --- a/crates/nvisy-engine/src/lib.rs +++ b/crates/nvisy-engine/src/lib.rs @@ -25,11 +25,17 @@ mod pipeline; mod provider; #[doc(inline)] -pub use elide::recognition::Scope; +pub use elide::codec::FormatRegistry; #[doc(inline)] -pub use elide_core::entity::Entity; +pub use elide::recognition::Scope; #[doc(inline)] pub use elide_core::{Error, ErrorKind, Result}; +/// Authored redaction governance: policies, rules, predicates, +/// operators, retention. +#[doc(inline)] +pub use nvisy_schema::policy; +#[doc(inline)] +pub use nvisy_schema::{annotation, entity, file, modality, plan, primitive}; pub use self::analyzer::PatternGuardrails; pub use self::pipeline::{ diff --git a/crates/nvisy-engine/src/pipeline/analyzed.rs b/crates/nvisy-engine/src/pipeline/analyzed.rs index dcc4d74ce..5cae840bf 100644 --- a/crates/nvisy-engine/src/pipeline/analyzed.rs +++ b/crates/nvisy-engine/src/pipeline/analyzed.rs @@ -49,9 +49,10 @@ use serde::{Deserialize, Serialize}; /// /// `correlation_id` on the persisted scope is always `None`; the /// anonymize call supplies a fresh id from the passed -/// [`Document`](nvisy_schema::file::Document) so anonymize-side -/// tracing spans are distinct from the analyze-side ones. +/// [`Document`] so anonymize-side tracing spans are distinct +/// from the analyze-side ones. /// +/// [`Document`]: nvisy_schema::file::Document /// [`Scope`]: elide::recognition::Scope #[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema)] #[serde(rename_all = "camelCase")] diff --git a/crates/nvisy-engine/src/provider/llm/prompt.rs b/crates/nvisy-engine/src/provider/llm/prompt.rs index 212b25888..90b322fc3 100644 --- a/crates/nvisy-engine/src/provider/llm/prompt.rs +++ b/crates/nvisy-engine/src/provider/llm/prompt.rs @@ -7,8 +7,10 @@ use serde::{Deserialize, Serialize}; /// Where a recognizer's Jinja2 prompt template comes from. /// -/// Omitted from an [`LlmRecognizer`](super::LlmRecognizer) means -/// "use elide's default recognition prompt for this modality." +/// Omitted from an [`LlmRecognizer`] means "use elide's default +/// recognition prompt for this modality." +/// +/// [`LlmRecognizer`]: super::LlmRecognizer #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)] #[serde(tag = "source", rename_all = "snake_case")] pub enum LlmPrompt { diff --git a/crates/nvisy-policy/src/action/mod.rs b/crates/nvisy-policy/src/action/mod.rs index af7c96872..757379355 100644 --- a/crates/nvisy-policy/src/action/mod.rs +++ b/crates/nvisy-policy/src/action/mod.rs @@ -1,11 +1,11 @@ //! Actions a rule can trigger when it matches an entity. //! -//! Composed via [`PolicyAction`](super::PolicyAction), which the -//! engine dispatches on: [`Redact`] runs the per-modality -//! redaction operator, [`Suppress`] short-circuits redaction -//! for the entity, [`Audit`] records the match for downstream -//! reporting without altering the document. +//! Composed via [`PolicyAction`], which the engine dispatches on: +//! [`Redact`] runs the per-modality redaction operator, [`Suppress`] +//! short-circuits redaction for the entity, [`Audit`] records the +//! match for downstream reporting without altering the document. //! +//! [`PolicyAction`]: super::PolicyAction //! [`Redact`]: super::PolicyAction::Redact //! [`Suppress`]: super::PolicyAction::Suppress //! [`Audit`]: super::PolicyAction::Audit diff --git a/crates/nvisy-policy/src/rule.rs b/crates/nvisy-policy/src/rule.rs index b0196f5c2..9476f7e9b 100644 --- a/crates/nvisy-policy/src/rule.rs +++ b/crates/nvisy-policy/src/rule.rs @@ -1,11 +1,10 @@ //! One rule inside a [`Policy`]: shared identity/description //! fields, the match predicate, and the action ([`PolicyAction`]). //! -//! The engine compiles a rule's [`predicate`](PolicyRule::predicate) -//! into an elide anonymizer rule at request time. Three shapes -//! are recognised as fast paths and route to the matching -//! [`Anonymizer`] builder method; everything else compiles to a -//! catalog-aware closure: +//! The engine compiles a rule's [`predicate`] into an elide +//! anonymizer rule at request time. Three shapes are recognised +//! as fast paths and route to the matching [`Anonymizer`] builder +//! method; everything else compiles to a catalog-aware closure: //! //! - [`Predicate::LabelOneOf`] with a single label → [`Anonymizer::with_label`] //! - [`Predicate::TagOneOf`] with a single tag → [`Anonymizer::with_tag`] @@ -18,6 +17,7 @@ //! compiles down to the same fast path. //! //! [`Policy`]: super::Policy +//! [`predicate`]: PolicyRule::predicate //! [`Anonymizer`]: https://docs.rs/elide/latest/elide/redaction/Anonymizer //! [`Anonymizer::with_label`]: https://docs.rs/elide/latest/elide/redaction/Anonymizer::with_label //! [`Anonymizer::with_tag`]: https://docs.rs/elide/latest/elide/redaction/Anonymizer::with_tag @@ -61,15 +61,17 @@ pub struct PolicyRule { pub action: PolicyAction, } -/// What a rule does when its [`predicate`](PolicyRule::predicate) -/// matches. +/// What a rule does when its [`predicate`] matches. /// -/// Three verbs: [`Redact`](PolicyAction::Redact) transforms the -/// entity with one operator per modality; -/// [`Suppress`](PolicyAction::Suppress) drops the entity entirely -/// (false-positive marker) and stamps a reason onto the audit; -/// [`Audit`](PolicyAction::Audit) flags it for human review without -/// transforming. +/// Three verbs: [`Redact`] transforms the entity with one operator +/// per modality; [`Suppress`] drops the entity entirely (false-positive +/// marker) and stamps a reason onto the audit; [`Audit`] flags it for +/// human review without transforming. +/// +/// [`predicate`]: PolicyRule::predicate +/// [`Redact`]: PolicyAction::Redact +/// [`Suppress`]: PolicyAction::Suppress +/// [`Audit`]: PolicyAction::Audit #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)] #[serde(tag = "kind", rename_all = "camelCase")] pub enum PolicyAction { diff --git a/crates/nvisy-schema/src/annotation.rs b/crates/nvisy-schema/src/annotation.rs index eae8e2602..ed7f060ca 100644 --- a/crates/nvisy-schema/src/annotation.rs +++ b/crates/nvisy-schema/src/annotation.rs @@ -1,5 +1,4 @@ -//! Caller-supplied region annotations re-exported from -//! `elide_core::recognition::annotation`. +//! Caller-supplied region annotations passed to the analyzer. //! //! Two directions, two types. An [`Inclusion`] adds a candidate //! region ("there may be an entity here"); recognizers that diff --git a/crates/nvisy-schema/src/entity.rs b/crates/nvisy-schema/src/entity.rs index 54632c656..4d2b238bb 100644 --- a/crates/nvisy-schema/src/entity.rs +++ b/crates/nvisy-schema/src/entity.rs @@ -1,9 +1,13 @@ -//! Entity-domain types re-exported from `elide_core::entity`. +//! Detected entities, their labels, and their audit trail. //! -//! Wire types on [`policy`] and [`plan`] carry [`Label`] and -//! [`LabelRef`] directly. -//! -//! [`plan`]: crate::plan -//! [`policy`]: crate::policy +//! [`Entity`] is the modality-generic detection record produced +//! by the analyzer and consumed by the anonymizer. [`Label`] and +//! [`LabelRef`] name the entity kind; [`LabelCatalog`] holds the +//! deployment's label vocabulary. [`Provenance`] carries the +//! audit trail (which rule / model / pattern produced each +//! detection). -pub use elide_core::entity::{Label, LabelRef}; +pub use elide_core::entity::provenance::{ + Attribution, Event, EventKind, ModelEvent, PatternEvent, Provenance, RuleMatch, +}; +pub use elide_core::entity::{Entity, EntityCoRef, EntityRef, Label, LabelCatalog, LabelRef}; diff --git a/crates/nvisy-schema/src/lib.rs b/crates/nvisy-schema/src/lib.rs index 296aa860d..6e85b7cd6 100644 --- a/crates/nvisy-schema/src/lib.rs +++ b/crates/nvisy-schema/src/lib.rs @@ -22,6 +22,9 @@ //! //! [`nvisy-policy`]: https://docs.rs/nvisy-policy +/// Authored redaction governance: policies, rules, predicates, +/// operators, retention. +#[doc(inline)] pub use nvisy_policy as policy; pub mod annotation; diff --git a/crates/nvisy-schema/src/modality.rs b/crates/nvisy-schema/src/modality.rs index 85b086109..28b0e603f 100644 --- a/crates/nvisy-schema/src/modality.rs +++ b/crates/nvisy-schema/src/modality.rs @@ -1,8 +1,15 @@ -//! Modality-specific runtime types re-exported from `elide_core::modality`. +//! Modality markers and traits parameterising `Entity` and +//! `EntityRecord`. //! -//! Wire types on [`policy`] (audio redaction operators) carry -//! [`Waveform`] directly. +//! [`Modality`] is the trait every marker implements; [`Text`], +//! [`Tabular`], [`Image`], and [`Audio`] are the four markers. +//! [`Waveform`] appears directly on audio redaction operators in +//! [`policy`]. //! //! [`policy`]: crate::policy -pub use elide_core::modality::audio::Waveform; +pub use elide_core::modality::audio::{Audio, Waveform}; +pub use elide_core::modality::image::Image; +pub use elide_core::modality::tabular::Tabular; +pub use elide_core::modality::text::Text; +pub use elide_core::modality::{Modality, ModalityData, ModalityLocation, ModalityReplacement}; diff --git a/crates/nvisy-schema/src/plan/label.rs b/crates/nvisy-schema/src/plan/label.rs index e3ad3b95d..2e7980cf5 100644 --- a/crates/nvisy-schema/src/plan/label.rs +++ b/crates/nvisy-schema/src/plan/label.rs @@ -3,16 +3,17 @@ //! Two distinct sources the engine unions into one //! `elide_core::entity::LabelCatalog` at compile time: //! -//! - [`builtins`](LabelCatalogParams::builtins): names of labels -//! from `elide-core`'s shipped builtin set -//! (`LabelCatalog::with_builtins`). Engine looks each name up -//! against the full builtin catalog and copies the matching -//! [`Label`] across; unknown names log a warning and are -//! skipped (typos don't fail the request). -//! - [`custom`](LabelCatalogParams::custom): schemas the caller -//! defined inline, beyond the builtin set. Names that collide -//! with a builtin replace it (last write wins, matching -//! `LabelCatalog::insert` semantics). +//! - [`builtins`]: names of labels from `elide-core`'s shipped +//! builtin set (`LabelCatalog::with_builtins`). Engine looks +//! each name up against the full builtin catalog and copies +//! the matching [`Label`] across; unknown names log a warning +//! and are skipped (typos don't fail the request). +//! - [`custom`]: schemas the caller defined inline, beyond the +//! builtin set. Names that collide with a builtin replace it +//! (last write wins, matching `LabelCatalog::insert` semantics). +//! +//! [`builtins`]: LabelCatalogParams::builtins +//! [`custom`]: LabelCatalogParams::custom //! //! Empty default. Server-side deployments may pre-populate via //! the `analyzer` server-default block in the config, but the diff --git a/crates/nvisy-schema/src/plan/mod.rs b/crates/nvisy-schema/src/plan/mod.rs index ff532d387..1fd3d9d0d 100644 --- a/crates/nvisy-schema/src/plan/mod.rs +++ b/crates/nvisy-schema/src/plan/mod.rs @@ -1,13 +1,11 @@ -//! Analyzer plan. +//! Authored recognition plan: recognizers, enrichers, dedup, scope. //! -//! Serialisable description of how to build an -//! `elide::detection::Analyzer` for a request. -//! -//! Symmetric with [`policy`]. Where policy describes redaction -//! governance (which entities to hide and how), the plan -//! describes recognition (which entities to find and how). Both -//! are pure data; the engine compiles them into elide runtime -//! values at request time. +//! Serialisable description of how to build an analyzer for a +//! request. Symmetric with [`policy`]. Where policy describes +//! redaction governance (which entities to hide and how), the +//! plan describes recognition (which entities to find and how). +//! Both are pure data; the engine compiles them into elide +//! runtime values at request time. //! //! ## Layout //! diff --git a/crates/nvisy-schema/src/primitive.rs b/crates/nvisy-schema/src/primitive.rs index cde1b69ce..020357c02 100644 --- a/crates/nvisy-schema/src/primitive.rs +++ b/crates/nvisy-schema/src/primitive.rs @@ -1,13 +1,14 @@ -//! Primitive value types re-exported from `elide_core::primitive`. +//! Primitive value types wire schemas carry directly. //! -//! Wire types on [`plan`] and [`policy`] carry these directly. -//! The re-export means an SDK caller can construct them without -//! adding `elide-core` as a separate dep. +//! Bounding boxes, confidence, colors, languages, country codes, +//! time spans, and friends. Wire types on [`plan`] and [`policy`] +//! use these as leaf fields. //! //! [`plan`]: crate::plan //! [`policy`]: crate::policy pub use elide_core::primitive::{ - BoundingBox, Color, Confidence, ConfidenceThreshold, CountryCode, LanguageTag, Languages, - Point, Polygon, TimeSpan, + BoundingBox, Color, Confidence, ConfidenceThreshold, CountryCode, Dimensions, Dpi, Language, + LanguageProvenance, LanguageSpan, LanguageTag, Languages, PixelRegion, Point, Polygon, + TimeSpan, UnitBoundingBox, };