From e06579904461b3476d23ec5f9c980e2a314f00f9 Mon Sep 17 00:00:00 2001 From: Oleh Martsokha Date: Thu, 23 Jul 2026 01:59:14 +0200 Subject: [PATCH] Drop nvisy-context crate, bump elide + spin Deletes the nvisy-context crate: no built-in recognizer consumed its reference-data types and every analyze_document callsite passed &[]. Also drops the dead contexts parameter from Engine::analyze_document and trims the schema umbrella + prose accordingly. Bumps elide 33dea523 -> a29a152e (no source changes needed) and unyanks spin 0.9.8 -> 0.9.9 to clear cargo-deny advisories. Co-Authored-By: Claude Opus 4.7 --- Cargo.lock | 218 +++--------------- Cargo.toml | 2 - README.md | 3 +- crates/nvisy-context/Cargo.toml | 44 ---- crates/nvisy-context/README.md | 30 --- .../nvisy-context/src/analytic/embedding.rs | 41 ---- crates/nvisy-context/src/analytic/mod.rs | 21 -- crates/nvisy-context/src/analytic/pattern.rs | 46 ---- crates/nvisy-context/src/biometric/face.rs | 53 ----- crates/nvisy-context/src/biometric/mod.rs | 21 -- crates/nvisy-context/src/biometric/voice.rs | 53 ----- crates/nvisy-context/src/document/mod.rs | 21 -- .../nvisy-context/src/document/signature.rs | 47 ---- crates/nvisy-context/src/document/template.rs | 40 ---- crates/nvisy-context/src/entry.rs | 84 ------- .../nvisy-context/src/geospatial/address.rs | 30 --- .../src/geospatial/coordinates.rs | 30 --- crates/nvisy-context/src/geospatial/mod.rs | 23 -- crates/nvisy-context/src/geospatial/region.rs | 100 -------- crates/nvisy-context/src/lib.rs | 61 ----- .../nvisy-context/src/reference/credential.rs | 77 ------- crates/nvisy-context/src/reference/image.rs | 17 -- crates/nvisy-context/src/reference/mod.rs | 29 --- crates/nvisy-context/src/reference/tag.rs | 15 -- crates/nvisy-context/src/reference/text.rs | 60 ----- crates/nvisy-context/src/temporal/date.rs | 36 --- crates/nvisy-context/src/temporal/datetime.rs | 43 ---- crates/nvisy-context/src/temporal/mod.rs | 29 --- crates/nvisy-context/src/temporal/time.rs | 41 ---- crates/nvisy-context/src/temporal/timespan.rs | 29 --- crates/nvisy-engine/src/pipeline/mod.rs | 10 - crates/nvisy-engine/tests/multimodal.rs | 10 +- crates/nvisy-engine/tests/patterns.rs | 12 +- crates/nvisy-policy/README.md | 4 +- crates/nvisy-schema/Cargo.toml | 3 +- crates/nvisy-schema/README.md | 15 +- crates/nvisy-schema/src/lib.rs | 15 +- crates/nvisy-schema/src/primitive.rs | 8 +- 38 files changed, 59 insertions(+), 1362 deletions(-) delete mode 100644 crates/nvisy-context/Cargo.toml delete mode 100644 crates/nvisy-context/README.md delete mode 100644 crates/nvisy-context/src/analytic/embedding.rs delete mode 100644 crates/nvisy-context/src/analytic/mod.rs delete mode 100644 crates/nvisy-context/src/analytic/pattern.rs delete mode 100644 crates/nvisy-context/src/biometric/face.rs delete mode 100644 crates/nvisy-context/src/biometric/mod.rs delete mode 100644 crates/nvisy-context/src/biometric/voice.rs delete mode 100644 crates/nvisy-context/src/document/mod.rs delete mode 100644 crates/nvisy-context/src/document/signature.rs delete mode 100644 crates/nvisy-context/src/document/template.rs delete mode 100644 crates/nvisy-context/src/entry.rs delete mode 100644 crates/nvisy-context/src/geospatial/address.rs delete mode 100644 crates/nvisy-context/src/geospatial/coordinates.rs delete mode 100644 crates/nvisy-context/src/geospatial/mod.rs delete mode 100644 crates/nvisy-context/src/geospatial/region.rs delete mode 100644 crates/nvisy-context/src/lib.rs delete mode 100644 crates/nvisy-context/src/reference/credential.rs delete mode 100644 crates/nvisy-context/src/reference/image.rs delete mode 100644 crates/nvisy-context/src/reference/mod.rs delete mode 100644 crates/nvisy-context/src/reference/tag.rs delete mode 100644 crates/nvisy-context/src/reference/text.rs delete mode 100644 crates/nvisy-context/src/temporal/date.rs delete mode 100644 crates/nvisy-context/src/temporal/datetime.rs delete mode 100644 crates/nvisy-context/src/temporal/mod.rs delete mode 100644 crates/nvisy-context/src/temporal/time.rs delete mode 100644 crates/nvisy-context/src/temporal/timespan.rs diff --git a/Cargo.lock b/Cargo.lock index 03c07d01..d32d9d1a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -603,7 +603,7 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "strsim 0.11.1", + "strsim", "syn", ] @@ -670,47 +670,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "deluxe" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ed332aaf752b459088acf3dd4eca323e3ef4b83c70a84ca48fb0ec5305f1488" -dependencies = [ - "deluxe-core", - "deluxe-macros", - "once_cell", - "proc-macro2", - "syn", -] - -[[package]] -name = "deluxe-core" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eddada51c8576df9d6a8450c351ff63042b092c9458b8ac7d20f89cbd0ffd313" -dependencies = [ - "arrayvec", - "proc-macro2", - "quote", - "strsim 0.10.0", - "syn", -] - -[[package]] -name = "deluxe-macros" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f87546d9c837f0b7557e47b8bd6eae52c3c223141b76aa233c345c9ab41d9117" -dependencies = [ - "deluxe-core", - "heck 0.4.1", - "if_chain", - "proc-macro-crate 1.3.1", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "derive_builder" version = "0.20.2" @@ -839,7 +798,7 @@ checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" [[package]] name = "elide" version = "0.1.0" -source = "git+https://github.com/nvisycom/elide?branch=main#33dea52314905c633d9bbd9a30486bca6bfb01ea" +source = "git+https://github.com/nvisycom/elide?branch=main#a29a152ec00d3d2d3ca36ee4b9e55a867744b17e" dependencies = [ "async-trait", "elide-codec", @@ -875,7 +834,7 @@ dependencies = [ [[package]] name = "elide-codec" version = "0.1.0" -source = "git+https://github.com/nvisycom/elide?branch=main#33dea52314905c633d9bbd9a30486bca6bfb01ea" +source = "git+https://github.com/nvisycom/elide?branch=main#a29a152ec00d3d2d3ca36ee4b9e55a867744b17e" dependencies = [ "async-trait", "bytes", @@ -899,7 +858,7 @@ dependencies = [ [[package]] name = "elide-context" version = "0.1.0" -source = "git+https://github.com/nvisycom/elide?branch=main#33dea52314905c633d9bbd9a30486bca6bfb01ea" +source = "git+https://github.com/nvisycom/elide?branch=main#a29a152ec00d3d2d3ca36ee4b9e55a867744b17e" dependencies = [ "async-trait", "elide-core", @@ -910,7 +869,7 @@ dependencies = [ [[package]] name = "elide-core" version = "0.1.0" -source = "git+https://github.com/nvisycom/elide?branch=main#33dea52314905c633d9bbd9a30486bca6bfb01ea" +source = "git+https://github.com/nvisycom/elide?branch=main#a29a152ec00d3d2d3ca36ee4b9e55a867744b17e" dependencies = [ "async-trait", "bytes", @@ -928,7 +887,7 @@ dependencies = [ [[package]] name = "elide-detection" version = "0.1.0" -source = "git+https://github.com/nvisycom/elide?branch=main#33dea52314905c633d9bbd9a30486bca6bfb01ea" +source = "git+https://github.com/nvisycom/elide?branch=main#a29a152ec00d3d2d3ca36ee4b9e55a867744b17e" dependencies = [ "async-trait", "elide-core", @@ -941,7 +900,7 @@ dependencies = [ [[package]] name = "elide-lingua" version = "0.1.0" -source = "git+https://github.com/nvisycom/elide?branch=main#33dea52314905c633d9bbd9a30486bca6bfb01ea" +source = "git+https://github.com/nvisycom/elide?branch=main#a29a152ec00d3d2d3ca36ee4b9e55a867744b17e" dependencies = [ "async-trait", "elide-core", @@ -952,7 +911,7 @@ dependencies = [ [[package]] name = "elide-llm" version = "0.1.0" -source = "git+https://github.com/nvisycom/elide?branch=main#33dea52314905c633d9bbd9a30486bca6bfb01ea" +source = "git+https://github.com/nvisycom/elide?branch=main#a29a152ec00d3d2d3ca36ee4b9e55a867744b17e" dependencies = [ "async-trait", "derive_builder", @@ -972,7 +931,7 @@ dependencies = [ [[package]] name = "elide-ner" version = "0.1.0" -source = "git+https://github.com/nvisycom/elide?branch=main#33dea52314905c633d9bbd9a30486bca6bfb01ea" +source = "git+https://github.com/nvisycom/elide?branch=main#a29a152ec00d3d2d3ca36ee4b9e55a867744b17e" dependencies = [ "async-trait", "derive_builder", @@ -986,7 +945,7 @@ dependencies = [ [[package]] name = "elide-ocr" version = "0.1.0" -source = "git+https://github.com/nvisycom/elide?branch=main#33dea52314905c633d9bbd9a30486bca6bfb01ea" +source = "git+https://github.com/nvisycom/elide?branch=main#a29a152ec00d3d2d3ca36ee4b9e55a867744b17e" dependencies = [ "async-trait", "elide-core", @@ -996,7 +955,7 @@ dependencies = [ [[package]] name = "elide-orchestration" version = "0.1.0" -source = "git+https://github.com/nvisycom/elide?branch=main#33dea52314905c633d9bbd9a30486bca6bfb01ea" +source = "git+https://github.com/nvisycom/elide?branch=main#a29a152ec00d3d2d3ca36ee4b9e55a867744b17e" dependencies = [ "bytes", "elide-codec", @@ -1010,7 +969,7 @@ dependencies = [ [[package]] name = "elide-pattern" version = "0.1.0" -source = "git+https://github.com/nvisycom/elide?branch=main#33dea52314905c633d9bbd9a30486bca6bfb01ea" +source = "git+https://github.com/nvisycom/elide?branch=main#a29a152ec00d3d2d3ca36ee4b9e55a867744b17e" dependencies = [ "aho-corasick", "async-trait", @@ -1030,7 +989,7 @@ dependencies = [ [[package]] name = "elide-redaction" version = "0.1.0" -source = "git+https://github.com/nvisycom/elide?branch=main#33dea52314905c633d9bbd9a30486bca6bfb01ea" +source = "git+https://github.com/nvisycom/elide?branch=main#a29a152ec00d3d2d3ca36ee4b9e55a867744b17e" dependencies = [ "async-trait", "bytes", @@ -1045,7 +1004,7 @@ dependencies = [ [[package]] name = "elide-stt" version = "0.1.0" -source = "git+https://github.com/nvisycom/elide?branch=main#33dea52314905c633d9bbd9a30486bca6bfb01ea" +source = "git+https://github.com/nvisycom/elide?branch=main#a29a152ec00d3d2d3ca36ee4b9e55a867744b17e" dependencies = [ "async-trait", "elide-core", @@ -1490,12 +1449,6 @@ dependencies = [ "stable_deref_trait", ] -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - [[package]] name = "heck" version = "0.5.0" @@ -1759,12 +1712,6 @@ dependencies = [ "icu_properties", ] -[[package]] -name = "if_chain" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd62e6b5e86ea8eeeb8db1de02880a6abc01a397b2ebb64b5d74ac255318f5cb" - [[package]] name = "image" version = "0.25.10" @@ -2285,15 +2232,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "nanoid" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ffa00dec017b5b1a8b7cf5e2c008bfda1aa7e0697ac1508b491fdf2622fb4d8" -dependencies = [ - "rand 0.8.6", -] - [[package]] name = "new_debug_unreachable" version = "1.0.6" @@ -2427,21 +2365,6 @@ dependencies = [ "libm", ] -[[package]] -name = "nvisy-context" -version = "0.1.0" -dependencies = [ - "derive_builder", - "derive_more", - "elide-core", - "jiff", - "schemars", - "semver", - "serde", - "serde_json", - "uuid", -] - [[package]] name = "nvisy-engine" version = "0.1.0" @@ -2488,7 +2411,6 @@ dependencies = [ "elide-core", "hipstr", "jiff", - "nvisy-context", "nvisy-policy", "schemars", "serde", @@ -2743,23 +2665,13 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" -[[package]] -name = "proc-macro-crate" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" -dependencies = [ - "once_cell", - "toml_edit 0.19.15", -] - [[package]] name = "proc-macro-crate" version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" dependencies = [ - "toml_edit 0.25.12+spec-1.1.0", + "toml_edit", ] [[package]] @@ -2910,24 +2822,13 @@ version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" -[[package]] -name = "rand" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" -dependencies = [ - "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", -] - [[package]] name = "rand" version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" dependencies = [ - "rand_chacha 0.9.0", + "rand_chacha", "rand_core 0.9.5", ] @@ -2942,16 +2843,6 @@ dependencies = [ "rand_core 0.10.1", ] -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.4", -] - [[package]] name = "rand_chacha" version = "0.9.0" @@ -2962,15 +2853,6 @@ dependencies = [ "rand_core 0.9.5", ] -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom 0.2.17", -] - [[package]] name = "rand_core" version = "0.9.5" @@ -3024,7 +2906,7 @@ dependencies = [ "paste", "profiling", "rand 0.9.4", - "rand_chacha 0.9.0", + "rand_chacha", "simd_helpers", "thiserror", "v_frame", @@ -3267,18 +3149,18 @@ checksum = "47b34b781b31e5d73e9fbc8689c70551fd1ade9a19e3e28cfec8580a79290cc4" [[package]] name = "rig" -version = "0.39.0" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e98e2e8f01c4c5bc23f577983634fa4d5244ffb070ea14c23b1ea5bd406e5cac" +checksum = "9aac59326725633a25c21ef2c24d33c4d00dc38a1f0cc097205a7a9bde70b482" dependencies = [ "rig-core", ] [[package]] name = "rig-core" -version = "0.39.0" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80a4bc7a93b329c4e1a66d5fd211d79990e7331e3c701f057c29f135f548686d" +checksum = "d8731dd5532b3a12ce1613af73073fb2051ef750f50c504778c21d55ae933cac" dependencies = [ "as-any", "async-stream", @@ -3293,7 +3175,6 @@ dependencies = [ "indexmap", "mime", "mime_guess", - "nanoid", "ordered-float", "pin-project-lite", "reqwest", @@ -3312,14 +3193,13 @@ dependencies = [ [[package]] name = "rig-derive" -version = "0.39.0" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5531bfa887b371eab658a92de7db35003370bbeee208ff5e68bbb81a5ae92d3d" +checksum = "b3e98dde7a4e59e083e7396126ee4c83498c5bff605d126654e67815fa230a78" dependencies = [ "convert_case 0.11.0", - "deluxe", "indoc", - "proc-macro-crate 3.5.0", + "proc-macro-crate", "proc-macro2", "quote", "serde_json", @@ -3786,9 +3666,9 @@ dependencies = [ [[package]] name = "spin" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +checksum = "3763264f6b73151db08c50ff20d7d8a0b8796e021cdea7ceedad07b80155fa0e" dependencies = [ "lock_api", ] @@ -3823,12 +3703,6 @@ dependencies = [ "quote", ] -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - [[package]] name = "strsim" version = "0.11.1" @@ -3859,7 +3733,7 @@ version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7" dependencies = [ - "heck 0.5.0", + "heck", "proc-macro2", "quote", "syn", @@ -3871,7 +3745,7 @@ version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab85eea0270ee17587ed4156089e10b9e6880ee688791d45a905f5b1ca36f664" dependencies = [ - "heck 0.5.0", + "heck", "proc-macro2", "quote", "syn", @@ -4140,18 +4014,12 @@ dependencies = [ "indexmap", "serde_core", "serde_spanned", - "toml_datetime 1.1.1+spec-1.1.0", + "toml_datetime", "toml_parser", "toml_writer", - "winnow 1.0.3", + "winnow", ] -[[package]] -name = "toml_datetime" -version = "0.6.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" - [[package]] name = "toml_datetime" version = "1.1.1+spec-1.1.0" @@ -4161,17 +4029,6 @@ dependencies = [ "serde_core", ] -[[package]] -name = "toml_edit" -version = "0.19.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" -dependencies = [ - "indexmap", - "toml_datetime 0.6.11", - "winnow 0.5.40", -] - [[package]] name = "toml_edit" version = "0.25.12+spec-1.1.0" @@ -4179,9 +4036,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2153edc6955a6c354fad8f5efd38b6a8769bdccf9fe50f8e1329f81b0baa5d7" dependencies = [ "indexmap", - "toml_datetime 1.1.1+spec-1.1.0", + "toml_datetime", "toml_parser", - "winnow 1.0.3", + "winnow", ] [[package]] @@ -4190,7 +4047,7 @@ version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" dependencies = [ - "winnow 1.0.3", + "winnow", ] [[package]] @@ -4844,15 +4701,6 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" -[[package]] -name = "winnow" -version = "0.5.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" -dependencies = [ - "memchr", -] - [[package]] name = "winnow" version = "1.0.3" diff --git a/Cargo.toml b/Cargo.toml index 5a60cf72..bf8b402f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,6 @@ resolver = "3" members = [ "./crates/elide-bento", - "./crates/nvisy-context", "./crates/nvisy-engine", "./crates/nvisy-policy", "./crates/nvisy-schema", @@ -45,7 +44,6 @@ elide-stt = { git = "https://github.com/nvisycom/elide", branch = "main", defaul elide-bento = { path = "./crates/elide-bento", version = "0.1.0" } # Internal crates -nvisy-context = { path = "./crates/nvisy-context", version = "0.1.0" } nvisy-engine = { path = "./crates/nvisy-engine", version = "0.1.0" } nvisy-policy = { path = "./crates/nvisy-policy", version = "0.1.0" } nvisy-schema = { path = "./crates/nvisy-schema", version = "0.1.0" } diff --git a/README.md b/README.md index 97301363..7415e5b4 100644 --- a/README.md +++ b/README.md @@ -22,9 +22,8 @@ Rust crates ([`crates/`](crates/)) — library only, no long-running process. Hosts (a SaaS backend, a Tauri app, a language SDK, a custom pipeline) embed the engine directly. -- **[nvisy-context](crates/nvisy-context/)**: wire schema for reference-data collections (analytic, biometric, document, geospatial, reference, temporal) - **[nvisy-policy](crates/nvisy-policy/)**: wire schema for redaction governance (rules, predicates, retention, audit) -- **[nvisy-schema](crates/nvisy-schema/)**: umbrella crate re-exporting `nvisy-context` + `nvisy-policy` alongside plan and file types +- **[nvisy-schema](crates/nvisy-schema/)**: wire schema for plan, file, and the `elide-core` slice; re-exports `nvisy-policy` - **[nvisy-engine](crates/nvisy-engine/)**: stateless pipeline (decode, analyze, apply) wrapping elide, hosting the per-modality orchestrator and the deployment-side NER / LLM recognizer configuration - **[elide-bento](crates/elide-bento/)**: BentoML-hosted NER and OCR client implementing elide's recognizer traits diff --git a/crates/nvisy-context/Cargo.toml b/crates/nvisy-context/Cargo.toml deleted file mode 100644 index 26fc0c25..00000000 --- a/crates/nvisy-context/Cargo.toml +++ /dev/null @@ -1,44 +0,0 @@ -# https://doc.rust-lang.org/cargo/reference/manifest.html - -[package] -name = "nvisy-context" -description = "Wire schema for Nvisy contexts: persistent reference-data collections for detection" -keywords = ["nvisy", "schema", "context", "reference-data"] -categories = ["data-structures", "api-bindings"] -readme = "README.md" - -version = { workspace = true } -rust-version = { workspace = true } -edition = { workspace = true } -license = { workspace = true } -publish = { workspace = true } - -authors = { workspace = true } -repository = { workspace = true } -homepage = { workspace = true } -documentation = { workspace = true } - -[package.metadata.docs.rs] -all-features = true -rustdoc-args = ["--cfg", "docsrs"] - -[dependencies] -# Elide crates -elide-core = { workspace = true, features = ["serde", "schema"] } - -# Serialization -serde = { workspace = true, features = ["derive"] } -schemars = { workspace = true, features = ["uuid1", "semver1"] } - -# Derive macros and error handling -derive_builder = { workspace = true, features = [] } -derive_more = { workspace = true, features = ["from"] } - -# Primitive datatypes -uuid = { workspace = true, features = ["v7"] } -jiff = { workspace = true, features = ["serde"] } -semver = { workspace = true, features = ["serde"] } - -[dev-dependencies] -# Serialization -serde_json = { workspace = true, features = [] } diff --git a/crates/nvisy-context/README.md b/crates/nvisy-context/README.md deleted file mode 100644 index 235f65db..00000000 --- a/crates/nvisy-context/README.md +++ /dev/null @@ -1,30 +0,0 @@ -# nvisy-context - -[![Build](https://img.shields.io/github/actions/workflow/status/nvisycom/runtime/runtime-build.yml?branch=main&label=build%20%26%20test&style=flat-square)](https://github.com/nvisycom/runtime/actions/workflows/runtime-build.yml) - -Wire schema for Nvisy contexts: persistent reference-data collections -that tell detection *what to look for*. - -## Overview - -A `Context` holds reusable reference data (names, faces, voices, -patterns, embeddings) that recognizers consult during detection. It is -separate from policy, which controls *what to do* when something is -found. - -Sibling to `nvisy-policy` (what to do when detection fires) and -`nvisy-schema` (umbrella re-exporting both). - -## Changelog - -See [CHANGELOG.md](../../CHANGELOG.md) for release notes and version history. - -## License - -Apache 2.0 License, see [LICENSE.txt](../../LICENSE.txt) - -## Support - -- **Documentation**: [docs.nvisy.com](https://docs.nvisy.com) -- **Issues**: [GitHub Issues](https://github.com/nvisycom/runtime/issues) -- **Email**: [support@nvisy.com](mailto:support@nvisy.com) diff --git a/crates/nvisy-context/src/analytic/embedding.rs b/crates/nvisy-context/src/analytic/embedding.rs deleted file mode 100644 index 16e3066b..00000000 --- a/crates/nvisy-context/src/analytic/embedding.rs +++ /dev/null @@ -1,41 +0,0 @@ -//! Embedding reference data for similarity search. - -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -/// Distance metric for vector similarity comparison. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[derive(Serialize, Deserialize, JsonSchema)] -#[serde(rename_all = "snake_case")] -#[non_exhaustive] -pub enum DistanceMetric { - /// Cosine similarity (1 − cos θ). - Cosine, - /// Euclidean (L2) distance. - Euclidean, - /// Dot product (inner product). - DotProduct, - /// Manhattan (L1) distance. - Manhattan, -} - -/// Pre-computed embedding vector for similarity comparison. -#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] -#[serde(rename_all = "camelCase")] -pub struct EmbeddingData { - /// The embedding vector values. - pub vector: Vec, - /// Identifier of the model/algorithm that produced this embedding. - #[serde(skip_serializing_if = "Option::is_none")] - pub algorithm: Option, - /// Distance metric to use for comparison. - #[serde(skip_serializing_if = "Option::is_none")] - pub distance_metric: Option, -} - -impl EmbeddingData { - /// Dimensionality of the embedding vector. - pub fn dimensions(&self) -> usize { - self.vector.len() - } -} diff --git a/crates/nvisy-context/src/analytic/mod.rs b/crates/nvisy-context/src/analytic/mod.rs deleted file mode 100644 index 2487456a..00000000 --- a/crates/nvisy-context/src/analytic/mod.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Computed representations for similarity search and pattern matching. - -mod embedding; -mod pattern; - -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -pub use self::embedding::{DistanceMetric, EmbeddingData}; -pub use self::pattern::{GlobPattern, PatternData, PatternExpression, RegexPattern}; - -/// Analytic computation variants. -#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] -#[serde(tag = "kind", rename_all = "snake_case")] -#[non_exhaustive] -pub enum AnalyticVariant { - /// Pre-computed embedding vector for similarity search. - Embedding(EmbeddingData), - /// Regex or glob pattern for matching. - Pattern(PatternData), -} diff --git a/crates/nvisy-context/src/analytic/pattern.rs b/crates/nvisy-context/src/analytic/pattern.rs deleted file mode 100644 index d5248bc0..00000000 --- a/crates/nvisy-context/src/analytic/pattern.rs +++ /dev/null @@ -1,46 +0,0 @@ -//! Pattern reference data for regex/glob matching. - -use derive_more::From; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -/// A regular expression pattern. -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)] -#[serde(rename_all = "camelCase")] -pub struct RegexPattern { - /// The regex expression string. - pub expression: String, -} - -/// A shell-style glob pattern. -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)] -#[serde(rename_all = "camelCase")] -pub struct GlobPattern { - /// The glob expression string. - pub expression: String, -} - -/// A pattern expression with its syntax type. -#[derive(Debug, Clone, PartialEq, Eq, From, Serialize, Deserialize, JsonSchema)] -#[serde(tag = "syntax", rename_all = "snake_case")] -#[non_exhaustive] -pub enum PatternExpression { - /// Regular expression pattern. - Regex(RegexPattern), - /// Shell-style glob pattern. - Glob(GlobPattern), -} - -/// A named pattern for detection matching. -/// -/// `label` describes the intent (for humans/LLMs); `pattern` carries -/// the expression and its type. -#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] -#[serde(rename_all = "camelCase")] -pub struct PatternData { - /// Human-readable label describing what this pattern matches. - pub label: String, - /// The pattern expression and its type. - #[serde(flatten)] - pub pattern: PatternExpression, -} diff --git a/crates/nvisy-context/src/biometric/face.rs b/crates/nvisy-context/src/biometric/face.rs deleted file mode 100644 index eed28f43..00000000 --- a/crates/nvisy-context/src/biometric/face.rs +++ /dev/null @@ -1,53 +0,0 @@ -//! Face biometric reference data. - -use elide_core::primitive::BoundingBox; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; -use uuid::Uuid; - -/// Reference face data for identity matching. -#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] -#[serde(rename_all = "camelCase")] -pub struct FaceData { - /// Id of the file holding the reference face image. - pub image_source: Uuid, - /// Bounding box of the face within the image. - #[serde(skip_serializing_if = "Option::is_none")] - pub region: Option, - /// Base64-encoded face embedding / template. - #[serde(skip_serializing_if = "Option::is_none")] - pub template: Option, - /// Algorithm that produced the template (e.g. `"arcface"`, `"facenet"`). - #[serde(skip_serializing_if = "Option::is_none")] - pub algorithm: Option, -} - -impl FaceData { - /// Create face data pointing at a source image. - pub fn new(image_source: Uuid) -> Self { - Self { - image_source, - region: None, - template: None, - algorithm: None, - } - } - - /// Set the face bounding box. - pub fn with_region(mut self, region: BoundingBox) -> Self { - self.region = Some(region); - self - } - - /// Set the encoded face template. - pub fn with_template(mut self, template: impl Into) -> Self { - self.template = Some(template.into()); - self - } - - /// Set the extraction algorithm. - pub fn with_algorithm(mut self, algorithm: impl Into) -> Self { - self.algorithm = Some(algorithm.into()); - self - } -} diff --git a/crates/nvisy-context/src/biometric/mod.rs b/crates/nvisy-context/src/biometric/mod.rs deleted file mode 100644 index 461a5886..00000000 --- a/crates/nvisy-context/src/biometric/mod.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Biometric reference data for identity verification. - -mod face; -mod voice; - -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -pub use self::face::FaceData; -pub use self::voice::VoiceData; - -/// Biometric identity verification variants. -#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] -#[serde(tag = "kind", rename_all = "snake_case")] -#[non_exhaustive] -pub enum BiometricVariant { - /// Reference face for identity matching. - Face(FaceData), - /// Reference voiceprint for speaker identification. - Voice(VoiceData), -} diff --git a/crates/nvisy-context/src/biometric/voice.rs b/crates/nvisy-context/src/biometric/voice.rs deleted file mode 100644 index 96884dab..00000000 --- a/crates/nvisy-context/src/biometric/voice.rs +++ /dev/null @@ -1,53 +0,0 @@ -//! Voice biometric reference data. - -use elide_core::primitive::TimeSpan; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; -use uuid::Uuid; - -/// Reference voice data for speaker identification. -#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] -#[serde(rename_all = "camelCase")] -pub struct VoiceData { - /// Id of the file holding the reference audio. - pub audio_source: Uuid, - /// Segment within the audio used for enrollment. - #[serde(skip_serializing_if = "Option::is_none")] - pub segment: Option, - /// Base64-encoded speaker embedding / voiceprint. - #[serde(skip_serializing_if = "Option::is_none")] - pub template: Option, - /// Algorithm that produced the voiceprint (e.g. `"ecapa-tdnn"`, `"x-vector"`). - #[serde(skip_serializing_if = "Option::is_none")] - pub algorithm: Option, -} - -impl VoiceData { - /// Create voice data pointing at a source audio. - pub fn new(audio_source: Uuid) -> Self { - Self { - audio_source, - segment: None, - template: None, - algorithm: None, - } - } - - /// Set the enrollment segment. - pub fn with_segment(mut self, segment: TimeSpan) -> Self { - self.segment = Some(segment); - self - } - - /// Set the encoded voiceprint. - pub fn with_template(mut self, template: impl Into) -> Self { - self.template = Some(template.into()); - self - } - - /// Set the extraction algorithm. - pub fn with_algorithm(mut self, algorithm: impl Into) -> Self { - self.algorithm = Some(algorithm.into()); - self - } -} diff --git a/crates/nvisy-context/src/document/mod.rs b/crates/nvisy-context/src/document/mod.rs deleted file mode 100644 index 9d878b11..00000000 --- a/crates/nvisy-context/src/document/mod.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Document templates and handwritten signatures. - -mod signature; -mod template; - -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -pub use self::signature::SignatureData; -pub use self::template::TemplateData; - -/// Document-related reference variants. -#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] -#[serde(tag = "kind", rename_all = "snake_case")] -#[non_exhaustive] -pub enum DocumentVariant { - /// Reference document template for layout classification. - Template(TemplateData), - /// Handwritten signature for verification. - Signature(SignatureData), -} diff --git a/crates/nvisy-context/src/document/signature.rs b/crates/nvisy-context/src/document/signature.rs deleted file mode 100644 index e5ea2ccf..00000000 --- a/crates/nvisy-context/src/document/signature.rs +++ /dev/null @@ -1,47 +0,0 @@ -//! Signature reference data. - -use elide_core::primitive::BoundingBox; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; -use uuid::Uuid; - -/// Reference handwritten signature for verification. -#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] -#[serde(rename_all = "camelCase")] -pub struct SignatureData { - /// Id of the file holding the reference signature image. - pub image_source: Uuid, - /// Bounding box of the signature within the image. - #[serde(skip_serializing_if = "Option::is_none")] - pub region: Option, - /// Identity of the signer this signature belongs to. - #[serde(skip_serializing_if = "Option::is_none")] - pub signer_id: Option, - /// Algorithm used for signature verification. - #[serde(skip_serializing_if = "Option::is_none")] - pub algorithm: Option, -} - -impl SignatureData { - /// Create signature data pointing at a source image. - pub fn new(image_source: Uuid) -> Self { - Self { - image_source, - region: None, - signer_id: None, - algorithm: None, - } - } - - /// Set the signer identity. - pub fn with_signer_id(mut self, signer_id: impl Into) -> Self { - self.signer_id = Some(signer_id.into()); - self - } - - /// Set the verification algorithm. - pub fn with_algorithm(mut self, algorithm: impl Into) -> Self { - self.algorithm = Some(algorithm.into()); - self - } -} diff --git a/crates/nvisy-context/src/document/template.rs b/crates/nvisy-context/src/document/template.rs deleted file mode 100644 index f3a673a2..00000000 --- a/crates/nvisy-context/src/document/template.rs +++ /dev/null @@ -1,40 +0,0 @@ -//! Document template reference data. - -use elide_core::primitive::BoundingBox; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; -use uuid::Uuid; - -/// Reference document template for layout/type classification. -/// -/// Used to detect documents of a known type (ID cards, passports, forms, -/// invoices) by comparing their visual layout against this reference. -#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] -#[serde(rename_all = "camelCase")] -pub struct TemplateData { - /// Id of the file holding the reference template image. - pub image_source: Uuid, - /// Optional sub-region of interest within the template. - #[serde(skip_serializing_if = "Option::is_none")] - pub region: Option, - /// Document type label (e.g. `"passport"`, `"drivers_license"`, `"invoice"`). - #[serde(skip_serializing_if = "Option::is_none")] - pub document_type: Option, -} - -impl TemplateData { - /// Create template data pointing at a source image. - pub fn new(image_source: Uuid) -> Self { - Self { - image_source, - region: None, - document_type: None, - } - } - - /// Set the document type label. - pub fn with_document_type(mut self, document_type: impl Into) -> Self { - self.document_type = Some(document_type.into()); - self - } -} diff --git a/crates/nvisy-context/src/entry.rs b/crates/nvisy-context/src/entry.rs deleted file mode 100644 index bc0fc9fa..00000000 --- a/crates/nvisy-context/src/entry.rs +++ /dev/null @@ -1,84 +0,0 @@ -//! Context entry types for reference data. - -use derive_more::From; -use jiff::Timestamp; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; -use uuid::Uuid; - -use super::analytic::AnalyticVariant; -use super::biometric::BiometricVariant; -use super::document::DocumentVariant; -use super::geospatial::GeospatialVariant; -use super::reference::ReferenceVariant; -use super::temporal::TemporalVariant; - -/// Top-level domain classification for context reference data. -/// -/// Each domain contains a nested enum of specific variants, -/// keeping modality and semantic purpose cleanly separated. -#[derive(Debug, Clone, From, Serialize, Deserialize, JsonSchema)] -#[serde(tag = "domain", content = "data", rename_all = "snake_case")] -#[non_exhaustive] -pub enum ContextEntryData { - /// Identity verification via biological traits. - Biometric(BiometricVariant), - /// Geographic regions and addresses. - Geospatial(GeospatialVariant), - /// Computed representations for similarity search and pattern matching. - Analytic(AnalyticVariant), - /// Raw data for direct comparison against input. - Reference(ReferenceVariant), - /// Date and time-based matching. - Temporal(TemporalVariant), - /// Document templates and handwritten signatures. - Document(DocumentVariant), -} - -/// A single reference-data entry within a [`Context`]. -/// -/// [`Context`]: super::Context -#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] -#[serde(rename_all = "camelCase")] -pub struct ContextEntry { - /// Unique identifier for this entry. - pub id: Uuid, - /// Human-readable label. - #[serde(skip_serializing_if = "Option::is_none")] - pub label: Option, - /// When this entry was created. - #[schemars(with = "String")] - pub created_at: Timestamp, - /// When this entry should stop being used. - #[serde(skip_serializing_if = "Option::is_none")] - #[schemars(with = "Option")] - pub expires_at: Option, - /// Semantically typed payload. - #[serde(flatten)] - pub data: ContextEntryData, -} - -impl ContextEntry { - /// Create a new context entry with a generated UUID and current timestamp. - pub fn new(data: ContextEntryData) -> Self { - Self { - id: Uuid::now_v7(), - label: None, - created_at: Timestamp::now(), - expires_at: None, - data, - } - } - - /// Set a human-readable label on this entry. - pub fn with_label(mut self, label: impl Into) -> Self { - self.label = Some(label.into()); - self - } - - /// Set an expiration timestamp on this entry. - pub fn with_expires_at(mut self, expires_at: Timestamp) -> Self { - self.expires_at = Some(expires_at); - self - } -} diff --git a/crates/nvisy-context/src/geospatial/address.rs b/crates/nvisy-context/src/geospatial/address.rs deleted file mode 100644 index 5b92413a..00000000 --- a/crates/nvisy-context/src/geospatial/address.rs +++ /dev/null @@ -1,30 +0,0 @@ -//! Structured address reference data. - -use std::collections::BTreeMap; - -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -/// Structured address reference. -#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] -#[serde(rename_all = "camelCase")] -pub struct AddressData { - /// Street line (e.g. `"123 Main St"`). - #[serde(skip_serializing_if = "Option::is_none")] - pub street: Option, - /// City name. - #[serde(skip_serializing_if = "Option::is_none")] - pub city: Option, - /// State, province, or administrative area. - #[serde(skip_serializing_if = "Option::is_none")] - pub state: Option, - /// Postal / ZIP code. - #[serde(skip_serializing_if = "Option::is_none")] - pub postal_code: Option, - /// ISO 3166-1 alpha-2 country code. - #[serde(skip_serializing_if = "Option::is_none")] - pub country: Option, - /// Additional free-form address fields. - #[serde(default, skip_serializing_if = "BTreeMap::is_empty")] - pub extra: BTreeMap, -} diff --git a/crates/nvisy-context/src/geospatial/coordinates.rs b/crates/nvisy-context/src/geospatial/coordinates.rs deleted file mode 100644 index ac39e3a8..00000000 --- a/crates/nvisy-context/src/geospatial/coordinates.rs +++ /dev/null @@ -1,30 +0,0 @@ -//! Geographic coordinate primitives. - -use elide_core::primitive::Point; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -/// A geographic coordinate (latitude/longitude). -#[derive(Debug, Clone, Copy, Serialize, Deserialize, JsonSchema)] -#[serde(rename_all = "camelCase")] -pub struct GeoCoordinate { - /// Latitude in decimal degrees (−90 to 90). - pub lat: f64, - /// Longitude in decimal degrees (−180 to 180). - pub lng: f64, -} - -impl GeoCoordinate { - /// Create a new coordinate. - pub fn new(lat: f64, lng: f64) -> Self { - Self { lat, lng } - } - - /// Convert to a [`Point`] for polygon operations. - pub fn to_point(self) -> Point { - Point { - x: self.lng, - y: self.lat, - } - } -} diff --git a/crates/nvisy-context/src/geospatial/mod.rs b/crates/nvisy-context/src/geospatial/mod.rs deleted file mode 100644 index 7fa7f131..00000000 --- a/crates/nvisy-context/src/geospatial/mod.rs +++ /dev/null @@ -1,23 +0,0 @@ -//! Geospatial reference data for location-based matching. - -mod address; -mod coordinates; -mod region; - -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -pub use self::address::AddressData; -pub use self::coordinates::GeoCoordinate; -pub use self::region::{GeoBounds, GeoShape, RegionData}; - -/// Geospatial location variants. -#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] -#[serde(tag = "kind", rename_all = "snake_case")] -#[non_exhaustive] -pub enum GeospatialVariant { - /// Geographic region (bounds, circle, or polygon). - Region(RegionData), - /// Structured postal address. - Address(AddressData), -} diff --git a/crates/nvisy-context/src/geospatial/region.rs b/crates/nvisy-context/src/geospatial/region.rs deleted file mode 100644 index 7d8ec1c3..00000000 --- a/crates/nvisy-context/src/geospatial/region.rs +++ /dev/null @@ -1,100 +0,0 @@ -//! Geospatial region data for location-based detection. - -use elide_core::primitive::Polygon; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -use super::coordinates::GeoCoordinate; - -/// A geographic bounding box defined by its south-west and north-east corners. -#[derive(Debug, Clone, Copy, Serialize, Deserialize, JsonSchema)] -#[serde(rename_all = "camelCase")] -pub struct GeoBounds { - /// South-west corner. - pub south_west: GeoCoordinate, - /// North-east corner. - pub north_east: GeoCoordinate, -} - -impl GeoBounds { - /// Create bounds from corner coordinates. - pub fn new(south_west: GeoCoordinate, north_east: GeoCoordinate) -> Self { - Self { - south_west, - north_east, - } - } - - /// Check whether a coordinate falls within this bounding box. - pub fn contains(&self, point: &GeoCoordinate) -> bool { - point.lat >= self.south_west.lat - && point.lat <= self.north_east.lat - && point.lng >= self.south_west.lng - && point.lng <= self.north_east.lng - } -} - -/// Shape of a geospatial region. -#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] -#[serde(tag = "shape", rename_all = "snake_case")] -#[non_exhaustive] -pub enum GeoShape { - /// Axis-aligned bounding rectangle. - Bounds(GeoBounds), - /// Circular region defined by center and radius. - Circle { - /// Center of the circle. - center: GeoCoordinate, - /// Radius in meters. - radius_m: f64, - }, - /// Arbitrary polygon defined by vertices. - Polygon { - /// Boundary vertices in order (x = lng, y = lat). - boundary: Polygon, - }, -} - -/// Geospatial region reference data for location-based detection. -#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] -#[serde(rename_all = "camelCase")] -pub struct RegionData { - /// The geographic region. - #[serde(flatten)] - pub region: GeoShape, - /// Optional human-readable name for this region. - #[serde(skip_serializing_if = "Option::is_none")] - pub name: Option, -} - -impl RegionData { - /// Create region data from bounds. - pub fn from_bounds(bounds: GeoBounds) -> Self { - Self { - region: GeoShape::Bounds(bounds), - name: None, - } - } - - /// Create a circular region. - pub fn from_circle(center: GeoCoordinate, radius_m: f64) -> Self { - Self { - region: GeoShape::Circle { center, radius_m }, - name: None, - } - } - - /// Create a polygon region. - pub fn from_polygon(boundary: Polygon) -> Self { - Self { - region: GeoShape::Polygon { boundary }, - name: None, - } - } - - /// Set a name on this region. - pub fn with_name(mut self, name: impl Into) -> Self { - self.name = Some(name.into()); - self - } -} diff --git a/crates/nvisy-context/src/lib.rs b/crates/nvisy-context/src/lib.rs deleted file mode 100644 index 0cfa73ac..00000000 --- a/crates/nvisy-context/src/lib.rs +++ /dev/null @@ -1,61 +0,0 @@ -#![forbid(unsafe_code)] -#![cfg_attr(docsrs, feature(doc_cfg))] -#![doc = include_str!("../README.md")] - -//! ## Reference -//! -//! Persistent reference-data collections for detection. -//! -//! A [`Context`] holds reusable reference data (names, faces, -//! voices, patterns, embeddings) that tells detection *what to -//! look for*. It is separate from policy (which controls *what -//! to do* when something is found). - -pub mod analytic; -pub mod biometric; -pub mod document; -mod entry; -pub mod geospatial; -pub mod reference; -pub mod temporal; - -use derive_builder::Builder; -use schemars::JsonSchema; -use semver::Version; -use serde::{Deserialize, Serialize}; -use uuid::Uuid; - -pub use self::entry::{ContextEntry, ContextEntryData}; - -/// A persistent, reusable collection of reference data for detection. -#[derive(Debug, Clone, Builder, Serialize, Deserialize, JsonSchema)] -#[builder( - name = "ContextBuilder", - pattern = "owned", - setter(into, strip_option, prefix = "with") -)] -#[serde(rename_all = "camelCase")] -pub struct Context { - /// Unique identifier for this context. - #[builder(default = "Uuid::now_v7()")] - pub id: Uuid, - /// Human-readable label for this context. - pub name: String, - /// Context version. - #[schemars(with = "String")] - pub version: Version, - /// Optional longer description. - #[builder(default)] - #[serde(skip_serializing_if = "Option::is_none")] - pub description: Option, - /// Reference-data entries. - #[builder(default)] - pub entries: Vec, -} - -impl Context { - /// Start building a new context. - pub fn builder() -> ContextBuilder { - ContextBuilder::default() - } -} diff --git a/crates/nvisy-context/src/reference/credential.rs b/crates/nvisy-context/src/reference/credential.rs deleted file mode 100644 index eb4c63b9..00000000 --- a/crates/nvisy-context/src/reference/credential.rs +++ /dev/null @@ -1,77 +0,0 @@ -//! Credential reference data for secret detection. - -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -/// Classification of credential secrets. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[derive(Serialize, Deserialize, JsonSchema)] -#[serde(rename_all = "snake_case")] -#[non_exhaustive] -pub enum CredentialKind { - /// API key. - ApiKey, - /// OAuth access or refresh token. - OauthToken, - /// Password or passphrase. - Password, - /// Private key (SSH, TLS, etc.). - PrivateKey, - /// Other credential type. - Other, -} - -/// A reference credential for detecting leaked secrets. -/// -/// The `value` field is intentionally excluded from serialization to -/// prevent plaintext secrets from appearing in logs or API responses. -/// It is only accepted during deserialization (ingest). -#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] -#[serde(rename_all = "camelCase")] -pub struct CredentialData { - /// The credential value (API key, token, etc.). - /// - /// Excluded from serialization output to prevent leaking secrets. - /// Round-trip deserialization yields an empty string. - #[serde(default, skip_serializing)] - pub value: String, - /// Classification of this credential. - #[serde(skip_serializing_if = "Option::is_none")] - pub credential_kind: Option, - /// Service or provider this credential belongs to. - #[serde(skip_serializing_if = "Option::is_none")] - pub provider: Option, -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn value_is_not_serialized() { - let cred = CredentialData { - value: "sk-secret-token".to_owned(), - credential_kind: Some(CredentialKind::ApiKey), - provider: Some("openai".to_owned()), - }; - let json = serde_json::to_string(&cred).unwrap(); - assert!( - !json.contains("sk-secret-token"), - "serialized JSON must not contain plaintext value, got: {json}" - ); - assert!(json.contains(r#""credentialKind":"api_key""#)); - } - - #[test] - fn round_trip_defaults_value_to_empty() { - // Serialize without value, then deserialize: value must default to empty string. - let cred = CredentialData { - value: "secret".to_owned(), - credential_kind: None, - provider: None, - }; - let json = serde_json::to_string(&cred).unwrap(); - let back: CredentialData = serde_json::from_str(&json).unwrap(); - assert_eq!(back.value, ""); - } -} diff --git a/crates/nvisy-context/src/reference/image.rs b/crates/nvisy-context/src/reference/image.rs deleted file mode 100644 index 7df9671e..00000000 --- a/crates/nvisy-context/src/reference/image.rs +++ /dev/null @@ -1,17 +0,0 @@ -//! Image reference data for object matching. - -use elide_core::primitive::BoundingBox; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; -use uuid::Uuid; - -/// Reference image for object/scene matching. -#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] -#[serde(rename_all = "camelCase")] -pub struct ImageData { - /// Id of the file holding the reference image. - pub image_source: Uuid, - /// Optional sub-region within the image. - #[serde(skip_serializing_if = "Option::is_none")] - pub region: Option, -} diff --git a/crates/nvisy-context/src/reference/mod.rs b/crates/nvisy-context/src/reference/mod.rs deleted file mode 100644 index cf265600..00000000 --- a/crates/nvisy-context/src/reference/mod.rs +++ /dev/null @@ -1,29 +0,0 @@ -//! Raw reference data for direct comparison against input. - -mod credential; -mod image; -mod tag; -mod text; - -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -pub use self::credential::{CredentialData, CredentialKind}; -pub use self::image::ImageData; -pub use self::tag::TagData; -pub use self::text::{TextData, TextEntry}; - -/// Direct comparison reference variants. -#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] -#[serde(tag = "kind", rename_all = "snake_case")] -#[non_exhaustive] -pub enum ReferenceVariant { - /// Names, identifiers, or phrases to match. - Text(TextData), - /// Keyword tag for classification and routing. - Tag(TagData), - /// API keys, tokens, or known secret patterns. - Credential(CredentialData), - /// Reference image for object/scene matching. - Image(ImageData), -} diff --git a/crates/nvisy-context/src/reference/tag.rs b/crates/nvisy-context/src/reference/tag.rs deleted file mode 100644 index 4753f4c4..00000000 --- a/crates/nvisy-context/src/reference/tag.rs +++ /dev/null @@ -1,15 +0,0 @@ -//! Tag reference data for keyword-based routing. - -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -/// A keyword tag for classification and routing. -#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] -#[serde(rename_all = "camelCase")] -pub struct TagData { - /// The tag value (e.g. `"pii"`, `"financial"`, `"hipaa"`). - pub value: String, - /// Optional category grouping related tags. - #[serde(skip_serializing_if = "Option::is_none")] - pub category: Option, -} diff --git a/crates/nvisy-context/src/reference/text.rs b/crates/nvisy-context/src/reference/text.rs deleted file mode 100644 index 265b6730..00000000 --- a/crates/nvisy-context/src/reference/text.rs +++ /dev/null @@ -1,60 +0,0 @@ -//! Text reference data for direct comparison. - -use elide_core::primitive::LanguageTag; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -/// A labeled text value for reference matching. -/// -/// The `key` is a human/LLM-readable label describing what this value -/// represents (e.g. `"full_name"`, `"account_number"`). The `value` is -/// the literal string used for pattern matching. -#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] -#[serde(rename_all = "camelCase")] -pub struct TextEntry { - /// Human/LLM-readable label. - pub key: String, - /// Literal value for pattern matching. - pub value: String, -} - -/// Textual reference data as key-value pairs. -/// -/// Keys describe *what* a value represents (for humans and LLMs); -/// values are the literal strings used for matching. -#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema)] -#[serde(rename_all = "camelCase")] -pub struct TextData { - /// Key-value pairs for matching. - #[serde(default, skip_serializing_if = "Vec::is_empty")] - pub entries: Vec, - /// BCP-47 language tag for locale-sensitive matching. - #[serde(skip_serializing_if = "Option::is_none")] - pub language: Option, -} - -impl TextData { - /// Create text data from a list of entries. - pub fn new(entries: Vec) -> Self { - Self { - entries, - language: None, - } - } - - /// Set the language for locale-sensitive matching. - pub fn with_language(mut self, language: LanguageTag) -> Self { - self.language = Some(language); - self - } -} - -impl TextEntry { - /// Create a labeled text entry. - pub fn new(key: impl Into, value: impl Into) -> Self { - Self { - key: key.into(), - value: value.into(), - } - } -} diff --git a/crates/nvisy-context/src/temporal/date.rs b/crates/nvisy-context/src/temporal/date.rs deleted file mode 100644 index 0a60b87c..00000000 --- a/crates/nvisy-context/src/temporal/date.rs +++ /dev/null @@ -1,36 +0,0 @@ -//! Date and date-range reference data. - -use jiff::civil::Date; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -/// A date or date-range reference for temporal matching. -#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] -#[serde(rename_all = "camelCase")] -pub struct DateData { - /// Start (or only) date. - #[schemars(with = "String")] - pub start: Date, - /// End date for a range. When `None` this represents a single date. - #[serde(skip_serializing_if = "Option::is_none")] - #[schemars(with = "Option")] - pub end: Option, -} - -impl DateData { - /// Create a single-date reference. - pub fn single(date: Date) -> Self { - Self { - start: date, - end: None, - } - } - - /// Create a date-range reference. - pub fn range(start: Date, end: Date) -> Self { - Self { - start, - end: Some(end), - } - } -} diff --git a/crates/nvisy-context/src/temporal/datetime.rs b/crates/nvisy-context/src/temporal/datetime.rs deleted file mode 100644 index d9e44737..00000000 --- a/crates/nvisy-context/src/temporal/datetime.rs +++ /dev/null @@ -1,43 +0,0 @@ -//! Date-time reference data. - -use jiff::civil::DateTime; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -/// A date-time or date-time range reference for temporal matching. -/// -/// Uses naive (timezone-unaware) date-times from [`DateTime`]. -/// For timezone-aware timestamps, use the entry-level `created_at` / -/// `expires_at` fields on [`ContextEntry`]. -/// -/// [`ContextEntry`]: crate::ContextEntry -/// [`DateTime`]: jiff::civil::DateTime -#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] -#[serde(rename_all = "camelCase")] -pub struct DateTimeData { - /// Start (or only) date-time. - #[schemars(with = "String")] - pub start: DateTime, - /// End date-time for a range. When `None` this represents a single instant. - #[serde(skip_serializing_if = "Option::is_none")] - #[schemars(with = "Option")] - pub end: Option, -} - -impl DateTimeData { - /// Create a single date-time reference. - pub fn single(dt: DateTime) -> Self { - Self { - start: dt, - end: None, - } - } - - /// Create a date-time range reference. - pub fn range(start: DateTime, end: DateTime) -> Self { - Self { - start, - end: Some(end), - } - } -} diff --git a/crates/nvisy-context/src/temporal/mod.rs b/crates/nvisy-context/src/temporal/mod.rs deleted file mode 100644 index 274551bb..00000000 --- a/crates/nvisy-context/src/temporal/mod.rs +++ /dev/null @@ -1,29 +0,0 @@ -//! Date, time, and datetime reference data. - -mod date; -mod datetime; -mod time; -mod timespan; - -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -pub use self::date::DateData; -pub use self::datetime::DateTimeData; -pub use self::time::TimeData; -pub use self::timespan::TimeSpanData; - -/// Temporal matching variants. -#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] -#[serde(tag = "kind", rename_all = "snake_case")] -#[non_exhaustive] -pub enum TemporalVariant { - /// Date or date-range to match (e.g. birthdays, expiry dates). - Date(DateData), - /// Time-of-day or time range (e.g. business hours). - Time(TimeData), - /// Date-time or date-time range (e.g. appointment timestamps). - DateTime(DateTimeData), - /// Time span reference for matching audio/video segments. - TimeSpan(TimeSpanData), -} diff --git a/crates/nvisy-context/src/temporal/time.rs b/crates/nvisy-context/src/temporal/time.rs deleted file mode 100644 index c7734b50..00000000 --- a/crates/nvisy-context/src/temporal/time.rs +++ /dev/null @@ -1,41 +0,0 @@ -//! Time-of-day reference data. - -use jiff::civil::Time; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -/// A time-of-day or time range reference for temporal matching. -/// -/// Uses naive (timezone-unaware) times from [`Time`]. -/// Useful for matching recurring time patterns (e.g. business hours). -/// -/// [`Time`]: jiff::civil::Time -#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] -#[serde(rename_all = "camelCase")] -pub struct TimeData { - /// Start (or only) time. - #[schemars(with = "String")] - pub start: Time, - /// End time for a range. When `None` this represents a single time. - #[serde(skip_serializing_if = "Option::is_none")] - #[schemars(with = "Option")] - pub end: Option