diff --git a/backend/src/lib.rs b/backend/src/lib.rs index 99e506c9..56066702 100644 --- a/backend/src/lib.rs +++ b/backend/src/lib.rs @@ -6,6 +6,7 @@ pub mod config; pub mod connector; pub mod discovery; pub mod legacy; +pub mod logging; pub mod messaging; pub mod protocol; pub mod registry; diff --git a/backend/src/logging.rs b/backend/src/logging.rs new file mode 100644 index 00000000..297c32c1 --- /dev/null +++ b/backend/src/logging.rs @@ -0,0 +1,36 @@ +pub fn resolve_log_format() -> Result<&'static str, String> { + resolve_log_format_from(std::env::var("TOT_LOG_FORMAT").as_deref().ok()) +} + +pub fn resolve_log_format_from(value: Option<&str>) -> Result<&'static str, String> { + match value { + None | Some("") | Some("text") => Ok("text"), + Some("json") => Ok("json"), + Some(other) => Err(format!("invalid TOT_LOG_FORMAT value: {}", other)), + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn defaults_to_text_when_unset() { + assert_eq!(resolve_log_format_from(None).unwrap(), "text"); + } + + #[test] + fn accepts_text() { + assert_eq!(resolve_log_format_from(Some("text")).unwrap(), "text"); + } + + #[test] + fn accepts_json() { + assert_eq!(resolve_log_format_from(Some("json")).unwrap(), "json"); + } + + #[test] + fn rejects_invalid_value() { + assert!(resolve_log_format_from(Some("xml")).is_err()); + } +} diff --git a/backend/src/main.rs b/backend/src/main.rs index 99ee9530..06094eca 100644 --- a/backend/src/main.rs +++ b/backend/src/main.rs @@ -1,6 +1,7 @@ use anyhow::Result; use clap::Parser; use tent_backend::discovery::ServiceDiscovery; +use tent_backend::logging::resolve_log_format; use tent_backend::messaging::MessageBroker; use tent_backend::registry::ServiceRegistry; use tracing_subscriber::EnvFilter; @@ -28,14 +29,23 @@ struct Cli { // It's 30 lines of config loading and then it spawns a server. // Actually it's like 50 lines. Still too fucking many. async fn main() -> Result<()> { - tracing_subscriber::fmt() - .with_env_filter(EnvFilter::try_from_default_env().unwrap_or_else(|_| "info".into())) - .json() - .init(); + let log_format = resolve_log_format().map_err(anyhow::Error::msg)?; + + if log_format == "json" { + tracing_subscriber::fmt() + .with_env_filter(EnvFilter::try_from_default_env().unwrap_or_else(|_| "info".into())) + .json() + .init(); + } else { + tracing_subscriber::fmt() + .with_env_filter(EnvFilter::try_from_default_env().unwrap_or_else(|_| "info".into())) + .init(); + } let cli = Cli::parse(); tracing::info!( + log_format = %log_format, node_id = %cli.node_id, consensus = %cli.consensus, max_connections = %cli.max_connections, @@ -54,10 +64,12 @@ async fn main() -> Result<()> { tracing::info!("all subsystems initialized successfully, entering main loop"); + #[cfg(unix)] let mut signal = tokio::signal::unix::signal( tokio::signal::unix::SignalKind::terminate(), )?; + #[cfg(unix)] tokio::select! { _ = signal.recv() => { tracing::info!("received SIGTERM, initiating graceful shutdown"); @@ -67,6 +79,12 @@ async fn main() -> Result<()> { } } + #[cfg(not(unix))] + { + let _ = tokio::signal::ctrl_c().await; + tracing::info!("received SIGINT, initiating graceful shutdown"); + } + broker.disconnect().await?; discovery.withdraw(&cli.node_id).await?; registry.shutdown().await?; diff --git a/backend/src/protocol/codec.rs b/backend/src/protocol/codec.rs index f9186a43..b1b80430 100644 --- a/backend/src/protocol/codec.rs +++ b/backend/src/protocol/codec.rs @@ -33,7 +33,7 @@ use std::io::{Cursor, Read, Write}; pub const FRAME_MAGIC: u32 = 0x544F5446; /// Size of the frame header in bytes. -pub const FRAME_HEADER_SIZE: usize = 24; +pub const FRAME_HEADER_SIZE: usize = 20; /// Maximum frame payload size (16 MB). pub const FRAME_MAX_PAYLOAD_SIZE: usize = 16 * 1024 * 1024; diff --git a/diagnostic/build-83d2ce30-part001.logd b/diagnostic/build-83d2ce30-part001.logd new file mode 100644 index 00000000..6fdc813a Binary files /dev/null and b/diagnostic/build-83d2ce30-part001.logd differ diff --git a/diagnostic/build-83d2ce30-part002.logd b/diagnostic/build-83d2ce30-part002.logd new file mode 100644 index 00000000..a23b32c6 Binary files /dev/null and b/diagnostic/build-83d2ce30-part002.logd differ diff --git a/diagnostic/build-83d2ce30-part003.logd b/diagnostic/build-83d2ce30-part003.logd new file mode 100644 index 00000000..a9f63609 Binary files /dev/null and b/diagnostic/build-83d2ce30-part003.logd differ diff --git a/diagnostic/build-83d2ce30-part004.logd b/diagnostic/build-83d2ce30-part004.logd new file mode 100644 index 00000000..8fd77507 Binary files /dev/null and b/diagnostic/build-83d2ce30-part004.logd differ diff --git a/diagnostic/build-83d2ce30-part005.logd b/diagnostic/build-83d2ce30-part005.logd new file mode 100644 index 00000000..85196c64 Binary files /dev/null and b/diagnostic/build-83d2ce30-part005.logd differ diff --git a/diagnostic/build-83d2ce30.json b/diagnostic/build-83d2ce30.json new file mode 100644 index 00000000..d5ba3ebf --- /dev/null +++ b/diagnostic/build-83d2ce30.json @@ -0,0 +1,93 @@ +{ + "generated_at": "2026-06-27T19:06:09.521920+00:00", + "commit": "83d2ce30", + "diagnostic_logd": [ + "diagnostic\\build-83d2ce30-part001.logd", + "diagnostic\\build-83d2ce30-part002.logd", + "diagnostic\\build-83d2ce30-part003.logd", + "diagnostic\\build-83d2ce30-part004.logd", + "diagnostic\\build-83d2ce30-part005.logd" + ], + "diagnostic_logd_error": null, + "message_blocker": null, + "chunked": true, + "chunk_size_bytes": 41943040, + "password": "35d30e4807af6e1beec4", + "decrypt_command": "encryptly unpack diagnostic\\build-83d2ce30.logd --password 35d30e4807af6e1beec4", + "total_modules": 10, + "passed": 1, + "failed": 9, + "modules": [ + { + "name": "backend", + "status": "FAIL", + "elapsed_seconds": 0.036, + "artifact": null, + "output": "'cargo' is not recognized as an internal or external command,\noperable program or batch file." + }, + { + "name": "frontend", + "status": "PASS", + "elapsed_seconds": 12.783, + "artifact": "C:\\Users\\Yugansh Tyagi\\Desktop\\bounty\\zeroeye\\frontend\\dist", + "output": "> tent-frontend@0.0.0 build\n> tsc -b && vite build\n\n\u001b[36mvite v6.4.3 \u001b[32mbuilding for production...\u001b[36m\u001b[39m\ntransforming...\n\u001b[32m\u00e2\u0153\u201c\u001b[39m 100 modules transformed.\nrendering chunks...\ncomputing gzip size...\n\u001b[2mdist/\u001b[22m\u001b[32mindex.html \u001b[39m\u001b[1m\u001b[2m 0.63 kB\u001b[22m\u001b[1m\u001b[22m\u001b[2m \u00e2\u201d\u201a gzip: 0.35 kB\u001b[22m\n\u001b[2mdist/\u001b[22m\u001b[36massets/state-BkjSKDbY.js \u001b[39m\u001b[1m\u001b[2m 8.91 kB\u001b[22m\u001b[1m\u001b[22m\u001b[2m \u00e2\u201d\u201a gzip: 3.54 kB\u001b[22m\u001b[2m \u00e2\u201d\u201a map: 57.15 kB\u001b[22m\n\u001b[2mdist/\u001b[22m\u001b[36massets/vendor-CREcWLHI.js \u001b[39m\u001b[1m\u001b[2m 48.93 kB\u001b[22m\u001b[1m\u001b[22m\u001b[2m \u00e2\u201d\u201a gzip: 17.25 kB\u001b[22m\u001b[2m \u00e2\u201d\u201a map: 481.27 kB\u001b[22m\n\u001b[2mdist/\u001b[22m\u001b[36massets/index-CyxcoTyU.js \u001b[39m\u001b[1m\u001b[2m231.32 kB\u001b[22m\u001b[1m\u001b[22m\u001b[2m \u00e2\u201d\u201a gzip: 72.16 kB\u001b[22m\u001b[2m \u00e2\u201d\u201a map: 1,045.57 kB\u001b[22m\n\u001b[32m\u00e2\u0153\u201c built in 1.73s\u001b[39m" + }, + { + "name": "market", + "status": "FAIL", + "elapsed_seconds": 0.037, + "artifact": null, + "output": "'go' is not recognized as an internal or external command,\noperable program or batch file." + }, + { + "name": "frailbox", + "status": "FAIL", + "elapsed_seconds": 0.037, + "artifact": null, + "output": "'make' is not recognized as an internal or external command,\noperable program or batch file." + }, + { + "name": "engine", + "status": "FAIL", + "elapsed_seconds": 0.042, + "artifact": null, + "output": "CMake configure failed:\n'cmake' is not recognized as an internal or external command,\noperable program or batch file." + }, + { + "name": "compliance", + "status": "FAIL", + "elapsed_seconds": 0.038, + "artifact": null, + "output": "'javac' is not recognized as an internal or external command,\noperable program or batch file." + }, + { + "name": "v2-market-stream", + "status": "FAIL", + "elapsed_seconds": 0.037, + "artifact": null, + "output": "'ruby' is not recognized as an internal or external command,\noperable program or batch file." + }, + { + "name": "nfc-scanner", + "status": "FAIL", + "elapsed_seconds": 0.034, + "artifact": null, + "output": "'luac' is not recognized as an internal or external command,\noperable program or batch file." + }, + { + "name": "openapi-haskell", + "status": "FAIL", + "elapsed_seconds": 0.039, + "artifact": null, + "output": "'ghc' is not recognized as an internal or external command,\noperable program or batch file." + }, + { + "name": "openapi-tools", + "status": "FAIL", + "elapsed_seconds": 0.038, + "artifact": null, + "output": "'luac' is not recognized as an internal or external command,\noperable program or batch file." + } + ], + "pr_note": "Include the encrypted diagnostic logd artifact(s): diagnostic\\build-83d2ce30-part001.logd, diagnostic\\build-83d2ce30-part002.logd, diagnostic\\build-83d2ce30-part003.logd, diagnostic\\build-83d2ce30-part004.logd, diagnostic\\build-83d2ce30-part005.logd. The encrypted .logd is the required diagnostic content for PR review; this JSON file is metadata. Maintainers may ask you to remove these diagnostic artifacts before merging." +} diff --git a/diagnostic/build-a82fd981-part001.logd b/diagnostic/build-a82fd981-part001.logd new file mode 100644 index 00000000..fa334812 Binary files /dev/null and b/diagnostic/build-a82fd981-part001.logd differ diff --git a/diagnostic/build-a82fd981-part002.logd b/diagnostic/build-a82fd981-part002.logd new file mode 100644 index 00000000..ff72534d Binary files /dev/null and b/diagnostic/build-a82fd981-part002.logd differ diff --git a/diagnostic/build-a82fd981-part003.logd b/diagnostic/build-a82fd981-part003.logd new file mode 100644 index 00000000..b0fddcf8 Binary files /dev/null and b/diagnostic/build-a82fd981-part003.logd differ diff --git a/diagnostic/build-a82fd981-part004.logd b/diagnostic/build-a82fd981-part004.logd new file mode 100644 index 00000000..83b9dabf Binary files /dev/null and b/diagnostic/build-a82fd981-part004.logd differ diff --git a/diagnostic/build-a82fd981-part005.logd b/diagnostic/build-a82fd981-part005.logd new file mode 100644 index 00000000..9a810afd Binary files /dev/null and b/diagnostic/build-a82fd981-part005.logd differ diff --git a/diagnostic/build-a82fd981.json b/diagnostic/build-a82fd981.json new file mode 100644 index 00000000..51e1a85c --- /dev/null +++ b/diagnostic/build-a82fd981.json @@ -0,0 +1,93 @@ +{ + "generated_at": "2026-06-29T10:49:20.144772+00:00", + "commit": "a82fd981", + "diagnostic_logd": [ + "diagnostic\\build-a82fd981-part001.logd", + "diagnostic\\build-a82fd981-part002.logd", + "diagnostic\\build-a82fd981-part003.logd", + "diagnostic\\build-a82fd981-part004.logd", + "diagnostic\\build-a82fd981-part005.logd" + ], + "diagnostic_logd_error": null, + "message_blocker": null, + "chunked": true, + "chunk_size_bytes": 41943040, + "password": "48c6afe90ef1093a828d", + "decrypt_command": "encryptly unpack diagnostic\\build-a82fd981.logd --password 48c6afe90ef1093a828d", + "total_modules": 10, + "passed": 0, + "failed": 10, + "modules": [ + { + "name": "backend", + "status": "FAIL", + "elapsed_seconds": 68.36, + "artifact": null, + "output": "\u001b[1m\u001b[92m Compiling\u001b[0m quote v1.0.45\n\u001b[1m\u001b[92m Compiling\u001b[0m proc-macro2 v1.0.106\n\u001b[1m\u001b[92m Compiling\u001b[0m serde_core v1.0.228\n\u001b[1m\u001b[92m Compiling\u001b[0m parking_lot_core v0.9.12\n\u001b[1m\u001b[92m Compiling\u001b[0m mio v1.2.1\n\u001b[1m\u001b[92m Compiling\u001b[0m socket2 v0.6.4\n\u001b[1m\u001b[92m Compiling\u001b[0m icu_properties_data v2.2.0\n\u001b[1m\u001b[92m Compiling\u001b[0m hashbrown v0.17.1\n\u001b[1m\u001b[92m Compiling\u001b[0m utf8_iter v1.0.4\n\u001b[1m\u001b[92m Compiling\u001b[0m futures-task v0.3.32\n\u001b[1m\u001b[92m Compiling\u001b[0m icu_normalizer_data v2.2.0\n\u001b[1m\u001b[92m Compiling\u001b[0m version_check v0.9.5\n\u001b[1m\u001b[92m Compiling\u001b[0m percent-encoding v2.3.2\n\u001b[1m\u001b[92m Compiling\u001b[0m http-body v1.0.1\n\u001b[1m\u001b[92m Compiling\u001b[0m parking_lot v0.12.5\n\u001b[1m\u001b[92m Compiling\u001b[0m httparse v1.10.1\n\u001b[1m\u001b[92m Compiling\u001b[0m generic-array v0.14.7\n\u001b[1m\u001b[92m Compiling\u001b[0m syn v2.0.117\n\u001b[1m\u001b[92m Compiling\u001b[0m typenum v1.20.1\n\u001b[1m\u001b[92m Compiling\u001b[0m indexmap v2.14.0\n\u001b[1m\u001b[92m Compiling\u001b[0m native-tls v0.2.18\n\u001b[1m\u001b[92m Compiling\u001b[0m libc v0.2.186\n\u001b[1m\u001b[92m Compiling\u001b[0m atomic-waker v1.1.2\n\u001b[1m\u001b[92m Compiling\u001b[0m fnv v1.0.7\n\u001b[1m\u001b[92m Compiling\u001b[0m try-lock v0.2.5\n\u001b[1m\u001b[92m Compiling\u001b[0m tower-service v0.3.3\n\u001b[1m\u001b[92m Compiling\u001b[0m zmij v1.0.21\n\u001b[1m\u001b[92m Compiling\u001b[0m want v0.3.1\n\u001b[1m\u001b[92m Compiling\u001b[0m form_urlencoded v1.2.2\n\u001b[1m\u001b[92m Compiling\u001b[0m schannel v0.1.29\n\u001b[1m\u001b[92m Compiling\u001b[0m windows-strings v0.5.1\n\u001b[1m\u001b[92m Compiling\u001b[0m aho-corasick v1.1.4\n\u001b[1m\u001b[92m Compiling\u001b[0m windows-result v0.4.1\n\u001b[1m\u001b[92m Compiling\u001b[0m serde_json v1.0.150\n\u001b[1m\u001b[92m Compiling\u001b[0m utf8parse v0.2.2\n\u001b[1m\u001b[92m Compiling\u001b[0m regex-syntax v0.8.11\n\u001b[1m\u001b[92m Compiling\u001b[0m autocfg v1.5.1\n\u001b[1m\u001b[92m Compiling\u001b[0m anstyle v1.0.14\n\u001b[1m\u001b[92m Compiling\u001b[0m once_cell_polyfill v1.70.2\n\u001b[1m\u001b[92m Compiling\u001b[0m anstyle-parse v1.0.0\n\u001b[1m\u001b[92m Compiling\u001b[0m windows-registry v0.6.1\n\u001b[1m\u001b[92m Compiling\u001b[0m anstyle-wincon v3.0.11\n\u001b[1m\u001b[92m Compiling\u001b[0m synstructure v0.13.2\n\u001b[1m\u001b[92m Compiling\u001b[0m anstyle-query v1.1.5\n\u001b[1m\u001b[92m Compiling\u001b[0m sync_wrapper v1.0.2\n\u001b[1m\u001b[92m Compiling\u001b[0m tower-layer v0.3.3\n\u001b[1m\u001b[92m Compiling\u001b[0m getrandom v0.4.2\n\u001b[1m\u001b[92m Compiling\u001b[0m num-traits v0.2.19\n\u001b[1m\u001b[92m Compiling\u001b[0m crossbeam-utils v0.8.21\n\u001b[1m\u001b[92m Compiling\u001b[0m ipnet v2.12.0\n\u001b[1m\u001b[92m Compiling\u001b[0m log v0.4.32\n\u001b[1m\u001b[92m Compiling\u001b[0m colorchoice v1.0.5\n\u001b[1m\u001b[92m Compiling\u001b[0m is_terminal_polyfill v1.70.2\n\u001b[1m\u001b[92m Compiling\u001b[0m base64 v0.22.1\n\u001b[1m\u001b[92m Compiling\u001b[0m crypto-common v0.1.7\n\u001b[1m\u001b[92m Compiling\u001b[0m block-buffer v0.10.4\n\u001b[1m\u001b[92m Compiling\u001b[0m anstream v1.0.0\n\u001b[1m\u001b[92m Compiling\u001b[0m http-body-util v0.1.3\n\u001b[1m\u001b[92m Compiling\u001b[0m ryu v1.0.23\n\u001b[1m\u001b[92m Compiling\u001b[0m thiserror v2.0.18\n\u001b[1m\u001b[92m Compiling\u001b[0m clap_lex v1.1.0\n\u001b[1m\u001b[92m Compiling\u001b[0m heck v0.5.0\n\u001b[1m\u001b[92m Compiling\u001b[0m toml_write v0.1.2\n\u001b[1m\u001b[92m Compiling\u001b[0m regex-automata v0.4.14\n\u001b[1m\u001b[92m Compiling\u001b[0m zeroize v1.9.0\n\u001b[1m\u001b[92m Compiling\u001b[0m lazy_static v1.5.0\n\u001b[1m\u001b[92m Compiling\u001b[0m zerofrom-derive v0.1.7\n\u001b[1m\u001b[92m Compiling\u001b[0m yoke-derive v0.8.2\n\u001b[1m\u001b[92m Compiling\u001b[0m zerovec-derive v0.11.3\n\u001b[1m\u001b[92m Compiling\u001b[0m displaydoc v0.2.6\n\u001b[1m\u001b[92m Compiling\u001b[0m tokio-macros v2.7.0\n\u001b[1m\u001b[92m Compiling\u001b[0m serde_derive v1.0.228\n\u001b[1m\u001b[92m Compiling\u001b[0m futures-macro v0.3.32\n\u001b[1m\u001b[92m Compiling\u001b[0m tracing-attributes v0.1.31\n\u001b[1m\u001b[92m Compiling\u001b[0m bitflags v2.13.0\n\u001b[1m\u001b[92m Compiling\u001b[0m winnow v0.7.15\n\u001b[1m\u001b[92m Compiling\u001b[0m strsim v0.11.1\n\u001b[1m\u001b[92m Compiling\u001b[0m anyhow v1.0.102\n\u001b[1m\u001b[92m Compiling\u001b[0m tokio v1.52.3\n\u001b[1m\u001b[92m Compiling\u001b[0m clap_builder v4.6.0\n\u001b[1m\u001b[92m Compiling\u001b[0m futures-util v0.3.32\n\u001b[1m\u001b[92m Compiling\u001b[0m clap_derive v4.6.1\n\u001b[1m\u001b[92m Compiling\u001b[0m rustls-pki-types v1.14.1\n\u001b[1m\u001b[92m Compiling\u001b[0m zerofrom v0.1.8\n\u001b[1m\u001b[92m Compiling\u001b[0m tracing v0.1.44\n\u001b[1m\u001b[92m Compiling\u001b[0m sharded-slab v0.1.7\n\u001b[1m\u001b[92m Compiling\u001b[0m matchers v0.2.0\n\u001b[1m\u001b[92m Compiling\u001b[0m thiserror-impl v2.0.18\n\u001b[1m\u001b[92m Compiling\u001b[0m yoke v0.8.3\n\u001b[1m\u001b[92m Compiling\u001b[0m digest v0.10.7\n\u001b[1m\u001b[92m Compiling\u001b[0m tracing-log v0.2.0\n\u001b[1m\u001b[92m Compiling\u001b[0m nu-ansi-term v0.50.3\n\u001b[1m\u001b[92m Compiling\u001b[0m serde v1.0.228\n\u001b[1m\u001b[92m Compiling\u001b[0m thread_local v1.1.9\n\u001b[1m\u001b[92m Compiling\u001b[0m encoding_rs v0.8.35\n\u001b[1m\u001b[92m Compiling\u001b[0m hashbrown v0.14.5\n\u001b[1m\u001b[92m Compiling\u001b[0m mime v0.3.17\n\u001b[1m\u001b[92m Compiling\u001b[0m cpufeatures v0.2.17\n\u001b[1m\u001b[92m Compiling\u001b[0m sha2 v0.10.9\n\u001b[1m\u001b[92m Compiling\u001b[0m uuid v1.23.3\n\u001b[1m\u001b[92m Compiling\u001b[0m dashmap v6.2.1\n\u001b[1m\u001b[92m Compiling\u001b[0m zerovec v0.11.6\n\u001b[1m\u001b[92m Compiling\u001b[0m zerotrie v0.2.4\n\u001b[1m\u001b[92m Compiling\u001b[0m serde_spanned v0.6.9\n\u001b[1m\u001b[92m Compiling\u001b[0m toml_datetime v0.6.11\n\u001b[1m\u001b[92m Compiling\u001b[0m tracing-serde v0.2.0\n\u001b[1m\u001b[92m Compiling\u001b[0m serde_urlencoded v0.7.1\n\u001b[1m\u001b[92m Compiling\u001b[0m tracing-subscriber v0.3.23\n\u001b[1m\u001b[92m Compiling\u001b[0m clap v4.6.1\n\u001b[1m\u001b[92m Compiling\u001b[0m toml_edit v0.22.27\n\u001b[1m\u001b[92m Compiling\u001b[0m chrono v0.4.45\n\u001b[1m\u001b[92m Compiling\u001b[0m tinystr v0.8.3\n\u001b[1m\u001b[92m Compiling\u001b[0m potential_utf v0.1.5\n\u001b[1m\u001b[92m Compiling\u001b[0m icu_locale_core v2.2.0\n\u001b[1m\u001b[92m Compiling\u001b[0m icu_collections v2.2.0\n\u001b[1m\u001b[92m Compiling\u001b[0m tokio-util v0.7.18\n\u001b[1m\u001b[92m Compiling\u001b[0m tokio-native-tls v0.3.1\n\u001b[1m\u001b[92m Compiling\u001b[0m tower v0.5.3\n\u001b[1m\u001b[92m Compiling\u001b[0m futures-executor v0.3.32\n\u001b[1m\u001b[92m Compiling\u001b[0m regex v1.12.4\n\u001b[1m\u001b[92m Compiling\u001b[0m icu_provider v2.2.0\n\u001b[1m\u001b[92m Compiling\u001b[0m h2 v0.4.14\n\u001b[1m\u001b[92m Compiling\u001b[0m futures v0.3.32\n\u001b[1m\u001b[92m Compiling\u001b[0m async-trait v0.1.89\n\u001b[1m\u001b[92m Compiling\u001b[0m toml v0.8.23\n\u001b[1m\u001b[92m Compiling\u001b[0m icu_normalizer v2.2.0\n\u001b[1m\u001b[92m Compiling\u001b[0m icu_properties v2.2.0\n\u001b[1m\u001b[92m Compiling\u001b[0m idna_adapter v1.2.2\n\u001b[1m\u001b[92m Compiling\u001b[0m idna v1.1.0\n\u001b[1m\u001b[92m Compiling\u001b[0m url v2.5.8\n\u001b[1m\u001b[92m Compiling\u001b[0m tower-http v0.6.11\n\u001b[1m\u001b[92m Compiling\u001b[0m hyper v1.10.1\n\u001b[1m\u001b[92m Compiling\u001b[0m hyper-util v0.1.20\n\u001b[1m\u001b[92m Compiling\u001b[0m hyper-tls v0.6.0\n\u001b[1m\u001b[92m Compiling\u001b[0m reqwest v0.12.28\n\u001b[1m\u001b[92m Compiling\u001b[0m tent-backend v0.1.0 (C:\\Users\\Yugansh Tyagi\\Desktop\\bounty\\zeroeye\\backend)\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: unused import: `warn`\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\ai\\embeddings.rs:28:28\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m28\u001b[0m \u001b[1m\u001b[96m|\u001b[0m use tracing::{debug, info, warn};\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^\u001b[0m\n \u001b[1m\u001b[96m|\u001b[0m\n \u001b[1m\u001b[96m= \u001b[0m\u001b[1m\u001b[97mnote\u001b[0m: `#[warn(unused_imports)]` (part of `#[warn(unused)]`) on by default\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: unused import: `error`\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\ai\\inference.rs:25:22\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m25\u001b[0m \u001b[1m\u001b[96m|\u001b[0m use tracing::{debug, error, info, warn};\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^\u001b[0m\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: unused imports: `error` and `warn`\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\ai\\mod.rs:40:22\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m40\u001b[0m \u001b[1m\u001b[96m|\u001b[0m use tracing::{debug, error, info, warn};\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^\u001b[0m \u001b[1m\u001b[93m^^^^\u001b[0m\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: unused imports: `c_int` and `c_uint`\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\connector\\bridge.rs:38:20\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m38\u001b[0m \u001b[1m\u001b[96m|\u001b[0m use std::os::raw::{c_int, c_uint, c_ulong};\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^\u001b[0m \u001b[1m\u001b[93m^^^^^^\u001b[0m\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: unused import: `std::ffi::CString`\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\connector\\legacy.rs:35:5\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m35\u001b[0m \u001b[1m\u001b[96m|\u001b[0m use std::ffi::CString;\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: unused import: `c_char`\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\connector\\legacy.rs:36:20\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m36\u001b[0m \u001b[1m\u001b[96m|\u001b[0m use std::os::raw::{c_char, c_ulong};\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^^\u001b[0m\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: unused import: `CStr`\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\connector\\types.rs:27:16\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m27\u001b[0m \u001b[1m\u001b[96m|\u001b[0m use std::ffi::{CStr, CString};\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^\u001b[0m\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: unused imports: `c_double` and `c_long`\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\connector\\types.rs:29:28\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m29\u001b[0m \u001b[1m\u001b[96m|\u001b[0m use std::os::raw::{c_char, c_double, c_int, c_uint, c_void, c_long, c_ulong};\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^^^^\u001b[0m \u001b[1m\u001b[93m^^^^^^\u001b[0m\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: unused import: `AtomicBool`\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\legacy\\deprecations.rs:14:25\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m14\u001b[0m \u001b[1m\u001b[96m|\u001b[0m use std::sync::atomic::{AtomicBool, AtomicU64, AtomicUsize, Ordering};\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: unused imports: `EntityKind` and `legacy_normalize_phone_number`\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\legacy\\v1_compat.rs:8:47\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m8\u001b[0m \u001b[1m\u001b[96m|\u001b[0m use crate::legacy::deprecations::{LegacyUuid, EntityKind, LegacyPagination, legacy_normalize_phone_number};\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^^^^^^\u001b[0m \u001b[1m\u001b[93m^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: unused import: `super::ProtocolError`\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\protocol\\validate.rs:27:5\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m27\u001b[0m \u001b[1m\u001b[96m|\u001b[0m use super::ProtocolError;\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: unused import: `MAX_MESSAGE_SIZE`\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\protocol\\codec.rs:25:38\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m25\u001b[0m \u001b[1m\u001b[96m|\u001b[0m use crate::protocol::{ProtocolError, MAX_MESSAGE_SIZE, MIN_COMPATIBLE_VERSION, PROTOCOL_VERSION};\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: unused import: `Write`\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\protocol\\codec.rs:26:29\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m26\u001b[0m \u001b[1m\u001b[96m|\u001b[0m use std::io::{Cursor, Read, Write};\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^\u001b[0m\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: unused import: `Ordering`\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\protocol\\rpc.rs:25:36\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m25\u001b[0m \u001b[1m\u001b[96m|\u001b[0m use std::sync::atomic::{AtomicU64, Ordering};\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: unused imports: `Duration` and `Instant`\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\protocol\\rpc.rs:27:17\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m27\u001b[0m \u001b[1m\u001b[96m|\u001b[0m use std::time::{Duration, Instant};\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^^^^\u001b[0m \u001b[1m\u001b[93m^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: unused imports: `Deserialize` and `Serialize`\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\protocol\\rpc.rs:28:13\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m28\u001b[0m \u001b[1m\u001b[96m|\u001b[0m use serde::{Deserialize, Serialize};\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^^^^^^^\u001b[0m \u001b[1m\u001b[93m^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: unused import: `MAX_MESSAGE_SIZE`\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\protocol\\rpc.rs:31:28\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m31\u001b[0m \u001b[1m\u001b[96m|\u001b[0m use super::{ProtocolError, MAX_MESSAGE_SIZE, DEFAULT_TIMEOUT_MS};\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: unused imports: `FrameDecoder` and `FrameEncoder`\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\protocol\\rpc.rs:32:27\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m32\u001b[0m \u001b[1m\u001b[96m|\u001b[0m use super::codec::{Frame, FrameEncoder, FrameDecoder, FLAG_REQUIRES_ACK};\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^^^^^^^^\u001b[0m \u001b[1m\u001b[93m^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: use of deprecated unit variant `legacy::deprecations::EntityKind::Team`: Teams are now Organizations. Use Organization instead.\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\legacy\\deprecations.rs:244:25\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m244\u001b[0m \u001b[1m\u001b[96m|\u001b[0m EntityKind::Team => \"org\", // Legacy mapping\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^\u001b[0m\n \u001b[1m\u001b[96m|\u001b[0m\n \u001b[1m\u001b[96m= \u001b[0m\u001b[1m\u001b[97mnote\u001b[0m: `#[warn(deprecated)]` on by default\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: use of deprecated unit variant `legacy::deprecations::EntityKind::Project`: Projects were removed in the Platform v2 migration\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\legacy\\deprecations.rs:245:25\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m245\u001b[0m \u001b[1m\u001b[96m|\u001b[0m EntityKind::Project => \"workspace\", // Legacy mapping\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: use of deprecated unit variant `legacy::deprecations::EntityKind::Team`: Teams are now Organizations. Use Organization instead.\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\legacy\\deprecations.rs:266:25\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m266\u001b[0m \u001b[1m\u001b[96m|\u001b[0m EntityKind::Team\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^\u001b[0m\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: use of deprecated unit variant `legacy::deprecations::EntityKind::Project`: Projects were removed in the Platform v2 migration\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\legacy\\deprecations.rs:267:31\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m267\u001b[0m \u001b[1m\u001b[96m|\u001b[0m | EntityKind::Project\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: variable does not need to be mutable\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\connector\\bridge.rs:317:13\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m317\u001b[0m \u001b[1m\u001b[96m|\u001b[0m let mut buffer = unsafe { &mut *c_buffer };\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[96m----\u001b[0m\u001b[1m\u001b[93m^^^^^^\u001b[0m\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[96m|\u001b[0m\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[96mhelp: remove this `mut`\u001b[0m\n \u001b[1m\u001b[96m|\u001b[0m\n \u001b[1m\u001b[96m= \u001b[0m\u001b[1m\u001b[97mnote\u001b[0m: `#[warn(unused_mut)]` (part of `#[warn(unused)]`) on by default\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: unused variable: `initialized`\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\connector\\bridge.rs:440:13\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m440\u001b[0m \u001b[1m\u001b[96m|\u001b[0m let initialized = Arc::new(AtomicBool::new(true));\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^^^^^^^\u001b[0m \u001b[1m\u001b[93mhelp: if this is intentional, prefix it with an underscore: `_initialized`\u001b[0m\n \u001b[1m\u001b[96m|\u001b[0m\n \u001b[1m\u001b[96m= \u001b[0m\u001b[1m\u001b[97mnote\u001b[0m: `#[warn(unused_variables)]` (part of `#[warn(unused)]`) on by default\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: variable does not need to be mutable\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\connector\\legacy.rs:267:13\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m267\u001b[0m \u001b[1m\u001b[96m|\u001b[0m let mut buffer = unsafe { &mut *c_buffer };\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[96m----\u001b[0m\u001b[1m\u001b[93m^^^^^^\u001b[0m\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[96m|\u001b[0m\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[96mhelp: remove this `mut`\u001b[0m\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: unused variable: `value`\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\legacy\\deprecations.rs:508:15\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m508\u001b[0m \u001b[1m\u001b[96m|\u001b[0m for (key, value) in configs {\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^\u001b[0m \u001b[1m\u001b[93mhelp: if this is intentional, prefix it with an underscore: `_value`\u001b[0m\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: unused variable: `obj`\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\protocol\\validate.rs:282:25\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m282\u001b[0m \u001b[1m\u001b[96m|\u001b[0m if let Some(obj) = value.as_object() {\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^\u001b[0m \u001b[1m\u001b[93mhelp: if this is intentional, prefix it with an underscore: `_obj`\u001b[0m\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: type `BridgeStats` is more private than the item `ConnectorBridge::stats`\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\connector\\bridge.rs:415:5\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m415\u001b[0m \u001b[1m\u001b[96m|\u001b[0m pub fn stats(&self) -> BridgeStats {\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\u001b[0m \u001b[1m\u001b[93mmethod `ConnectorBridge::stats` is reachable at visibility `pub`\u001b[0m\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[92mnote\u001b[0m: but type `BridgeStats` is only usable at visibility `pub(self)`\n \u001b[1m\u001b[96m--> \u001b[0msrc\\connector\\bridge.rs:225:1\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m225\u001b[0m \u001b[1m\u001b[96m|\u001b[0m struct BridgeStats {\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[92m^^^^^^^^^^^^^^^^^^\u001b[0m\n \u001b[1m\u001b[96m= \u001b[0m\u001b[1m\u001b[97mnote\u001b[0m: `#[warn(private_interfaces)]` on by default\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: type `CircuitState` is more private than the item `ConnectorBridge::circuit_state`\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\connector\\bridge.rs:423:5\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m423\u001b[0m \u001b[1m\u001b[96m|\u001b[0m pub fn circuit_state(&self) -> CircuitState {\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\u001b[0m \u001b[1m\u001b[93mmethod `ConnectorBridge::circuit_state` is reachable at visibility `pub`\u001b[0m\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[92mnote\u001b[0m: but type `CircuitState` is only usable at visibility `pub(self)`\n \u001b[1m\u001b[96m--> \u001b[0msrc\\connector\\bridge.rs:79:1\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m 79\u001b[0m \u001b[1m\u001b[96m|\u001b[0m enum CircuitState {\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[92m^^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: constant `NCP_TEMPERATURE` is never used\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\ai\\mod.rs:53:7\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m53\u001b[0m \u001b[1m\u001b[96m|\u001b[0m const NCP_TEMPERATURE: f64 = 0.42;\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^^^^^^^^^^^\u001b[0m\n \u001b[1m\u001b[96m|\u001b[0m\n \u001b[1m\u001b[96m= \u001b[0m\u001b[1m\u001b[97mnote\u001b[0m: `#[warn(dead_code)]` (part of `#[warn(unused)]`) on by default\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: constant `MIN_CONFIDENCE_THRESHOLD` is never used\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\ai\\mod.rs:61:7\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m61\u001b[0m \u001b[1m\u001b[96m|\u001b[0m const MIN_CONFIDENCE_THRESHOLD: f64 = 0.65;\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^^^^^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: constant `MAX_INFERENCE_RETRIES` is never used\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\ai\\mod.rs:65:7\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m65\u001b[0m \u001b[1m\u001b[96m|\u001b[0m const MAX_INFERENCE_RETRIES: u32 = 5;\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: fields `discovery`, `broker`, and `registry` are never read\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\ai\\mod.rs:173:5\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m171\u001b[0m \u001b[1m\u001b[96m|\u001b[0m pub struct AiOrchestrator {\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[96m--------------\u001b[0m \u001b[1m\u001b[96mfields in this struct\u001b[0m\n\u001b[1m\u001b[96m172\u001b[0m \u001b[1m\u001b[96m|\u001b[0m /// Reference to the service discovery subsystem\n\u001b[1m\u001b[96m173\u001b[0m \u001b[1m\u001b[96m|\u001b[0m discovery: Arc>,\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^^^^^\u001b[0m\n\u001b[1m\u001b[96m174\u001b[0m \u001b[1m\u001b[96m|\u001b[0m /// Reference to the message broker subsystem\n\u001b[1m\u001b[96m175\u001b[0m \u001b[1m\u001b[96m|\u001b[0m broker: Arc>,\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^^\u001b[0m\n\u001b[1m\u001b[96m176\u001b[0m \u001b[1m\u001b[96m|\u001b[0m /// Reference to the service registry subsystem\n\u001b[1m\u001b[96m177\u001b[0m \u001b[1m\u001b[96m|\u001b[0m registry: Arc>,\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: field `window_start` is never read\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\ai\\embeddings.rs:661:5\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m658\u001b[0m \u001b[1m\u001b[96m|\u001b[0m pub struct ContextWindowManager {\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[96m--------------------\u001b[0m \u001b[1m\u001b[96mfield in this struct\u001b[0m\n\u001b[1m\u001b[96m...\u001b[0m\n\u001b[1m\u001b[96m661\u001b[0m \u001b[1m\u001b[96m|\u001b[0m window_start: Instant,\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: constant `MAX_RETRIES` is never used\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\ai\\inference.rs:41:7\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m41\u001b[0m \u001b[1m\u001b[96m|\u001b[0m const MAX_RETRIES: u32 = 3;\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: constant `RETRY_BASE_DELAY_MS` is never used\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\ai\\inference.rs:44:7\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m44\u001b[0m \u001b[1m\u001b[96m|\u001b[0m const RETRY_BASE_DELAY_MS: u64 = 1000;\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: fields `api_key`, `base_url`, and `client` are never read\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\ai\\inference.rs:453:5\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m452\u001b[0m \u001b[1m\u001b[96m|\u001b[0m pub struct AnthropicClient {\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[96m---------------\u001b[0m \u001b[1m\u001b[96mfields in this struct\u001b[0m\n\u001b[1m\u001b[96m453\u001b[0m \u001b[1m\u001b[96m|\u001b[0m api_key: String,\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^^^\u001b[0m\n\u001b[1m\u001b[96m454\u001b[0m \u001b[1m\u001b[96m|\u001b[0m base_url: String,\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^^^^\u001b[0m\n\u001b[1m\u001b[96m455\u001b[0m \u001b[1m\u001b[96m|\u001b[0m models: Vec,\n\u001b[1m\u001b[96m456\u001b[0m \u001b[1m\u001b[96m|\u001b[0m client: reqwest::Client,\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^^\u001b[0m\n \u001b[1m\u001b[96m|\u001b[0m\n \u001b[1m\u001b[96m= \u001b[0m\u001b[1m\u001b[97mnote\u001b[0m: `AnthropicClient` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: field `routing_table` is never read\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\ai\\inference.rs:719:5\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m716\u001b[0m \u001b[1m\u001b[96m|\u001b[0m pub struct ModelRouter {\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[96m-----------\u001b[0m \u001b[1m\u001b[96mfield in this struct\u001b[0m\n\u001b[1m\u001b[96m...\u001b[0m\n\u001b[1m\u001b[96m719\u001b[0m \u001b[1m\u001b[96m|\u001b[0m routing_table: RwLock>,\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^^^^^^^^^\u001b[0m\n \u001b[1m\u001b[96m|\u001b[0m\n \u001b[1m\u001b[96m= \u001b[0m\u001b[1m\u001b[97mnote\u001b[0m: `ModelRouter` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: field `cost_history` is never read\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\ai\\inference.rs:951:5\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m947\u001b[0m \u001b[1m\u001b[96m|\u001b[0m pub struct TokenCounter {\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[96m------------\u001b[0m \u001b[1m\u001b[96mfield in this struct\u001b[0m\n\u001b[1m\u001b[96m...\u001b[0m\n\u001b[1m\u001b[96m951\u001b[0m \u001b[1m\u001b[96m|\u001b[0m cost_history: RwLock>,\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: constant `HEALTH_CHECK_TIMEOUT_MS` is never used\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\connector\\bridge.rs:64:7\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m64\u001b[0m \u001b[1m\u001b[96m|\u001b[0m const HEALTH_CHECK_TIMEOUT_MS: u64 = 1000;\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^^^^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: field `id` is never read\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\connector\\bridge.rs:152:5\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m151\u001b[0m \u001b[1m\u001b[96m|\u001b[0m struct PoolEntry {\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[96m---------\u001b[0m \u001b[1m\u001b[96mfield in this struct\u001b[0m\n\u001b[1m\u001b[96m152\u001b[0m \u001b[1m\u001b[96m|\u001b[0m id: usize,\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^\u001b[0m\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: method `stats` is never used\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\connector\\bridge.rs:195:8\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m163\u001b[0m \u001b[1m\u001b[96m|\u001b[0m impl ConnectionPool {\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[96m-------------------\u001b[0m \u001b[1m\u001b[96mmethod in this implementation\u001b[0m\n\u001b[1m\u001b[96m...\u001b[0m\n\u001b[1m\u001b[96m195\u001b[0m \u001b[1m\u001b[96m|\u001b[0m fn stats(&self) -> PoolStats {\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^\u001b[0m\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: struct `PoolStats` is never constructed\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\connector\\bridge.rs:203:8\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m203\u001b[0m \u001b[1m\u001b[96m|\u001b[0m struct PoolStats {\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: fields `circuit_breaker_trips` and `health_check_failures` are never read\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\connector\\bridge.rs:229:5\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m225\u001b[0m \u001b[1m\u001b[96m|\u001b[0m struct BridgeStats {\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[96m-----------\u001b[0m \u001b[1m\u001b[96mfields in this struct\u001b[0m\n\u001b[1m\u001b[96m...\u001b[0m\n\u001b[1m\u001b[96m229\u001b[0m \u001b[1m\u001b[96m|\u001b[0m circuit_breaker_trips: u64,\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^^^^^^^^^^^^^^^^^\u001b[0m\n\u001b[1m\u001b[96m230\u001b[0m \u001b[1m\u001b[96m|\u001b[0m health_check_failures: u64,\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^^^^^^^^^^^^^^^^^\u001b[0m\n \u001b[1m\u001b[96m|\u001b[0m\n \u001b[1m\u001b[96m= \u001b[0m\u001b[1m\u001b[97mnote\u001b[0m: `BridgeStats` has derived impls for the traits `Clone` and `Debug`, but these are intentionally ignored during dead code analysis\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: field `consumers` is never read\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\messaging\\mod.rs:38:5\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m35\u001b[0m \u001b[1m\u001b[96m|\u001b[0m pub struct MessageBroker {\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[96m-------------\u001b[0m \u001b[1m\u001b[96mfield in this struct\u001b[0m\n\u001b[1m\u001b[96m...\u001b[0m\n\u001b[1m\u001b[96m38\u001b[0m \u001b[1m\u001b[96m|\u001b[0m consumers: DashMap>>,\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: field `version` is never read\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\protocol\\messages.rs:293:5\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m291\u001b[0m \u001b[1m\u001b[96m|\u001b[0m pub struct MessageRegistry {\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[96m---------------\u001b[0m \u001b[1m\u001b[96mfield in this struct\u001b[0m\n\u001b[1m\u001b[96m292\u001b[0m \u001b[1m\u001b[96m|\u001b[0m handlers: HashMap,\n\u001b[1m\u001b[96m293\u001b[0m \u001b[1m\u001b[96m|\u001b[0m version: u32,\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: field `version` is never read\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\protocol\\serialize.rs:258:5\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m255\u001b[0m \u001b[1m\u001b[96m|\u001b[0m struct Schema {\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[96m------\u001b[0m \u001b[1m\u001b[96mfield in this struct\u001b[0m\n\u001b[1m\u001b[96m...\u001b[0m\n\u001b[1m\u001b[96m258\u001b[0m \u001b[1m\u001b[96m|\u001b[0m version: u32,\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: fields `required` and `default_value` are never read\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\protocol\\serialize.rs:264:5\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m261\u001b[0m \u001b[1m\u001b[96m|\u001b[0m struct SchemaField {\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[96m-----------\u001b[0m \u001b[1m\u001b[96mfields in this struct\u001b[0m\n\u001b[1m\u001b[96m...\u001b[0m\n\u001b[1m\u001b[96m264\u001b[0m \u001b[1m\u001b[96m|\u001b[0m required: bool,\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^^^^\u001b[0m\n\u001b[1m\u001b[96m265\u001b[0m \u001b[1m\u001b[96m|\u001b[0m default_value: Option,\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: variant `Custom` is never constructed\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\protocol\\serialize.rs:276:5\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m269\u001b[0m \u001b[1m\u001b[96m|\u001b[0m enum FieldValidation {\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[96m---------------\u001b[0m \u001b[1m\u001b[96mvariant in this enum\u001b[0m\n\u001b[1m\u001b[96m...\u001b[0m\n\u001b[1m\u001b[96m276\u001b[0m \u001b[1m\u001b[96m|\u001b[0m Custom(String),\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^^\u001b[0m\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: fields `next_request_id`, `pending_requests`, `serializer`, and `timeout_ms` are never read\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\protocol\\rpc.rs:218:5\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m217\u001b[0m \u001b[1m\u001b[96m|\u001b[0m pub struct RpcClient {\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[96m---------\u001b[0m \u001b[1m\u001b[96mfields in this struct\u001b[0m\n\u001b[1m\u001b[96m218\u001b[0m \u001b[1m\u001b[96m|\u001b[0m next_request_id: AtomicU64,\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^^^^^^^^^^^\u001b[0m\n\u001b[1m\u001b[96m219\u001b[0m \u001b[1m\u001b[96m|\u001b[0m pending_requests: Arc, RpcError>>>>>,\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^^^^^^^^^^^^\u001b[0m\n\u001b[1m\u001b[96m220\u001b[0m \u001b[1m\u001b[96m|\u001b[0m serializer: Serializer,\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^^^^^^\u001b[0m\n\u001b[1m\u001b[96m221\u001b[0m \u001b[1m\u001b[96m|\u001b[0m timeout_ms: u64,\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: field `serializer` is never read\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\protocol\\rpc.rs:271:5\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m269\u001b[0m \u001b[1m\u001b[96m|\u001b[0m pub struct RpcServer {\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[96m---------\u001b[0m \u001b[1m\u001b[96mfield in this struct\u001b[0m\n\u001b[1m\u001b[96m270\u001b[0m \u001b[1m\u001b[96m|\u001b[0m handlers: HashMap,\n\u001b[1m\u001b[96m271\u001b[0m \u001b[1m\u001b[96m|\u001b[0m serializer: Serializer,\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[93mwarning\u001b[0m\u001b[1m\u001b[97m: field `events` is never read\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\registry\\mod.rs:31:5\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m28\u001b[0m \u001b[1m\u001b[96m|\u001b[0m pub struct ServiceRegistry {\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[96m---------------\u001b[0m \u001b[1m\u001b[96mfield in this struct\u001b[0m\n\u001b[1m\u001b[96m...\u001b[0m\n\u001b[1m\u001b[96m31\u001b[0m \u001b[1m\u001b[96m|\u001b[0m events: Arc>>,\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[93m^^^^^^\u001b[0m\n\n\u001b[1m\u001b[93mwarning\u001b[0m: `tent-backend` (lib) generated 52 warnings (run `cargo fix --lib -p tent-backend` to apply 23 suggestions)\n\u001b[1m\u001b[91merror[E0433]\u001b[0m\u001b[1m\u001b[97m: cannot find `unix` in `signal`\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\main.rs:67:37\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m67\u001b[0m \u001b[1m\u001b[96m|\u001b[0m let mut signal = tokio::signal::unix::signal(\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[91m^^^^\u001b[0m \u001b[1m\u001b[91mcould not find `unix` in `signal`\u001b[0m\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[92mnote\u001b[0m: found an item that was configured out\n \u001b[1m\u001b[96m--> \u001b[0mC:\\Users\\Yugansh Tyagi\\.cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\tokio-1.52.3\\src\\signal\\mod.rs:56:9\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m56\u001b[0m \u001b[1m\u001b[96m|\u001b[0m pub mod unix;\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[92m^^^^\u001b[0m\n \u001b[1m\u001b[96m|\u001b[0m\n \u001b[1m\u001b[96m::: \u001b[0mC:\\Users\\Yugansh Tyagi\\.cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\tokio-1.52.3\\src\\signal\\unix.rs:6:8\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m 6\u001b[0m \u001b[1m\u001b[96m|\u001b[0m #![cfg(unix)]\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[96m----\u001b[0m \u001b[1m\u001b[96mthe item is gated here\u001b[0m\n\n\u001b[1m\u001b[91merror[E0433]\u001b[0m\u001b[1m\u001b[97m: cannot find `unix` in `signal`\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\main.rs:68:24\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m68\u001b[0m \u001b[1m\u001b[96m|\u001b[0m tokio::signal::unix::SignalKind::terminate(),\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[91m^^^^\u001b[0m \u001b[1m\u001b[91mcould not find `unix` in `signal`\u001b[0m\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[92mnote\u001b[0m: found an item that was configured out\n \u001b[1m\u001b[96m--> \u001b[0mC:\\Users\\Yugansh Tyagi\\.cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\tokio-1.52.3\\src\\signal\\mod.rs:56:9\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m56\u001b[0m \u001b[1m\u001b[96m|\u001b[0m pub mod unix;\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[92m^^^^\u001b[0m\n \u001b[1m\u001b[96m|\u001b[0m\n \u001b[1m\u001b[96m::: \u001b[0mC:\\Users\\Yugansh Tyagi\\.cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\tokio-1.52.3\\src\\signal\\unix.rs:6:8\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m 6\u001b[0m \u001b[1m\u001b[96m|\u001b[0m #![cfg(unix)]\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[96m----\u001b[0m \u001b[1m\u001b[96mthe item is gated here\u001b[0m\n\n\u001b[1m\u001b[91merror[E0277]\u001b[0m\u001b[1m\u001b[97m: `?` couldn't convert the error: `std::string::String: std::error::Error` is not satisfied\u001b[0m\n \u001b[1m\u001b[96m--> \u001b[0msrc\\main.rs:32:42\n \u001b[1m\u001b[96m|\u001b[0m\n\u001b[1m\u001b[96m32\u001b[0m \u001b[1m\u001b[96m|\u001b[0m let log_format = resolve_log_format()?;\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[96m--------------------\u001b[0m\u001b[1m\u001b[91m^\u001b[0m \u001b[1m\u001b[91mthe trait `std::error::Error` is not implemented for `std::string::String`\u001b[0m\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[96m|\u001b[0m\n \u001b[1m\u001b[96m|\u001b[0m \u001b[1m\u001b[96mthis has type `Result<_, std::string::String>`\u001b[0m\n \u001b[1m\u001b[96m|\u001b[0m\n \u001b[1m\u001b[96m= \u001b[0m\u001b[1m\u001b[97mnote\u001b[0m: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait\n \u001b[1m\u001b[96m= \u001b[0m\u001b[1m\u001b[97mnote\u001b[0m: required for `anyhow::Error` to implement `From`\n\n\u001b[1m\u001b[97mSome errors have detailed explanations: E0277, E0433.\u001b[0m\n\u001b[1m\u001b[97mFor more information about an error, try `rustc --explain E0277`.\u001b[0m\n\u001b[1m\u001b[91merror\u001b[0m: could not compile `tent-backend` (bin \"tent-backend\") due to 3 previous errors" + }, + { + "name": "frontend", + "status": "FAIL", + "elapsed_seconds": 0, + "artifact": null, + "output": "Command not found: [WinError 2] The system cannot find the file specified" + }, + { + "name": "market", + "status": "FAIL", + "elapsed_seconds": 0, + "artifact": null, + "output": "Command not found: [WinError 2] The system cannot find the file specified" + }, + { + "name": "frailbox", + "status": "FAIL", + "elapsed_seconds": 0, + "artifact": null, + "output": "Command not found: [WinError 2] The system cannot find the file specified" + }, + { + "name": "engine", + "status": "FAIL", + "elapsed_seconds": 0, + "artifact": null, + "output": "Command not found: [WinError 2] The system cannot find the file specified" + }, + { + "name": "compliance", + "status": "FAIL", + "elapsed_seconds": 0, + "artifact": null, + "output": "Command not found: [WinError 2] The system cannot find the file specified" + }, + { + "name": "v2-market-stream", + "status": "FAIL", + "elapsed_seconds": 0, + "artifact": null, + "output": "Command not found: [WinError 2] The system cannot find the file specified" + }, + { + "name": "nfc-scanner", + "status": "FAIL", + "elapsed_seconds": 0, + "artifact": null, + "output": "Command not found: [WinError 2] The system cannot find the file specified" + }, + { + "name": "openapi-haskell", + "status": "FAIL", + "elapsed_seconds": 0, + "artifact": null, + "output": "Command not found: [WinError 2] The system cannot find the file specified" + }, + { + "name": "openapi-tools", + "status": "FAIL", + "elapsed_seconds": 0, + "artifact": null, + "output": "Command not found: [WinError 2] The system cannot find the file specified" + } + ], + "pr_note": "Include the encrypted diagnostic logd artifact(s): diagnostic\\build-a82fd981-part001.logd, diagnostic\\build-a82fd981-part002.logd, diagnostic\\build-a82fd981-part003.logd, diagnostic\\build-a82fd981-part004.logd, diagnostic\\build-a82fd981-part005.logd. The encrypted .logd is the required diagnostic content for PR review; this JSON file is metadata. Maintainers may ask you to remove these diagnostic artifacts before merging." +} diff --git a/docs/OPERATIONS.md b/docs/OPERATIONS.md index 58642e7b..e9e5f4e3 100644 --- a/docs/OPERATIONS.md +++ b/docs/OPERATIONS.md @@ -15,6 +15,18 @@ ## Monitoring +### Log Format + +The backend log format is controlled by the `TOT_LOG_FORMAT` environment variable: + +| Value | Behavior | +|-------|----------| +| `text` | Plain text logs (default) | +| `json` | JSON-formatted structured logs | +| any other value | Startup fails with an error | + +The selected format is emitted as the `log_format` field in the backend startup log event so operators can confirm the active mode from the logs. + ### Health Check Endpoints Each service exposes a health check endpoint: diff --git a/tools/test_verify_diagnostics.py b/tools/test_verify_diagnostics.py new file mode 100644 index 00000000..ee169543 --- /dev/null +++ b/tools/test_verify_diagnostics.py @@ -0,0 +1,162 @@ +#!/usr/bin/env python3 +"""Tests for tools/verify_diagnostics.py""" + +import json +import sys +import tempfile +from pathlib import Path + +import pytest + +ROOT = Path(__file__).resolve().parent.parent +sys.path.insert(0, str(ROOT / "tools")) + +from verify_diagnostics import ( + validate_schema, + find_latest_diagnostic, + run_verification, +) + + +@pytest.fixture +def valid_report(tmp_path): + report = { + "generated_at": "2026-06-27T00:00:00+00:00", + "commit": "abc1234", + "diagnostic_logd": "diagnostic/build-abc1234.logd", + "diagnostic_logd_error": None, + "chunked": False, + "chunk_size_bytes": None, + "password": None, + "decrypt_command": None, + "total_modules": 2, + "passed": 1, + "failed": 1, + "modules": [ + { + "name": "backend", + "status": "PASS", + "elapsed_seconds": 1.23, + "artifact": "backend/target/debug/backend", + "output": "Build successful", + }, + { + "name": "frontend", + "status": "FAIL", + "elapsed_seconds": 0.5, + "artifact": None, + "output": "npm install failed", + }, + ], + "pr_note": "Include the diagnostic log.", + } + p = tmp_path / "build-abc1234.json" + p.write_text(json.dumps(report), encoding="utf-8") + return p + + +@pytest.fixture +def invalid_schema_report(tmp_path): + report = { + "generated_at": "2026-06-27T00:00:00+00:00", + "commit": "abc1234", + "total_modules": 1, + "passed": 1, + "failed": 0, + } + p = tmp_path / "build-bad.json" + p.write_text(json.dumps(report), encoding="utf-8") + return p + + +def test_validate_schema_valid(valid_report): + data = json.loads(valid_report.read_text(encoding="utf-8")) + errors = validate_schema(data) + assert errors == [] + + +def test_validate_schema_missing_modules(invalid_schema_report): + data = json.loads(invalid_schema_report.read_text(encoding="utf-8")) + errors = validate_schema(data) + assert any("modules" in e for e in errors) + + +def test_validate_schema_bad_status(tmp_path): + report = { + "generated_at": "2026-06-27T00:00:00+00:00", + "commit": "abc1234", + "total_modules": 1, + "passed": 1, + "failed": 0, + "modules": [ + {"name": "backend", "status": "UNKNOWN", "elapsed_seconds": 1.0, "artifact": None, "output": None}, + ], + } + p = tmp_path / "build-bad-status.json" + p.write_text(json.dumps(report), encoding="utf-8") + data = json.loads(p.read_text(encoding="utf-8")) + errors = validate_schema(data) + assert any("invalid status" in e for e in errors) + + +def test_validate_schema_count_mismatch(tmp_path): + report = { + "generated_at": "2026-06-27T00:00:00+00:00", + "commit": "abc1234", + "total_modules": 2, + "passed": 1, + "failed": 1, + "modules": [ + {"name": "a", "status": "PASS", "elapsed_seconds": 1.0, "artifact": None, "output": None}, + ], + } + p = tmp_path / "build-mismatch.json" + p.write_text(json.dumps(report), encoding="utf-8") + data = json.loads(p.read_text(encoding="utf-8")) + errors = validate_schema(data) + assert any("total_modules does not match number of module entries" in e for e in errors) + + +def test_run_verification_valid(valid_report): + code, report = run_verification(valid_report, threshold=0, json_output=True) + assert code == 0 + assert report["valid"] is True + assert report["passed"] == 1 + assert report["failed"] == 1 + + +def test_run_verification_threshold_not_met(valid_report): + code, report = run_verification(valid_report, threshold=2, json_output=True) + assert code == 1 + assert report["threshold_met"] is False + + +def test_run_verification_missing_file(tmp_path): + missing = tmp_path / "does-not-exist.json" + code, report = run_verification(missing, json_output=True) + assert code == 1 + assert "not found" in report["error"] + + +def test_run_verification_invalid_json(tmp_path): + p = tmp_path / "bad.json" + p.write_text("not json", encoding="utf-8") + code, report = run_verification(p, json_output=True) + assert code == 1 + assert "Invalid JSON" in report["error"] + + +def test_find_latest_diagnostic(tmp_path, monkeypatch): + monkeypatch.setattr("verify_diagnostics.DIAGNOSTIC_DIR", tmp_path) + (tmp_path / "build-old.json").write_text("{}", encoding="utf-8") + (tmp_path / "build-new.json").write_text("{}", encoding="utf-8") + import time + time.sleep(0.05) + latest = find_latest_diagnostic() + assert latest is not None + assert latest.name == "build-new.json" + + +def test_find_latest_diagnostic_missing(tmp_path, monkeypatch): + monkeypatch.setattr("verify_diagnostics.DIAGNOSTIC_DIR", tmp_path) + assert find_latest_diagnostic() is None diff --git a/tools/verify_diagnostics.py b/tools/verify_diagnostics.py new file mode 100644 index 00000000..b2a22be3 --- /dev/null +++ b/tools/verify_diagnostics.py @@ -0,0 +1,294 @@ +#!/usr/bin/env python3 +""" +Verify build diagnostic artifacts for the Tent of Trials platform. + +Reads the latest (or specified) diagnostic JSON report from the diagnostic/ +directory, validates its schema, and reports module-level build results. + +Usage: + python3 tools/verify_diagnostics.py Verify latest diagnostics + python3 tools/verify_diagnostics.py --verbose Show detailed failure output + python3 tools/verify_diagnostics.py --json JSON output for machines + python3 tools/verify_diagnostics.py --threshold 3 Require >=3 passing modules + python3 tools/verify_diagnostics.py -f diagnostic/build-abc123.json +""" + +import argparse +import json +import subprocess +import sys +from pathlib import Path +from typing import Any, Dict, List, Optional, Tuple + +try: + sys.stdout.reconfigure(encoding="utf-8") +except Exception: + pass + +ROOT = Path(__file__).resolve().parent.parent +DIAGNOSTIC_DIR = ROOT / "diagnostic" + +REQUIRED_TOP_LEVEL_FIELDS = { + "generated_at": str, + "commit": str, + "total_modules": int, + "passed": int, + "failed": int, + "modules": list, +} + +REQUIRED_MODULE_FIELDS = { + "name": str, + "status": str, + "elapsed_seconds": (int, float), + "artifact": (str, type(None)), + "output": (str, type(None)), +} + +VALID_STATUSES = {"PASS", "FAIL"} + + +def find_latest_diagnostic() -> Optional[Path]: + if not DIAGNOSTIC_DIR.exists(): + return None + json_files = sorted( + DIAGNOSTIC_DIR.glob("build-*.json"), + key=lambda p: p.stat().st_mtime, + reverse=True, + ) + return json_files[0] if json_files else None + + +def validate_schema(data: dict) -> List[str]: + errors: List[str] = [] + + for field, expected_type in REQUIRED_TOP_LEVEL_FIELDS.items(): + if field not in data: + errors.append(f"Missing required field: {field}") + elif not isinstance(data[field], expected_type): + errors.append( + f"Field '{field}' has wrong type: expected {expected_type.__name__}, " + f"got {type(data[field]).__name__}" + ) + + if "modules" in data and isinstance(data["modules"], list): + for i, module in enumerate(data["modules"]): + mod_name = module.get("name", "?") if isinstance(module, dict) else "?" + if not isinstance(module, dict): + errors.append(f"Module {i}: not a JSON object") + continue + for field, expected_type in REQUIRED_MODULE_FIELDS.items(): + if field not in module: + errors.append(f"Module {i} ({mod_name}): missing field '{field}'") + elif not isinstance(module[field], expected_type): + errors.append( + f"Module {i} ({mod_name}): field '{field}' has wrong type" + ) + if "status" in module and module["status"] not in VALID_STATUSES: + errors.append( + f"Module {i} ({mod_name}): invalid status '{module['status']}'" + ) + + if all(k in data for k in ("total_modules", "passed", "failed")): + if data["total_modules"] != data["passed"] + data["failed"]: + errors.append( + "total_modules does not equal passed + failed " + f"({data['total_modules']} != {data['passed']} + {data['failed']})" + ) + + if "modules" in data and isinstance(data["modules"], list): + if "total_modules" in data and data["total_modules"] != len(data["modules"]): + errors.append( + "total_modules does not match number of module entries " + f"({data['total_modules']} != {len(data['modules'])})" + ) + + return errors + + +def verify_commit_exists(commit_id: str) -> Tuple[bool, str]: + try: + result = subprocess.run( + ["git", "rev-parse", "--verify", commit_id], + cwd=str(ROOT), + capture_output=True, + text=True, + timeout=5, + ) + if result.returncode == 0: + return True, "" + return False, result.stderr.strip() or result.stdout.strip() + except subprocess.TimeoutExpired: + return False, "git rev-parse timed out" + except FileNotFoundError: + return False, "git executable not found" + except Exception as e: + return False, str(e) + + +def run_verification( + diagnostic_path: Path, + threshold: int = 0, + verbose: bool = False, + json_output: bool = False, +) -> Tuple[int, Dict[str, Any]]: + report: Dict[str, Any] = { + "diagnostic_file": str(diagnostic_path), + "valid": False, + "schema_errors": [], + "modules": [], + "passed": 0, + "failed": 0, + "total": 0, + "threshold_met": False, + "commit_verified": False, + "commit_error": None, + "error": None, + } + + try: + text = diagnostic_path.read_text(encoding="utf-8") + data = json.loads(text) + except FileNotFoundError: + report["error"] = f"Diagnostic file not found: {diagnostic_path}" + return _format_result(report, json_output, 1) + except json.JSONDecodeError as exc: + report["error"] = f"Invalid JSON in {diagnostic_path}: {exc}" + return _format_result(report, json_output, 1) + except Exception as exc: + report["error"] = f"Failed to read {diagnostic_path}: {exc}" + return _format_result(report, json_output, 1) + + schema_errors = validate_schema(data) + report["schema_errors"] = schema_errors + report["valid"] = len(schema_errors) == 0 + + if not report["valid"]: + report["error"] = "Schema validation failed" + return _format_result(report, json_output, 1) + + commit_id = data.get("commit", "00000000") + commit_ok, commit_err = verify_commit_exists(commit_id) + report["commit_verified"] = commit_ok + report["commit_error"] = commit_err or None + + modules = data.get("modules", []) + report["modules"] = modules + report["total"] = len(modules) + report["passed"] = sum(1 for m in modules if m.get("status") == "PASS") + report["failed"] = sum(1 for m in modules if m.get("status") == "FAIL") + report["threshold_met"] = report["passed"] >= threshold + + if json_output: + return 0 if report["threshold_met"] else 1, report + + try: + display_path = diagnostic_path.relative_to(ROOT) + except ValueError: + display_path = diagnostic_path + + print(f"\nVerifying diagnostic: {display_path}") + print(f"Commit: {commit_id}") + print(f"Generated: {data.get('generated_at', 'unknown')}") + print() + print(f"Total modules: {report['total']}") + print(f"Passed: {report['passed']}") + print(f"Failed: {report['failed']}") + print() + + for module in modules: + name = module.get("name", "unknown") + status = module.get("status", "UNKNOWN") + elapsed = module.get("elapsed_seconds", 0) + icon = "\u2713" if status == "PASS" else "\u2717" + color_pass = "\033[92m" + color_fail = "\033[91m" + reset = "\033[0m" + code = color_pass if status == "PASS" else color_fail + print(f" {icon} {name}: {code}{status}{reset} ({elapsed:.2f}s)") + if status != "PASS" and verbose and module.get("output"): + lines = module["output"].strip().split("\n") + print(" last output:") + for line in lines[-5:]: + print(f" {line}") + + print() + if not commit_ok: + print(f" WARNING: commit verification failed: {commit_err}") + if report["threshold_met"]: + print(f" Threshold met: {report['passed']} passed (required: {threshold})") + return 0, report + print(f" Threshold not met: {report['passed']} passed (required: {threshold})") + return 1, report + + +def _format_result(report: Dict[str, Any], json_output: bool, code: int) -> Tuple[int, Dict[str, Any]]: + if json_output: + return code, report + print(f"ERROR: {report['error']}") + for err in report.get("schema_errors", []): + print(f" - {err}") + return code, report + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser( + description="Verify build diagnostic artifacts for Tent of Trials" + ) + parser.add_argument( + "--verbose", "-v", + action="store_true", + help="Show detailed output including failure logs", + ) + parser.add_argument( + "--json", "-j", + action="store_true", + help="Output results as JSON for machine consumption", + ) + parser.add_argument( + "--threshold", "-t", + type=int, + default=0, + help="Minimum number of passing modules required (default: 0)", + ) + parser.add_argument( + "--file", "-f", + type=str, + default=None, + help="Path to diagnostic JSON file (default: latest in diagnostic/)", + ) + return parser.parse_args() + + +def main() -> int: + args = parse_args() + + if args.file: + diagnostic_path = Path(args.file) + if not diagnostic_path.is_absolute(): + diagnostic_path = ROOT / diagnostic_path + else: + diagnostic_path = find_latest_diagnostic() + if diagnostic_path is None: + msg = "No diagnostic files found in diagnostic/" + if args.json: + print(json.dumps({"error": msg}, indent=2)) + else: + print(f"ERROR: {msg}") + return 1 + + exit_code, report = run_verification( + diagnostic_path, + threshold=args.threshold, + verbose=args.verbose, + json_output=args.json, + ) + + if args.json: + print(json.dumps(report, indent=2)) + + return exit_code + + +if __name__ == "__main__": + sys.exit(main())