Problem
Engine::analyze_document now accepts contexts: &[Context] on its signature as a placeholder — no built-in recognizer in the workspace consumes them. Reference-data collections (names, faces, voices, patterns, embeddings) round-trip cleanly through the schema but never actually gate detection.
Sketch
A decorator recognizer wraps a base recognizer and post-filters (or pre-boosts) its output using the caller's Context entries. Roughly:
struct ContextEnhanced<R> {
inner: R,
contexts: Vec<Context>,
}
impl<M: Modality, R: Recognizer<M>> Recognizer<M> for ContextEnhanced<R> {
async fn recognize(&self, input: ...) -> Result<Vec<Entity<M>>> {
let mut entities = self.inner.recognize(input).await?;
// Walk contexts, boost matching entities' confidence, add
// context-derived entities, filter false-positives against
// known safe values, etc.
Ok(entities)
}
}
Per-variant handling:
ReferenceVariant::Text → literal / regex boost.
AnalyticVariant::Pattern → additional regex matcher.
AnalyticVariant::Embedding → similarity boost against embeddings from LLM/NER.
BiometricVariant::Face / ::Voice → not applicable to text/tabular; only for image/audio pipelines.
DocumentVariant::Signature / ::Template → structural match hints.
GeospatialVariant::* → post-filter by location.
TemporalVariant::* → post-filter by date/time.
Wiring
Two options for how the engine attaches contexts:
A. Attach in build_orchestrator. Wrap every recognizer the analyzer compile builds. Contexts flow through the pipeline uniformly. Simple.
B. Explicit opt-in per recognizer. RecognizerParams gets a context: bool flag; only recognizers that ask for context get the decorator. More surgical, respects "unused deps are free."
Lean toward A for simplicity + minimal wire churn.
Definition of done
References
crates/nvisy-context/src/lib.rs — Context + variant taxonomy.
crates/nvisy-engine/src/engine/mod.rs::analyze_document — placeholder.
- The
elide::recognition::context::Enhanced pattern (currently used only for PatternRecognizer via context_enhanced: bool) — same shape, more general.
Problem
Engine::analyze_documentnow acceptscontexts: &[Context]on its signature as a placeholder — no built-in recognizer in the workspace consumes them. Reference-data collections (names, faces, voices, patterns, embeddings) round-trip cleanly through the schema but never actually gate detection.Sketch
A decorator recognizer wraps a base recognizer and post-filters (or pre-boosts) its output using the caller's
Contextentries. Roughly:Per-variant handling:
ReferenceVariant::Text→ literal / regex boost.AnalyticVariant::Pattern→ additional regex matcher.AnalyticVariant::Embedding→ similarity boost against embeddings from LLM/NER.BiometricVariant::Face/::Voice→ not applicable to text/tabular; only for image/audio pipelines.DocumentVariant::Signature/::Template→ structural match hints.GeospatialVariant::*→ post-filter by location.TemporalVariant::*→ post-filter by date/time.Wiring
Two options for how the engine attaches contexts:
A. Attach in
build_orchestrator. Wrap every recognizer the analyzer compile builds. Contexts flow through the pipeline uniformly. Simple.B. Explicit opt-in per recognizer.
RecognizerParamsgets acontext: boolflag; only recognizers that ask for context get the decorator. More surgical, respects "unused deps are free."Lean toward A for simplicity + minimal wire churn.
Definition of done
ContextEnhanced<R>decorator implementation innvisy-engine(or upstream inelideif the pattern is broadly useful).ContextEnhancedwhencontextsis non-empty.Engine::analyze_document.References
crates/nvisy-context/src/lib.rs— Context + variant taxonomy.crates/nvisy-engine/src/engine/mod.rs::analyze_document— placeholder.elide::recognition::context::Enhancedpattern (currently used only forPatternRecognizerviacontext_enhanced: bool) — same shape, more general.