From 661a4e73d922cec5e1883d60520d27f2a3a973e0 Mon Sep 17 00:00:00 2001 From: rgrant Date: Fri, 13 Feb 2026 21:37:59 +0000 Subject: [PATCH 01/23] 20260213 prep for agentic-shepherd code map --- .gitignore | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.gitignore b/.gitignore index 92e817d4..2033b0b1 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,8 @@ lcov.info # Logs *.log /tmp + +# Agentic-Shepherd +.agentic-shepherd/code-map.md +.agentic-shepherd/log/ + From a0f0af55f63e0e17fe5d5b4a4627755068587733 Mon Sep 17 00:00:00 2001 From: rgrant Date: Fri, 23 Jan 2026 20:03:24 +0000 Subject: [PATCH 02/23] 20260123 cargo-vet init --- supply-chain/audits.toml | 4 + supply-chain/config.toml | 2137 +++++++++++++++++++++++++++++++++++++ supply-chain/imports.lock | 2 + 3 files changed, 2143 insertions(+) create mode 100644 supply-chain/audits.toml create mode 100644 supply-chain/config.toml create mode 100644 supply-chain/imports.lock diff --git a/supply-chain/audits.toml b/supply-chain/audits.toml new file mode 100644 index 00000000..2772ccb2 --- /dev/null +++ b/supply-chain/audits.toml @@ -0,0 +1,4 @@ + +# cargo-vet audits file + +[audits] diff --git a/supply-chain/config.toml b/supply-chain/config.toml new file mode 100644 index 00000000..d3ea600e --- /dev/null +++ b/supply-chain/config.toml @@ -0,0 +1,2137 @@ + +# cargo-vet config file + +[cargo-vet] +version = "0.10" + +[policy.async-anthropic] +audit-as-crates-io = true + +[policy."backon:1.5.1@git:341ea10a868218c5b1bcdfdd168df71b5e7e8c67"] +audit-as-crates-io = true + +[policy."backon:1.5.2"] + +[policy.gemini_client_rs] +audit-as-crates-io = true + +[policy.httpmock] +audit-as-crates-io = true + +[policy.inquire] +audit-as-crates-io = true + +[policy.openai] +audit-as-crates-io = true + +[policy.openai_responses] +audit-as-crates-io = true + +[policy.rmcp] +audit-as-crates-io = true + +[policy.rmcp-macros] +audit-as-crates-io = true + +[policy.saphyr] +audit-as-crates-io = true + +[policy.saphyr-parser] +audit-as-crates-io = true + +[policy.schematic] +audit-as-crates-io = true + +[policy.schematic_macros] +audit-as-crates-io = true + +[policy.schematic_types] +audit-as-crates-io = true + +[[exemptions.addr2line]] +version = "0.24.2" +criteria = "safe-to-deploy" + +[[exemptions.adler2]] +version = "2.0.1" +criteria = "safe-to-deploy" + +[[exemptions.ahash]] +version = "0.8.12" +criteria = "safe-to-deploy" + +[[exemptions.aho-corasick]] +version = "1.1.3" +criteria = "safe-to-deploy" + +[[exemptions.allocator-api2]] +version = "0.2.21" +criteria = "safe-to-deploy" + +[[exemptions.android_system_properties]] +version = "0.1.5" +criteria = "safe-to-deploy" + +[[exemptions.ansi-str]] +version = "0.9.0" +criteria = "safe-to-deploy" + +[[exemptions.ansi_colours]] +version = "1.2.3" +criteria = "safe-to-deploy" + +[[exemptions.ansitok]] +version = "0.3.0" +criteria = "safe-to-deploy" + +[[exemptions.anstream]] +version = "0.6.20" +criteria = "safe-to-deploy" + +[[exemptions.anstyle]] +version = "1.0.11" +criteria = "safe-to-deploy" + +[[exemptions.anstyle-parse]] +version = "0.2.7" +criteria = "safe-to-deploy" + +[[exemptions.anstyle-query]] +version = "1.1.4" +criteria = "safe-to-deploy" + +[[exemptions.anstyle-wincon]] +version = "3.0.10" +criteria = "safe-to-deploy" + +[[exemptions.anyhow]] +version = "1.0.100" +criteria = "safe-to-deploy" + +[[exemptions.arc-swap]] +version = "1.7.1" +criteria = "safe-to-deploy" + +[[exemptions.arraydeque]] +version = "0.5.1" +criteria = "safe-to-deploy" + +[[exemptions.arrayvec]] +version = "0.7.6" +criteria = "safe-to-deploy" + +[[exemptions.assert-json-diff]] +version = "2.0.2" +criteria = "safe-to-deploy" + +[[exemptions.assert_matches]] +version = "1.5.0" +criteria = "safe-to-run" + +[[exemptions.async-anthropic]] +version = "0.6.0@git:f20061ddc5de1f9ba929f6490bed0c1fa92ac644" +criteria = "safe-to-deploy" + +[[exemptions.async-fn-stream]] +version = "0.2.2" +criteria = "safe-to-deploy" + +[[exemptions.async-lock]] +version = "3.4.1" +criteria = "safe-to-deploy" + +[[exemptions.async-object-pool]] +version = "0.2.0" +criteria = "safe-to-deploy" + +[[exemptions.async-stream]] +version = "0.3.6" +criteria = "safe-to-deploy" + +[[exemptions.async-stream-impl]] +version = "0.3.6" +criteria = "safe-to-deploy" + +[[exemptions.async-trait]] +version = "0.1.89" +criteria = "safe-to-deploy" + +[[exemptions.atomic-waker]] +version = "1.1.2" +criteria = "safe-to-deploy" + +[[exemptions.autocfg]] +version = "1.5.0" +criteria = "safe-to-deploy" + +[[exemptions.backon]] +version = "1.5.1@git:341ea10a868218c5b1bcdfdd168df71b5e7e8c67" +criteria = "safe-to-deploy" + +[[exemptions.backon]] +version = "1.5.2" +criteria = "safe-to-deploy" + +[[exemptions.backtrace]] +version = "0.3.75" +criteria = "safe-to-deploy" + +[[exemptions.base64]] +version = "0.21.7" +criteria = "safe-to-deploy" + +[[exemptions.base64]] +version = "0.22.1" +criteria = "safe-to-deploy" + +[[exemptions.bat]] +version = "0.25.0" +criteria = "safe-to-deploy" + +[[exemptions.bincode]] +version = "1.3.3" +criteria = "safe-to-deploy" + +[[exemptions.bit-set]] +version = "0.8.0" +criteria = "safe-to-deploy" + +[[exemptions.bit-vec]] +version = "0.8.0" +criteria = "safe-to-deploy" + +[[exemptions.bitflags]] +version = "1.3.2" +criteria = "safe-to-deploy" + +[[exemptions.bitflags]] +version = "2.9.4" +criteria = "safe-to-deploy" + +[[exemptions.block-buffer]] +version = "0.10.4" +criteria = "safe-to-deploy" + +[[exemptions.borrow-or-share]] +version = "0.2.4" +criteria = "safe-to-deploy" + +[[exemptions.bstr]] +version = "1.12.0" +criteria = "safe-to-deploy" + +[[exemptions.bumpalo]] +version = "3.19.0" +criteria = "safe-to-deploy" + +[[exemptions.bytecount]] +version = "0.6.9" +criteria = "safe-to-deploy" + +[[exemptions.bytemuck]] +version = "1.23.2" +criteria = "safe-to-deploy" + +[[exemptions.bytes]] +version = "1.10.1" +criteria = "safe-to-deploy" + +[[exemptions.bytesize]] +version = "1.3.3" +criteria = "safe-to-deploy" + +[[exemptions.caseless]] +version = "0.2.2" +criteria = "safe-to-deploy" + +[[exemptions.cc]] +version = "1.2.38" +criteria = "safe-to-deploy" + +[[exemptions.cfg-if]] +version = "1.0.3" +criteria = "safe-to-deploy" + +[[exemptions.cfg_aliases]] +version = "0.2.1" +criteria = "safe-to-deploy" + +[[exemptions.chrono]] +version = "0.4.42" +criteria = "safe-to-deploy" + +[[exemptions.clap]] +version = "4.5.48" +criteria = "safe-to-deploy" + +[[exemptions.clap_builder]] +version = "4.5.48" +criteria = "safe-to-deploy" + +[[exemptions.clap_derive]] +version = "4.5.47" +criteria = "safe-to-deploy" + +[[exemptions.clap_lex]] +version = "0.7.5" +criteria = "safe-to-deploy" + +[[exemptions.clean-path]] +version = "0.2.1" +criteria = "safe-to-deploy" + +[[exemptions.clircle]] +version = "0.6.1" +criteria = "safe-to-deploy" + +[[exemptions.colorchoice]] +version = "1.0.4" +criteria = "safe-to-deploy" + +[[exemptions.comfy-table]] +version = "7.2.1" +criteria = "safe-to-deploy" + +[[exemptions.comrak]] +version = "0.49.0" +criteria = "safe-to-deploy" + +[[exemptions.concurrent-queue]] +version = "2.5.0" +criteria = "safe-to-deploy" + +[[exemptions.console]] +version = "0.15.11" +criteria = "safe-to-deploy" + +[[exemptions.console]] +version = "0.16.1" +criteria = "safe-to-deploy" + +[[exemptions.content_inspector]] +version = "0.2.4" +criteria = "safe-to-deploy" + +[[exemptions.convert_case]] +version = "0.7.1" +criteria = "safe-to-deploy" + +[[exemptions.convert_case]] +version = "0.8.0" +criteria = "safe-to-deploy" + +[[exemptions.coolor]] +version = "1.1.0" +criteria = "safe-to-deploy" + +[[exemptions.core-foundation]] +version = "0.10.1" +criteria = "safe-to-deploy" + +[[exemptions.core-foundation-sys]] +version = "0.8.7" +criteria = "safe-to-deploy" + +[[exemptions.cpufeatures]] +version = "0.2.17" +criteria = "safe-to-deploy" + +[[exemptions.crc32fast]] +version = "1.5.0" +criteria = "safe-to-deploy" + +[[exemptions.crokey]] +version = "1.3.0" +criteria = "safe-to-deploy" + +[[exemptions.crokey-proc_macros]] +version = "1.3.0" +criteria = "safe-to-deploy" + +[[exemptions.crossbeam]] +version = "0.8.4" +criteria = "safe-to-deploy" + +[[exemptions.crossbeam-channel]] +version = "0.5.15" +criteria = "safe-to-deploy" + +[[exemptions.crossbeam-deque]] +version = "0.8.6" +criteria = "safe-to-deploy" + +[[exemptions.crossbeam-epoch]] +version = "0.9.18" +criteria = "safe-to-deploy" + +[[exemptions.crossbeam-queue]] +version = "0.3.12" +criteria = "safe-to-deploy" + +[[exemptions.crossbeam-utils]] +version = "0.8.21" +criteria = "safe-to-deploy" + +[[exemptions.crossterm]] +version = "0.29.0" +criteria = "safe-to-deploy" + +[[exemptions.crossterm_winapi]] +version = "0.9.1" +criteria = "safe-to-deploy" + +[[exemptions.crypto-common]] +version = "0.1.6" +criteria = "safe-to-deploy" + +[[exemptions.darling]] +version = "0.20.11" +criteria = "safe-to-deploy" + +[[exemptions.darling]] +version = "0.21.3" +criteria = "safe-to-deploy" + +[[exemptions.darling_core]] +version = "0.20.11" +criteria = "safe-to-deploy" + +[[exemptions.darling_core]] +version = "0.21.3" +criteria = "safe-to-deploy" + +[[exemptions.darling_macro]] +version = "0.20.11" +criteria = "safe-to-deploy" + +[[exemptions.darling_macro]] +version = "0.21.3" +criteria = "safe-to-deploy" + +[[exemptions.data-encoding]] +version = "2.9.0" +criteria = "safe-to-deploy" + +[[exemptions.deranged]] +version = "0.5.3" +criteria = "safe-to-deploy" + +[[exemptions.derive_builder]] +version = "0.20.2" +criteria = "safe-to-deploy" + +[[exemptions.derive_builder_core]] +version = "0.20.2" +criteria = "safe-to-deploy" + +[[exemptions.derive_builder_macro]] +version = "0.20.2" +criteria = "safe-to-deploy" + +[[exemptions.derive_more]] +version = "2.0.1" +criteria = "safe-to-deploy" + +[[exemptions.derive_more-impl]] +version = "2.0.1" +criteria = "safe-to-deploy" + +[[exemptions.dhat]] +version = "0.3.3" +criteria = "safe-to-deploy" + +[[exemptions.diff]] +version = "0.1.13" +criteria = "safe-to-run" + +[[exemptions.digest]] +version = "0.10.7" +criteria = "safe-to-deploy" + +[[exemptions.directories]] +version = "6.0.0" +criteria = "safe-to-deploy" + +[[exemptions.dirs]] +version = "6.0.0" +criteria = "safe-to-deploy" + +[[exemptions.dirs-sys]] +version = "0.5.0" +criteria = "safe-to-deploy" + +[[exemptions.displaydoc]] +version = "0.2.5" +criteria = "safe-to-deploy" + +[[exemptions.document-features]] +version = "0.2.11" +criteria = "safe-to-deploy" + +[[exemptions.duct]] +version = "1.1.0" +criteria = "safe-to-deploy" + +[[exemptions.duct_sh]] +version = "1.0.0" +criteria = "safe-to-deploy" + +[[exemptions.dyn-clone]] +version = "1.0.20" +criteria = "safe-to-deploy" + +[[exemptions.dyn-hash]] +version = "0.2.2" +criteria = "safe-to-deploy" + +[[exemptions.either]] +version = "1.15.0" +criteria = "safe-to-deploy" + +[[exemptions.email_address]] +version = "0.2.9" +criteria = "safe-to-deploy" + +[[exemptions.encode_unicode]] +version = "1.0.0" +criteria = "safe-to-deploy" + +[[exemptions.encoding_rs]] +version = "0.8.35" +criteria = "safe-to-deploy" + +[[exemptions.encoding_rs_io]] +version = "0.1.7" +criteria = "safe-to-deploy" + +[[exemptions.entities]] +version = "1.0.1" +criteria = "safe-to-deploy" + +[[exemptions.env_home]] +version = "0.1.0" +criteria = "safe-to-deploy" + +[[exemptions.equivalent]] +version = "1.0.2" +criteria = "safe-to-deploy" + +[[exemptions.erased-serde]] +version = "0.4.8" +criteria = "safe-to-deploy" + +[[exemptions.errno]] +version = "0.3.14" +criteria = "safe-to-deploy" + +[[exemptions.event-listener]] +version = "5.4.1" +criteria = "safe-to-deploy" + +[[exemptions.event-listener-strategy]] +version = "0.5.4" +criteria = "safe-to-deploy" + +[[exemptions.eventsource-stream]] +version = "0.2.3" +criteria = "safe-to-deploy" + +[[exemptions.fallible-iterator]] +version = "0.3.0" +criteria = "safe-to-deploy" + +[[exemptions.fallible-streaming-iterator]] +version = "0.1.9" +criteria = "safe-to-deploy" + +[[exemptions.fancy-regex]] +version = "0.16.2" +criteria = "safe-to-deploy" + +[[exemptions.fastrand]] +version = "2.3.0" +criteria = "safe-to-deploy" + +[[exemptions.find-msvc-tools]] +version = "0.1.2" +criteria = "safe-to-deploy" + +[[exemptions.flate2]] +version = "1.1.2" +criteria = "safe-to-deploy" + +[[exemptions.fluent-uri]] +version = "0.4.1" +criteria = "safe-to-deploy" + +[[exemptions.fnv]] +version = "1.0.7" +criteria = "safe-to-deploy" + +[[exemptions.foldhash]] +version = "0.1.5" +criteria = "safe-to-deploy" + +[[exemptions.foldhash]] +version = "0.2.0" +criteria = "safe-to-deploy" + +[[exemptions.form_urlencoded]] +version = "1.2.2" +criteria = "safe-to-deploy" + +[[exemptions.fraction]] +version = "0.15.3" +criteria = "safe-to-deploy" + +[[exemptions.futures]] +version = "0.3.31" +criteria = "safe-to-deploy" + +[[exemptions.futures-channel]] +version = "0.3.31" +criteria = "safe-to-deploy" + +[[exemptions.futures-core]] +version = "0.3.31" +criteria = "safe-to-deploy" + +[[exemptions.futures-executor]] +version = "0.3.31" +criteria = "safe-to-deploy" + +[[exemptions.futures-io]] +version = "0.3.31" +criteria = "safe-to-deploy" + +[[exemptions.futures-macro]] +version = "0.3.31" +criteria = "safe-to-deploy" + +[[exemptions.futures-sink]] +version = "0.3.31" +criteria = "safe-to-deploy" + +[[exemptions.futures-task]] +version = "0.3.31" +criteria = "safe-to-deploy" + +[[exemptions.futures-timer]] +version = "3.0.3" +criteria = "safe-to-deploy" + +[[exemptions.futures-util]] +version = "0.3.31" +criteria = "safe-to-deploy" + +[[exemptions.gemini_client_rs]] +version = "0.6.2@git:e745b8824cd3aa2d1914f6beadc577a98c59821d" +criteria = "safe-to-deploy" + +[[exemptions.generic-array]] +version = "0.14.7" +criteria = "safe-to-deploy" + +[[exemptions.getrandom]] +version = "0.2.16" +criteria = "safe-to-deploy" + +[[exemptions.getrandom]] +version = "0.3.4" +criteria = "safe-to-deploy" + +[[exemptions.gimli]] +version = "0.31.1" +criteria = "safe-to-deploy" + +[[exemptions.glob]] +version = "0.3.3" +criteria = "safe-to-deploy" + +[[exemptions.globset]] +version = "0.4.16" +criteria = "safe-to-deploy" + +[[exemptions.grep-matcher]] +version = "0.1.7" +criteria = "safe-to-deploy" + +[[exemptions.grep-printer]] +version = "0.2.2" +criteria = "safe-to-deploy" + +[[exemptions.grep-regex]] +version = "0.1.13" +criteria = "safe-to-deploy" + +[[exemptions.grep-searcher]] +version = "0.1.14" +criteria = "safe-to-deploy" + +[[exemptions.h2]] +version = "0.4.12" +criteria = "safe-to-deploy" + +[[exemptions.hashbrown]] +version = "0.15.5" +criteria = "safe-to-deploy" + +[[exemptions.hashbrown]] +version = "0.16.1" +criteria = "safe-to-deploy" + +[[exemptions.hashlink]] +version = "0.10.0" +criteria = "safe-to-deploy" + +[[exemptions.heck]] +version = "0.5.0" +criteria = "safe-to-deploy" + +[[exemptions.home]] +version = "0.5.11" +criteria = "safe-to-deploy" + +[[exemptions.http]] +version = "1.3.1" +criteria = "safe-to-deploy" + +[[exemptions.http-body]] +version = "1.0.1" +criteria = "safe-to-deploy" + +[[exemptions.http-body-util]] +version = "0.1.3" +criteria = "safe-to-deploy" + +[[exemptions.httparse]] +version = "1.10.1" +criteria = "safe-to-deploy" + +[[exemptions.httpdate]] +version = "1.0.3" +criteria = "safe-to-deploy" + +[[exemptions.httpmock]] +version = "0.8.2@git:00d4c80d5f53e7db884c7c950c47f8faea87e061" +criteria = "safe-to-deploy" + +[[exemptions.humantime]] +version = "2.3.0" +criteria = "safe-to-deploy" + +[[exemptions.hyper]] +version = "1.7.0" +criteria = "safe-to-deploy" + +[[exemptions.hyper-rustls]] +version = "0.27.7" +criteria = "safe-to-deploy" + +[[exemptions.hyper-timeout]] +version = "0.5.2" +criteria = "safe-to-deploy" + +[[exemptions.hyper-util]] +version = "0.1.17" +criteria = "safe-to-deploy" + +[[exemptions.iana-time-zone]] +version = "0.1.64" +criteria = "safe-to-deploy" + +[[exemptions.iana-time-zone-haiku]] +version = "0.1.2" +criteria = "safe-to-deploy" + +[[exemptions.icu_collections]] +version = "2.0.0" +criteria = "safe-to-deploy" + +[[exemptions.icu_locale_core]] +version = "2.0.0" +criteria = "safe-to-deploy" + +[[exemptions.icu_normalizer]] +version = "2.0.0" +criteria = "safe-to-deploy" + +[[exemptions.icu_normalizer_data]] +version = "2.0.0" +criteria = "safe-to-deploy" + +[[exemptions.icu_properties]] +version = "2.0.1" +criteria = "safe-to-deploy" + +[[exemptions.icu_properties_data]] +version = "2.0.1" +criteria = "safe-to-deploy" + +[[exemptions.icu_provider]] +version = "2.0.0" +criteria = "safe-to-deploy" + +[[exemptions.ident_case]] +version = "1.0.1" +criteria = "safe-to-deploy" + +[[exemptions.idna]] +version = "1.1.0" +criteria = "safe-to-deploy" + +[[exemptions.idna_adapter]] +version = "1.2.1" +criteria = "safe-to-deploy" + +[[exemptions.ignore]] +version = "0.4.23" +criteria = "safe-to-deploy" + +[[exemptions.indexmap]] +version = "2.11.4" +criteria = "safe-to-deploy" + +[[exemptions.indoc]] +version = "2.0.6" +criteria = "safe-to-deploy" + +[[exemptions.inquire]] +version = "0.9.1@git:c84710515dc4ee176bff9cae28f92d7b35ce310e" +criteria = "safe-to-deploy" + +[[exemptions.insta]] +version = "1.43.2" +criteria = "safe-to-deploy" + +[[exemptions.inventory]] +version = "0.3.21" +criteria = "safe-to-deploy" + +[[exemptions.io-uring]] +version = "0.7.10" +criteria = "safe-to-deploy" + +[[exemptions.ipnet]] +version = "2.11.0" +criteria = "safe-to-deploy" + +[[exemptions.iri-string]] +version = "0.7.8" +criteria = "safe-to-deploy" + +[[exemptions.is_ci]] +version = "1.2.0" +criteria = "safe-to-deploy" + +[[exemptions.is_terminal_polyfill]] +version = "1.70.1" +criteria = "safe-to-deploy" + +[[exemptions.itertools]] +version = "0.13.0" +criteria = "safe-to-deploy" + +[[exemptions.itertools]] +version = "0.14.0" +criteria = "safe-to-deploy" + +[[exemptions.itoa]] +version = "1.0.15" +criteria = "safe-to-deploy" + +[[exemptions.jetscii]] +version = "0.5.3" +criteria = "safe-to-deploy" + +[[exemptions.js-sys]] +version = "0.3.80" +criteria = "safe-to-deploy" + +[[exemptions.jsonschema]] +version = "0.37.4" +criteria = "safe-to-deploy" + +[[exemptions.jsonwebtoken]] +version = "9.3.1" +criteria = "safe-to-deploy" + +[[exemptions.lazy-regex]] +version = "3.4.1" +criteria = "safe-to-deploy" + +[[exemptions.lazy-regex-proc_macros]] +version = "3.4.1" +criteria = "safe-to-deploy" + +[[exemptions.lazy_static]] +version = "1.5.0" +criteria = "safe-to-deploy" + +[[exemptions.libc]] +version = "0.2.175" +criteria = "safe-to-deploy" + +[[exemptions.libredox]] +version = "0.1.10" +criteria = "safe-to-deploy" + +[[exemptions.libsqlite3-sys]] +version = "0.35.0" +criteria = "safe-to-deploy" + +[[exemptions.linkme]] +version = "0.3.33" +criteria = "safe-to-deploy" + +[[exemptions.linkme-impl]] +version = "0.3.33" +criteria = "safe-to-deploy" + +[[exemptions.linux-raw-sys]] +version = "0.11.0" +criteria = "safe-to-deploy" + +[[exemptions.litemap]] +version = "0.8.0" +criteria = "safe-to-deploy" + +[[exemptions.litrs]] +version = "0.4.2" +criteria = "safe-to-deploy" + +[[exemptions.lock_api]] +version = "0.4.13" +criteria = "safe-to-deploy" + +[[exemptions.log]] +version = "0.4.28" +criteria = "safe-to-deploy" + +[[exemptions.lru-slab]] +version = "0.1.2" +criteria = "safe-to-deploy" + +[[exemptions.macon]] +version = "1.3.0" +criteria = "safe-to-deploy" + +[[exemptions.macon_api]] +version = "1.3.0" +criteria = "safe-to-deploy" + +[[exemptions.macon_derive]] +version = "1.3.0" +criteria = "safe-to-deploy" + +[[exemptions.matchers]] +version = "0.2.0" +criteria = "safe-to-deploy" + +[[exemptions.memchr]] +version = "2.7.5" +criteria = "safe-to-deploy" + +[[exemptions.memmap2]] +version = "0.9.8" +criteria = "safe-to-deploy" + +[[exemptions.miette]] +version = "7.6.0" +criteria = "safe-to-deploy" + +[[exemptions.miette-derive]] +version = "7.6.0" +criteria = "safe-to-deploy" + +[[exemptions.mime]] +version = "0.3.17" +criteria = "safe-to-deploy" + +[[exemptions.mime_guess]] +version = "2.0.5" +criteria = "safe-to-deploy" + +[[exemptions.minijinja]] +version = "2.12.0" +criteria = "safe-to-deploy" + +[[exemptions.minimad]] +version = "0.13.1" +criteria = "safe-to-deploy" + +[[exemptions.minimal-lexical]] +version = "0.2.1" +criteria = "safe-to-deploy" + +[[exemptions.miniz_oxide]] +version = "0.8.9" +criteria = "safe-to-deploy" + +[[exemptions.mintex]] +version = "0.1.4" +criteria = "safe-to-deploy" + +[[exemptions.mio]] +version = "1.0.4" +criteria = "safe-to-deploy" + +[[exemptions.nom]] +version = "7.1.3" +criteria = "safe-to-deploy" + +[[exemptions.nu-ansi-term]] +version = "0.50.1" +criteria = "safe-to-deploy" + +[[exemptions.num]] +version = "0.4.3" +criteria = "safe-to-deploy" + +[[exemptions.num-bigint]] +version = "0.4.6" +criteria = "safe-to-deploy" + +[[exemptions.num-cmp]] +version = "0.1.0" +criteria = "safe-to-deploy" + +[[exemptions.num-complex]] +version = "0.4.6" +criteria = "safe-to-deploy" + +[[exemptions.num-conv]] +version = "0.1.0" +criteria = "safe-to-deploy" + +[[exemptions.num-integer]] +version = "0.1.46" +criteria = "safe-to-deploy" + +[[exemptions.num-iter]] +version = "0.1.45" +criteria = "safe-to-deploy" + +[[exemptions.num-rational]] +version = "0.4.2" +criteria = "safe-to-deploy" + +[[exemptions.num-traits]] +version = "0.2.19" +criteria = "safe-to-deploy" + +[[exemptions.num_threads]] +version = "0.1.7" +criteria = "safe-to-deploy" + +[[exemptions.object]] +version = "0.36.7" +criteria = "safe-to-deploy" + +[[exemptions.octocrab]] +version = "0.45.0" +criteria = "safe-to-deploy" + +[[exemptions.ollama-rs]] +version = "0.3.2" +criteria = "safe-to-deploy" + +[[exemptions.once_cell]] +version = "1.21.3" +criteria = "safe-to-deploy" + +[[exemptions.once_cell_polyfill]] +version = "1.70.1" +criteria = "safe-to-deploy" + +[[exemptions.onig]] +version = "6.5.1" +criteria = "safe-to-deploy" + +[[exemptions.onig_sys]] +version = "69.9.1" +criteria = "safe-to-deploy" + +[[exemptions.open-editor]] +version = "1.1.0" +criteria = "safe-to-deploy" + +[[exemptions.openai]] +version = "1.1.1@git:b49a3e1f8dd3196a789a142eeee221c920da4791" +criteria = "safe-to-deploy" + +[[exemptions.openai_responses]] +version = "0.1.6@git:803a4104ec2848ce2bd86c80c28593d7108b35d1" +criteria = "safe-to-deploy" + +[[exemptions.openssl-probe]] +version = "0.1.6" +criteria = "safe-to-deploy" + +[[exemptions.option-ext]] +version = "0.2.0" +criteria = "safe-to-deploy" + +[[exemptions.ordered-float]] +version = "5.0.0" +criteria = "safe-to-deploy" + +[[exemptions.os_pipe]] +version = "1.2.2" +criteria = "safe-to-deploy" + +[[exemptions.outref]] +version = "0.5.2" +criteria = "safe-to-deploy" + +[[exemptions.owo-colors]] +version = "4.2.2" +criteria = "safe-to-deploy" + +[[exemptions.parking]] +version = "2.2.1" +criteria = "safe-to-deploy" + +[[exemptions.parking_lot]] +version = "0.12.4" +criteria = "safe-to-deploy" + +[[exemptions.parking_lot_core]] +version = "0.9.11" +criteria = "safe-to-deploy" + +[[exemptions.paste]] +version = "1.0.15" +criteria = "safe-to-deploy" + +[[exemptions.path-tree]] +version = "0.8.3" +criteria = "safe-to-deploy" + +[[exemptions.path_abs]] +version = "0.5.1" +criteria = "safe-to-deploy" + +[[exemptions.pem]] +version = "3.0.5" +criteria = "safe-to-deploy" + +[[exemptions.percent-encoding]] +version = "2.3.2" +criteria = "safe-to-deploy" + +[[exemptions.pest]] +version = "2.8.2" +criteria = "safe-to-deploy" + +[[exemptions.pest_derive]] +version = "2.8.2" +criteria = "safe-to-deploy" + +[[exemptions.pest_generator]] +version = "2.8.2" +criteria = "safe-to-deploy" + +[[exemptions.pest_meta]] +version = "2.8.2" +criteria = "safe-to-deploy" + +[[exemptions.pin-project]] +version = "1.1.10" +criteria = "safe-to-deploy" + +[[exemptions.pin-project-internal]] +version = "1.1.10" +criteria = "safe-to-deploy" + +[[exemptions.pin-project-lite]] +version = "0.2.16" +criteria = "safe-to-deploy" + +[[exemptions.pin-utils]] +version = "0.1.0" +criteria = "safe-to-deploy" + +[[exemptions.pkg-config]] +version = "0.3.32" +criteria = "safe-to-deploy" + +[[exemptions.plist]] +version = "1.8.0" +criteria = "safe-to-deploy" + +[[exemptions.potential_utf]] +version = "0.1.3" +criteria = "safe-to-deploy" + +[[exemptions.powerfmt]] +version = "0.2.0" +criteria = "safe-to-deploy" + +[[exemptions.ppv-lite86]] +version = "0.2.21" +criteria = "safe-to-deploy" + +[[exemptions.pretty_assertions]] +version = "1.4.1" +criteria = "safe-to-run" + +[[exemptions.proc-macro2]] +version = "1.0.101" +criteria = "safe-to-deploy" + +[[exemptions.quick-xml]] +version = "0.38.4" +criteria = "safe-to-deploy" + +[[exemptions.quinn]] +version = "0.11.9" +criteria = "safe-to-deploy" + +[[exemptions.quinn-proto]] +version = "0.11.13" +criteria = "safe-to-deploy" + +[[exemptions.quinn-udp]] +version = "0.5.14" +criteria = "safe-to-deploy" + +[[exemptions.quote]] +version = "1.0.40" +criteria = "safe-to-deploy" + +[[exemptions.r-efi]] +version = "5.3.0" +criteria = "safe-to-deploy" + +[[exemptions.rand]] +version = "0.9.2" +criteria = "safe-to-deploy" + +[[exemptions.rand_chacha]] +version = "0.9.0" +criteria = "safe-to-deploy" + +[[exemptions.rand_core]] +version = "0.9.3" +criteria = "safe-to-deploy" + +[[exemptions.rayon]] +version = "1.11.0" +criteria = "safe-to-deploy" + +[[exemptions.rayon-core]] +version = "1.13.0" +criteria = "safe-to-deploy" + +[[exemptions.redox_syscall]] +version = "0.5.17" +criteria = "safe-to-deploy" + +[[exemptions.redox_users]] +version = "0.5.2" +criteria = "safe-to-deploy" + +[[exemptions.ref-cast]] +version = "1.0.24" +criteria = "safe-to-deploy" + +[[exemptions.ref-cast-impl]] +version = "1.0.24" +criteria = "safe-to-deploy" + +[[exemptions.referencing]] +version = "0.37.4" +criteria = "safe-to-deploy" + +[[exemptions.regex]] +version = "1.11.2" +criteria = "safe-to-deploy" + +[[exemptions.regex-automata]] +version = "0.4.10" +criteria = "safe-to-deploy" + +[[exemptions.regex-syntax]] +version = "0.8.6" +criteria = "safe-to-deploy" + +[[exemptions.relative-path]] +version = "2.0.1" +criteria = "safe-to-deploy" + +[[exemptions.reqwest]] +version = "0.12.23" +criteria = "safe-to-deploy" + +[[exemptions.reqwest-eventsource]] +version = "0.6.0" +criteria = "safe-to-deploy" + +[[exemptions.rgb]] +version = "0.8.52" +criteria = "safe-to-deploy" + +[[exemptions.ring]] +version = "0.17.14" +criteria = "safe-to-deploy" + +[[exemptions.rmcp]] +version = "0.1.5@git:18346b94e4e71463a06d93852cfc26c683ca5b83" +criteria = "safe-to-deploy" + +[[exemptions.rmcp-macros]] +version = "0.1.5@git:18346b94e4e71463a06d93852cfc26c683ca5b83" +criteria = "safe-to-deploy" + +[[exemptions.rusqlite]] +version = "0.37.0" +criteria = "safe-to-deploy" + +[[exemptions.rustc-demangle]] +version = "0.1.26" +criteria = "safe-to-deploy" + +[[exemptions.rustc-hash]] +version = "1.1.0" +criteria = "safe-to-deploy" + +[[exemptions.rustc-hash]] +version = "2.1.1" +criteria = "safe-to-deploy" + +[[exemptions.rustix]] +version = "1.1.2" +criteria = "safe-to-deploy" + +[[exemptions.rustls]] +version = "0.23.35" +criteria = "safe-to-deploy" + +[[exemptions.rustls-native-certs]] +version = "0.8.1" +criteria = "safe-to-deploy" + +[[exemptions.rustls-pki-types]] +version = "1.12.0" +criteria = "safe-to-deploy" + +[[exemptions.rustls-webpki]] +version = "0.103.6" +criteria = "safe-to-deploy" + +[[exemptions.rustversion]] +version = "1.0.22" +criteria = "safe-to-deploy" + +[[exemptions.ryu]] +version = "1.0.20" +criteria = "safe-to-deploy" + +[[exemptions.same-file]] +version = "1.0.6" +criteria = "safe-to-deploy" + +[[exemptions.saphyr]] +version = "0.0.6@git:b7dff7bf64516936b4ffc3ac76160138eb325118" +criteria = "safe-to-deploy" + +[[exemptions.saphyr-parser]] +version = "0.0.6@git:b7dff7bf64516936b4ffc3ac76160138eb325118" +criteria = "safe-to-deploy" + +[[exemptions.scc]] +version = "2.4.0" +criteria = "safe-to-run" + +[[exemptions.schannel]] +version = "0.1.28" +criteria = "safe-to-deploy" + +[[exemptions.schemars]] +version = "0.8.22" +criteria = "safe-to-deploy" + +[[exemptions.schemars]] +version = "1.0.4" +criteria = "safe-to-deploy" + +[[exemptions.schemars_derive]] +version = "0.8.22" +criteria = "safe-to-deploy" + +[[exemptions.schemars_derive]] +version = "1.0.4" +criteria = "safe-to-deploy" + +[[exemptions.schematic]] +version = "0.18.12@git:533dc9ada5af11a74f44adfe19d7c056a174db32" +criteria = "safe-to-deploy" + +[[exemptions.schematic_macros]] +version = "0.18.11@git:533dc9ada5af11a74f44adfe19d7c056a174db32" +criteria = "safe-to-deploy" + +[[exemptions.schematic_types]] +version = "0.10.6@git:533dc9ada5af11a74f44adfe19d7c056a174db32" +criteria = "safe-to-deploy" + +[[exemptions.scopeguard]] +version = "1.2.0" +criteria = "safe-to-deploy" + +[[exemptions.sdd]] +version = "3.0.10" +criteria = "safe-to-run" + +[[exemptions.secrecy]] +version = "0.10.3" +criteria = "safe-to-deploy" + +[[exemptions.security-framework]] +version = "3.5.0" +criteria = "safe-to-deploy" + +[[exemptions.security-framework-sys]] +version = "2.15.0" +criteria = "safe-to-deploy" + +[[exemptions.semver]] +version = "1.0.27" +criteria = "safe-to-deploy" + +[[exemptions.serde]] +version = "1.0.226" +criteria = "safe-to-deploy" + +[[exemptions.serde_core]] +version = "1.0.226" +criteria = "safe-to-deploy" + +[[exemptions.serde_derive]] +version = "1.0.226" +criteria = "safe-to-deploy" + +[[exemptions.serde_derive_internals]] +version = "0.29.1" +criteria = "safe-to-deploy" + +[[exemptions.serde_json]] +version = "1.0.145" +criteria = "safe-to-deploy" + +[[exemptions.serde_json5]] +version = "0.2.1" +criteria = "safe-to-deploy" + +[[exemptions.serde_path_to_error]] +version = "0.1.20" +criteria = "safe-to-deploy" + +[[exemptions.serde_regex]] +version = "1.1.0" +criteria = "safe-to-deploy" + +[[exemptions.serde_spanned]] +version = "0.6.9" +criteria = "safe-to-deploy" + +[[exemptions.serde_spanned]] +version = "1.0.2" +criteria = "safe-to-deploy" + +[[exemptions.serde_urlencoded]] +version = "0.7.1" +criteria = "safe-to-deploy" + +[[exemptions.serde_with]] +version = "3.14.1" +criteria = "safe-to-deploy" + +[[exemptions.serde_with_macros]] +version = "3.14.1" +criteria = "safe-to-deploy" + +[[exemptions.serde_yaml]] +version = "0.9.34+deprecated" +criteria = "safe-to-deploy" + +[[exemptions.serial_test]] +version = "3.2.0" +criteria = "safe-to-run" + +[[exemptions.serial_test_derive]] +version = "3.2.0" +criteria = "safe-to-run" + +[[exemptions.sha1]] +version = "0.10.6" +criteria = "safe-to-deploy" + +[[exemptions.sha2]] +version = "0.10.9" +criteria = "safe-to-deploy" + +[[exemptions.sharded-slab]] +version = "0.1.7" +criteria = "safe-to-deploy" + +[[exemptions.shared_child]] +version = "1.1.1" +criteria = "safe-to-deploy" + +[[exemptions.shared_thread]] +version = "0.2.0" +criteria = "safe-to-deploy" + +[[exemptions.shlex]] +version = "1.3.0" +criteria = "safe-to-deploy" + +[[exemptions.sigchld]] +version = "0.2.4" +criteria = "safe-to-deploy" + +[[exemptions.signal-hook]] +version = "0.3.18" +criteria = "safe-to-deploy" + +[[exemptions.signal-hook-mio]] +version = "0.2.4" +criteria = "safe-to-deploy" + +[[exemptions.signal-hook-registry]] +version = "1.4.6" +criteria = "safe-to-deploy" + +[[exemptions.similar]] +version = "2.7.0" +criteria = "safe-to-deploy" + +[[exemptions.simple_asn1]] +version = "0.6.3" +criteria = "safe-to-deploy" + +[[exemptions.slab]] +version = "0.4.11" +criteria = "safe-to-deploy" + +[[exemptions.smallvec]] +version = "1.15.1" +criteria = "safe-to-deploy" + +[[exemptions.snafu]] +version = "0.8.9" +criteria = "safe-to-deploy" + +[[exemptions.snafu-derive]] +version = "0.8.9" +criteria = "safe-to-deploy" + +[[exemptions.socket2]] +version = "0.6.0" +criteria = "safe-to-deploy" + +[[exemptions.stable_deref_trait]] +version = "1.2.0" +criteria = "safe-to-deploy" + +[[exemptions.starbase_styles]] +version = "0.6.3" +criteria = "safe-to-deploy" + +[[exemptions.static_assertions]] +version = "1.1.0" +criteria = "safe-to-deploy" + +[[exemptions.std_prelude]] +version = "0.2.12" +criteria = "safe-to-deploy" + +[[exemptions.strict]] +version = "0.2.0" +criteria = "safe-to-deploy" + +[[exemptions.stringmetrics]] +version = "2.2.2" +criteria = "safe-to-deploy" + +[[exemptions.strip-ansi-escapes]] +version = "0.2.1" +criteria = "safe-to-deploy" + +[[exemptions.strsim]] +version = "0.11.1" +criteria = "safe-to-deploy" + +[[exemptions.subtle]] +version = "2.6.1" +criteria = "safe-to-deploy" + +[[exemptions.supports-color]] +version = "3.0.2" +criteria = "safe-to-deploy" + +[[exemptions.syn]] +version = "2.0.106" +criteria = "safe-to-deploy" + +[[exemptions.sync_wrapper]] +version = "1.0.2" +criteria = "safe-to-deploy" + +[[exemptions.synstructure]] +version = "0.13.2" +criteria = "safe-to-deploy" + +[[exemptions.syntect]] +version = "5.2.0" +criteria = "safe-to-deploy" + +[[exemptions.tabwriter]] +version = "1.4.1" +criteria = "safe-to-deploy" + +[[exemptions.tempfile]] +version = "3.22.0" +criteria = "safe-to-deploy" + +[[exemptions.termcolor]] +version = "1.4.1" +criteria = "safe-to-deploy" + +[[exemptions.termimad]] +version = "0.34.0" +criteria = "safe-to-deploy" + +[[exemptions.terminal-colorsaurus]] +version = "0.4.8" +criteria = "safe-to-deploy" + +[[exemptions.terminal-trx]] +version = "0.2.4" +criteria = "safe-to-deploy" + +[[exemptions.terminal_size]] +version = "0.4.3" +criteria = "safe-to-deploy" + +[[exemptions.test-log]] +version = "0.2.18" +criteria = "safe-to-deploy" + +[[exemptions.test-log-macros]] +version = "0.2.18" +criteria = "safe-to-deploy" + +[[exemptions.thiserror]] +version = "1.0.69" +criteria = "safe-to-deploy" + +[[exemptions.thiserror]] +version = "2.0.16" +criteria = "safe-to-deploy" + +[[exemptions.thiserror-impl]] +version = "1.0.69" +criteria = "safe-to-deploy" + +[[exemptions.thiserror-impl]] +version = "2.0.16" +criteria = "safe-to-deploy" + +[[exemptions.thousands]] +version = "0.2.0" +criteria = "safe-to-deploy" + +[[exemptions.thread_local]] +version = "1.1.9" +criteria = "safe-to-deploy" + +[[exemptions.time]] +version = "0.3.44" +criteria = "safe-to-deploy" + +[[exemptions.time-core]] +version = "0.1.6" +criteria = "safe-to-deploy" + +[[exemptions.time-macros]] +version = "0.2.24" +criteria = "safe-to-deploy" + +[[exemptions.timeago]] +version = "0.5.0" +criteria = "safe-to-deploy" + +[[exemptions.tinystr]] +version = "0.8.1" +criteria = "safe-to-deploy" + +[[exemptions.tinyvec]] +version = "1.10.0" +criteria = "safe-to-deploy" + +[[exemptions.tinyvec_macros]] +version = "0.1.1" +criteria = "safe-to-deploy" + +[[exemptions.tokio]] +version = "1.47.1" +criteria = "safe-to-deploy" + +[[exemptions.tokio-macros]] +version = "2.5.0" +criteria = "safe-to-deploy" + +[[exemptions.tokio-rustls]] +version = "0.26.3" +criteria = "safe-to-deploy" + +[[exemptions.tokio-stream]] +version = "0.1.17" +criteria = "safe-to-deploy" + +[[exemptions.tokio-util]] +version = "0.7.16" +criteria = "safe-to-deploy" + +[[exemptions.toml]] +version = "0.5.11" +criteria = "safe-to-deploy" + +[[exemptions.toml]] +version = "0.8.23" +criteria = "safe-to-deploy" + +[[exemptions.toml]] +version = "0.9.7" +criteria = "safe-to-deploy" + +[[exemptions.toml_datetime]] +version = "0.6.11" +criteria = "safe-to-deploy" + +[[exemptions.toml_datetime]] +version = "0.7.2" +criteria = "safe-to-deploy" + +[[exemptions.toml_edit]] +version = "0.22.27" +criteria = "safe-to-deploy" + +[[exemptions.toml_parser]] +version = "1.0.3" +criteria = "safe-to-deploy" + +[[exemptions.toml_write]] +version = "0.1.2" +criteria = "safe-to-deploy" + +[[exemptions.toml_writer]] +version = "1.0.3" +criteria = "safe-to-deploy" + +[[exemptions.tower]] +version = "0.5.2" +criteria = "safe-to-deploy" + +[[exemptions.tower-http]] +version = "0.6.6" +criteria = "safe-to-deploy" + +[[exemptions.tower-layer]] +version = "0.3.3" +criteria = "safe-to-deploy" + +[[exemptions.tower-service]] +version = "0.3.3" +criteria = "safe-to-deploy" + +[[exemptions.tracing]] +version = "0.1.41" +criteria = "safe-to-deploy" + +[[exemptions.tracing-attributes]] +version = "0.1.30" +criteria = "safe-to-deploy" + +[[exemptions.tracing-core]] +version = "0.1.34" +criteria = "safe-to-deploy" + +[[exemptions.tracing-log]] +version = "0.2.0" +criteria = "safe-to-deploy" + +[[exemptions.tracing-serde]] +version = "0.2.0" +criteria = "safe-to-deploy" + +[[exemptions.tracing-subscriber]] +version = "0.3.20" +criteria = "safe-to-deploy" + +[[exemptions.try-lock]] +version = "0.2.5" +criteria = "safe-to-deploy" + +[[exemptions.typed-arena]] +version = "2.0.2" +criteria = "safe-to-deploy" + +[[exemptions.typeid]] +version = "1.0.3" +criteria = "safe-to-deploy" + +[[exemptions.typenum]] +version = "1.18.0" +criteria = "safe-to-deploy" + +[[exemptions.typetag]] +version = "0.2.20" +criteria = "safe-to-deploy" + +[[exemptions.typetag-impl]] +version = "0.2.20" +criteria = "safe-to-deploy" + +[[exemptions.ucd-trie]] +version = "0.1.7" +criteria = "safe-to-deploy" + +[[exemptions.unicase]] +version = "2.8.1" +criteria = "safe-to-deploy" + +[[exemptions.unicode-general-category]] +version = "1.1.0" +criteria = "safe-to-deploy" + +[[exemptions.unicode-ident]] +version = "1.0.19" +criteria = "safe-to-deploy" + +[[exemptions.unicode-normalization]] +version = "0.1.24" +criteria = "safe-to-deploy" + +[[exemptions.unicode-segmentation]] +version = "1.12.0" +criteria = "safe-to-deploy" + +[[exemptions.unicode-width]] +version = "0.1.14" +criteria = "safe-to-deploy" + +[[exemptions.unicode-width]] +version = "0.2.1" +criteria = "safe-to-deploy" + +[[exemptions.unicode_categories]] +version = "0.1.1" +criteria = "safe-to-deploy" + +[[exemptions.unsafe-libyaml]] +version = "0.2.11" +criteria = "safe-to-deploy" + +[[exemptions.untrusted]] +version = "0.9.0" +criteria = "safe-to-deploy" + +[[exemptions.url]] +version = "2.5.7" +criteria = "safe-to-deploy" + +[[exemptions.utf8_iter]] +version = "1.0.4" +criteria = "safe-to-deploy" + +[[exemptions.utf8parse]] +version = "0.2.2" +criteria = "safe-to-deploy" + +[[exemptions.uuid-simd]] +version = "0.8.0" +criteria = "safe-to-deploy" + +[[exemptions.valuable]] +version = "0.1.1" +criteria = "safe-to-deploy" + +[[exemptions.valuable-serde]] +version = "0.1.1" +criteria = "safe-to-deploy" + +[[exemptions.vcpkg]] +version = "0.2.15" +criteria = "safe-to-deploy" + +[[exemptions.version_check]] +version = "0.9.5" +criteria = "safe-to-deploy" + +[[exemptions.vsimd]] +version = "0.8.0" +criteria = "safe-to-deploy" + +[[exemptions.vte]] +version = "0.14.1" +criteria = "safe-to-deploy" + +[[exemptions.walkdir]] +version = "2.5.0" +criteria = "safe-to-deploy" + +[[exemptions.want]] +version = "0.3.1" +criteria = "safe-to-deploy" + +[[exemptions.wasi]] +version = "0.11.1+wasi-snapshot-preview1" +criteria = "safe-to-deploy" + +[[exemptions.wasip2]] +version = "1.0.1+wasi-0.2.4" +criteria = "safe-to-deploy" + +[[exemptions.wasm-bindgen]] +version = "0.2.103" +criteria = "safe-to-deploy" + +[[exemptions.wasm-bindgen-backend]] +version = "0.2.103" +criteria = "safe-to-deploy" + +[[exemptions.wasm-bindgen-futures]] +version = "0.4.53" +criteria = "safe-to-deploy" + +[[exemptions.wasm-bindgen-macro]] +version = "0.2.103" +criteria = "safe-to-deploy" + +[[exemptions.wasm-bindgen-macro-support]] +version = "0.2.103" +criteria = "safe-to-deploy" + +[[exemptions.wasm-bindgen-shared]] +version = "0.2.103" +criteria = "safe-to-deploy" + +[[exemptions.wasm-streams]] +version = "0.4.2" +criteria = "safe-to-deploy" + +[[exemptions.web-sys]] +version = "0.3.80" +criteria = "safe-to-deploy" + +[[exemptions.web-time]] +version = "1.1.0" +criteria = "safe-to-deploy" + +[[exemptions.webpki-roots]] +version = "1.0.2" +criteria = "safe-to-deploy" + +[[exemptions.which]] +version = "8.0.0" +criteria = "safe-to-deploy" + +[[exemptions.winapi]] +version = "0.3.9" +criteria = "safe-to-deploy" + +[[exemptions.winapi-i686-pc-windows-gnu]] +version = "0.4.0" +criteria = "safe-to-deploy" + +[[exemptions.winapi-util]] +version = "0.1.11" +criteria = "safe-to-deploy" + +[[exemptions.winapi-x86_64-pc-windows-gnu]] +version = "0.4.0" +criteria = "safe-to-deploy" + +[[exemptions.windows]] +version = "0.56.0" +criteria = "safe-to-deploy" + +[[exemptions.windows-core]] +version = "0.56.0" +criteria = "safe-to-deploy" + +[[exemptions.windows-implement]] +version = "0.56.0" +criteria = "safe-to-deploy" + +[[exemptions.windows-interface]] +version = "0.56.0" +criteria = "safe-to-deploy" + +[[exemptions.windows-link]] +version = "0.1.3" +criteria = "safe-to-deploy" + +[[exemptions.windows-link]] +version = "0.2.0" +criteria = "safe-to-deploy" + +[[exemptions.windows-result]] +version = "0.1.2" +criteria = "safe-to-deploy" + +[[exemptions.windows-sys]] +version = "0.52.0" +criteria = "safe-to-deploy" + +[[exemptions.windows-sys]] +version = "0.59.0" +criteria = "safe-to-deploy" + +[[exemptions.windows-sys]] +version = "0.60.2" +criteria = "safe-to-deploy" + +[[exemptions.windows-sys]] +version = "0.61.0" +criteria = "safe-to-deploy" + +[[exemptions.windows-targets]] +version = "0.52.6" +criteria = "safe-to-deploy" + +[[exemptions.windows-targets]] +version = "0.53.3" +criteria = "safe-to-deploy" + +[[exemptions.windows_aarch64_gnullvm]] +version = "0.52.6" +criteria = "safe-to-deploy" + +[[exemptions.windows_aarch64_gnullvm]] +version = "0.53.0" +criteria = "safe-to-deploy" + +[[exemptions.windows_aarch64_msvc]] +version = "0.52.6" +criteria = "safe-to-deploy" + +[[exemptions.windows_aarch64_msvc]] +version = "0.53.0" +criteria = "safe-to-deploy" + +[[exemptions.windows_i686_gnu]] +version = "0.52.6" +criteria = "safe-to-deploy" + +[[exemptions.windows_i686_gnu]] +version = "0.53.0" +criteria = "safe-to-deploy" + +[[exemptions.windows_i686_gnullvm]] +version = "0.52.6" +criteria = "safe-to-deploy" + +[[exemptions.windows_i686_gnullvm]] +version = "0.53.0" +criteria = "safe-to-deploy" + +[[exemptions.windows_i686_msvc]] +version = "0.52.6" +criteria = "safe-to-deploy" + +[[exemptions.windows_i686_msvc]] +version = "0.53.0" +criteria = "safe-to-deploy" + +[[exemptions.windows_x86_64_gnu]] +version = "0.52.6" +criteria = "safe-to-deploy" + +[[exemptions.windows_x86_64_gnu]] +version = "0.53.0" +criteria = "safe-to-deploy" + +[[exemptions.windows_x86_64_gnullvm]] +version = "0.52.6" +criteria = "safe-to-deploy" + +[[exemptions.windows_x86_64_gnullvm]] +version = "0.53.0" +criteria = "safe-to-deploy" + +[[exemptions.windows_x86_64_msvc]] +version = "0.52.6" +criteria = "safe-to-deploy" + +[[exemptions.windows_x86_64_msvc]] +version = "0.53.0" +criteria = "safe-to-deploy" + +[[exemptions.winnow]] +version = "0.7.13" +criteria = "safe-to-deploy" + +[[exemptions.winsafe]] +version = "0.0.19" +criteria = "safe-to-deploy" + +[[exemptions.wit-bindgen]] +version = "0.46.0" +criteria = "safe-to-deploy" + +[[exemptions.writeable]] +version = "0.6.1" +criteria = "safe-to-deploy" + +[[exemptions.xterm-color]] +version = "1.0.1" +criteria = "safe-to-deploy" + +[[exemptions.yansi]] +version = "1.0.1" +criteria = "safe-to-run" + +[[exemptions.yoke]] +version = "0.8.0" +criteria = "safe-to-deploy" + +[[exemptions.yoke-derive]] +version = "0.8.0" +criteria = "safe-to-deploy" + +[[exemptions.zerocopy]] +version = "0.8.27" +criteria = "safe-to-deploy" + +[[exemptions.zerocopy-derive]] +version = "0.8.27" +criteria = "safe-to-deploy" + +[[exemptions.zerofrom]] +version = "0.1.6" +criteria = "safe-to-deploy" + +[[exemptions.zerofrom-derive]] +version = "0.1.6" +criteria = "safe-to-deploy" + +[[exemptions.zeroize]] +version = "1.8.1" +criteria = "safe-to-deploy" + +[[exemptions.zerotrie]] +version = "0.2.2" +criteria = "safe-to-deploy" + +[[exemptions.zerovec]] +version = "0.11.4" +criteria = "safe-to-deploy" + +[[exemptions.zerovec-derive]] +version = "0.11.1" +criteria = "safe-to-deploy" diff --git a/supply-chain/imports.lock b/supply-chain/imports.lock new file mode 100644 index 00000000..0c397a40 --- /dev/null +++ b/supply-chain/imports.lock @@ -0,0 +1,2 @@ + +# cargo-vet imports lock From 29de084e71b0c9ff367baa2645a704fc80a5bc30 Mon Sep 17 00:00:00 2001 From: rgrant Date: Fri, 23 Jan 2026 21:29:41 +0000 Subject: [PATCH 03/23] 20260123 allow some audit imports. 381 still exempted. --- supply-chain/config.toml | 582 +------- supply-chain/imports.lock | 2846 +++++++++++++++++++++++++++++++++++++ 2 files changed, 2864 insertions(+), 564 deletions(-) diff --git a/supply-chain/config.toml b/supply-chain/config.toml index d3ea600e..0c3afb38 100644 --- a/supply-chain/config.toml +++ b/supply-chain/config.toml @@ -4,6 +4,24 @@ [cargo-vet] version = "0.10" +[imports.bytecode-alliance] +url = "https://raw.githubusercontent.com/bytecodealliance/wasmtime/main/supply-chain/audits.toml" + +[imports.embark-studios] +url = "https://raw.githubusercontent.com/EmbarkStudios/rust-ecosystem/main/audits.toml" + +[imports.google] +url = "https://raw.githubusercontent.com/google/supply-chain/main/audits.toml" + +[imports.isrg] +url = "https://raw.githubusercontent.com/divviup/libprio-rs/main/supply-chain/audits.toml" + +[imports.mozilla] +url = "https://raw.githubusercontent.com/mozilla/supply-chain/main/audits.toml" + +[imports.zcash] +url = "https://raw.githubusercontent.com/zcash/rust-ecosystem/main/supply-chain/audits.toml" + [policy.async-anthropic] audit-as-crates-io = true @@ -52,10 +70,6 @@ audit-as-crates-io = true version = "0.24.2" criteria = "safe-to-deploy" -[[exemptions.adler2]] -version = "2.0.1" -criteria = "safe-to-deploy" - [[exemptions.ahash]] version = "0.8.12" criteria = "safe-to-deploy" @@ -64,14 +78,6 @@ criteria = "safe-to-deploy" version = "1.1.3" criteria = "safe-to-deploy" -[[exemptions.allocator-api2]] -version = "0.2.21" -criteria = "safe-to-deploy" - -[[exemptions.android_system_properties]] -version = "0.1.5" -criteria = "safe-to-deploy" - [[exemptions.ansi-str]] version = "0.9.0" criteria = "safe-to-deploy" @@ -112,22 +118,10 @@ criteria = "safe-to-deploy" version = "1.7.1" criteria = "safe-to-deploy" -[[exemptions.arraydeque]] -version = "0.5.1" -criteria = "safe-to-deploy" - -[[exemptions.arrayvec]] -version = "0.7.6" -criteria = "safe-to-deploy" - [[exemptions.assert-json-diff]] version = "2.0.2" criteria = "safe-to-deploy" -[[exemptions.assert_matches]] -version = "1.5.0" -criteria = "safe-to-run" - [[exemptions.async-anthropic]] version = "0.6.0@git:f20061ddc5de1f9ba929f6490bed0c1fa92ac644" criteria = "safe-to-deploy" @@ -156,14 +150,6 @@ criteria = "safe-to-deploy" version = "0.1.89" criteria = "safe-to-deploy" -[[exemptions.atomic-waker]] -version = "1.1.2" -criteria = "safe-to-deploy" - -[[exemptions.autocfg]] -version = "1.5.0" -criteria = "safe-to-deploy" - [[exemptions.backon]] version = "1.5.1@git:341ea10a868218c5b1bcdfdd168df71b5e7e8c67" criteria = "safe-to-deploy" @@ -176,14 +162,6 @@ criteria = "safe-to-deploy" version = "0.3.75" criteria = "safe-to-deploy" -[[exemptions.base64]] -version = "0.21.7" -criteria = "safe-to-deploy" - -[[exemptions.base64]] -version = "0.22.1" -criteria = "safe-to-deploy" - [[exemptions.bat]] version = "0.25.0" criteria = "safe-to-deploy" @@ -192,26 +170,6 @@ criteria = "safe-to-deploy" version = "1.3.3" criteria = "safe-to-deploy" -[[exemptions.bit-set]] -version = "0.8.0" -criteria = "safe-to-deploy" - -[[exemptions.bit-vec]] -version = "0.8.0" -criteria = "safe-to-deploy" - -[[exemptions.bitflags]] -version = "1.3.2" -criteria = "safe-to-deploy" - -[[exemptions.bitflags]] -version = "2.9.4" -criteria = "safe-to-deploy" - -[[exemptions.block-buffer]] -version = "0.10.4" -criteria = "safe-to-deploy" - [[exemptions.borrow-or-share]] version = "0.2.4" criteria = "safe-to-deploy" @@ -220,10 +178,6 @@ criteria = "safe-to-deploy" version = "1.12.0" criteria = "safe-to-deploy" -[[exemptions.bumpalo]] -version = "3.19.0" -criteria = "safe-to-deploy" - [[exemptions.bytecount]] version = "0.6.9" criteria = "safe-to-deploy" @@ -248,14 +202,6 @@ criteria = "safe-to-deploy" version = "1.2.38" criteria = "safe-to-deploy" -[[exemptions.cfg-if]] -version = "1.0.3" -criteria = "safe-to-deploy" - -[[exemptions.cfg_aliases]] -version = "0.2.1" -criteria = "safe-to-deploy" - [[exemptions.chrono]] version = "0.4.42" criteria = "safe-to-deploy" @@ -328,10 +274,6 @@ criteria = "safe-to-deploy" version = "0.10.1" criteria = "safe-to-deploy" -[[exemptions.core-foundation-sys]] -version = "0.8.7" -criteria = "safe-to-deploy" - [[exemptions.cpufeatures]] version = "0.2.17" criteria = "safe-to-deploy" @@ -380,10 +322,6 @@ criteria = "safe-to-deploy" version = "0.9.1" criteria = "safe-to-deploy" -[[exemptions.crypto-common]] -version = "0.1.6" -criteria = "safe-to-deploy" - [[exemptions.darling]] version = "0.20.11" criteria = "safe-to-deploy" @@ -404,10 +342,6 @@ criteria = "safe-to-deploy" version = "0.20.11" criteria = "safe-to-deploy" -[[exemptions.darling_macro]] -version = "0.21.3" -criteria = "safe-to-deploy" - [[exemptions.data-encoding]] version = "2.9.0" criteria = "safe-to-deploy" @@ -460,14 +394,6 @@ criteria = "safe-to-deploy" version = "0.5.0" criteria = "safe-to-deploy" -[[exemptions.displaydoc]] -version = "0.2.5" -criteria = "safe-to-deploy" - -[[exemptions.document-features]] -version = "0.2.11" -criteria = "safe-to-deploy" - [[exemptions.duct]] version = "1.1.0" criteria = "safe-to-deploy" @@ -484,10 +410,6 @@ criteria = "safe-to-deploy" version = "0.2.2" criteria = "safe-to-deploy" -[[exemptions.either]] -version = "1.15.0" -criteria = "safe-to-deploy" - [[exemptions.email_address]] version = "0.2.9" criteria = "safe-to-deploy" @@ -496,10 +418,6 @@ criteria = "safe-to-deploy" version = "1.0.0" criteria = "safe-to-deploy" -[[exemptions.encoding_rs]] -version = "0.8.35" -criteria = "safe-to-deploy" - [[exemptions.encoding_rs_io]] version = "0.1.7" criteria = "safe-to-deploy" @@ -512,18 +430,10 @@ criteria = "safe-to-deploy" version = "0.1.0" criteria = "safe-to-deploy" -[[exemptions.equivalent]] -version = "1.0.2" -criteria = "safe-to-deploy" - [[exemptions.erased-serde]] version = "0.4.8" criteria = "safe-to-deploy" -[[exemptions.errno]] -version = "0.3.14" -criteria = "safe-to-deploy" - [[exemptions.event-listener]] version = "5.4.1" criteria = "safe-to-deploy" @@ -548,10 +458,6 @@ criteria = "safe-to-deploy" version = "0.16.2" criteria = "safe-to-deploy" -[[exemptions.fastrand]] -version = "2.3.0" -criteria = "safe-to-deploy" - [[exemptions.find-msvc-tools]] version = "0.1.2" criteria = "safe-to-deploy" @@ -564,54 +470,10 @@ criteria = "safe-to-deploy" version = "0.4.1" criteria = "safe-to-deploy" -[[exemptions.fnv]] -version = "1.0.7" -criteria = "safe-to-deploy" - -[[exemptions.foldhash]] -version = "0.1.5" -criteria = "safe-to-deploy" - -[[exemptions.foldhash]] -version = "0.2.0" -criteria = "safe-to-deploy" - -[[exemptions.form_urlencoded]] -version = "1.2.2" -criteria = "safe-to-deploy" - [[exemptions.fraction]] version = "0.15.3" criteria = "safe-to-deploy" -[[exemptions.futures]] -version = "0.3.31" -criteria = "safe-to-deploy" - -[[exemptions.futures-channel]] -version = "0.3.31" -criteria = "safe-to-deploy" - -[[exemptions.futures-core]] -version = "0.3.31" -criteria = "safe-to-deploy" - -[[exemptions.futures-executor]] -version = "0.3.31" -criteria = "safe-to-deploy" - -[[exemptions.futures-io]] -version = "0.3.31" -criteria = "safe-to-deploy" - -[[exemptions.futures-macro]] -version = "0.3.31" -criteria = "safe-to-deploy" - -[[exemptions.futures-sink]] -version = "0.3.31" -criteria = "safe-to-deploy" - [[exemptions.futures-task]] version = "0.3.31" criteria = "safe-to-deploy" @@ -640,14 +502,6 @@ criteria = "safe-to-deploy" version = "0.3.4" criteria = "safe-to-deploy" -[[exemptions.gimli]] -version = "0.31.1" -criteria = "safe-to-deploy" - -[[exemptions.glob]] -version = "0.3.3" -criteria = "safe-to-deploy" - [[exemptions.globset]] version = "0.4.16" criteria = "safe-to-deploy" @@ -684,22 +538,10 @@ criteria = "safe-to-deploy" version = "0.10.0" criteria = "safe-to-deploy" -[[exemptions.heck]] -version = "0.5.0" -criteria = "safe-to-deploy" - -[[exemptions.home]] -version = "0.5.11" -criteria = "safe-to-deploy" - [[exemptions.http]] version = "1.3.1" criteria = "safe-to-deploy" -[[exemptions.http-body]] -version = "1.0.1" -criteria = "safe-to-deploy" - [[exemptions.http-body-util]] version = "0.1.3" criteria = "safe-to-deploy" @@ -708,10 +550,6 @@ criteria = "safe-to-deploy" version = "1.10.1" criteria = "safe-to-deploy" -[[exemptions.httpdate]] -version = "1.0.3" -criteria = "safe-to-deploy" - [[exemptions.httpmock]] version = "0.8.2@git:00d4c80d5f53e7db884c7c950c47f8faea87e061" criteria = "safe-to-deploy" @@ -736,62 +574,10 @@ criteria = "safe-to-deploy" version = "0.1.17" criteria = "safe-to-deploy" -[[exemptions.iana-time-zone]] -version = "0.1.64" -criteria = "safe-to-deploy" - -[[exemptions.iana-time-zone-haiku]] -version = "0.1.2" -criteria = "safe-to-deploy" - -[[exemptions.icu_collections]] -version = "2.0.0" -criteria = "safe-to-deploy" - -[[exemptions.icu_locale_core]] -version = "2.0.0" -criteria = "safe-to-deploy" - -[[exemptions.icu_normalizer]] -version = "2.0.0" -criteria = "safe-to-deploy" - -[[exemptions.icu_normalizer_data]] -version = "2.0.0" -criteria = "safe-to-deploy" - -[[exemptions.icu_properties]] -version = "2.0.1" -criteria = "safe-to-deploy" - -[[exemptions.icu_properties_data]] -version = "2.0.1" -criteria = "safe-to-deploy" - -[[exemptions.icu_provider]] -version = "2.0.0" -criteria = "safe-to-deploy" - -[[exemptions.ident_case]] -version = "1.0.1" -criteria = "safe-to-deploy" - -[[exemptions.idna]] -version = "1.1.0" -criteria = "safe-to-deploy" - -[[exemptions.idna_adapter]] -version = "1.2.1" -criteria = "safe-to-deploy" - [[exemptions.ignore]] version = "0.4.23" criteria = "safe-to-deploy" -[[exemptions.indexmap]] -version = "2.11.4" -criteria = "safe-to-deploy" - [[exemptions.indoc]] version = "2.0.6" criteria = "safe-to-deploy" @@ -836,10 +622,6 @@ criteria = "safe-to-deploy" version = "0.14.0" criteria = "safe-to-deploy" -[[exemptions.itoa]] -version = "1.0.15" -criteria = "safe-to-deploy" - [[exemptions.jetscii]] version = "0.5.3" criteria = "safe-to-deploy" @@ -864,10 +646,6 @@ criteria = "safe-to-deploy" version = "3.4.1" criteria = "safe-to-deploy" -[[exemptions.lazy_static]] -version = "1.5.0" -criteria = "safe-to-deploy" - [[exemptions.libc]] version = "0.2.175" criteria = "safe-to-deploy" @@ -892,10 +670,6 @@ criteria = "safe-to-deploy" version = "0.11.0" criteria = "safe-to-deploy" -[[exemptions.litemap]] -version = "0.8.0" -criteria = "safe-to-deploy" - [[exemptions.litrs]] version = "0.4.2" criteria = "safe-to-deploy" @@ -904,10 +678,6 @@ criteria = "safe-to-deploy" version = "0.4.13" criteria = "safe-to-deploy" -[[exemptions.log]] -version = "0.4.28" -criteria = "safe-to-deploy" - [[exemptions.lru-slab]] version = "0.1.2" criteria = "safe-to-deploy" @@ -924,10 +694,6 @@ criteria = "safe-to-deploy" version = "1.3.0" criteria = "safe-to-deploy" -[[exemptions.matchers]] -version = "0.2.0" -criteria = "safe-to-deploy" - [[exemptions.memchr]] version = "2.7.5" criteria = "safe-to-deploy" @@ -964,10 +730,6 @@ criteria = "safe-to-deploy" version = "0.2.1" criteria = "safe-to-deploy" -[[exemptions.miniz_oxide]] -version = "0.8.9" -criteria = "safe-to-deploy" - [[exemptions.mintex]] version = "0.1.4" criteria = "safe-to-deploy" @@ -976,14 +738,6 @@ criteria = "safe-to-deploy" version = "1.0.4" criteria = "safe-to-deploy" -[[exemptions.nom]] -version = "7.1.3" -criteria = "safe-to-deploy" - -[[exemptions.nu-ansi-term]] -version = "0.50.1" -criteria = "safe-to-deploy" - [[exemptions.num]] version = "0.4.3" criteria = "safe-to-deploy" @@ -1000,26 +754,6 @@ criteria = "safe-to-deploy" version = "0.4.6" criteria = "safe-to-deploy" -[[exemptions.num-conv]] -version = "0.1.0" -criteria = "safe-to-deploy" - -[[exemptions.num-integer]] -version = "0.1.46" -criteria = "safe-to-deploy" - -[[exemptions.num-iter]] -version = "0.1.45" -criteria = "safe-to-deploy" - -[[exemptions.num-rational]] -version = "0.4.2" -criteria = "safe-to-deploy" - -[[exemptions.num-traits]] -version = "0.2.19" -criteria = "safe-to-deploy" - [[exemptions.num_threads]] version = "0.1.7" criteria = "safe-to-deploy" @@ -1068,10 +802,6 @@ criteria = "safe-to-deploy" version = "0.1.6" criteria = "safe-to-deploy" -[[exemptions.option-ext]] -version = "0.2.0" -criteria = "safe-to-deploy" - [[exemptions.ordered-float]] version = "5.0.0" criteria = "safe-to-deploy" @@ -1116,10 +846,6 @@ criteria = "safe-to-deploy" version = "3.0.5" criteria = "safe-to-deploy" -[[exemptions.percent-encoding]] -version = "2.3.2" -criteria = "safe-to-deploy" - [[exemptions.pest]] version = "2.8.2" criteria = "safe-to-deploy" @@ -1144,18 +870,6 @@ criteria = "safe-to-deploy" version = "1.1.10" criteria = "safe-to-deploy" -[[exemptions.pin-project-lite]] -version = "0.2.16" -criteria = "safe-to-deploy" - -[[exemptions.pin-utils]] -version = "0.1.0" -criteria = "safe-to-deploy" - -[[exemptions.pkg-config]] -version = "0.3.32" -criteria = "safe-to-deploy" - [[exemptions.plist]] version = "1.8.0" criteria = "safe-to-deploy" @@ -1164,10 +878,6 @@ criteria = "safe-to-deploy" version = "0.1.3" criteria = "safe-to-deploy" -[[exemptions.powerfmt]] -version = "0.2.0" -criteria = "safe-to-deploy" - [[exemptions.ppv-lite86]] version = "0.2.21" criteria = "safe-to-deploy" @@ -1192,38 +902,10 @@ criteria = "safe-to-deploy" version = "0.11.13" criteria = "safe-to-deploy" -[[exemptions.quinn-udp]] -version = "0.5.14" -criteria = "safe-to-deploy" - -[[exemptions.quote]] -version = "1.0.40" -criteria = "safe-to-deploy" - [[exemptions.r-efi]] version = "5.3.0" criteria = "safe-to-deploy" -[[exemptions.rand]] -version = "0.9.2" -criteria = "safe-to-deploy" - -[[exemptions.rand_chacha]] -version = "0.9.0" -criteria = "safe-to-deploy" - -[[exemptions.rand_core]] -version = "0.9.3" -criteria = "safe-to-deploy" - -[[exemptions.rayon]] -version = "1.11.0" -criteria = "safe-to-deploy" - -[[exemptions.rayon-core]] -version = "1.13.0" -criteria = "safe-to-deploy" - [[exemptions.redox_syscall]] version = "0.5.17" criteria = "safe-to-deploy" @@ -1288,18 +970,6 @@ criteria = "safe-to-deploy" version = "0.37.0" criteria = "safe-to-deploy" -[[exemptions.rustc-demangle]] -version = "0.1.26" -criteria = "safe-to-deploy" - -[[exemptions.rustc-hash]] -version = "1.1.0" -criteria = "safe-to-deploy" - -[[exemptions.rustc-hash]] -version = "2.1.1" -criteria = "safe-to-deploy" - [[exemptions.rustix]] version = "1.1.2" criteria = "safe-to-deploy" @@ -1320,10 +990,6 @@ criteria = "safe-to-deploy" version = "0.103.6" criteria = "safe-to-deploy" -[[exemptions.rustversion]] -version = "1.0.22" -criteria = "safe-to-deploy" - [[exemptions.ryu]] version = "1.0.20" criteria = "safe-to-deploy" @@ -1400,18 +1066,6 @@ criteria = "safe-to-deploy" version = "1.0.27" criteria = "safe-to-deploy" -[[exemptions.serde]] -version = "1.0.226" -criteria = "safe-to-deploy" - -[[exemptions.serde_core]] -version = "1.0.226" -criteria = "safe-to-deploy" - -[[exemptions.serde_derive]] -version = "1.0.226" -criteria = "safe-to-deploy" - [[exemptions.serde_derive_internals]] version = "0.29.1" criteria = "safe-to-deploy" @@ -1464,18 +1118,6 @@ criteria = "safe-to-run" version = "3.2.0" criteria = "safe-to-run" -[[exemptions.sha1]] -version = "0.10.6" -criteria = "safe-to-deploy" - -[[exemptions.sha2]] -version = "0.10.9" -criteria = "safe-to-deploy" - -[[exemptions.sharded-slab]] -version = "0.1.7" -criteria = "safe-to-deploy" - [[exemptions.shared_child]] version = "1.1.1" criteria = "safe-to-deploy" @@ -1484,10 +1126,6 @@ criteria = "safe-to-deploy" version = "0.2.0" criteria = "safe-to-deploy" -[[exemptions.shlex]] -version = "1.3.0" -criteria = "safe-to-deploy" - [[exemptions.sigchld]] version = "0.2.4" criteria = "safe-to-deploy" @@ -1504,10 +1142,6 @@ criteria = "safe-to-deploy" version = "1.4.6" criteria = "safe-to-deploy" -[[exemptions.similar]] -version = "2.7.0" -criteria = "safe-to-deploy" - [[exemptions.simple_asn1]] version = "0.6.3" criteria = "safe-to-deploy" @@ -1516,10 +1150,6 @@ criteria = "safe-to-deploy" version = "0.4.11" criteria = "safe-to-deploy" -[[exemptions.smallvec]] -version = "1.15.1" -criteria = "safe-to-deploy" - [[exemptions.snafu]] version = "0.8.9" criteria = "safe-to-deploy" @@ -1532,22 +1162,10 @@ criteria = "safe-to-deploy" version = "0.6.0" criteria = "safe-to-deploy" -[[exemptions.stable_deref_trait]] -version = "1.2.0" -criteria = "safe-to-deploy" - [[exemptions.starbase_styles]] version = "0.6.3" criteria = "safe-to-deploy" -[[exemptions.static_assertions]] -version = "1.1.0" -criteria = "safe-to-deploy" - -[[exemptions.std_prelude]] -version = "0.2.12" -criteria = "safe-to-deploy" - [[exemptions.strict]] version = "0.2.0" criteria = "safe-to-deploy" @@ -1560,14 +1178,6 @@ criteria = "safe-to-deploy" version = "0.2.1" criteria = "safe-to-deploy" -[[exemptions.strsim]] -version = "0.11.1" -criteria = "safe-to-deploy" - -[[exemptions.subtle]] -version = "2.6.1" -criteria = "safe-to-deploy" - [[exemptions.supports-color]] version = "3.0.2" criteria = "safe-to-deploy" @@ -1580,10 +1190,6 @@ criteria = "safe-to-deploy" version = "1.0.2" criteria = "safe-to-deploy" -[[exemptions.synstructure]] -version = "0.13.2" -criteria = "safe-to-deploy" - [[exemptions.syntect]] version = "5.2.0" criteria = "safe-to-deploy" @@ -1624,18 +1230,10 @@ criteria = "safe-to-deploy" version = "0.2.18" criteria = "safe-to-deploy" -[[exemptions.thiserror]] -version = "1.0.69" -criteria = "safe-to-deploy" - [[exemptions.thiserror]] version = "2.0.16" criteria = "safe-to-deploy" -[[exemptions.thiserror-impl]] -version = "1.0.69" -criteria = "safe-to-deploy" - [[exemptions.thiserror-impl]] version = "2.0.16" criteria = "safe-to-deploy" @@ -1644,10 +1242,6 @@ criteria = "safe-to-deploy" version = "0.2.0" criteria = "safe-to-deploy" -[[exemptions.thread_local]] -version = "1.1.9" -criteria = "safe-to-deploy" - [[exemptions.time]] version = "0.3.44" criteria = "safe-to-deploy" @@ -1664,18 +1258,10 @@ criteria = "safe-to-deploy" version = "0.5.0" criteria = "safe-to-deploy" -[[exemptions.tinystr]] -version = "0.8.1" -criteria = "safe-to-deploy" - [[exemptions.tinyvec]] version = "1.10.0" criteria = "safe-to-deploy" -[[exemptions.tinyvec_macros]] -version = "0.1.1" -criteria = "safe-to-deploy" - [[exemptions.tokio]] version = "1.47.1" criteria = "safe-to-deploy" @@ -1688,10 +1274,6 @@ criteria = "safe-to-deploy" version = "0.26.3" criteria = "safe-to-deploy" -[[exemptions.tokio-stream]] -version = "0.1.17" -criteria = "safe-to-deploy" - [[exemptions.tokio-util]] version = "0.7.16" criteria = "safe-to-deploy" @@ -1748,34 +1330,10 @@ criteria = "safe-to-deploy" version = "0.3.3" criteria = "safe-to-deploy" -[[exemptions.tracing]] -version = "0.1.41" -criteria = "safe-to-deploy" - -[[exemptions.tracing-attributes]] -version = "0.1.30" -criteria = "safe-to-deploy" - -[[exemptions.tracing-core]] -version = "0.1.34" -criteria = "safe-to-deploy" - -[[exemptions.tracing-log]] -version = "0.2.0" -criteria = "safe-to-deploy" - [[exemptions.tracing-serde]] version = "0.2.0" criteria = "safe-to-deploy" -[[exemptions.tracing-subscriber]] -version = "0.3.20" -criteria = "safe-to-deploy" - -[[exemptions.try-lock]] -version = "0.2.5" -criteria = "safe-to-deploy" - [[exemptions.typed-arena]] version = "2.0.2" criteria = "safe-to-deploy" @@ -1800,10 +1358,6 @@ criteria = "safe-to-deploy" version = "0.1.7" criteria = "safe-to-deploy" -[[exemptions.unicase]] -version = "2.8.1" -criteria = "safe-to-deploy" - [[exemptions.unicode-general-category]] version = "1.1.0" criteria = "safe-to-deploy" @@ -1812,22 +1366,6 @@ criteria = "safe-to-deploy" version = "1.0.19" criteria = "safe-to-deploy" -[[exemptions.unicode-normalization]] -version = "0.1.24" -criteria = "safe-to-deploy" - -[[exemptions.unicode-segmentation]] -version = "1.12.0" -criteria = "safe-to-deploy" - -[[exemptions.unicode-width]] -version = "0.1.14" -criteria = "safe-to-deploy" - -[[exemptions.unicode-width]] -version = "0.2.1" -criteria = "safe-to-deploy" - [[exemptions.unicode_categories]] version = "0.1.1" criteria = "safe-to-deploy" @@ -1840,34 +1378,14 @@ criteria = "safe-to-deploy" version = "0.9.0" criteria = "safe-to-deploy" -[[exemptions.url]] -version = "2.5.7" -criteria = "safe-to-deploy" - -[[exemptions.utf8_iter]] -version = "1.0.4" -criteria = "safe-to-deploy" - -[[exemptions.utf8parse]] -version = "0.2.2" -criteria = "safe-to-deploy" - [[exemptions.uuid-simd]] version = "0.8.0" criteria = "safe-to-deploy" -[[exemptions.valuable]] -version = "0.1.1" -criteria = "safe-to-deploy" - [[exemptions.valuable-serde]] version = "0.1.1" criteria = "safe-to-deploy" -[[exemptions.vcpkg]] -version = "0.2.15" -criteria = "safe-to-deploy" - [[exemptions.version_check]] version = "0.9.5" criteria = "safe-to-deploy" @@ -1884,18 +1402,10 @@ criteria = "safe-to-deploy" version = "2.5.0" criteria = "safe-to-deploy" -[[exemptions.want]] -version = "0.3.1" -criteria = "safe-to-deploy" - [[exemptions.wasi]] version = "0.11.1+wasi-snapshot-preview1" criteria = "safe-to-deploy" -[[exemptions.wasip2]] -version = "1.0.1+wasi-0.2.4" -criteria = "safe-to-deploy" - [[exemptions.wasm-bindgen]] version = "0.2.103" criteria = "safe-to-deploy" @@ -1972,14 +1482,6 @@ criteria = "safe-to-deploy" version = "0.56.0" criteria = "safe-to-deploy" -[[exemptions.windows-link]] -version = "0.1.3" -criteria = "safe-to-deploy" - -[[exemptions.windows-link]] -version = "0.2.0" -criteria = "safe-to-deploy" - [[exemptions.windows-result]] version = "0.1.2" criteria = "safe-to-deploy" @@ -2080,14 +1582,6 @@ criteria = "safe-to-deploy" version = "0.0.19" criteria = "safe-to-deploy" -[[exemptions.wit-bindgen]] -version = "0.46.0" -criteria = "safe-to-deploy" - -[[exemptions.writeable]] -version = "0.6.1" -criteria = "safe-to-deploy" - [[exemptions.xterm-color]] version = "1.0.1" criteria = "safe-to-deploy" @@ -2095,43 +1589,3 @@ criteria = "safe-to-deploy" [[exemptions.yansi]] version = "1.0.1" criteria = "safe-to-run" - -[[exemptions.yoke]] -version = "0.8.0" -criteria = "safe-to-deploy" - -[[exemptions.yoke-derive]] -version = "0.8.0" -criteria = "safe-to-deploy" - -[[exemptions.zerocopy]] -version = "0.8.27" -criteria = "safe-to-deploy" - -[[exemptions.zerocopy-derive]] -version = "0.8.27" -criteria = "safe-to-deploy" - -[[exemptions.zerofrom]] -version = "0.1.6" -criteria = "safe-to-deploy" - -[[exemptions.zerofrom-derive]] -version = "0.1.6" -criteria = "safe-to-deploy" - -[[exemptions.zeroize]] -version = "1.8.1" -criteria = "safe-to-deploy" - -[[exemptions.zerotrie]] -version = "0.2.2" -criteria = "safe-to-deploy" - -[[exemptions.zerovec]] -version = "0.11.4" -criteria = "safe-to-deploy" - -[[exemptions.zerovec-derive]] -version = "0.11.1" -criteria = "safe-to-deploy" diff --git a/supply-chain/imports.lock b/supply-chain/imports.lock index 0c397a40..bf6328ef 100644 --- a/supply-chain/imports.lock +++ b/supply-chain/imports.lock @@ -1,2 +1,2848 @@ # cargo-vet imports lock + +[[publisher.bumpalo]] +version = "3.19.0" +when = "2025-06-24" +user-id = 696 +user-login = "fitzgen" +user-name = "Nick Fitzgerald" + +[[publisher.encoding_rs]] +version = "0.8.35" +when = "2024-10-24" +user-id = 4484 +user-login = "hsivonen" +user-name = "Henri Sivonen" + +[[publisher.unicode-normalization]] +version = "0.1.24" +when = "2024-09-17" +user-id = 1139 +user-login = "Manishearth" +user-name = "Manish Goregaokar" + +[[publisher.unicode-segmentation]] +version = "1.12.0" +when = "2024-09-13" +user-id = 1139 +user-login = "Manishearth" +user-name = "Manish Goregaokar" + +[[publisher.unicode-width]] +version = "0.1.14" +when = "2024-09-19" +user-id = 1139 +user-login = "Manishearth" +user-name = "Manish Goregaokar" + +[[publisher.unicode-width]] +version = "0.2.1" +when = "2025-06-09" +user-id = 1139 +user-login = "Manishearth" +user-name = "Manish Goregaokar" + +[[publisher.utf8_iter]] +version = "1.0.4" +when = "2023-12-01" +user-id = 4484 +user-login = "hsivonen" +user-name = "Henri Sivonen" + +[[publisher.wasip2]] +version = "1.0.1+wasi-0.2.4" +when = "2025-09-15" +user-id = 1 +user-login = "alexcrichton" +user-name = "Alex Crichton" + +[[publisher.wit-bindgen]] +version = "0.43.0" +when = "2025-06-24" +user-id = 73222 +user-login = "wasmtime-publish" + +[[audits.bytecode-alliance.wildcard-audits.bumpalo]] +who = "Nick Fitzgerald " +criteria = "safe-to-deploy" +user-id = 696 # Nick Fitzgerald (fitzgen) +start = "2019-03-16" +end = "2026-08-21" + +[[audits.bytecode-alliance.wildcard-audits.wasip2]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +user-id = 1 # Alex Crichton (alexcrichton) +start = "2025-08-10" +end = "2026-08-21" +notes = """ +This is a Bytecode Alliance authored crate. +""" + +[[audits.bytecode-alliance.wildcard-audits.wit-bindgen]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +user-id = 73222 # wasmtime-publish +start = "2023-01-01" +end = "2026-06-03" +notes = """ +The Bytecode Alliance uses the `wasmtime-publish` crates.io account to automate +publication of this crate from CI. This repository requires all PRs are reviewed +by a Bytecode Alliance maintainer and it owned by the Bytecode Alliance itself. +""" + +[[audits.bytecode-alliance.audits.allocator-api2]] +who = "Chris Fallin " +criteria = "safe-to-deploy" +delta = "0.2.18 -> 0.2.20" +notes = """ +The changes appear to be reasonable updates from Rust's stdlib imported into +`allocator-api2`'s copy of this code. +""" + +[[audits.bytecode-alliance.audits.atomic-waker]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +version = "1.1.2" +notes = "Contains `unsafe` code but it's well-documented and scoped to what it's intended to be doing. Otherwise a well-focused and straightforward crate." + +[[audits.bytecode-alliance.audits.base64]] +who = "Pat Hickey " +criteria = "safe-to-deploy" +version = "0.21.0" +notes = "This crate has no dependencies, no build.rs, and contains no unsafe code." + +[[audits.bytecode-alliance.audits.bitflags]] +who = "Jamey Sharp " +criteria = "safe-to-deploy" +delta = "2.1.0 -> 2.2.1" +notes = """ +This version adds unsafe impls of traits from the bytemuck crate when built +with that library enabled, but I believe the impls satisfy the documented +safety requirements for bytemuck. The other changes are minor. +""" + +[[audits.bytecode-alliance.audits.bitflags]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +delta = "2.3.2 -> 2.3.3" +notes = """ +Nothing outside the realm of what one would expect from a bitflags generator, +all as expected. +""" + +[[audits.bytecode-alliance.audits.bitflags]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +delta = "2.4.1 -> 2.6.0" +notes = """ +Changes in how macros are invoked and various bits and pieces of macro-fu. +Otherwise no major changes and nothing dealing with `unsafe`. +""" + +[[audits.bytecode-alliance.audits.bitflags]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +delta = "2.7.0 -> 2.9.4" +notes = "Tweaks to the macro, nothing out of order." + +[[audits.bytecode-alliance.audits.block-buffer]] +who = "Benjamin Bouvier " +criteria = "safe-to-deploy" +delta = "0.9.0 -> 0.10.2" + +[[audits.bytecode-alliance.audits.cfg-if]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +version = "1.0.0" +notes = "I am the author of this crate." + +[[audits.bytecode-alliance.audits.crypto-common]] +who = "Benjamin Bouvier " +criteria = "safe-to-deploy" +version = "0.1.3" + +[[audits.bytecode-alliance.audits.errno]] +who = "Dan Gohman " +criteria = "safe-to-deploy" +version = "0.3.0" +notes = "This crate uses libc and windows-sys APIs to get and set the raw OS error value." + +[[audits.bytecode-alliance.audits.errno]] +who = "Dan Gohman " +criteria = "safe-to-deploy" +delta = "0.3.0 -> 0.3.1" +notes = "Just a dependency version bump and a bug fix for redox" + +[[audits.bytecode-alliance.audits.errno]] +who = "Dan Gohman " +criteria = "safe-to-deploy" +delta = "0.3.9 -> 0.3.10" + +[[audits.bytecode-alliance.audits.fastrand]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +delta = "2.0.0 -> 2.0.1" +notes = """ +This update had a few doc updates but no otherwise-substantial source code +updates. +""" + +[[audits.bytecode-alliance.audits.fastrand]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +delta = "2.1.1 -> 2.3.0" +notes = "Minor refactoring, nothing new." + +[[audits.bytecode-alliance.audits.futures]] +who = "Joel Dice " +criteria = "safe-to-deploy" +version = "0.3.31" + +[[audits.bytecode-alliance.audits.futures-channel]] +who = "Joel Dice " +criteria = "safe-to-deploy" +version = "0.3.31" + +[[audits.bytecode-alliance.audits.futures-core]] +who = "Pat Hickey " +criteria = "safe-to-deploy" +version = "0.3.27" +notes = "Unsafe used to implement a concurrency primitive AtomicWaker. Well-commented and not obviously incorrect. Like my other audits of these concurrency primitives inside the futures family, I couldn't certify that it is correct without formal methods, but that is out of scope for this vetting." + +[[audits.bytecode-alliance.audits.futures-core]] +who = "Pat Hickey " +criteria = "safe-to-deploy" +delta = "0.3.28 -> 0.3.31" + +[[audits.bytecode-alliance.audits.futures-executor]] +who = "Joel Dice " +criteria = "safe-to-deploy" +version = "0.3.31" + +[[audits.bytecode-alliance.audits.futures-io]] +who = "Joel Dice " +criteria = "safe-to-deploy" +version = "0.3.31" + +[[audits.bytecode-alliance.audits.futures-macro]] +who = "Joel Dice " +criteria = "safe-to-deploy" +version = "0.3.31" + +[[audits.bytecode-alliance.audits.futures-sink]] +who = "Pat Hickey " +criteria = "safe-to-deploy" +version = "0.3.27" + +[[audits.bytecode-alliance.audits.futures-sink]] +who = "Pat Hickey " +criteria = "safe-to-deploy" +delta = "0.3.28 -> 0.3.31" + +[[audits.bytecode-alliance.audits.gimli]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +delta = "0.29.0 -> 0.31.0" +notes = "Various updates here and there, nothing too major, what you'd expect from a DWARF parsing crate." + +[[audits.bytecode-alliance.audits.gimli]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +delta = "0.31.0 -> 0.31.1" +notes = "No fundmanetally new `unsafe` code, some small refactoring of existing code. Lots of changes in tests, not as many changes in the rest of the crate. More dwarf!" + +[[audits.bytecode-alliance.audits.heck]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +delta = "0.4.1 -> 0.5.0" +notes = "Minor changes for a `no_std` upgrade but otherwise everything looks as expected." + +[[audits.bytecode-alliance.audits.http-body]] +who = "Pat Hickey " +criteria = "safe-to-deploy" +version = "1.0.0-rc.2" + +[[audits.bytecode-alliance.audits.http-body]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +delta = "1.0.0-rc.2 -> 1.0.0" +notes = "Only minor changes made for a stable release." + +[[audits.bytecode-alliance.audits.iana-time-zone-haiku]] +who = "Dan Gohman " +criteria = "safe-to-deploy" +version = "0.1.2" + +[[audits.bytecode-alliance.audits.idna]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +version = "0.3.0" +notes = """ +This is a crate without unsafe code or usage of the standard library. The large +size of this crate comes from the large generated unicode tables file. This +crate is broadly used throughout the ecosystem and does not contain anything +suspicious. +""" + +[[audits.bytecode-alliance.audits.log]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +delta = "0.4.22 -> 0.4.27" +notes = "Lots of minor updates to macros and such, nothing touching `unsafe`" + +[[audits.bytecode-alliance.audits.log]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +delta = "0.4.27 -> 0.4.28" +notes = "Minor doc updates and lots new tests, nothing out of the ordinary." + +[[audits.bytecode-alliance.audits.matchers]] +who = "Pat Hickey " +criteria = "safe-to-deploy" +version = "0.1.0" + +[[audits.bytecode-alliance.audits.matchers]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +delta = "0.1.0 -> 0.2.0" +notes = "Some unsafe code, but not more than before. Nothing awry." + +[[audits.bytecode-alliance.audits.miniz_oxide]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +version = "0.7.1" +notes = """ +This crate is a Rust implementation of zlib compression/decompression and has +been used by default by the Rust standard library for quite some time. It's also +a default dependency of the popular `backtrace` crate for decompressing debug +information. This crate forbids unsafe code and does not otherwise access system +resources. It's originally a port of the `miniz.c` library as well, and given +its own longevity should be relatively hardened against some of the more common +compression-related issues. +""" + +[[audits.bytecode-alliance.audits.miniz_oxide]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +delta = "0.7.1 -> 0.8.0" +notes = "Minor updates, using new Rust features like `const`, no major changes." + +[[audits.bytecode-alliance.audits.miniz_oxide]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +delta = "0.8.0 -> 0.8.5" +notes = """ +Lots of small updates here and there, for example around modernizing Rust +idioms. No new `unsafe` code and everything looks like what you'd expect a +compression library to be doing. +""" + +[[audits.bytecode-alliance.audits.miniz_oxide]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +delta = "0.8.5 -> 0.8.9" +notes = "No new unsafe code, just refactorings." + +[[audits.bytecode-alliance.audits.nu-ansi-term]] +who = "Pat Hickey " +criteria = "safe-to-deploy" +version = "0.46.0" +notes = "one use of unsafe to call windows specific api to get console handle." + +[[audits.bytecode-alliance.audits.nu-ansi-term]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +delta = "0.46.0 -> 0.50.1" +notes = "Lots of stylistic/rust-related chanegs, plus new features, but nothing out of the ordrinary." + +[[audits.bytecode-alliance.audits.percent-encoding]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +version = "2.2.0" +notes = """ +This crate is a single-file crate that does what it says on the tin. There are +a few `unsafe` blocks related to utf-8 validation which are locally verifiable +as correct and otherwise this crate is good to go. +""" + +[[audits.bytecode-alliance.audits.pin-utils]] +who = "Pat Hickey " +criteria = "safe-to-deploy" +version = "0.1.0" + +[[audits.bytecode-alliance.audits.pkg-config]] +who = "Pat Hickey " +criteria = "safe-to-deploy" +version = "0.3.25" +notes = "This crate shells out to the pkg-config executable, but it appears to sanitize inputs reasonably." + +[[audits.bytecode-alliance.audits.pkg-config]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +delta = "0.3.26 -> 0.3.29" +notes = """ +No `unsafe` additions or anything outside of the purview of the crate in this +change. +""" + +[[audits.bytecode-alliance.audits.pkg-config]] +who = "Chris Fallin " +criteria = "safe-to-deploy" +delta = "0.3.29 -> 0.3.32" + +[[audits.bytecode-alliance.audits.rustc-demangle]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +version = "0.1.21" +notes = "I am the author of this crate." + +[[audits.bytecode-alliance.audits.rustc-demangle]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +delta = "0.1.21 -> 0.1.24" + +[[audits.bytecode-alliance.audits.sha1]] +who = "Andrew Brown " +criteria = "safe-to-deploy" +delta = "0.10.5 -> 0.10.6" +notes = "Only new code is some loongarch64 additions which include assembly code for that platform." + +[[audits.bytecode-alliance.audits.sharded-slab]] +who = "Pat Hickey " +criteria = "safe-to-deploy" +version = "0.1.4" +notes = "I always really enjoy reading eliza's code, she left perfect comments at every use of unsafe." + +[[audits.bytecode-alliance.audits.shlex]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +version = "1.1.0" +notes = "Only minor `unsafe` code blocks which look valid and otherwise does what it says on the tin." + +[[audits.bytecode-alliance.audits.thread_local]] +who = "Pat Hickey " +criteria = "safe-to-deploy" +version = "1.1.4" +notes = "uses unsafe to implement thread local storage of objects" + +[[audits.bytecode-alliance.audits.tracing-attributes]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +delta = "0.1.28 -> 0.1.30" +notes = "Few code changes, a pretty minor update." + +[[audits.bytecode-alliance.audits.tracing-core]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +delta = "0.1.33 -> 0.1.34" +notes = "Mostly just an update with Rust stylistic conventions changing. Nothing awry." + +[[audits.bytecode-alliance.audits.tracing-log]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +version = "0.1.3" +notes = """ +This is a standard adapter between the `log` ecosystem and the `tracing` +ecosystem. There's one `unsafe` block in this crate and it's well-scoped. +""" + +[[audits.bytecode-alliance.audits.tracing-log]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +delta = "0.1.3 -> 0.2.0" +notes = "Nothing out of the ordinary, a typical major version update and nothing awry." + +[[audits.bytecode-alliance.audits.tracing-subscriber]] +who = "Pat Hickey " +criteria = "safe-to-deploy" +version = "0.3.17" + +[[audits.bytecode-alliance.audits.try-lock]] +who = "Pat Hickey " +criteria = "safe-to-deploy" +version = "0.2.4" +notes = "Implements a concurrency primitive with atomics, and is not obviously incorrect" + +[[audits.bytecode-alliance.audits.unicase]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +version = "2.6.0" +notes = """ +This crate contains no `unsafe` code and no unnecessary use of the standard +library. +""" + +[[audits.bytecode-alliance.audits.vcpkg]] +who = "Pat Hickey " +criteria = "safe-to-deploy" +version = "0.2.15" +notes = "no build.rs, no macros, no unsafe. It reads the filesystem and makes copies of DLLs into OUT_DIR." + +[[audits.bytecode-alliance.audits.want]] +who = "Pat Hickey " +criteria = "safe-to-deploy" +version = "0.3.0" + +[[audits.bytecode-alliance.audits.wit-bindgen]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +delta = "0.43.0 -> 0.45.0" +notes = "The Bytecode Alliance is the author of this crate" + +[[audits.bytecode-alliance.audits.wit-bindgen]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +delta = "0.45.0 -> 0.45.1" +notes = "The Bytecode Alliance is the author of this crate" + +[[audits.bytecode-alliance.audits.wit-bindgen]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +delta = "0.45.1 -> 0.46.0" +notes = "The Bytecode Alliance is the author of this crate" + +[[audits.embark-studios.audits.cfg_aliases]] +who = "Johan Andersson " +criteria = "safe-to-deploy" +version = "0.1.1" +notes = "No unsafe usage or ambient capabilities" + +[[audits.embark-studios.audits.ident_case]] +who = "Johan Andersson " +criteria = "safe-to-deploy" +version = "1.0.1" +notes = "No unsafe usage or ambient capabilities" + +[[audits.embark-studios.audits.idna]] +who = "Johan Andersson " +criteria = "safe-to-deploy" +delta = "0.3.0 -> 0.4.0" +notes = "No unsafe usage or ambient capabilities" + +[[audits.embark-studios.audits.similar]] +who = "Johan Andersson " +criteria = "safe-to-deploy" +version = "2.2.1" +notes = "No unsafe usage or ambient capabilities" + +[[audits.embark-studios.audits.std_prelude]] +who = "Johan Andersson " +criteria = "safe-to-deploy" +version = "0.2.12" +notes = "No unsafe usage or ambient capabilities. Only re-exports std types. However I would not recommend using this crate as it is an unnecessary dependency and indirection, and makes it harder to audit other code over standard explicit std imports" + +[[audits.embark-studios.audits.thiserror]] +who = "Johan Andersson " +criteria = "safe-to-deploy" +version = "1.0.40" +notes = "Wrapper over implementation crate, found no unsafe or ambient capabilities used" + +[[audits.embark-studios.audits.thiserror-impl]] +who = "Johan Andersson " +criteria = "safe-to-deploy" +version = "1.0.40" +notes = "Found no unsafe or ambient capabilities used" + +[[audits.embark-studios.audits.valuable]] +who = "Johan Andersson " +criteria = "safe-to-deploy" +version = "0.1.0" +notes = "No unsafe usage or ambient capabilities, sane build script" + +[[audits.google.audits.adler2]] +who = "Lukasz Anforowicz " +criteria = "safe-to-deploy" +version = "2.0.0" +notes = ''' +This audit has been reviewed in https://crrev.com/c/5811890 + +The crate is fairly easy to read thanks to its small size and rich comments. + +I've grepped for `-i cipher`, `-i crypto`, `\bfs\b`, `\bnet\b`, and +`\bunsafe\b`. There were no hits (except for a comment in `README.md` +and `lib.rs` pointing out "Zero `unsafe`"). +''' +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.android_system_properties]] +who = "Manish Goregaokar " +criteria = "safe-to-deploy" +version = "0.1.5" +notes = "Android system API FFI" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.arrayvec]] +who = "Lukasz Anforowicz " +criteria = "safe-to-deploy" +version = "0.7.6" +notes = ''' +Grepped for `-i cipher`, `-i crypto`, `'\bfs\b'`, `'\bnet\b'` and there were +no hits, except for some `net` usage in tests. + +The crate has quite a few bits of `unsafe` Rust. The audit comments can be +found in https://chromium-review.googlesource.com/c/chromium/src/+/6187726/2 +''' +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.assert_matches]] +who = "ChromeOS" +criteria = "safe-to-run" +version = "1.5.0" +aggregated-from = "https://chromium.googlesource.com/chromiumos/third_party/rust_crates/+/refs/heads/main/cargo-vet/audits.toml?format=TEXT" + +[[audits.google.audits.autocfg]] +who = "Manish Goregaokar " +criteria = "safe-to-deploy" +version = "1.4.0" +notes = "Contains no unsafe" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.base64]] +who = "amarjotgill " +criteria = "safe-to-deploy" +version = "0.22.1" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.bitflags]] +who = "Lukasz Anforowicz " +criteria = "safe-to-deploy" +version = "1.3.2" +notes = """ +Security review of earlier versions of the crate can be found at +(Google-internal, sorry): go/image-crate-chromium-security-review + +The crate exposes a function marked as `unsafe`, but doesn't use any +`unsafe` blocks (except for tests of the single `unsafe` function). I +think this justifies marking this crate as `ub-risk-1`. + +Additional review comments can be found at https://crrev.com/c/4723145/31 +""" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.core-foundation-sys]] +who = "Manish Goregaokar " +criteria = "safe-to-deploy" +version = "0.8.7" +notes = "OSX system APIs" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.displaydoc]] +who = "Manish Goregaokar " +criteria = "safe-to-deploy" +version = "0.2.5" +notes = "No unsafe code" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.either]] +who = "Manish Goregaokar " +criteria = "safe-to-deploy" +version = "1.13.0" +notes = "Unsafe code pertaining to wrapping Pin APIs. Mostly passes invariants down." +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.either]] +who = "Daniel Cheng " +criteria = "safe-to-deploy" +delta = "1.13.0 -> 1.14.0" +notes = """ +Inheriting ub-risk-1 from the baseline review of 1.13.0. While the delta has some diffs in unsafe code, they are either: +- migrating code to use helper macros +- migrating match patterns to take advantage of default bindings mode from RFC 2005 +Either way, the result is code that does exactly the same thing and does not change the risk of UB. + +See https://crrev.com/c/6323164 for more audit details. +""" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.either]] +who = "Lukasz Anforowicz " +criteria = "safe-to-deploy" +delta = "1.14.0 -> 1.15.0" +notes = "The delta in `lib.rs` only tweaks doc comments and `#[cfg(feature = \"std\")]`." +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.equivalent]] +who = "George Burgess IV " +criteria = "safe-to-deploy" +version = "1.0.1" +aggregated-from = "https://chromium.googlesource.com/chromiumos/third_party/rust_crates/+/refs/heads/main/cargo-vet/audits.toml?format=TEXT" + +[[audits.google.audits.equivalent]] +who = "Jonathan Hao " +criteria = "safe-to-deploy" +delta = "1.0.1 -> 1.0.2" +notes = "No changes to any .rs files or Rust code." +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.fastrand]] +who = "George Burgess IV " +criteria = "safe-to-deploy" +version = "1.9.0" +notes = """ +`does-not-implement-crypto` is certified because this crate explicitly says +that the RNG here is not cryptographically secure. +""" +aggregated-from = "https://chromium.googlesource.com/chromiumos/third_party/rust_crates/+/refs/heads/main/cargo-vet/audits.toml?format=TEXT" + +[[audits.google.audits.foldhash]] +who = "Lukasz Anforowicz " +criteria = "safe-to-deploy" +version = "0.1.3" +notes = """ +`ub-risk-2` review notes can be found in https://crrev.com/c/6071306/5/third_party/rust/chromium_crates_io/vendor/foldhash-0.1.3/src/seed.rs + +`does-not-implement-crypto` based on `README.md` which explicitly says that +\"Foldhash is **not appropriate for any cryptographic purpose**.\" +""" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.foldhash]] +who = "Adrian Taylor " +criteria = "safe-to-deploy" +delta = "0.1.3 -> 0.1.4" +notes = "No changes to safety-relevant code" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.foldhash]] +who = "Chris Palmer " +criteria = "safe-to-deploy" +delta = "0.1.4 -> 0.1.5" +notes = "No new `unsafe`." +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.glob]] +who = "George Burgess IV " +criteria = "safe-to-deploy" +version = "0.3.1" +aggregated-from = "https://chromium.googlesource.com/chromiumos/third_party/rust_crates/+/refs/heads/main/cargo-vet/audits.toml?format=TEXT" + +[[audits.google.audits.glob]] +who = "Dustin J. Mitchell " +criteria = "safe-to-deploy" +delta = "0.3.1 -> 0.3.2" +notes = "Still no unsafe" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.heck]] +who = "Lukasz Anforowicz " +criteria = "safe-to-deploy" +version = "0.4.1" +notes = """ +Grepped for `-i cipher`, `-i crypto`, `'\bfs\b'``, `'\bnet\b'``, `'\bunsafe\b'`` +and there were no hits. + +`heck` (version `0.3.3`) has been added to Chromium in +https://source.chromium.org/chromium/chromium/src/+/28841c33c77833cc30b286f9ae24c97e7a8f4057 +""" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.httpdate]] +who = "George Burgess IV " +criteria = "safe-to-deploy" +version = "1.0.3" +aggregated-from = "https://chromium.googlesource.com/chromiumos/third_party/rust_crates/+/refs/heads/main/cargo-vet/audits.toml?format=TEXT" + +[[audits.google.audits.iana-time-zone]] +who = "Manish Goregaokar " +criteria = "safe-to-deploy" +version = "0.1.61" +notes = "Some unsafe: interfacing with system timezone APIs" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.icu_collections]] +who = "Manish Goregaokar " +criteria = "safe-to-deploy" +version = "2.0.0-beta1" +notes = """ +Two instances of unsafe : + - Non-safety related unsafe API that imposes additional invariants + - `from_utf8` for known-UTF8 integer + +Comments added/improved in https://github.com/unicode-org/icu4x/pull/6056. +""" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.icu_collections]] +who = "Manish Goregaokar " +criteria = "safe-to-deploy" +delta = "2.0.0-beta1 -> 2.0.0-beta2" +notes = "from_utf8 unsafe removed. no new unsafe added" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.icu_locale_core]] +who = "Manish Goregaokar " +criteria = "safe-to-deploy" +version = "2.0.0-beta2" +notes = """ +All unsafe code commented (and improved from prior version): + - A checklisted ULE impl + - from-utf8 code on known-ASCII + - Some unchecked indexing around maintained invariants +""" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.icu_normalizer]] +who = "Manish Goregaokar " +criteria = "safe-to-deploy" +version = "2.0.0-beta2" +notes = """ +All unsafe is unchecked `char` and `str` conversion, mostly well-commented. +""" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.icu_normalizer_data]] +who = "Manish Goregaokar " +criteria = "safe-to-deploy" +version = "2.0.0-beta1" +notes = "Contains codegenned unsafe only, using safe Bake impls from zerovec/zerotrie" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.icu_normalizer_data]] +who = "Manish Goregaokar " +criteria = "safe-to-deploy" +delta = "2.0.0-beta1 -> 2.0.0-beta2" +notes = "Contains codegenned unsafe only, using safe Bake impls from zerovec/zerotrie" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.icu_properties]] +who = "Manish Goregaokar " +criteria = "safe-to-deploy" +version = "2.0.0-beta2" +notes = "All unsafe was removed" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.icu_properties_data]] +who = "Manish Goregaokar " +criteria = "safe-to-deploy" +version = "2.0.0-beta1" +notes = "Contains codegenned unsafe only, using safe Bake impls from zerovec/zerotrie" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.icu_properties_data]] +who = "Manish Goregaokar " +criteria = "safe-to-deploy" +delta = "2.0.0-beta1 -> 2.0.0-beta2" +notes = "Contains codegenned unsafe only, using safe Bake impls from zerovec/zerotrie" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.icu_provider]] +who = "Manish Goregaokar " +criteria = "safe-to-deploy" +version = "2.0.0-beta1" +notes = """ +All unsafe code commented: + - Minor unsafe transmutes between types which are identical but not type-system-provably so. + - One unsafe EqULE impl + - Some repr(transparent) transmutes + - A from_utf8_unchecked for an ascii-validated string + +Comment improvements can be found in https://github.com/unicode-org/icu4x/pull/6056 +""" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.icu_provider]] +who = "Manish Goregaokar " +criteria = "safe-to-deploy" +delta = "2.0.0-beta1 -> 2.0.0-beta2" +notes = "from_utf8_unchecked unsafe remove, all other unsafe not meaningfully changed" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.indexmap]] +who = "Lukasz Anforowicz " +criteria = "safe-to-deploy" +version = "2.7.1" +notes = ''' +Grepped for `-i cipher`, `-i crypto`, `'\bfs\b'`, `'\bnet\b'` +and there were no hits. + +There is a little bit of `unsafe` Rust code - the audit can be found at +https://chromium-review.googlesource.com/c/chromium/src/+/6187726/2 +''' +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.indexmap]] +who = "Lukasz Anforowicz " +criteria = "safe-to-deploy" +delta = "2.7.1 -> 2.8.0" +notes = """ +No `unsafe` introduced or affected in: +* `indexmap_with_default!` and `indexset_with_default!` macros +* New `PartialEq` implementations +* `fn slice_eq` in `util.rs` +""" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.itoa]] +who = "Lukasz Anforowicz " +criteria = "safe-to-deploy" +version = "1.0.10" +notes = ''' +I grepped for \"crypt\", \"cipher\", \"fs\", \"net\" - there were no hits. + +There are a few places where `unsafe` is used. Unsafe review notes can be found +in https://crrev.com/c/5350697. + +Version 1.0.1 of this crate has been added to Chromium in +https://crrev.com/c/3321896. +''' +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.itoa]] +who = "Lukasz Anforowicz " +criteria = "safe-to-deploy" +delta = "1.0.10 -> 1.0.11" +notes = """ +Straightforward diff between 1.0.10 and 1.0.11 - only 3 commits: + +* Bumping up the version +* A touch up of comments +* And my own PR to make `unsafe` blocks more granular: + https://github.com/dtolnay/itoa/pull/42 +""" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.itoa]] +who = "Liza Burakova " +criteria = "safe-to-deploy" +delta = "1.0.11 -> 1.0.14" +notes = """ +Unsafe review at https://crrev.com/c/6051067 +""" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.itoa]] +who = "Daniel Cheng " +criteria = "safe-to-deploy" +delta = "1.0.14 -> 1.0.15" +notes = "Only minor rustdoc changes." +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.lazy_static]] +who = "Lukasz Anforowicz " +criteria = "safe-to-deploy" +version = "1.4.0" +notes = ''' +I grepped for \"crypt\", \"cipher\", \"fs\", \"net\" - there were no hits. + +There are two places where `unsafe` is used. Unsafe review notes can be found +in https://crrev.com/c/5347418. + +This crate has been added to Chromium in https://crrev.com/c/3321895. +''' +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.lazy_static]] +who = "Lukasz Anforowicz " +criteria = "safe-to-deploy" +delta = "1.4.0 -> 1.5.0" +notes = "Unsafe review notes: https://crrev.com/c/5650836" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.litemap]] +who = "Manish Goregaokar " +criteria = "safe-to-deploy" +version = "0.7.4" +notes = "Contains no unsafe" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.litemap]] +who = "Daniel Cheng " +criteria = "safe-to-deploy" +delta = "0.7.4 -> 0.7.5" +notes = "Delta implements the entry API but doesn't add or change any unsafe code." +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.log]] +who = "danakj " +criteria = "safe-to-deploy" +version = "0.4.22" +notes = """ +Unsafe review in https://docs.google.com/document/d/1IXQbD1GhTRqNHIGxq6yy7qHqxeO4CwN5noMFXnqyDIM/edit?usp=sharing + +Unsafety is generally very well-documented, with one exception, which we +describe in the review doc. +""" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.nom]] +who = "danakj@chromium.org" +criteria = "safe-to-deploy" +version = "7.1.3" +notes = """ +Reviewed in https://chromium-review.googlesource.com/c/chromium/src/+/5046153 +""" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.num-integer]] +who = "Manish Goregaokar " +criteria = "safe-to-deploy" +version = "0.1.46" +notes = "Contains no unsafe" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.num-iter]] +who = "George Burgess IV " +criteria = "safe-to-deploy" +version = "0.1.43" +aggregated-from = "https://chromium.googlesource.com/chromiumos/third_party/rust_crates/+/refs/heads/main/cargo-vet/audits.toml?format=TEXT" + +[[audits.google.audits.num-rational]] +who = "Manish Goregaokar " +criteria = "safe-to-deploy" +version = "0.4.2" +notes = "Contains no unsafe" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.num-traits]] +who = "Manish Goregaokar " +criteria = "safe-to-deploy" +version = "0.2.19" +notes = "Contains a single line of float-to-int unsafe with decent safety comments" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.pin-project-lite]] +who = "David Koloski " +criteria = "safe-to-deploy" +version = "0.2.9" +notes = "Reviewed on https://fxrev.dev/824504" +aggregated-from = "https://fuchsia.googlesource.com/fuchsia/+/refs/heads/main/third_party/rust_crates/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.pin-project-lite]] +who = "David Koloski " +criteria = "safe-to-deploy" +delta = "0.2.9 -> 0.2.13" +notes = "Audited at https://fxrev.dev/946396" +aggregated-from = "https://fuchsia.googlesource.com/fuchsia/+/refs/heads/main/third_party/rust_crates/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.quote]] +who = "Lukasz Anforowicz " +criteria = "safe-to-deploy" +version = "1.0.35" +notes = """ +Grepped for \"unsafe\", \"crypt\", \"cipher\", \"fs\", \"net\" - there were no hits +(except for benign \"net\" hit in tests and \"fs\" hit in README.md) +""" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.quote]] +who = "Adrian Taylor " +criteria = "safe-to-deploy" +delta = "1.0.35 -> 1.0.36" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.quote]] +who = "Lukasz Anforowicz " +criteria = "safe-to-deploy" +delta = "1.0.36 -> 1.0.37" +notes = """ +The delta just 1) inlines/expands `impl ToTokens` that used to be handled via +`primitive!` macro and 2) adds `impl ToTokens` for `CStr` and `CString`. +""" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.quote]] +who = "Dustin J. Mitchell " +criteria = "safe-to-deploy" +delta = "1.0.37 -> 1.0.38" +notes = "Still no unsafe" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.quote]] +who = "Daniel Cheng " +criteria = "safe-to-deploy" +delta = "1.0.38 -> 1.0.39" +notes = "Only minor changes for clippy lints and documentation." +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.quote]] +who = "Lukasz Anforowicz " +criteria = "safe-to-deploy" +delta = "1.0.39 -> 1.0.40" +notes = """ +The delta is just a simplification of how `tokens.extend(...)` call is made. +Still no `unsafe` anywhere. +""" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.rand]] +who = "Lukasz Anforowicz " +criteria = "safe-to-deploy" +version = "0.8.5" +notes = """ +For more detailed unsafe review notes please see https://crrev.com/c/6362797 +""" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.rand_chacha]] +who = "Lukasz Anforowicz " +criteria = "safe-to-deploy" +version = "0.3.1" +notes = """ +For more detailed unsafe review notes please see https://crrev.com/c/6362797 +""" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.rand_core]] +who = "Lukasz Anforowicz " +criteria = "safe-to-deploy" +version = "0.6.4" +notes = """ +For more detailed unsafe review notes please see https://crrev.com/c/6362797 +""" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.rustversion]] +who = "Lukasz Anforowicz " +criteria = "safe-to-deploy" +version = "1.0.14" +notes = """ +Grepped for `-i cipher`, `-i crypto`, `'\bfs\b'``, `'\bnet\b'``, `'\bunsafe\b'`` +and there were no hits except for: + +* Using trivially-safe `unsafe` in test code: + + ``` + tests/test_const.rs:unsafe fn _unsafe() {} + tests/test_const.rs:const _UNSAFE: () = unsafe { _unsafe() }; + ``` + +* Using `unsafe` in a string: + + ``` + src/constfn.rs: \"unsafe\" => Qualifiers::Unsafe, + ``` + +* Using `std::fs` in `build/build.rs` to write `${OUT_DIR}/version.expr` + which is later read back via `include!` used in `src/lib.rs`. + +Version `1.0.6` of this crate has been added to Chromium in +https://source.chromium.org/chromium/chromium/src/+/28841c33c77833cc30b286f9ae24c97e7a8f4057 +""" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.rustversion]] +who = "Adrian Taylor " +criteria = "safe-to-deploy" +delta = "1.0.14 -> 1.0.15" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.rustversion]] +who = "danakj " +criteria = "safe-to-deploy" +delta = "1.0.15 -> 1.0.16" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.rustversion]] +who = "Dustin J. Mitchell " +criteria = "safe-to-deploy" +delta = "1.0.16 -> 1.0.17" +notes = "Just updates windows compat" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.rustversion]] +who = "Liza Burakova " +criteria = "safe-to-deploy" +delta = "1.0.17 -> 1.0.18" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.rustversion]] +who = "Dustin J. Mitchell " +criteria = "safe-to-deploy" +delta = "1.0.18 -> 1.0.19" +notes = "No unsafe, just doc changes" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.rustversion]] +who = "Daniel Cheng " +criteria = "safe-to-deploy" +delta = "1.0.19 -> 1.0.20" +notes = "Only minor updates to documentation and the mock today used for testing." +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.serde]] +who = "Lukasz Anforowicz " +criteria = "safe-to-deploy" +version = "1.0.197" +notes = """ +Grepped for `-i cipher`, `-i crypto`, `'\bfs\b'`, `'\bnet\b'`, `'\bunsafe\b'`. + +There were some hits for `net`, but they were related to serialization and +not actually opening any connections or anything like that. + +There were 2 hits of `unsafe` when grepping: +* In `fn as_str` in `impl Buf` +* In `fn serialize` in `impl Serialize for net::Ipv4Addr` + +Unsafe review comments can be found in https://crrev.com/c/5350573/2 (this +review also covered `serde_json_lenient`). + +Version 1.0.130 of the crate has been added to Chromium in +https://crrev.com/c/3265545. The CL description contains a link to a +(Google-internal, sorry) document with a mini security review. +""" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.serde]] +who = "Dustin J. Mitchell " +criteria = "safe-to-deploy" +delta = "1.0.197 -> 1.0.198" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.serde]] +who = "danakj " +criteria = "safe-to-deploy" +delta = "1.0.198 -> 1.0.201" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.serde]] +who = "Dustin J. Mitchell " +criteria = "safe-to-deploy" +delta = "1.0.201 -> 1.0.202" +notes = "Trivial changes" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.serde]] +who = "Lukasz Anforowicz " +criteria = "safe-to-deploy" +delta = "1.0.202 -> 1.0.203" +notes = "s/doc_cfg/docsrs/ + tuple_impls/tuple_impl_body-related changes" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.serde]] +who = "Adrian Taylor " +criteria = "safe-to-deploy" +delta = "1.0.203 -> 1.0.204" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.serde]] +who = "Lukasz Anforowicz " +criteria = "safe-to-deploy" +delta = "1.0.204 -> 1.0.207" +notes = "The small change in `src/private/ser.rs` should have no impact on `ub-risk-2`." +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.serde]] +who = "Lukasz Anforowicz " +criteria = "safe-to-deploy" +delta = "1.0.207 -> 1.0.209" +notes = """ +The delta carries fairly small changes in `src/private/de.rs` and +`src/private/ser.rs` (see https://crrev.com/c/5812194/2..5). AFAICT the +delta has no impact on the `unsafe`, `from_utf8_unchecked`-related parts +of the crate (in `src/de/format.rs` and `src/ser/impls.rs`). +""" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.serde]] +who = "Adrian Taylor " +criteria = "safe-to-deploy" +delta = "1.0.209 -> 1.0.210" +notes = "Almost no new code - just feature rearrangement" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.serde]] +who = "Liza Burakova " +criteria = "safe-to-deploy" +delta = "1.0.210 -> 1.0.213" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.serde]] +who = "Dustin J. Mitchell " +criteria = "safe-to-deploy" +delta = "1.0.213 -> 1.0.214" +notes = "No unsafe, no crypto" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.serde]] +who = "Adrian Taylor " +criteria = "safe-to-deploy" +delta = "1.0.214 -> 1.0.215" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.serde]] +who = "Lukasz Anforowicz " +criteria = "safe-to-deploy" +delta = "1.0.215 -> 1.0.216" +notes = "The delta makes minor changes in `build.rs` - switching to the `?` syntax sugar." +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.serde]] +who = "Dustin J. Mitchell " +criteria = "safe-to-deploy" +delta = "1.0.216 -> 1.0.217" +notes = "Minimal changes, nothing unsafe" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.serde]] +who = "Daniel Cheng " +criteria = "safe-to-deploy" +delta = "1.0.217 -> 1.0.218" +notes = "No changes outside comments and documentation." +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.serde]] +who = "Lukasz Anforowicz " +criteria = "safe-to-deploy" +delta = "1.0.218 -> 1.0.219" +notes = "Just allowing `clippy::elidable_lifetime_names`." +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.serde_derive]] +who = "Lukasz Anforowicz " +criteria = "safe-to-deploy" +version = "1.0.197" +notes = "Grepped for \"unsafe\", \"crypt\", \"cipher\", \"fs\", \"net\" - there were no hits" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.serde_derive]] +who = "danakj " +criteria = "safe-to-deploy" +delta = "1.0.197 -> 1.0.201" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.serde_derive]] +who = "Dustin J. Mitchell " +criteria = "safe-to-deploy" +delta = "1.0.201 -> 1.0.202" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.serde_derive]] +who = "Lukasz Anforowicz " +criteria = "safe-to-deploy" +delta = "1.0.202 -> 1.0.203" +notes = "Grepped for \"unsafe\", \"crypt\", \"cipher\", \"fs\", \"net\" - there were no hits" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.serde_derive]] +who = "Adrian Taylor " +criteria = "safe-to-deploy" +delta = "1.0.203 -> 1.0.204" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.serde_derive]] +who = "Lukasz Anforowicz " +criteria = "safe-to-deploy" +delta = "1.0.204 -> 1.0.207" +notes = 'Grepped for \"unsafe\", \"crypt\", \"cipher\", \"fs\", \"net\" - there were no hits' +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.serde_derive]] +who = "Lukasz Anforowicz " +criteria = "safe-to-deploy" +delta = "1.0.207 -> 1.0.209" +notes = ''' +There are no code changes in this delta - see https://crrev.com/c/5812194/2..5 + +I've neverthless also grepped for `-i cipher`, `-i crypto`, `\bfs\b`, +`\bnet\b`, and `\bunsafe\b`. There were no hits. +''' +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.serde_derive]] +who = "Adrian Taylor " +criteria = "safe-to-deploy" +delta = "1.0.209 -> 1.0.210" +notes = "Almost no new code - just feature rearrangement" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.serde_derive]] +who = "Liza Burakova " +criteria = "safe-to-deploy" +delta = "1.0.210 -> 1.0.213" +notes = "Grepped for 'unsafe', 'crypt', 'cipher', 'fs', 'net' - there were no hits" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.serde_derive]] +who = "Dustin J. Mitchell " +criteria = "safe-to-deploy" +delta = "1.0.213 -> 1.0.214" +notes = "No changes to unsafe, no crypto" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.serde_derive]] +who = "Adrian Taylor " +criteria = "safe-to-deploy" +delta = "1.0.214 -> 1.0.215" +notes = "Minor changes should not impact UB risk" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.serde_derive]] +who = "Lukasz Anforowicz " +criteria = "safe-to-deploy" +delta = "1.0.215 -> 1.0.216" +notes = "The delta adds `#[automatically_derived]` in a few places. Still no `unsafe`." +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.serde_derive]] +who = "Dustin J. Mitchell " +criteria = "safe-to-deploy" +delta = "1.0.216 -> 1.0.217" +notes = "No changes" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.serde_derive]] +who = "Daniel Cheng " +criteria = "safe-to-deploy" +delta = "1.0.217 -> 1.0.218" +notes = "No changes outside comments and documentation." +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.serde_derive]] +who = "Lukasz Anforowicz " +criteria = "safe-to-deploy" +delta = "1.0.218 -> 1.0.219" +notes = "Minor changes (clippy tweaks, using `mem::take` instead of `mem::replace`)." +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.sha1]] +who = "David Koloski " +criteria = "safe-to-deploy" +version = "0.10.5" +notes = "Reviewed on https://fxrev.dev/712371." +aggregated-from = "https://fuchsia.googlesource.com/fuchsia/+/refs/heads/main/third_party/rust_crates/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.smallvec]] +who = "Manish Goregaokar " +criteria = "safe-to-deploy" +version = "1.13.2" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.smallvec]] +who = "Jonathan Hao " +criteria = "safe-to-deploy" +delta = "1.13.2 -> 1.14.0" +notes = """ +WARNING: This certification is a result of a **partial** audit. The +`malloc_size_of` feature has **not** been audited. This feature does +not explicitly document its safety requirements. +See also https://chromium-review.googlesource.com/c/chromium/src/+/6275133/comment/ea0d7a93_98051a2e/ +and https://github.com/servo/malloc_size_of/issues/8. +This feature is banned in gnrt_config.toml. +""" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.stable_deref_trait]] +who = "Manish Goregaokar " +criteria = "safe-to-deploy" +version = "1.2.0" +notes = "Purely a trait, crates using this should be carefully vetted since self-referential stuff can be super tricky around various unsafe rust edges." +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.static_assertions]] +who = "Lukasz Anforowicz " +criteria = "safe-to-deploy" +version = "1.1.0" +notes = """ +Grepped for `-i cipher`, `-i crypto`, `'\bfs\b'`, `'\bnet\b'`, `'\bunsafe\b'` +and there were no hits except for one `unsafe`. + +The lambda where `unsafe` is used is never invoked (e.g. the `unsafe` code +never runs) and is only introduced for some compile-time checks. Additional +unsafe review comments can be found in https://crrev.com/c/5353376. + +This crate has been added to Chromium in https://crrev.com/c/3736562. The CL +description contains a link to a document with an additional security review. +""" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.strsim]] +who = "danakj@chromium.org" +criteria = "safe-to-deploy" +version = "0.10.0" +notes = """ +Reviewed in https://crrev.com/c/5171063 + +Previously reviewed during security review and the audit is grandparented in. +""" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.synstructure]] +who = "Manish Goregaokar " +criteria = "safe-to-deploy" +version = "0.13.1" +notes = "Exposes unsafe codegen APIs but does not itself contain unsafe" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.tinyvec_macros]] +who = "George Burgess IV " +criteria = "safe-to-deploy" +version = "0.1.0" +aggregated-from = "https://chromium.googlesource.com/chromiumos/third_party/rust_crates/+/refs/heads/main/cargo-vet/audits.toml?format=TEXT" + +[[audits.google.audits.tokio-stream]] +who = "David Koloski " +criteria = "safe-to-deploy" +version = "0.1.11" +notes = "Reviewed on https://fxrev.dev/804724" +aggregated-from = "https://fuchsia.googlesource.com/fuchsia/+/refs/heads/main/third_party/rust_crates/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.tokio-stream]] +who = "David Koloski " +criteria = "safe-to-deploy" +delta = "0.1.11 -> 0.1.14" +notes = "Reviewed on https://fxrev.dev/907732." +aggregated-from = "https://fuchsia.googlesource.com/fuchsia/+/refs/heads/main/third_party/rust_crates/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.utf8parse]] +who = "David Koloski " +criteria = "safe-to-deploy" +version = "0.2.1" +notes = "Reviewed on https://fxrev.dev/904811" +aggregated-from = "https://fuchsia.googlesource.com/fuchsia/+/refs/heads/main/third_party/rust_crates/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.writeable]] +who = "Manish Goregaokar " +criteria = "safe-to-deploy" +version = "0.6.0" +notes = "Contains three lines of unsafe, thoroughly commented: one is for from-UTF8 on ASCII, the other two are for from-UTF8 on a datastructure that keeps track of a buffer with partial UTF8 validation. Relatively straigtforward." +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.writeable]] +who = "Daniel Cheng " +criteria = "safe-to-deploy" +delta = "0.6.0 -> 0.6.1" +notes = "Minor comment/documentation updates and switch to a non-panicking alternative to split_at()." +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.yoke]] +who = "Manish Goregaokar " +criteria = "safe-to-deploy" +version = "0.7.5" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.yoke]] +who = "Daniel Cheng " +criteria = "safe-to-deploy" +delta = "0.7.5 -> 0.8.0" +notes = """ +Cleaning up a previous hack for adding trait bounds to yoke objects. Unsafe changes: +- deleting the hack itself removes a lot of unsafe use required in the hack's implementation +- changes another unsafe use to remove the use of the hack, now that it's no longer needed + + +See https://crrev.com/c/6323349 for more audit notes. +""" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.yoke-derive]] +who = "Manish Goregaokar " +criteria = "safe-to-deploy" +version = "0.7.5" +notes = "Custom derive implementing the `Yokeable` trait. Generally generates simple code that asserts covariance." +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.yoke-derive]] +who = "Daniel Cheng " +criteria = "safe-to-deploy" +delta = "0.7.5 -> 0.8.0" +notes = "No code changes: only incrementing the version." +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.zerofrom]] +who = "Manish Goregaokar " +criteria = "safe-to-deploy" +version = "0.1.5" +notes = "Contains no unsafe" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.zerofrom]] +who = "Daniel Cheng " +criteria = "safe-to-deploy" +delta = "0.1.5 -> 0.1.6" +notes = "Only minor cfg tweaks." +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.zerofrom-derive]] +who = "Manish Goregaokar " +criteria = "safe-to-deploy" +version = "0.1.5" +notes = "Contains no unsafe" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.zerofrom-derive]] +who = "Daniel Cheng " +criteria = "safe-to-deploy" +delta = "0.1.5 -> 0.1.6" +notes = "Only a minor clippy adjustment." +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.zerotrie]] +who = "Manish Goregaokar " +criteria = "safe-to-deploy" +version = "0.2.0" +notes = "Minor repr(transparent) unsafe code. Improved comments in https://github.com/unicode-org/icu4x/pull/6054" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.google.audits.zerotrie]] +who = "Daniel Cheng " +criteria = "safe-to-deploy" +delta = "0.2.0 -> 0.2.1" +notes = """ +Changes in unsafe blocks are wrapping direct calls to `core::mem::transmute` with the `transparent_ref_from_store` wrapper. +No safety guarantees change, but providing the `transparent_ref_from_store` as a wrapper provides a convenient marker that this transmute operation is actually sound. + +See https://crrev.com/c/6323349 for more audit notes. +""" +aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" + +[[audits.isrg.audits.base64]] +who = "Tim Geoghegan " +criteria = "safe-to-deploy" +delta = "0.21.0 -> 0.21.1" + +[[audits.isrg.audits.base64]] +who = "Brandon Pitman " +criteria = "safe-to-deploy" +delta = "0.21.1 -> 0.21.2" + +[[audits.isrg.audits.base64]] +who = "David Cook " +criteria = "safe-to-deploy" +delta = "0.21.2 -> 0.21.3" + +[[audits.isrg.audits.block-buffer]] +who = "David Cook " +criteria = "safe-to-deploy" +version = "0.9.0" + +[[audits.isrg.audits.cfg-if]] +who = "David Cook " +criteria = "safe-to-deploy" +delta = "1.0.0 -> 1.0.1" + +[[audits.isrg.audits.cfg-if]] +who = "J.C. Jones " +criteria = "safe-to-deploy" +delta = "1.0.1 -> 1.0.3" + +[[audits.isrg.audits.num-iter]] +who = "David Cook " +criteria = "safe-to-deploy" +delta = "0.1.43 -> 0.1.44" + +[[audits.isrg.audits.num-iter]] +who = "David Cook " +criteria = "safe-to-deploy" +delta = "0.1.44 -> 0.1.45" + +[[audits.isrg.audits.rand]] +who = "David Cook " +criteria = "safe-to-deploy" +delta = "0.8.5 -> 0.9.1" + +[[audits.isrg.audits.rand]] +who = "Tim Geoghegan " +criteria = "safe-to-deploy" +delta = "0.9.1 -> 0.9.2" + +[[audits.isrg.audits.rand_chacha]] +who = "David Cook " +criteria = "safe-to-deploy" +delta = "0.3.1 -> 0.9.0" + +[[audits.isrg.audits.rand_core]] +who = "David Cook " +criteria = "safe-to-deploy" +delta = "0.6.4 -> 0.9.3" + +[[audits.isrg.audits.rayon]] +who = "Brandon Pitman " +criteria = "safe-to-deploy" +delta = "1.6.1 -> 1.7.0" + +[[audits.isrg.audits.rayon]] +who = "David Cook " +criteria = "safe-to-deploy" +delta = "1.7.0 -> 1.8.0" + +[[audits.isrg.audits.rayon]] +who = "Ameer Ghani " +criteria = "safe-to-deploy" +delta = "1.8.0 -> 1.8.1" + +[[audits.isrg.audits.rayon]] +who = "Brandon Pitman " +criteria = "safe-to-deploy" +delta = "1.8.1 -> 1.9.0" + +[[audits.isrg.audits.rayon]] +who = "Brandon Pitman " +criteria = "safe-to-deploy" +delta = "1.9.0 -> 1.10.0" + +[[audits.isrg.audits.rayon]] +who = "David Cook " +criteria = "safe-to-deploy" +delta = "1.10.0 -> 1.11.0" +notes = """ +I compared src/slice/sort.rs against the file library/core/src/slice/sort.rs +from the standard library, as of commit e501add. +""" + +[[audits.isrg.audits.rayon-core]] +who = "Ameer Ghani " +criteria = "safe-to-deploy" +version = "1.12.1" + +[[audits.isrg.audits.rayon-core]] +who = "David Cook " +criteria = "safe-to-deploy" +delta = "1.12.1 -> 1.13.0" + +[[audits.isrg.audits.serde]] +who = "J.C. Jones " +criteria = "safe-to-deploy" +delta = "1.0.219 -> 1.0.224" + +[[audits.isrg.audits.serde]] +who = "J.C. Jones " +criteria = "safe-to-deploy" +delta = "1.0.224 -> 1.0.225" + +[[audits.isrg.audits.serde]] +who = "Tim Geoghegan " +criteria = "safe-to-deploy" +delta = "1.0.225 -> 1.0.226" + +[[audits.isrg.audits.serde_core]] +who = "J.C. Jones " +criteria = "safe-to-deploy" +version = "1.0.224" + +[[audits.isrg.audits.serde_core]] +who = "J.C. Jones " +criteria = "safe-to-deploy" +delta = "1.0.224 -> 1.0.225" + +[[audits.isrg.audits.serde_core]] +who = "Tim Geoghegan " +criteria = "safe-to-deploy" +delta = "1.0.225 -> 1.0.226" + +[[audits.isrg.audits.serde_derive]] +who = "J.C. Jones " +criteria = "safe-to-deploy" +delta = "1.0.219 -> 1.0.224" + +[[audits.isrg.audits.serde_derive]] +who = "J.C. Jones " +criteria = "safe-to-deploy" +delta = "1.0.224 -> 1.0.225" + +[[audits.isrg.audits.serde_derive]] +who = "Tim Geoghegan " +criteria = "safe-to-deploy" +delta = "1.0.225 -> 1.0.226" + +[[audits.isrg.audits.sha2]] +who = "David Cook " +criteria = "safe-to-deploy" +version = "0.10.2" + +[[audits.isrg.audits.sha2]] +who = "David Cook " +criteria = "safe-to-deploy" +delta = "0.10.8 -> 0.10.9" + +[[audits.isrg.audits.subtle]] +who = "David Cook " +criteria = "safe-to-deploy" +delta = "2.5.0 -> 2.6.1" + +[[audits.isrg.audits.thiserror]] +who = "Brandon Pitman " +criteria = "safe-to-deploy" +delta = "1.0.40 -> 1.0.43" + +[[audits.isrg.audits.thiserror-impl]] +who = "Brandon Pitman " +criteria = "safe-to-deploy" +delta = "1.0.40 -> 1.0.43" + +[[audits.mozilla.wildcard-audits.encoding_rs]] +who = "Henri Sivonen " +criteria = "safe-to-deploy" +user-id = 4484 # Henri Sivonen (hsivonen) +start = "2019-02-26" +end = "2025-10-23" +notes = "I, Henri Sivonen, wrote encoding_rs for Gecko and have reviewed contributions by others. There are two caveats to the certification: 1) The crate does things that are documented to be UB but that do not appear to actually be UB due to integer types differing from the general rule; https://github.com/hsivonen/encoding_rs/issues/79 . 2) It would be prudent to re-review the code that reinterprets buffers of integers as SIMD vectors; see https://github.com/hsivonen/encoding_rs/issues/87 ." +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.wildcard-audits.unicode-normalization]] +who = "Manish Goregaokar " +criteria = "safe-to-deploy" +user-id = 1139 # Manish Goregaokar (Manishearth) +start = "2019-11-06" +end = "2026-02-01" +notes = "All code written or reviewed by Manish" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.wildcard-audits.unicode-segmentation]] +who = "Manish Goregaokar " +criteria = "safe-to-deploy" +user-id = 1139 # Manish Goregaokar (Manishearth) +start = "2019-05-15" +end = "2026-02-01" +notes = "All code written or reviewed by Manish" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.wildcard-audits.unicode-width]] +who = "Manish Goregaokar " +criteria = "safe-to-deploy" +user-id = 1139 # Manish Goregaokar (Manishearth) +start = "2019-12-05" +end = "2026-02-01" +notes = "All code written or reviewed by Manish" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.wildcard-audits.utf8_iter]] +who = "Makoto Kato " +criteria = "safe-to-deploy" +user-id = 4484 # Henri Sivonen (hsivonen) +start = "2022-04-19" +end = "2024-06-16" +notes = "Maintained by Henri Sivonen who works at Mozilla." +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.adler2]] +who = "Erich Gubler " +criteria = "safe-to-deploy" +delta = "2.0.0 -> 2.0.1" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.allocator-api2]] +who = "Nicolas Silva " +criteria = "safe-to-deploy" +version = "0.2.18" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.allocator-api2]] +who = "Mike Hommey " +criteria = "safe-to-deploy" +delta = "0.2.20 -> 0.2.21" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.arraydeque]] +who = "Lars Eggert " +criteria = "safe-to-deploy" +version = "0.5.1" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.bit-set]] +who = "Aria Beingessner " +criteria = "safe-to-deploy" +version = "0.5.2" +notes = "Another crate I own via contain-rs that is ancient and maintenance mode, no known issues." +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.bit-set]] +who = "Mike Hommey " +criteria = "safe-to-deploy" +delta = "0.5.2 -> 0.5.3" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.bit-set]] +who = "Teodor Tanasoaia " +criteria = "safe-to-deploy" +delta = "0.5.3 -> 0.6.0" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.bit-set]] +who = "Jim Blandy " +criteria = "safe-to-deploy" +delta = "0.6.0 -> 0.8.0" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.bit-vec]] +who = "Aria Beingessner " +criteria = "safe-to-deploy" +version = "0.6.3" +notes = "Another crate I own via contain-rs that is ancient and in maintenance mode but otherwise perfectly fine." +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.bit-vec]] +who = "Teodor Tanasoaia " +criteria = "safe-to-deploy" +delta = "0.6.3 -> 0.7.0" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.bit-vec]] +who = "Jim Blandy " +criteria = "safe-to-deploy" +delta = "0.7.0 -> 0.8.0" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.bitflags]] +who = "Alex Franchuk " +criteria = "safe-to-deploy" +delta = "1.3.2 -> 2.0.2" +notes = "Removal of some unsafe code/methods. No changes to externals, just some refactoring (mostly internal)." +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.bitflags]] +who = "Nicolas Silva " +criteria = "safe-to-deploy" +delta = "2.0.2 -> 2.1.0" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.bitflags]] +who = "Teodor Tanasoaia " +criteria = "safe-to-deploy" +delta = "2.2.1 -> 2.3.2" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.bitflags]] +who = "Mike Hommey " +criteria = "safe-to-deploy" +delta = "2.3.3 -> 2.4.0" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.bitflags]] +who = "Jan-Erik Rediger " +criteria = "safe-to-deploy" +delta = "2.4.0 -> 2.4.1" +notes = "Only allowing new clippy lints" +aggregated-from = "https://raw.githubusercontent.com/mozilla/glean/main/supply-chain/audits.toml" + +[[audits.mozilla.audits.bitflags]] +who = [ + "Teodor Tanasoaia ", + "Erich Gubler ", +] +criteria = "safe-to-deploy" +delta = "2.6.0 -> 2.7.0" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.block-buffer]] +who = "Mike Hommey " +criteria = "safe-to-deploy" +delta = "0.10.2 -> 0.10.3" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.cfg_aliases]] +who = "Alex Franchuk " +criteria = "safe-to-deploy" +delta = "0.1.1 -> 0.2.1" +notes = "Very minor changes." +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.crypto-common]] +who = "Mike Hommey " +criteria = "safe-to-deploy" +delta = "0.1.3 -> 0.1.6" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.document-features]] +who = "Erich Gubler " +criteria = "safe-to-deploy" +version = "0.2.8" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.document-features]] +who = "Erich Gubler " +criteria = "safe-to-deploy" +delta = "0.2.8 -> 0.2.9" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.document-features]] +who = "Erich Gubler " +criteria = "safe-to-deploy" +delta = "0.2.9 -> 0.2.10" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.document-features]] +who = "Teodor Tanasoaia " +criteria = "safe-to-deploy" +delta = "0.2.10 -> 0.2.11" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.errno]] +who = "Mike Hommey " +criteria = "safe-to-deploy" +delta = "0.3.1 -> 0.3.3" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.fastrand]] +who = "Mike Hommey " +criteria = "safe-to-deploy" +delta = "1.9.0 -> 2.0.0" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.fastrand]] +who = "Mike Hommey " +criteria = "safe-to-deploy" +delta = "2.0.1 -> 2.1.0" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.fastrand]] +who = "Chris Martin " +criteria = "safe-to-deploy" +delta = "2.1.0 -> 2.1.1" +notes = "Fairly trivial changes, no chance of security regression." +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.fnv]] +who = "Bobby Holley " +criteria = "safe-to-deploy" +version = "1.0.7" +notes = "Simple hasher implementation with no unsafe code." +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.foldhash]] +who = "Erich Gubler " +criteria = "safe-to-deploy" +delta = "0.1.5 -> 0.2.0" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.form_urlencoded]] +who = "Valentin Gosu " +criteria = "safe-to-deploy" +version = "1.2.0" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.form_urlencoded]] +who = "Valentin Gosu " +criteria = "safe-to-deploy" +delta = "1.2.0 -> 1.2.1" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.form_urlencoded]] +who = "edgul " +criteria = "safe-to-deploy" +delta = "1.2.1 -> 1.2.2" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.futures-core]] +who = "Mike Hommey " +criteria = "safe-to-deploy" +delta = "0.3.27 -> 0.3.28" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.futures-sink]] +who = "Mike Hommey " +criteria = "safe-to-deploy" +delta = "0.3.27 -> 0.3.28" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.gimli]] +who = "Alex Franchuk " +criteria = "safe-to-deploy" +version = "0.30.0" +notes = """ +Unsafe code blocks are sound. Minimal dependencies used. No use of +side-effectful std functions. +""" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.gimli]] +who = "Chris Martin " +criteria = "safe-to-deploy" +delta = "0.30.0 -> 0.29.0" +notes = "No unsafe code, mostly algorithms and parsing. Very unlikely to cause security issues." +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.home]] +who = "Nika Layzell " +criteria = "safe-to-deploy" +version = "0.5.3" +notes = """ +Crate with straightforward code for determining the user's HOME directory. Only +unsafe code is used to invoke the Windows SHGetFolderPathW API to get the +profile directory when the USERPROFILE environment variable is unavailable. +""" +aggregated-from = "https://raw.githubusercontent.com/mozilla/cargo-vet/main/supply-chain/audits.toml" + +[[audits.mozilla.audits.home]] +who = "Nika Layzell " +criteria = "safe-to-deploy" +delta = "0.5.3 -> 0.5.11" +aggregated-from = "https://raw.githubusercontent.com/mozilla/cargo-vet/main/supply-chain/audits.toml" + +[[audits.mozilla.audits.iana-time-zone]] +who = "Mark Hammond " +criteria = "safe-to-deploy" +delta = "0.1.61 -> 0.1.63" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.iana-time-zone]] +who = "Erich Gubler " +criteria = "safe-to-deploy" +delta = "0.1.63 -> 0.1.64" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.icu_collections]] +who = "Makoto Kato " +criteria = "safe-to-deploy" +delta = "2.0.0-beta2 -> 2.0.0" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.icu_locale_core]] +who = "Makoto Kato " +criteria = "safe-to-deploy" +delta = "2.0.0-beta2 -> 2.0.0" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.icu_normalizer]] +who = "Makoto Kato " +criteria = "safe-to-deploy" +delta = "2.0.0-beta2 -> 2.0.0" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.icu_normalizer_data]] +who = "Makoto Kato " +criteria = "safe-to-deploy" +delta = "2.0.0-beta2 -> 2.0.0" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.icu_properties]] +who = "Makoto Kato " +criteria = "safe-to-deploy" +delta = "2.0.0-beta2 -> 2.0.1" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.icu_properties_data]] +who = "Makoto Kato " +criteria = "safe-to-deploy" +delta = "2.0.0-beta2 -> 2.0.1" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.icu_provider]] +who = "Makoto Kato " +criteria = "safe-to-deploy" +delta = "2.0.0-beta2 -> 2.0.0" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.idna]] +who = "Valentin Gosu " +criteria = "safe-to-deploy" +delta = "0.4.0 -> 0.5.0" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.idna]] +who = "Henri Sivonen " +criteria = "safe-to-deploy" +delta = "0.5.0 -> 1.0.2" +notes = "In the 0.5.0 to 1.0.2 delta, I, Henri Sivonen, rewrote the non-Punycode internals of the crate and made the changes to the Punycode code." +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.idna]] +who = "Valentin Gosu " +criteria = "safe-to-deploy" +delta = "1.0.2 -> 1.0.3" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.idna]] +who = "edgul " +criteria = "safe-to-deploy" +delta = "1.0.3 -> 1.1.0" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.idna_adapter]] +who = "Valentin Gosu " +criteria = "safe-to-deploy" +version = "1.2.0" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.idna_adapter]] +who = "Makoto Kato " +criteria = "safe-to-deploy" +delta = "1.2.0 -> 1.2.1" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.indexmap]] +who = "Erich Gubler " +criteria = "safe-to-deploy" +delta = "2.8.0 -> 2.11.4" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.litemap]] +who = "Makoto Kato " +criteria = "safe-to-deploy" +delta = "0.7.5 -> 0.8.0" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.num-conv]] +who = "Alex Franchuk " +criteria = "safe-to-deploy" +version = "0.1.0" +notes = """ +Very straightforward, simple crate. No dependencies, unsafe, extern, +side-effectful std functions, etc. +""" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.option-ext]] +who = "Nika Layzell " +criteria = "safe-to-deploy" +version = "0.2.0" +aggregated-from = "https://raw.githubusercontent.com/mozilla/cargo-vet/main/supply-chain/audits.toml" + +[[audits.mozilla.audits.percent-encoding]] +who = "Valentin Gosu " +criteria = "safe-to-deploy" +delta = "2.2.0 -> 2.3.0" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.percent-encoding]] +who = "Valentin Gosu " +criteria = "safe-to-deploy" +delta = "2.3.0 -> 2.3.1" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.percent-encoding]] +who = "edgul " +criteria = "safe-to-deploy" +delta = "2.3.1 -> 2.3.2" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.pin-project-lite]] +who = "Mike Hommey " +criteria = "safe-to-deploy" +delta = "0.2.13 -> 0.2.14" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.pin-project-lite]] +who = "Nika Layzell " +criteria = "safe-to-deploy" +delta = "0.2.14 -> 0.2.16" +notes = """ +Only functional change is to work around a bug in the negative_impls feature +(https://github.com/taiki-e/pin-project/issues/340#issuecomment-2432146009) +""" +aggregated-from = "https://raw.githubusercontent.com/mozilla/cargo-vet/main/supply-chain/audits.toml" + +[[audits.mozilla.audits.pkg-config]] +who = "Mike Hommey " +criteria = "safe-to-deploy" +delta = "0.3.25 -> 0.3.26" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.powerfmt]] +who = "Alex Franchuk " +criteria = "safe-to-deploy" +version = "0.2.0" +notes = """ +A tiny bit of unsafe code to implement functionality that isn't in stable rust +yet, but it's all valid. Otherwise it's a pretty simple crate. +""" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.quinn-udp]] +who = "Max Inden " +criteria = "safe-to-deploy" +version = "0.5.4" +notes = "This is a small crate, providing safe wrappers around various low-level networking specific operating system features. Given that the Rust standard library does not provide safe wrappers for these low-level features, safe wrappers need to be build in the crate itself, i.e. `quinn-udp`, thus requiring `unsafe` code." +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.quinn-udp]] +who = "Max Inden " +criteria = "safe-to-deploy" +delta = "0.5.4 -> 0.5.6" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.quinn-udp]] +who = "Max Inden " +criteria = "safe-to-deploy" +delta = "0.5.6 -> 0.5.8" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.quinn-udp]] +who = "Max Inden " +criteria = "safe-to-deploy" +delta = "0.5.8 -> 0.5.9" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.quinn-udp]] +who = "Max Leonard Inden " +criteria = "safe-to-deploy" +delta = "0.5.9 -> 0.5.10" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.quinn-udp]] +who = "Max Leonard Inden " +criteria = "safe-to-deploy" +delta = "0.5.10 -> 0.5.11" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.quinn-udp]] +who = "Max Leonard Inden " +criteria = "safe-to-deploy" +delta = "0.5.11 -> 0.5.12" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.quinn-udp]] +who = "Max Leonard Inden " +criteria = "safe-to-deploy" +delta = "0.5.12 -> 0.5.13" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.rayon]] +who = "Josh Stone " +criteria = "safe-to-deploy" +version = "1.5.3" +notes = "All code written or reviewed by Josh Stone or Niko Matsakis." +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.rayon]] +who = "Mike Hommey " +criteria = "safe-to-deploy" +delta = "1.5.3 -> 1.6.1" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.rustc-hash]] +who = "Bobby Holley " +criteria = "safe-to-deploy" +version = "1.1.0" +notes = "Straightforward crate with no unsafe code, does what it says on the tin." +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.rustc-hash]] +who = "Ben Dean-Kawamura " +criteria = "safe-to-deploy" +delta = "1.1.0 -> 2.1.1" +notes = "Simple hashing crate, no unsafe code." +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.sha2]] +who = "Mike Hommey " +criteria = "safe-to-deploy" +delta = "0.10.2 -> 0.10.6" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.sha2]] +who = "Jeff Muizelaar " +criteria = "safe-to-deploy" +delta = "0.10.6 -> 0.10.8" +notes = """ +The bulk of this is https://github.com/RustCrypto/hashes/pull/490 which adds aarch64 support along with another PR adding longson. +I didn't check the implementation thoroughly but there wasn't anything obviously nefarious. 0.10.8 has been out for more than a year +which suggests no one else has found anything either. +""" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.sharded-slab]] +who = "Mark Hammond " +criteria = "safe-to-deploy" +delta = "0.1.4 -> 0.1.7" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.shlex]] +who = "Max Inden " +criteria = "safe-to-deploy" +delta = "1.1.0 -> 1.3.0" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.similar]] +who = "Nika Layzell " +criteria = "safe-to-deploy" +delta = "2.2.1 -> 2.7.0" +aggregated-from = "https://raw.githubusercontent.com/mozilla/cargo-vet/main/supply-chain/audits.toml" + +[[audits.mozilla.audits.smallvec]] +who = "Erich Gubler " +criteria = "safe-to-deploy" +delta = "1.14.0 -> 1.15.1" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.strsim]] +who = "Ben Dean-Kawamura " +criteria = "safe-to-deploy" +delta = "0.10.0 -> 0.11.1" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.subtle]] +who = "Simon Friedberger " +criteria = "safe-to-deploy" +version = "2.5.0" +notes = "The goal is to provide some constant-time correctness for cryptographic implementations. The approach is reasonable, it is known to be insufficient but this is pointed out in the documentation." +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.synstructure]] +who = "Nika Layzell " +criteria = "safe-to-deploy" +delta = "0.13.1 -> 0.13.2" +aggregated-from = "https://raw.githubusercontent.com/mozilla/cargo-vet/main/supply-chain/audits.toml" + +[[audits.mozilla.audits.thiserror]] +who = "Jan-Erik Rediger " +criteria = "safe-to-deploy" +delta = "1.0.43 -> 1.0.69" +aggregated-from = "https://raw.githubusercontent.com/mozilla/glean/main/supply-chain/audits.toml" + +[[audits.mozilla.audits.thiserror-impl]] +who = "Jan-Erik Rediger " +criteria = "safe-to-deploy" +delta = "1.0.43 -> 1.0.69" +aggregated-from = "https://raw.githubusercontent.com/mozilla/glean/main/supply-chain/audits.toml" + +[[audits.mozilla.audits.tinystr]] +who = "Makoto Kato " +criteria = "safe-to-deploy" +version = "0.7.0" +notes = "One of original auther was Zibi Braniecki who worked at Mozilla and maintained by ICU4X developers (Google and Mozilla). I've vetted the one instance of unsafe code." +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.tinystr]] +who = "Mike Hommey " +criteria = "safe-to-deploy" +delta = "0.7.0 -> 0.7.1" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.tinystr]] +who = "Makoto Kato " +criteria = "safe-to-deploy" +delta = "0.7.1 -> 0.7.4" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.tinystr]] +who = "Makoto Kato " +criteria = "safe-to-deploy" +delta = "0.7.4 -> 0.7.6" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.tinystr]] +who = "Makoto Kato " +criteria = "safe-to-deploy" +delta = "0.7.6 -> 0.8.1" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.tinyvec_macros]] +who = "Drew Willcoxon " +criteria = "safe-to-deploy" +delta = "0.1.0 -> 0.1.1" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.tracing]] +who = "Alex Franchuk " +criteria = "safe-to-deploy" +version = "0.1.37" +notes = """ +There's only one unsafe impl, and its purpose is to ensure correct behavior by +creating a non-Send marker type (it has nothing to do with soundness). All +dependencies make sense, and no side-effectful std functions are used. +""" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.tracing]] +who = "Mark Hammond " +criteria = "safe-to-deploy" +delta = "0.1.37 -> 0.1.41" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.tracing-attributes]] +who = "Alex Franchuk " +criteria = "safe-to-deploy" +version = "0.1.24" +notes = "No unsafe code, macros extensively tested and produce reasonable code." +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.tracing-attributes]] +who = "Mark Hammond " +criteria = "safe-to-deploy" +delta = "0.1.24 -> 0.1.28" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.tracing-core]] +who = "Alex Franchuk " +criteria = "safe-to-deploy" +version = "0.1.30" +notes = """ +Most unsafe code is in implementing non-std sync primitives. Unsafe impls are +logically correct and justified in comments, and unsafe code is sound and +justified in comments. +""" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.tracing-core]] +who = "Mark Hammond " +criteria = "safe-to-deploy" +delta = "0.1.30 -> 0.1.33" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.tracing-subscriber]] +who = "Mark Hammond " +criteria = "safe-to-deploy" +delta = "0.3.17 -> 0.3.19" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.tracing-subscriber]] +who = "Mark Hammond " +criteria = "safe-to-deploy" +delta = "0.3.19 -> 0.3.20" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.unicase]] +who = "Jan-Erik Rediger " +criteria = "safe-to-deploy" +delta = "2.6.0 -> 2.8.1" +notes = "Update to Unicode 15.0.0" +aggregated-from = "https://raw.githubusercontent.com/mozilla/glean/main/supply-chain/audits.toml" + +[[audits.mozilla.audits.url]] +who = "Valentin Gosu " +criteria = "safe-to-deploy" +version = "2.4.0" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.url]] +who = "Valentin Gosu " +criteria = "safe-to-deploy" +delta = "2.4.0 -> 2.4.1" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.url]] +who = "Valentin Gosu " +criteria = "safe-to-deploy" +delta = "2.4.1 -> 2.5.0" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.url]] +who = "Henri Sivonen " +criteria = "safe-to-deploy" +delta = "2.5.0 -> 2.5.1" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.url]] +who = "Valentin Gosu " +criteria = "safe-to-deploy" +delta = "2.5.1 -> 2.5.4" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.url]] +who = "edgul " +criteria = "safe-to-deploy" +delta = "2.5.4 -> 2.5.7" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.utf8parse]] +who = "Nika Layzell " +criteria = "safe-to-deploy" +delta = "0.2.1 -> 0.2.2" +aggregated-from = "https://raw.githubusercontent.com/mozilla/cargo-vet/main/supply-chain/audits.toml" + +[[audits.mozilla.audits.windows-link]] +who = "Mark Hammond " +criteria = "safe-to-deploy" +version = "0.1.1" +notes = "A microsoft crate allowing unsafe calls to windows apis." +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.windows-link]] +who = "Erich Gubler " +criteria = "safe-to-deploy" +delta = "0.1.1 -> 0.2.0" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.zerocopy]] +who = "Alex Franchuk " +criteria = "safe-to-deploy" +version = "0.7.32" +notes = """ +This crate is `no_std` so doesn't use any side-effectful std functions. It +contains quite a lot of `unsafe` code, however. I verified portions of this. It +also has a large, thorough test suite. The project claims to run tests with +Miri to have stronger soundness checks, and also claims to use formal +verification tools to prove correctness. +""" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.zerocopy]] +who = "Alex Franchuk " +criteria = "safe-to-deploy" +delta = "0.7.32 -> 0.8.27" +notes = """ +These changes are enormous, however unsafe code is kept somewhat minimal in +comparison. The safety properties of unsafe code blocks, traits, and other +types are thoroughly documented. The new build script is safe. All code is very +thoroughly tested. I expect their test coverage is quite high. +""" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.zerocopy-derive]] +who = "Alex Franchuk " +criteria = "safe-to-deploy" +version = "0.7.32" +notes = "Clean, safe macros for zerocopy." +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.zerocopy-derive]] +who = "Alex Franchuk " +criteria = "safe-to-deploy" +delta = "0.7.32 -> 0.8.27" +notes = """ +There are a lot of changes here, however they look reasonable. Unsafe code is +heavily documented, and there are extensive tests for the changes. +""" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.zeroize]] +who = "Benjamin Beurdouche " +criteria = "safe-to-deploy" +version = "1.8.1" +notes = """ +This code DOES contain unsafe code required to internally call volatiles +for deleting data. This is expected and documented behavior. +""" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.zerotrie]] +who = "Makoto Kato " +criteria = "safe-to-deploy" +delta = "0.2.1 -> 0.2.2" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.zerovec]] +who = "Makoto Kato " +criteria = "safe-to-deploy" +version = "0.9.4" +notes = "This crate is zero-copy data structure implmentation. Although this uses unsafe block in several code, it requires for zero-copy. And this has a comment in code why this uses unsafe and I audited code." +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.zerovec]] +who = "Makoto Kato " +criteria = "safe-to-deploy" +delta = "0.9.4 -> 0.10.1" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.zerovec]] +who = "Makoto Kato " +criteria = "safe-to-deploy" +delta = "0.10.1 -> 0.10.2" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.zerovec]] +who = "Mike Hommey " +criteria = "safe-to-deploy" +delta = "0.10.2 -> 0.10.4" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.zerovec]] +who = "Makoto Kato " +criteria = "safe-to-deploy" +delta = "0.10.4 -> 0.11.2" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.zerovec]] +who = "Makoto Kato " +criteria = "safe-to-deploy" +delta = "0.11.2 -> 0.11.3" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.zerovec]] +who = "Makoto Kato " +criteria = "safe-to-deploy" +delta = "0.11.3 -> 0.11.4" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.zerovec-derive]] +who = "Makoto Kato " +criteria = "safe-to-deploy" +version = "0.10.1" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.zerovec-derive]] +who = "Makoto Kato " +criteria = "safe-to-deploy" +delta = "0.10.1 -> 0.10.2" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.zerovec-derive]] +who = "Max Inden " +criteria = "safe-to-deploy" +delta = "0.10.2 -> 0.10.3" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.zerovec-derive]] +who = "Makoto Kato " +criteria = "safe-to-deploy" +delta = "0.10.3 -> 0.11.1" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.zcash.audits.autocfg]] +who = "Jack Grigg " +criteria = "safe-to-deploy" +delta = "1.4.0 -> 1.5.0" +notes = "Filesystem change is to remove the generated LLVM IR output file after probing." +aggregated-from = "https://raw.githubusercontent.com/zcash/zcash/master/qa/supply-chain/audits.toml" + +[[audits.zcash.audits.base64]] +who = "Jack Grigg " +criteria = "safe-to-deploy" +delta = "0.21.3 -> 0.21.4" +aggregated-from = "https://raw.githubusercontent.com/zcash/zcash/master/qa/supply-chain/audits.toml" + +[[audits.zcash.audits.base64]] +who = "Jack Grigg " +criteria = "safe-to-deploy" +delta = "0.21.4 -> 0.21.5" +aggregated-from = "https://raw.githubusercontent.com/zcash/zcash/master/qa/supply-chain/audits.toml" + +[[audits.zcash.audits.base64]] +who = "Daira-Emma Hopwood " +criteria = "safe-to-deploy" +delta = "0.21.5 -> 0.21.7" +aggregated-from = "https://raw.githubusercontent.com/zcash/zcash/master/qa/supply-chain/audits.toml" + +[[audits.zcash.audits.block-buffer]] +who = "Jack Grigg " +criteria = "safe-to-deploy" +delta = "0.10.3 -> 0.10.4" +notes = "Adds panics to prevent a block size of zero from causing unsoundness." +aggregated-from = "https://raw.githubusercontent.com/zcash/zcash/master/qa/supply-chain/audits.toml" + +[[audits.zcash.audits.darling_macro]] +who = "Jack Grigg " +criteria = "safe-to-deploy" +delta = "0.20.11 -> 0.21.3" +aggregated-from = "https://raw.githubusercontent.com/zcash/wallet/main/supply-chain/audits.toml" + +[[audits.zcash.audits.errno]] +who = "Jack Grigg " +criteria = "safe-to-deploy" +delta = "0.3.3 -> 0.3.8" +aggregated-from = "https://raw.githubusercontent.com/zcash/zcash/master/qa/supply-chain/audits.toml" + +[[audits.zcash.audits.errno]] +who = "Daira-Emma Hopwood " +criteria = "safe-to-deploy" +delta = "0.3.8 -> 0.3.9" +aggregated-from = "https://raw.githubusercontent.com/zcash/librustzcash/main/supply-chain/audits.toml" + +[[audits.zcash.audits.errno]] +who = "Jack Grigg " +criteria = "safe-to-deploy" +delta = "0.3.10 -> 0.3.11" +notes = "The `__errno` location for vxworks and cygwin looks correct from a quick search." +aggregated-from = "https://raw.githubusercontent.com/zcash/wallet/main/supply-chain/audits.toml" + +[[audits.zcash.audits.errno]] +who = "Jack Grigg " +criteria = "safe-to-deploy" +delta = "0.3.11 -> 0.3.13" +aggregated-from = "https://raw.githubusercontent.com/zcash/zcash/master/qa/supply-chain/audits.toml" + +[[audits.zcash.audits.errno]] +who = "Jack Grigg " +criteria = "safe-to-deploy" +delta = "0.3.13 -> 0.3.14" +aggregated-from = "https://raw.githubusercontent.com/zcash/librustzcash/main/supply-chain/audits.toml" + +[[audits.zcash.audits.glob]] +who = "Jack Grigg " +criteria = "safe-to-deploy" +delta = "0.3.2 -> 0.3.3" +aggregated-from = "https://raw.githubusercontent.com/zcash/librustzcash/main/supply-chain/audits.toml" + +[[audits.zcash.audits.http-body]] +who = "Jack Grigg " +criteria = "safe-to-deploy" +delta = "1.0.0 -> 1.0.1" +aggregated-from = "https://raw.githubusercontent.com/zcash/librustzcash/main/supply-chain/audits.toml" + +[[audits.zcash.audits.quinn-udp]] +who = "Jack Grigg " +criteria = "safe-to-deploy" +delta = "0.5.13 -> 0.5.14" +aggregated-from = "https://raw.githubusercontent.com/zcash/wallet/main/supply-chain/audits.toml" + +[[audits.zcash.audits.rustc-demangle]] +who = "Jack Grigg " +criteria = "safe-to-deploy" +delta = "0.1.24 -> 0.1.25" +aggregated-from = "https://raw.githubusercontent.com/zcash/zcash/master/qa/supply-chain/audits.toml" + +[[audits.zcash.audits.rustc-demangle]] +who = "Jack Grigg " +criteria = "safe-to-deploy" +delta = "0.1.25 -> 0.1.26" +notes = "Parser changes use existing parsing machinery in an obvious way." +aggregated-from = "https://raw.githubusercontent.com/zcash/wallet/main/supply-chain/audits.toml" + +[[audits.zcash.audits.rustversion]] +who = "Jack Grigg " +criteria = "safe-to-deploy" +delta = "1.0.20 -> 1.0.21" +notes = "Build script change is to fix building with `-Zfmt-debug=none`." +aggregated-from = "https://raw.githubusercontent.com/zcash/zcash/master/qa/supply-chain/audits.toml" + +[[audits.zcash.audits.rustversion]] +who = "Jack Grigg " +criteria = "safe-to-deploy" +delta = "1.0.21 -> 1.0.22" +notes = "Changes to generated code are to prepend a clippy annotation." +aggregated-from = "https://raw.githubusercontent.com/zcash/wallet/main/supply-chain/audits.toml" + +[[audits.zcash.audits.thread_local]] +who = "Jack Grigg " +criteria = "safe-to-deploy" +delta = "1.1.4 -> 1.1.7" +notes = """ +New `unsafe` usage: +- An extra `deallocate_bucket`, to replace a `Mutex::lock` with a `compare_exchange`. +- Setting and getting a `#[thread_local] static mut Option` on nightly. +""" +aggregated-from = "https://raw.githubusercontent.com/zcash/zcash/master/qa/supply-chain/audits.toml" + +[[audits.zcash.audits.thread_local]] +who = "Daira-Emma Hopwood " +criteria = "safe-to-deploy" +delta = "1.1.7 -> 1.1.8" +notes = """ +Adds `unsafe` code that makes an assumption that `ptr::null_mut::>()` is a valid representation +of an `AtomicPtr>`, but this is likely a correct assumption. +""" +aggregated-from = "https://raw.githubusercontent.com/zcash/zcash/master/qa/supply-chain/audits.toml" + +[[audits.zcash.audits.thread_local]] +who = "Jack Grigg " +criteria = "safe-to-deploy" +delta = "1.1.8 -> 1.1.9" +aggregated-from = "https://raw.githubusercontent.com/zcash/zcash/master/qa/supply-chain/audits.toml" + +[[audits.zcash.audits.tokio-stream]] +who = "Daira-Emma Hopwood " +criteria = "safe-to-deploy" +delta = "0.1.14 -> 0.1.15" +aggregated-from = "https://raw.githubusercontent.com/zcash/librustzcash/main/supply-chain/audits.toml" + +[[audits.zcash.audits.tokio-stream]] +who = "Jack Grigg " +criteria = "safe-to-deploy" +delta = "0.1.15 -> 0.1.17" +notes = """ +No new `unsafe` code or powerful imports. The new async polling logic added as +`StreamMap::poll_next_many` looks plausible. +""" +aggregated-from = "https://raw.githubusercontent.com/zcash/librustzcash/main/supply-chain/audits.toml" + +[[audits.zcash.audits.try-lock]] +who = "Jack Grigg " +criteria = "safe-to-deploy" +delta = "0.2.4 -> 0.2.5" +notes = "Bumps MSRV to remove unsafe code block." +aggregated-from = "https://raw.githubusercontent.com/zcash/zcash/master/qa/supply-chain/audits.toml" + +[[audits.zcash.audits.valuable]] +who = "Jack Grigg " +criteria = "safe-to-deploy" +delta = "0.1.0 -> 0.1.1" +notes = "Build script changes are for linting." +aggregated-from = "https://raw.githubusercontent.com/zcash/zcash/master/qa/supply-chain/audits.toml" + +[[audits.zcash.audits.want]] +who = "Jack Grigg " +criteria = "safe-to-deploy" +delta = "0.3.0 -> 0.3.1" +notes = """ +Migrates to `try-lock 0.2.4` to replace some unsafe APIs that were not marked +`unsafe` (but that were being used safely). +""" +aggregated-from = "https://raw.githubusercontent.com/zcash/zcash/master/qa/supply-chain/audits.toml" + +[[audits.zcash.audits.windows-link]] +who = "Jack Grigg " +criteria = "safe-to-deploy" +delta = "0.1.1 -> 0.1.3" +aggregated-from = "https://raw.githubusercontent.com/zcash/librustzcash/main/supply-chain/audits.toml" From 74556f7ea3ce08657e590d472487cf8de389594f Mon Sep 17 00:00:00 2001 From: rgrant Date: Fri, 23 Jan 2026 22:04:33 +0000 Subject: [PATCH 04/23] 20260123 upgrade to cargo-vet changed quoting. add example git hook. --- supply-chain/git-hook-pre-commit.sh | 4 ++++ supply-chain/imports.lock | 14 +++++++------- 2 files changed, 11 insertions(+), 7 deletions(-) create mode 100755 supply-chain/git-hook-pre-commit.sh diff --git a/supply-chain/git-hook-pre-commit.sh b/supply-chain/git-hook-pre-commit.sh new file mode 100755 index 00000000..d063d60d --- /dev/null +++ b/supply-chain/git-hook-pre-commit.sh @@ -0,0 +1,4 @@ +#!/bin/sh +# install +# cargo install --locked cargo-vet +cargo vet --locked diff --git a/supply-chain/imports.lock b/supply-chain/imports.lock index bf6328ef..a421f461 100644 --- a/supply-chain/imports.lock +++ b/supply-chain/imports.lock @@ -660,7 +660,7 @@ aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_p who = "Lukasz Anforowicz " criteria = "safe-to-deploy" delta = "1.14.0 -> 1.15.0" -notes = "The delta in `lib.rs` only tweaks doc comments and `#[cfg(feature = \"std\")]`." +notes = 'The delta in `lib.rs` only tweaks doc comments and `#[cfg(feature = "std")]`.' aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" [[audits.google.audits.equivalent]] @@ -694,7 +694,7 @@ notes = """ `ub-risk-2` review notes can be found in https://crrev.com/c/6071306/5/third_party/rust/chromium_crates_io/vendor/foldhash-0.1.3/src/seed.rs `does-not-implement-crypto` based on `README.md` which explicitly says that -\"Foldhash is **not appropriate for any cryptographic purpose**.\" +"Foldhash is **not appropriate for any cryptographic purpose**." """ aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" @@ -1021,8 +1021,8 @@ who = "Lukasz Anforowicz " criteria = "safe-to-deploy" version = "1.0.35" notes = """ -Grepped for \"unsafe\", \"crypt\", \"cipher\", \"fs\", \"net\" - there were no hits -(except for benign \"net\" hit in tests and \"fs\" hit in README.md) +Grepped for "unsafe", "crypt", "cipher", "fs", "net" - there were no hits +(except for benign "net" hit in tests and "fs" hit in README.md) """ aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" @@ -1111,7 +1111,7 @@ and there were no hits except for: * Using `unsafe` in a string: ``` - src/constfn.rs: \"unsafe\" => Qualifiers::Unsafe, + src/constfn.rs: "unsafe" => Qualifiers::Unsafe, ``` * Using `std::fs` in `build/build.rs` to write `${OUT_DIR}/version.expr` @@ -1293,7 +1293,7 @@ aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_p who = "Lukasz Anforowicz " criteria = "safe-to-deploy" version = "1.0.197" -notes = "Grepped for \"unsafe\", \"crypt\", \"cipher\", \"fs\", \"net\" - there were no hits" +notes = 'Grepped for "unsafe", "crypt", "cipher", "fs", "net" - there were no hits' aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" [[audits.google.audits.serde_derive]] @@ -1312,7 +1312,7 @@ aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_p who = "Lukasz Anforowicz " criteria = "safe-to-deploy" delta = "1.0.202 -> 1.0.203" -notes = "Grepped for \"unsafe\", \"crypt\", \"cipher\", \"fs\", \"net\" - there were no hits" +notes = 'Grepped for "unsafe", "crypt", "cipher", "fs", "net" - there were no hits' aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" [[audits.google.audits.serde_derive]] From 1c8004461cc6cc43cefb3b599228396cef3f7bcc Mon Sep 17 00:00:00 2001 From: rgrant Date: Fri, 13 Feb 2026 23:10:01 +0000 Subject: [PATCH 05/23] 20260213 add some trust to cargo vet config --- supply-chain/audits.toml | 792 ++++++++++++++++++++++++ supply-chain/config.toml | 580 ++---------------- supply-chain/imports.lock | 1213 ++++++++++++++++++++++++++++++++----- 3 files changed, 1884 insertions(+), 701 deletions(-) diff --git a/supply-chain/audits.toml b/supply-chain/audits.toml index 2772ccb2..46038059 100644 --- a/supply-chain/audits.toml +++ b/supply-chain/audits.toml @@ -2,3 +2,795 @@ # cargo-vet audits file [audits] + +[[trusted.aho-corasick]] +criteria = "safe-to-deploy" +user-id = 189 # Andrew Gallant (BurntSushi) +start = "2019-03-28" +end = "2027-02-13" + +[[trusted.anstream]] +criteria = "safe-to-deploy" +user-id = 6743 # Ed Page (epage) +start = "2023-03-16" +end = "2027-02-13" + +[[trusted.anstyle]] +criteria = "safe-to-deploy" +user-id = 6743 # Ed Page (epage) +start = "2022-05-18" +end = "2027-02-13" + +[[trusted.anstyle-parse]] +criteria = "safe-to-deploy" +user-id = 6743 # Ed Page (epage) +start = "2023-03-08" +end = "2027-02-13" + +[[trusted.anstyle-query]] +criteria = "safe-to-deploy" +user-id = 6743 # Ed Page (epage) +start = "2023-04-13" +end = "2027-02-13" + +[[trusted.anstyle-wincon]] +criteria = "safe-to-deploy" +user-id = 6743 # Ed Page (epage) +start = "2023-03-08" +end = "2027-02-13" + +[[trusted.async-stream]] +criteria = "safe-to-deploy" +user-id = 10 +start = "2019-06-07" +end = "2027-02-13" + +[[trusted.async-stream-impl]] +criteria = "safe-to-deploy" +user-id = 10 +start = "2019-08-13" +end = "2027-02-13" + +[[trusted.async-trait]] +criteria = "safe-to-deploy" +user-id = 3618 # David Tolnay (dtolnay) +start = "2019-07-23" +end = "2027-02-13" + +[[trusted.backtrace]] +criteria = "safe-to-deploy" +user-id = 55123 # rust-lang-owner +start = "2025-05-06" +end = "2027-02-13" + +[[trusted.bincode]] +criteria = "safe-to-deploy" +user-id = 3618 # David Tolnay (dtolnay) +start = "2019-04-08" +end = "2027-02-13" + +[[trusted.bstr]] +criteria = "safe-to-deploy" +user-id = 189 # Andrew Gallant (BurntSushi) +start = "2019-04-02" +end = "2027-02-13" + +[[trusted.bytes]] +criteria = "safe-to-deploy" +user-id = 6741 # Alice Ryhl (Darksonn) +start = "2021-01-11" +end = "2027-02-13" + +[[trusted.caseless]] +criteria = "safe-to-deploy" +user-id = 1139 # Manish Goregaokar (Manishearth) +start = "2024-12-30" +end = "2027-02-13" + +[[trusted.cc]] +criteria = "safe-to-deploy" +user-id = 55123 # rust-lang-owner +start = "2022-10-29" +end = "2027-02-13" + +[[trusted.clap]] +criteria = "safe-to-deploy" +user-id = 6743 # Ed Page (epage) +start = "2021-12-08" +end = "2027-02-13" + +[[trusted.clap_builder]] +criteria = "safe-to-deploy" +user-id = 6743 # Ed Page (epage) +start = "2023-03-28" +end = "2027-02-13" + +[[trusted.clap_derive]] +criteria = "safe-to-deploy" +user-id = 6743 # Ed Page (epage) +start = "2021-12-08" +end = "2027-02-13" + +[[trusted.clap_lex]] +criteria = "safe-to-deploy" +user-id = 6743 # Ed Page (epage) +start = "2022-04-15" +end = "2027-02-13" + +[[trusted.colorchoice]] +criteria = "safe-to-deploy" +user-id = 6743 # Ed Page (epage) +start = "2023-04-13" +end = "2027-02-13" + +[[trusted.dyn-clone]] +criteria = "safe-to-deploy" +user-id = 3618 # David Tolnay (dtolnay) +start = "2019-12-23" +end = "2027-02-13" + +[[trusted.dyn-hash]] +criteria = "safe-to-deploy" +user-id = 3618 # David Tolnay (dtolnay) +start = "2023-11-03" +end = "2027-02-13" + +[[trusted.encoding_rs_io]] +criteria = "safe-to-deploy" +user-id = 189 # Andrew Gallant (BurntSushi) +start = "2019-03-03" +end = "2027-02-13" + +[[trusted.erased-serde]] +criteria = "safe-to-deploy" +user-id = 3618 # David Tolnay (dtolnay) +start = "2020-01-06" +end = "2027-02-13" + +[[trusted.find-msvc-tools]] +criteria = "safe-to-deploy" +user-id = 539 # Josh Stone (cuviper) +start = "2025-08-29" +end = "2027-02-13" + +[[trusted.globset]] +criteria = "safe-to-deploy" +user-id = 189 # Andrew Gallant (BurntSushi) +start = "2019-04-15" +end = "2027-02-13" + +[[trusted.grep-matcher]] +criteria = "safe-to-deploy" +user-id = 189 # Andrew Gallant (BurntSushi) +start = "2019-04-15" +end = "2027-02-13" + +[[trusted.grep-printer]] +criteria = "safe-to-deploy" +user-id = 189 # Andrew Gallant (BurntSushi) +start = "2019-04-15" +end = "2027-02-13" + +[[trusted.grep-regex]] +criteria = "safe-to-deploy" +user-id = 189 # Andrew Gallant (BurntSushi) +start = "2019-04-15" +end = "2027-02-13" + +[[trusted.grep-searcher]] +criteria = "safe-to-deploy" +user-id = 189 # Andrew Gallant (BurntSushi) +start = "2019-04-15" +end = "2027-02-13" + +[[trusted.h2]] +criteria = "safe-to-deploy" +user-id = 359 # Sean McArthur (seanmonstar) +start = "2019-03-13" +end = "2027-02-13" + +[[trusted.hashbrown]] +criteria = "safe-to-deploy" +user-id = 55123 # rust-lang-owner +start = "2025-04-30" +end = "2027-02-13" + +[[trusted.http]] +criteria = "safe-to-deploy" +user-id = 359 # Sean McArthur (seanmonstar) +start = "2019-04-05" +end = "2027-02-13" + +[[trusted.http-body-util]] +criteria = "safe-to-deploy" +user-id = 359 # Sean McArthur (seanmonstar) +start = "2022-10-25" +end = "2027-02-13" + +[[trusted.httparse]] +criteria = "safe-to-deploy" +user-id = 359 # Sean McArthur (seanmonstar) +start = "2019-07-03" +end = "2027-02-13" + +[[trusted.hyper]] +criteria = "safe-to-deploy" +user-id = 359 # Sean McArthur (seanmonstar) +start = "2019-03-01" +end = "2027-02-13" + +[[trusted.hyper-util]] +criteria = "safe-to-deploy" +user-id = 359 # Sean McArthur (seanmonstar) +start = "2022-01-15" +end = "2027-02-13" + +[[trusted.ignore]] +criteria = "safe-to-deploy" +user-id = 189 # Andrew Gallant (BurntSushi) +start = "2019-04-15" +end = "2027-02-13" + +[[trusted.indexmap]] +criteria = "safe-to-deploy" +user-id = 539 # Josh Stone (cuviper) +start = "2020-01-15" +end = "2027-02-13" + +[[trusted.indoc]] +criteria = "safe-to-deploy" +user-id = 3618 # David Tolnay (dtolnay) +start = "2019-04-28" +end = "2027-02-13" + +[[trusted.inventory]] +criteria = "safe-to-deploy" +user-id = 3618 # David Tolnay (dtolnay) +start = "2019-08-15" +end = "2027-02-13" + +[[trusted.is_terminal_polyfill]] +criteria = "safe-to-deploy" +user-id = 6743 # Ed Page (epage) +start = "2024-05-02" +end = "2027-02-13" + +[[trusted.js-sys]] +criteria = "safe-to-deploy" +user-id = 1 # Alex Crichton (alexcrichton) +start = "2019-03-04" +end = "2027-02-13" + +[[trusted.libc]] +criteria = "safe-to-deploy" +user-id = 55123 # rust-lang-owner +start = "2024-08-15" +end = "2027-02-13" + +[[trusted.linkme]] +criteria = "safe-to-deploy" +user-id = 3618 # David Tolnay (dtolnay) +start = "2019-08-18" +end = "2027-02-13" + +[[trusted.linkme-impl]] +criteria = "safe-to-deploy" +user-id = 3618 # David Tolnay (dtolnay) +start = "2019-08-18" +end = "2027-02-13" + +[[trusted.linux-raw-sys]] +criteria = "safe-to-deploy" +user-id = 6825 # Dan Gohman (sunfishcode) +start = "2021-06-12" +end = "2027-02-13" + +[[trusted.lock_api]] +criteria = "safe-to-deploy" +user-id = 2915 # Amanieu d'Antras (Amanieu) +start = "2019-05-04" +end = "2027-02-13" + +[[trusted.memchr]] +criteria = "safe-to-deploy" +user-id = 189 # Andrew Gallant (BurntSushi) +start = "2019-07-07" +end = "2027-02-13" + +[[trusted.mime]] +criteria = "safe-to-deploy" +user-id = 359 # Sean McArthur (seanmonstar) +start = "2019-09-09" +end = "2027-02-13" + +[[trusted.num]] +criteria = "safe-to-deploy" +user-id = 539 # Josh Stone (cuviper) +start = "2020-01-10" +end = "2027-02-13" + +[[trusted.num-bigint]] +criteria = "safe-to-deploy" +user-id = 539 # Josh Stone (cuviper) +start = "2019-09-04" +end = "2027-02-13" + +[[trusted.num-complex]] +criteria = "safe-to-deploy" +user-id = 539 # Josh Stone (cuviper) +start = "2019-06-10" +end = "2027-02-13" + +[[trusted.once_cell_polyfill]] +criteria = "safe-to-deploy" +user-id = 6743 # Ed Page (epage) +start = "2025-05-22" +end = "2027-02-13" + +[[trusted.openssl-probe]] +criteria = "safe-to-deploy" +user-id = 1 # Alex Crichton (alexcrichton) +start = "2020-08-04" +end = "2027-02-13" + +[[trusted.ordered-float]] +criteria = "safe-to-deploy" +user-id = 2017 # Matt Brubeck (mbrubeck) +start = "2019-03-13" +end = "2027-02-13" + +[[trusted.parking_lot]] +criteria = "safe-to-deploy" +user-id = 2915 # Amanieu d'Antras (Amanieu) +start = "2019-05-04" +end = "2027-02-13" + +[[trusted.parking_lot_core]] +criteria = "safe-to-deploy" +user-id = 2915 # Amanieu d'Antras (Amanieu) +start = "2019-05-04" +end = "2027-02-13" + +[[trusted.paste]] +criteria = "safe-to-deploy" +user-id = 3618 # David Tolnay (dtolnay) +start = "2019-03-19" +end = "2027-02-13" + +[[trusted.potential_utf]] +criteria = "safe-to-deploy" +user-id = 1139 # Manish Goregaokar (Manishearth) +start = "2024-11-23" +end = "2027-02-13" + +[[trusted.proc-macro2]] +criteria = "safe-to-deploy" +user-id = 3618 # David Tolnay (dtolnay) +start = "2019-04-23" +end = "2027-02-13" + +[[trusted.quote]] +criteria = "safe-to-deploy" +user-id = 3618 # David Tolnay (dtolnay) +start = "2019-04-09" +end = "2027-02-13" + +[[trusted.ref-cast]] +criteria = "safe-to-deploy" +user-id = 3618 # David Tolnay (dtolnay) +start = "2019-05-05" +end = "2027-02-13" + +[[trusted.ref-cast-impl]] +criteria = "safe-to-deploy" +user-id = 3618 # David Tolnay (dtolnay) +start = "2019-05-05" +end = "2027-02-13" + +[[trusted.regex]] +criteria = "safe-to-deploy" +user-id = 189 # Andrew Gallant (BurntSushi) +start = "2019-02-27" +end = "2027-02-13" + +[[trusted.regex-automata]] +criteria = "safe-to-deploy" +user-id = 189 # Andrew Gallant (BurntSushi) +start = "2019-02-25" +end = "2027-02-13" + +[[trusted.regex-syntax]] +criteria = "safe-to-deploy" +user-id = 189 # Andrew Gallant (BurntSushi) +start = "2019-03-30" +end = "2027-02-13" + +[[trusted.reqwest]] +criteria = "safe-to-deploy" +user-id = 359 # Sean McArthur (seanmonstar) +start = "2019-03-04" +end = "2027-02-13" + +[[trusted.rustix]] +criteria = "safe-to-deploy" +user-id = 6825 # Dan Gohman (sunfishcode) +start = "2021-10-29" +end = "2027-02-13" + +[[trusted.ryu]] +criteria = "safe-to-deploy" +user-id = 3618 # David Tolnay (dtolnay) +start = "2019-05-02" +end = "2027-02-13" + +[[trusted.same-file]] +criteria = "safe-to-deploy" +user-id = 189 # Andrew Gallant (BurntSushi) +start = "2019-07-16" +end = "2027-02-13" + +[[trusted.scopeguard]] +criteria = "safe-to-deploy" +user-id = 2915 # Amanieu d'Antras (Amanieu) +start = "2020-02-16" +end = "2027-02-13" + +[[trusted.semver]] +criteria = "safe-to-deploy" +user-id = 3618 # David Tolnay (dtolnay) +start = "2021-05-25" +end = "2027-02-13" + +[[trusted.serde-untagged]] +criteria = "safe-to-deploy" +user-id = 3618 # David Tolnay (dtolnay) +start = "2023-08-27" +end = "2027-02-13" + +[[trusted.serde_derive_internals]] +criteria = "safe-to-deploy" +user-id = 3618 # David Tolnay (dtolnay) +start = "2019-09-08" +end = "2027-02-13" + +[[trusted.serde_json]] +criteria = "safe-to-deploy" +user-id = 3618 # David Tolnay (dtolnay) +start = "2019-02-28" +end = "2027-02-13" + +[[trusted.serde_path_to_error]] +criteria = "safe-to-deploy" +user-id = 3618 # David Tolnay (dtolnay) +start = "2019-08-20" +end = "2027-02-13" + +[[trusted.serde_spanned]] +criteria = "safe-to-deploy" +user-id = 6743 # Ed Page (epage) +start = "2023-01-20" +end = "2027-02-13" + +[[trusted.serde_yaml]] +criteria = "safe-to-deploy" +user-id = 3618 # David Tolnay (dtolnay) +start = "2019-05-02" +end = "2027-02-13" + +[[trusted.slab]] +criteria = "safe-to-deploy" +user-id = 6741 # Alice Ryhl (Darksonn) +start = "2021-10-13" +end = "2027-02-13" + +[[trusted.syn]] +criteria = "safe-to-deploy" +user-id = 3618 # David Tolnay (dtolnay) +start = "2019-03-01" +end = "2027-02-13" + +[[trusted.tabwriter]] +criteria = "safe-to-deploy" +user-id = 189 # Andrew Gallant (BurntSushi) +start = "2020-01-11" +end = "2027-02-13" + +[[trusted.termcolor]] +criteria = "safe-to-deploy" +user-id = 189 # Andrew Gallant (BurntSushi) +start = "2019-06-04" +end = "2027-02-13" + +[[trusted.thiserror]] +criteria = "safe-to-deploy" +user-id = 3618 # David Tolnay (dtolnay) +start = "2019-10-09" +end = "2027-02-13" + +[[trusted.thiserror-impl]] +criteria = "safe-to-deploy" +user-id = 3618 # David Tolnay (dtolnay) +start = "2019-10-09" +end = "2027-02-13" + +[[trusted.tokio]] +criteria = "safe-to-deploy" +user-id = 6741 # Alice Ryhl (Darksonn) +start = "2020-12-25" +end = "2027-02-13" + +[[trusted.tokio-macros]] +criteria = "safe-to-deploy" +user-id = 6741 # Alice Ryhl (Darksonn) +start = "2020-10-26" +end = "2027-02-13" + +[[trusted.tokio-util]] +criteria = "safe-to-deploy" +user-id = 6741 # Alice Ryhl (Darksonn) +start = "2021-01-12" +end = "2027-02-13" + +[[trusted.toml]] +criteria = "safe-to-deploy" +user-id = 1 # Alex Crichton (alexcrichton) +start = "2019-05-16" +end = "2027-02-13" + +[[trusted.toml]] +criteria = "safe-to-deploy" +user-id = 6743 # Ed Page (epage) +start = "2022-12-14" +end = "2027-02-13" + +[[trusted.toml_datetime]] +criteria = "safe-to-deploy" +user-id = 6743 # Ed Page (epage) +start = "2022-10-21" +end = "2027-02-13" + +[[trusted.toml_edit]] +criteria = "safe-to-deploy" +user-id = 6743 # Ed Page (epage) +start = "2021-09-13" +end = "2027-02-13" + +[[trusted.toml_parser]] +criteria = "safe-to-deploy" +user-id = 6743 # Ed Page (epage) +start = "2025-07-08" +end = "2027-02-13" + +[[trusted.toml_write]] +criteria = "safe-to-deploy" +user-id = 6743 # Ed Page (epage) +start = "2025-04-25" +end = "2027-02-13" + +[[trusted.tower]] +criteria = "safe-to-deploy" +user-id = 359 # Sean McArthur (seanmonstar) +start = "2024-09-09" +end = "2027-02-13" + +[[trusted.tower-http]] +criteria = "safe-to-deploy" +user-id = 359 # Sean McArthur (seanmonstar) +start = "2024-09-23" +end = "2027-02-13" + +[[trusted.tower-layer]] +criteria = "safe-to-deploy" +user-id = 10 +start = "2019-04-27" +end = "2027-02-13" + +[[trusted.typed-arena]] +criteria = "safe-to-deploy" +user-id = 696 # Nick Fitzgerald (fitzgen) +start = "2019-08-02" +end = "2027-02-13" + +[[trusted.typeid]] +criteria = "safe-to-deploy" +user-id = 3618 # David Tolnay (dtolnay) +start = "2024-05-13" +end = "2027-02-13" + +[[trusted.typetag]] +criteria = "safe-to-deploy" +user-id = 3618 # David Tolnay (dtolnay) +start = "2019-04-07" +end = "2027-02-13" + +[[trusted.typetag-impl]] +criteria = "safe-to-deploy" +user-id = 3618 # David Tolnay (dtolnay) +start = "2019-04-07" +end = "2027-02-13" + +[[trusted.ucd-trie]] +criteria = "safe-to-deploy" +user-id = 189 # Andrew Gallant (BurntSushi) +start = "2019-07-21" +end = "2027-02-13" + +[[trusted.unicode-ident]] +criteria = "safe-to-deploy" +user-id = 3618 # David Tolnay (dtolnay) +start = "2021-10-02" +end = "2027-02-13" + +[[trusted.unsafe-libyaml]] +criteria = "safe-to-deploy" +user-id = 3618 # David Tolnay (dtolnay) +start = "2022-07-03" +end = "2027-02-13" + +[[trusted.url]] +criteria = "safe-to-deploy" +user-id = 1139 # Manish Goregaokar (Manishearth) +start = "2021-02-18" +end = "2027-02-13" + +[[trusted.walkdir]] +criteria = "safe-to-deploy" +user-id = 189 # Andrew Gallant (BurntSushi) +start = "2019-06-09" +end = "2027-02-13" + +[[trusted.wasi]] +criteria = "safe-to-deploy" +user-id = 1 # Alex Crichton (alexcrichton) +start = "2020-06-03" +end = "2027-02-13" + +[[trusted.wasm-bindgen]] +criteria = "safe-to-deploy" +user-id = 1 # Alex Crichton (alexcrichton) +start = "2019-03-04" +end = "2027-02-13" + +[[trusted.wasm-bindgen-backend]] +criteria = "safe-to-deploy" +user-id = 1 # Alex Crichton (alexcrichton) +start = "2019-03-04" +end = "2027-02-13" + +[[trusted.wasm-bindgen-futures]] +criteria = "safe-to-deploy" +user-id = 1 # Alex Crichton (alexcrichton) +start = "2019-03-04" +end = "2027-02-13" + +[[trusted.wasm-bindgen-macro]] +criteria = "safe-to-deploy" +user-id = 1 # Alex Crichton (alexcrichton) +start = "2019-03-04" +end = "2027-02-13" + +[[trusted.wasm-bindgen-macro-support]] +criteria = "safe-to-deploy" +user-id = 1 # Alex Crichton (alexcrichton) +start = "2019-03-04" +end = "2027-02-13" + +[[trusted.wasm-bindgen-shared]] +criteria = "safe-to-deploy" +user-id = 1 # Alex Crichton (alexcrichton) +start = "2019-03-04" +end = "2027-02-13" + +[[trusted.web-sys]] +criteria = "safe-to-deploy" +user-id = 1 # Alex Crichton (alexcrichton) +start = "2019-03-04" +end = "2027-02-13" + +[[trusted.winapi-util]] +criteria = "safe-to-deploy" +user-id = 189 # Andrew Gallant (BurntSushi) +start = "2020-01-11" +end = "2027-02-13" + +[[trusted.windows]] +criteria = "safe-to-deploy" +user-id = 64539 # Kenny Kerr (kennykerr) +start = "2021-01-15" +end = "2027-02-13" + +[[trusted.windows-core]] +criteria = "safe-to-deploy" +user-id = 64539 # Kenny Kerr (kennykerr) +start = "2021-11-15" +end = "2027-02-13" + +[[trusted.windows-implement]] +criteria = "safe-to-deploy" +user-id = 64539 # Kenny Kerr (kennykerr) +start = "2022-01-27" +end = "2027-02-13" + +[[trusted.windows-interface]] +criteria = "safe-to-deploy" +user-id = 64539 # Kenny Kerr (kennykerr) +start = "2022-02-18" +end = "2027-02-13" + +[[trusted.windows-result]] +criteria = "safe-to-deploy" +user-id = 64539 # Kenny Kerr (kennykerr) +start = "2024-02-02" +end = "2027-02-13" + +[[trusted.windows-sys]] +criteria = "safe-to-deploy" +user-id = 64539 # Kenny Kerr (kennykerr) +start = "2021-11-15" +end = "2027-02-13" + +[[trusted.windows-targets]] +criteria = "safe-to-deploy" +user-id = 64539 # Kenny Kerr (kennykerr) +start = "2022-09-09" +end = "2027-02-13" + +[[trusted.windows_aarch64_gnullvm]] +criteria = "safe-to-deploy" +user-id = 64539 # Kenny Kerr (kennykerr) +start = "2022-09-01" +end = "2027-02-13" + +[[trusted.windows_aarch64_msvc]] +criteria = "safe-to-deploy" +user-id = 64539 # Kenny Kerr (kennykerr) +start = "2021-11-05" +end = "2027-02-13" + +[[trusted.windows_i686_gnu]] +criteria = "safe-to-deploy" +user-id = 64539 # Kenny Kerr (kennykerr) +start = "2021-10-28" +end = "2027-02-13" + +[[trusted.windows_i686_gnullvm]] +criteria = "safe-to-deploy" +user-id = 64539 # Kenny Kerr (kennykerr) +start = "2024-04-02" +end = "2027-02-13" + +[[trusted.windows_i686_msvc]] +criteria = "safe-to-deploy" +user-id = 64539 # Kenny Kerr (kennykerr) +start = "2021-10-27" +end = "2027-02-13" + +[[trusted.windows_x86_64_gnu]] +criteria = "safe-to-deploy" +user-id = 64539 # Kenny Kerr (kennykerr) +start = "2021-10-28" +end = "2027-02-13" + +[[trusted.windows_x86_64_gnullvm]] +criteria = "safe-to-deploy" +user-id = 64539 # Kenny Kerr (kennykerr) +start = "2022-09-01" +end = "2027-02-13" + +[[trusted.windows_x86_64_msvc]] +criteria = "safe-to-deploy" +user-id = 64539 # Kenny Kerr (kennykerr) +start = "2021-10-27" +end = "2027-02-13" + +[[trusted.winnow]] +criteria = "safe-to-deploy" +user-id = 6743 # Ed Page (epage) +start = "2023-02-22" +end = "2027-02-13" + +[[trusted.zmij]] +criteria = "safe-to-deploy" +user-id = 3618 # David Tolnay (dtolnay) +start = "2025-12-18" +end = "2027-02-13" diff --git a/supply-chain/config.toml b/supply-chain/config.toml index 0c3afb38..78a69e80 100644 --- a/supply-chain/config.toml +++ b/supply-chain/config.toml @@ -74,10 +74,6 @@ criteria = "safe-to-deploy" version = "0.8.12" criteria = "safe-to-deploy" -[[exemptions.aho-corasick]] -version = "1.1.3" -criteria = "safe-to-deploy" - [[exemptions.ansi-str]] version = "0.9.0" criteria = "safe-to-deploy" @@ -90,30 +86,6 @@ criteria = "safe-to-deploy" version = "0.3.0" criteria = "safe-to-deploy" -[[exemptions.anstream]] -version = "0.6.20" -criteria = "safe-to-deploy" - -[[exemptions.anstyle]] -version = "1.0.11" -criteria = "safe-to-deploy" - -[[exemptions.anstyle-parse]] -version = "0.2.7" -criteria = "safe-to-deploy" - -[[exemptions.anstyle-query]] -version = "1.1.4" -criteria = "safe-to-deploy" - -[[exemptions.anstyle-wincon]] -version = "3.0.10" -criteria = "safe-to-deploy" - -[[exemptions.anyhow]] -version = "1.0.100" -criteria = "safe-to-deploy" - [[exemptions.arc-swap]] version = "1.7.1" criteria = "safe-to-deploy" @@ -146,10 +118,6 @@ criteria = "safe-to-deploy" version = "0.3.6" criteria = "safe-to-deploy" -[[exemptions.async-trait]] -version = "0.1.89" -criteria = "safe-to-deploy" - [[exemptions.backon]] version = "1.5.1@git:341ea10a868218c5b1bcdfdd168df71b5e7e8c67" criteria = "safe-to-deploy" @@ -158,10 +126,6 @@ criteria = "safe-to-deploy" version = "1.5.2" criteria = "safe-to-deploy" -[[exemptions.backtrace]] -version = "0.3.75" -criteria = "safe-to-deploy" - [[exemptions.bat]] version = "0.25.0" criteria = "safe-to-deploy" @@ -174,10 +138,6 @@ criteria = "safe-to-deploy" version = "0.2.4" criteria = "safe-to-deploy" -[[exemptions.bstr]] -version = "1.12.0" -criteria = "safe-to-deploy" - [[exemptions.bytecount]] version = "0.6.9" criteria = "safe-to-deploy" @@ -186,16 +146,16 @@ criteria = "safe-to-deploy" version = "1.23.2" criteria = "safe-to-deploy" -[[exemptions.bytes]] -version = "1.10.1" -criteria = "safe-to-deploy" - [[exemptions.bytesize]] version = "1.3.3" criteria = "safe-to-deploy" -[[exemptions.caseless]] -version = "0.2.2" +[[exemptions.camino]] +version = "1.2.2" +criteria = "safe-to-deploy" + +[[exemptions.camino-tempfile]] +version = "1.4.1" criteria = "safe-to-deploy" [[exemptions.cc]] @@ -206,22 +166,6 @@ criteria = "safe-to-deploy" version = "0.4.42" criteria = "safe-to-deploy" -[[exemptions.clap]] -version = "4.5.48" -criteria = "safe-to-deploy" - -[[exemptions.clap_builder]] -version = "4.5.48" -criteria = "safe-to-deploy" - -[[exemptions.clap_derive]] -version = "4.5.47" -criteria = "safe-to-deploy" - -[[exemptions.clap_lex]] -version = "0.7.5" -criteria = "safe-to-deploy" - [[exemptions.clean-path]] version = "0.2.1" criteria = "safe-to-deploy" @@ -230,10 +174,6 @@ criteria = "safe-to-deploy" version = "0.6.1" criteria = "safe-to-deploy" -[[exemptions.colorchoice]] -version = "1.0.4" -criteria = "safe-to-deploy" - [[exemptions.comfy-table]] version = "7.2.1" criteria = "safe-to-deploy" @@ -263,7 +203,7 @@ version = "0.7.1" criteria = "safe-to-deploy" [[exemptions.convert_case]] -version = "0.8.0" +version = "0.10.0" criteria = "safe-to-deploy" [[exemptions.coolor]] @@ -330,6 +270,10 @@ criteria = "safe-to-deploy" version = "0.21.3" criteria = "safe-to-deploy" +[[exemptions.darling]] +version = "0.23.0" +criteria = "safe-to-deploy" + [[exemptions.darling_core]] version = "0.20.11" criteria = "safe-to-deploy" @@ -338,10 +282,18 @@ criteria = "safe-to-deploy" version = "0.21.3" criteria = "safe-to-deploy" +[[exemptions.darling_core]] +version = "0.23.0" +criteria = "safe-to-deploy" + [[exemptions.darling_macro]] version = "0.20.11" criteria = "safe-to-deploy" +[[exemptions.darling_macro]] +version = "0.23.0" +criteria = "safe-to-deploy" + [[exemptions.data-encoding]] version = "2.9.0" criteria = "safe-to-deploy" @@ -386,10 +338,6 @@ criteria = "safe-to-deploy" version = "6.0.0" criteria = "safe-to-deploy" -[[exemptions.dirs]] -version = "6.0.0" -criteria = "safe-to-deploy" - [[exemptions.dirs-sys]] version = "0.5.0" criteria = "safe-to-deploy" @@ -402,14 +350,6 @@ criteria = "safe-to-deploy" version = "1.0.0" criteria = "safe-to-deploy" -[[exemptions.dyn-clone]] -version = "1.0.20" -criteria = "safe-to-deploy" - -[[exemptions.dyn-hash]] -version = "0.2.2" -criteria = "safe-to-deploy" - [[exemptions.email_address]] version = "0.2.9" criteria = "safe-to-deploy" @@ -418,10 +358,6 @@ criteria = "safe-to-deploy" version = "1.0.0" criteria = "safe-to-deploy" -[[exemptions.encoding_rs_io]] -version = "0.1.7" -criteria = "safe-to-deploy" - [[exemptions.entities]] version = "1.0.1" criteria = "safe-to-deploy" @@ -430,10 +366,6 @@ criteria = "safe-to-deploy" version = "0.1.0" criteria = "safe-to-deploy" -[[exemptions.erased-serde]] -version = "0.4.8" -criteria = "safe-to-deploy" - [[exemptions.event-listener]] version = "5.4.1" criteria = "safe-to-deploy" @@ -502,54 +434,10 @@ criteria = "safe-to-deploy" version = "0.3.4" criteria = "safe-to-deploy" -[[exemptions.globset]] -version = "0.4.16" -criteria = "safe-to-deploy" - -[[exemptions.grep-matcher]] -version = "0.1.7" -criteria = "safe-to-deploy" - -[[exemptions.grep-printer]] -version = "0.2.2" -criteria = "safe-to-deploy" - -[[exemptions.grep-regex]] -version = "0.1.13" -criteria = "safe-to-deploy" - -[[exemptions.grep-searcher]] -version = "0.1.14" -criteria = "safe-to-deploy" - -[[exemptions.h2]] -version = "0.4.12" -criteria = "safe-to-deploy" - -[[exemptions.hashbrown]] -version = "0.15.5" -criteria = "safe-to-deploy" - -[[exemptions.hashbrown]] -version = "0.16.1" -criteria = "safe-to-deploy" - [[exemptions.hashlink]] version = "0.10.0" criteria = "safe-to-deploy" -[[exemptions.http]] -version = "1.3.1" -criteria = "safe-to-deploy" - -[[exemptions.http-body-util]] -version = "0.1.3" -criteria = "safe-to-deploy" - -[[exemptions.httparse]] -version = "1.10.1" -criteria = "safe-to-deploy" - [[exemptions.httpmock]] version = "0.8.2@git:00d4c80d5f53e7db884c7c950c47f8faea87e061" criteria = "safe-to-deploy" @@ -558,10 +446,6 @@ criteria = "safe-to-deploy" version = "2.3.0" criteria = "safe-to-deploy" -[[exemptions.hyper]] -version = "1.7.0" -criteria = "safe-to-deploy" - [[exemptions.hyper-rustls]] version = "0.27.7" criteria = "safe-to-deploy" @@ -570,18 +454,6 @@ criteria = "safe-to-deploy" version = "0.5.2" criteria = "safe-to-deploy" -[[exemptions.hyper-util]] -version = "0.1.17" -criteria = "safe-to-deploy" - -[[exemptions.ignore]] -version = "0.4.23" -criteria = "safe-to-deploy" - -[[exemptions.indoc]] -version = "2.0.6" -criteria = "safe-to-deploy" - [[exemptions.inquire]] version = "0.9.1@git:c84710515dc4ee176bff9cae28f92d7b35ce310e" criteria = "safe-to-deploy" @@ -590,10 +462,6 @@ criteria = "safe-to-deploy" version = "1.43.2" criteria = "safe-to-deploy" -[[exemptions.inventory]] -version = "0.3.21" -criteria = "safe-to-deploy" - [[exemptions.io-uring]] version = "0.7.10" criteria = "safe-to-deploy" @@ -606,14 +474,6 @@ criteria = "safe-to-deploy" version = "0.7.8" criteria = "safe-to-deploy" -[[exemptions.is_ci]] -version = "1.2.0" -criteria = "safe-to-deploy" - -[[exemptions.is_terminal_polyfill]] -version = "1.70.1" -criteria = "safe-to-deploy" - [[exemptions.itertools]] version = "0.13.0" criteria = "safe-to-deploy" @@ -630,6 +490,10 @@ criteria = "safe-to-deploy" version = "0.3.80" criteria = "safe-to-deploy" +[[exemptions.json-strip-comments]] +version = "3.1.0" +criteria = "safe-to-deploy" + [[exemptions.jsonschema]] version = "0.37.4" criteria = "safe-to-deploy" @@ -646,10 +510,6 @@ criteria = "safe-to-deploy" version = "3.4.1" criteria = "safe-to-deploy" -[[exemptions.libc]] -version = "0.2.175" -criteria = "safe-to-deploy" - [[exemptions.libredox]] version = "0.1.10" criteria = "safe-to-deploy" @@ -658,26 +518,10 @@ criteria = "safe-to-deploy" version = "0.35.0" criteria = "safe-to-deploy" -[[exemptions.linkme]] -version = "0.3.33" -criteria = "safe-to-deploy" - -[[exemptions.linkme-impl]] -version = "0.3.33" -criteria = "safe-to-deploy" - -[[exemptions.linux-raw-sys]] -version = "0.11.0" -criteria = "safe-to-deploy" - [[exemptions.litrs]] version = "0.4.2" criteria = "safe-to-deploy" -[[exemptions.lock_api]] -version = "0.4.13" -criteria = "safe-to-deploy" - [[exemptions.lru-slab]] version = "0.1.2" criteria = "safe-to-deploy" @@ -694,10 +538,6 @@ criteria = "safe-to-deploy" version = "1.3.0" criteria = "safe-to-deploy" -[[exemptions.memchr]] -version = "2.7.5" -criteria = "safe-to-deploy" - [[exemptions.memmap2]] version = "0.9.8" criteria = "safe-to-deploy" @@ -710,10 +550,6 @@ criteria = "safe-to-deploy" version = "7.6.0" criteria = "safe-to-deploy" -[[exemptions.mime]] -version = "0.3.17" -criteria = "safe-to-deploy" - [[exemptions.mime_guess]] version = "2.0.5" criteria = "safe-to-deploy" @@ -738,22 +574,10 @@ criteria = "safe-to-deploy" version = "1.0.4" criteria = "safe-to-deploy" -[[exemptions.num]] -version = "0.4.3" -criteria = "safe-to-deploy" - -[[exemptions.num-bigint]] -version = "0.4.6" -criteria = "safe-to-deploy" - [[exemptions.num-cmp]] version = "0.1.0" criteria = "safe-to-deploy" -[[exemptions.num-complex]] -version = "0.4.6" -criteria = "safe-to-deploy" - [[exemptions.num_threads]] version = "0.1.7" criteria = "safe-to-deploy" @@ -774,10 +598,6 @@ criteria = "safe-to-deploy" version = "1.21.3" criteria = "safe-to-deploy" -[[exemptions.once_cell_polyfill]] -version = "1.70.1" -criteria = "safe-to-deploy" - [[exemptions.onig]] version = "6.5.1" criteria = "safe-to-deploy" @@ -798,14 +618,6 @@ criteria = "safe-to-deploy" version = "0.1.6@git:803a4104ec2848ce2bd86c80c28593d7108b35d1" criteria = "safe-to-deploy" -[[exemptions.openssl-probe]] -version = "0.1.6" -criteria = "safe-to-deploy" - -[[exemptions.ordered-float]] -version = "5.0.0" -criteria = "safe-to-deploy" - [[exemptions.os_pipe]] version = "1.2.2" criteria = "safe-to-deploy" @@ -814,26 +626,10 @@ criteria = "safe-to-deploy" version = "0.5.2" criteria = "safe-to-deploy" -[[exemptions.owo-colors]] -version = "4.2.2" -criteria = "safe-to-deploy" - [[exemptions.parking]] version = "2.2.1" criteria = "safe-to-deploy" -[[exemptions.parking_lot]] -version = "0.12.4" -criteria = "safe-to-deploy" - -[[exemptions.parking_lot_core]] -version = "0.9.11" -criteria = "safe-to-deploy" - -[[exemptions.paste]] -version = "1.0.15" -criteria = "safe-to-deploy" - [[exemptions.path-tree]] version = "0.8.3" criteria = "safe-to-deploy" @@ -874,10 +670,6 @@ criteria = "safe-to-deploy" version = "1.8.0" criteria = "safe-to-deploy" -[[exemptions.potential_utf]] -version = "0.1.3" -criteria = "safe-to-deploy" - [[exemptions.ppv-lite86]] version = "0.2.21" criteria = "safe-to-deploy" @@ -886,10 +678,6 @@ criteria = "safe-to-deploy" version = "1.4.1" criteria = "safe-to-run" -[[exemptions.proc-macro2]] -version = "1.0.101" -criteria = "safe-to-deploy" - [[exemptions.quick-xml]] version = "0.38.4" criteria = "safe-to-deploy" @@ -914,38 +702,14 @@ criteria = "safe-to-deploy" version = "0.5.2" criteria = "safe-to-deploy" -[[exemptions.ref-cast]] -version = "1.0.24" -criteria = "safe-to-deploy" - -[[exemptions.ref-cast-impl]] -version = "1.0.24" -criteria = "safe-to-deploy" - [[exemptions.referencing]] version = "0.37.4" criteria = "safe-to-deploy" -[[exemptions.regex]] -version = "1.11.2" -criteria = "safe-to-deploy" - -[[exemptions.regex-automata]] -version = "0.4.10" -criteria = "safe-to-deploy" - -[[exemptions.regex-syntax]] -version = "0.8.6" -criteria = "safe-to-deploy" - [[exemptions.relative-path]] version = "2.0.1" criteria = "safe-to-deploy" -[[exemptions.reqwest]] -version = "0.12.23" -criteria = "safe-to-deploy" - [[exemptions.reqwest-eventsource]] version = "0.6.0" criteria = "safe-to-deploy" @@ -970,10 +734,6 @@ criteria = "safe-to-deploy" version = "0.37.0" criteria = "safe-to-deploy" -[[exemptions.rustix]] -version = "1.1.2" -criteria = "safe-to-deploy" - [[exemptions.rustls]] version = "0.23.35" criteria = "safe-to-deploy" @@ -990,14 +750,6 @@ criteria = "safe-to-deploy" version = "0.103.6" criteria = "safe-to-deploy" -[[exemptions.ryu]] -version = "1.0.20" -criteria = "safe-to-deploy" - -[[exemptions.same-file]] -version = "1.0.6" -criteria = "safe-to-deploy" - [[exemptions.saphyr]] version = "0.0.6@git:b7dff7bf64516936b4ffc3ac76160138eb325118" criteria = "safe-to-deploy" @@ -1031,19 +783,15 @@ version = "1.0.4" criteria = "safe-to-deploy" [[exemptions.schematic]] -version = "0.18.12@git:533dc9ada5af11a74f44adfe19d7c056a174db32" +version = "0.19.4@git:de733f0586ecef6ccccdcd4ce60b515fd82251bc" criteria = "safe-to-deploy" [[exemptions.schematic_macros]] -version = "0.18.11@git:533dc9ada5af11a74f44adfe19d7c056a174db32" +version = "0.19.3@git:de733f0586ecef6ccccdcd4ce60b515fd82251bc" criteria = "safe-to-deploy" [[exemptions.schematic_types]] -version = "0.10.6@git:533dc9ada5af11a74f44adfe19d7c056a174db32" -criteria = "safe-to-deploy" - -[[exemptions.scopeguard]] -version = "1.2.0" +version = "0.11.3@git:de733f0586ecef6ccccdcd4ce60b515fd82251bc" criteria = "safe-to-deploy" [[exemptions.sdd]] @@ -1062,38 +810,18 @@ criteria = "safe-to-deploy" version = "2.15.0" criteria = "safe-to-deploy" -[[exemptions.semver]] -version = "1.0.27" -criteria = "safe-to-deploy" - -[[exemptions.serde_derive_internals]] -version = "0.29.1" -criteria = "safe-to-deploy" - -[[exemptions.serde_json]] -version = "1.0.145" +[[exemptions.serde-content]] +version = "0.1.2" criteria = "safe-to-deploy" [[exemptions.serde_json5]] version = "0.2.1" criteria = "safe-to-deploy" -[[exemptions.serde_path_to_error]] -version = "0.1.20" -criteria = "safe-to-deploy" - [[exemptions.serde_regex]] version = "1.1.0" criteria = "safe-to-deploy" -[[exemptions.serde_spanned]] -version = "0.6.9" -criteria = "safe-to-deploy" - -[[exemptions.serde_spanned]] -version = "1.0.2" -criteria = "safe-to-deploy" - [[exemptions.serde_urlencoded]] version = "0.7.1" criteria = "safe-to-deploy" @@ -1106,10 +834,6 @@ criteria = "safe-to-deploy" version = "3.14.1" criteria = "safe-to-deploy" -[[exemptions.serde_yaml]] -version = "0.9.34+deprecated" -criteria = "safe-to-deploy" - [[exemptions.serial_test]] version = "3.2.0" criteria = "safe-to-run" @@ -1146,10 +870,6 @@ criteria = "safe-to-deploy" version = "0.6.3" criteria = "safe-to-deploy" -[[exemptions.slab]] -version = "0.4.11" -criteria = "safe-to-deploy" - [[exemptions.snafu]] version = "0.8.9" criteria = "safe-to-deploy" @@ -1162,10 +882,6 @@ criteria = "safe-to-deploy" version = "0.6.0" criteria = "safe-to-deploy" -[[exemptions.starbase_styles]] -version = "0.6.3" -criteria = "safe-to-deploy" - [[exemptions.strict]] version = "0.2.0" criteria = "safe-to-deploy" @@ -1178,14 +894,6 @@ criteria = "safe-to-deploy" version = "0.2.1" criteria = "safe-to-deploy" -[[exemptions.supports-color]] -version = "3.0.2" -criteria = "safe-to-deploy" - -[[exemptions.syn]] -version = "2.0.106" -criteria = "safe-to-deploy" - [[exemptions.sync_wrapper]] version = "1.0.2" criteria = "safe-to-deploy" @@ -1194,18 +902,10 @@ criteria = "safe-to-deploy" version = "5.2.0" criteria = "safe-to-deploy" -[[exemptions.tabwriter]] -version = "1.4.1" -criteria = "safe-to-deploy" - [[exemptions.tempfile]] version = "3.22.0" criteria = "safe-to-deploy" -[[exemptions.termcolor]] -version = "1.4.1" -criteria = "safe-to-deploy" - [[exemptions.termimad]] version = "0.34.0" criteria = "safe-to-deploy" @@ -1230,14 +930,6 @@ criteria = "safe-to-deploy" version = "0.2.18" criteria = "safe-to-deploy" -[[exemptions.thiserror]] -version = "2.0.16" -criteria = "safe-to-deploy" - -[[exemptions.thiserror-impl]] -version = "2.0.16" -criteria = "safe-to-deploy" - [[exemptions.thousands]] version = "0.2.0" criteria = "safe-to-deploy" @@ -1262,72 +954,28 @@ criteria = "safe-to-deploy" version = "1.10.0" criteria = "safe-to-deploy" -[[exemptions.tokio]] -version = "1.47.1" -criteria = "safe-to-deploy" - -[[exemptions.tokio-macros]] -version = "2.5.0" -criteria = "safe-to-deploy" - [[exemptions.tokio-rustls]] version = "0.26.3" criteria = "safe-to-deploy" -[[exemptions.tokio-util]] -version = "0.7.16" -criteria = "safe-to-deploy" - -[[exemptions.toml]] -version = "0.5.11" -criteria = "safe-to-deploy" - -[[exemptions.toml]] -version = "0.8.23" -criteria = "safe-to-deploy" - -[[exemptions.toml]] -version = "0.9.7" -criteria = "safe-to-deploy" - -[[exemptions.toml_datetime]] -version = "0.6.11" -criteria = "safe-to-deploy" - -[[exemptions.toml_datetime]] -version = "0.7.2" -criteria = "safe-to-deploy" - -[[exemptions.toml_edit]] -version = "0.22.27" -criteria = "safe-to-deploy" - -[[exemptions.toml_parser]] -version = "1.0.3" -criteria = "safe-to-deploy" - -[[exemptions.toml_write]] -version = "0.1.2" -criteria = "safe-to-deploy" - -[[exemptions.toml_writer]] -version = "1.0.3" +[[exemptions.tower-layer]] +version = "0.3.3" criteria = "safe-to-deploy" -[[exemptions.tower]] -version = "0.5.2" +[[exemptions.tower-service]] +version = "0.3.3" criteria = "safe-to-deploy" -[[exemptions.tower-http]] -version = "0.6.6" +[[exemptions.tracing]] +version = "0.1.44" criteria = "safe-to-deploy" -[[exemptions.tower-layer]] -version = "0.3.3" +[[exemptions.tracing-attributes]] +version = "0.1.31" criteria = "safe-to-deploy" -[[exemptions.tower-service]] -version = "0.3.3" +[[exemptions.tracing-core]] +version = "0.1.36" criteria = "safe-to-deploy" [[exemptions.tracing-serde]] @@ -1338,42 +986,18 @@ criteria = "safe-to-deploy" version = "2.0.2" criteria = "safe-to-deploy" -[[exemptions.typeid]] -version = "1.0.3" -criteria = "safe-to-deploy" - [[exemptions.typenum]] version = "1.18.0" criteria = "safe-to-deploy" -[[exemptions.typetag]] -version = "0.2.20" -criteria = "safe-to-deploy" - -[[exemptions.typetag-impl]] -version = "0.2.20" -criteria = "safe-to-deploy" - -[[exemptions.ucd-trie]] -version = "0.1.7" -criteria = "safe-to-deploy" - [[exemptions.unicode-general-category]] version = "1.1.0" criteria = "safe-to-deploy" -[[exemptions.unicode-ident]] -version = "1.0.19" -criteria = "safe-to-deploy" - [[exemptions.unicode_categories]] version = "0.1.1" criteria = "safe-to-deploy" -[[exemptions.unsafe-libyaml]] -version = "0.2.11" -criteria = "safe-to-deploy" - [[exemptions.untrusted]] version = "0.9.0" criteria = "safe-to-deploy" @@ -1398,14 +1022,6 @@ criteria = "safe-to-deploy" version = "0.14.1" criteria = "safe-to-deploy" -[[exemptions.walkdir]] -version = "2.5.0" -criteria = "safe-to-deploy" - -[[exemptions.wasi]] -version = "0.11.1+wasi-snapshot-preview1" -criteria = "safe-to-deploy" - [[exemptions.wasm-bindgen]] version = "0.2.103" criteria = "safe-to-deploy" @@ -1458,126 +1074,10 @@ criteria = "safe-to-deploy" version = "0.4.0" criteria = "safe-to-deploy" -[[exemptions.winapi-util]] -version = "0.1.11" -criteria = "safe-to-deploy" - [[exemptions.winapi-x86_64-pc-windows-gnu]] version = "0.4.0" criteria = "safe-to-deploy" -[[exemptions.windows]] -version = "0.56.0" -criteria = "safe-to-deploy" - -[[exemptions.windows-core]] -version = "0.56.0" -criteria = "safe-to-deploy" - -[[exemptions.windows-implement]] -version = "0.56.0" -criteria = "safe-to-deploy" - -[[exemptions.windows-interface]] -version = "0.56.0" -criteria = "safe-to-deploy" - -[[exemptions.windows-result]] -version = "0.1.2" -criteria = "safe-to-deploy" - -[[exemptions.windows-sys]] -version = "0.52.0" -criteria = "safe-to-deploy" - -[[exemptions.windows-sys]] -version = "0.59.0" -criteria = "safe-to-deploy" - -[[exemptions.windows-sys]] -version = "0.60.2" -criteria = "safe-to-deploy" - -[[exemptions.windows-sys]] -version = "0.61.0" -criteria = "safe-to-deploy" - -[[exemptions.windows-targets]] -version = "0.52.6" -criteria = "safe-to-deploy" - -[[exemptions.windows-targets]] -version = "0.53.3" -criteria = "safe-to-deploy" - -[[exemptions.windows_aarch64_gnullvm]] -version = "0.52.6" -criteria = "safe-to-deploy" - -[[exemptions.windows_aarch64_gnullvm]] -version = "0.53.0" -criteria = "safe-to-deploy" - -[[exemptions.windows_aarch64_msvc]] -version = "0.52.6" -criteria = "safe-to-deploy" - -[[exemptions.windows_aarch64_msvc]] -version = "0.53.0" -criteria = "safe-to-deploy" - -[[exemptions.windows_i686_gnu]] -version = "0.52.6" -criteria = "safe-to-deploy" - -[[exemptions.windows_i686_gnu]] -version = "0.53.0" -criteria = "safe-to-deploy" - -[[exemptions.windows_i686_gnullvm]] -version = "0.52.6" -criteria = "safe-to-deploy" - -[[exemptions.windows_i686_gnullvm]] -version = "0.53.0" -criteria = "safe-to-deploy" - -[[exemptions.windows_i686_msvc]] -version = "0.52.6" -criteria = "safe-to-deploy" - -[[exemptions.windows_i686_msvc]] -version = "0.53.0" -criteria = "safe-to-deploy" - -[[exemptions.windows_x86_64_gnu]] -version = "0.52.6" -criteria = "safe-to-deploy" - -[[exemptions.windows_x86_64_gnu]] -version = "0.53.0" -criteria = "safe-to-deploy" - -[[exemptions.windows_x86_64_gnullvm]] -version = "0.52.6" -criteria = "safe-to-deploy" - -[[exemptions.windows_x86_64_gnullvm]] -version = "0.53.0" -criteria = "safe-to-deploy" - -[[exemptions.windows_x86_64_msvc]] -version = "0.52.6" -criteria = "safe-to-deploy" - -[[exemptions.windows_x86_64_msvc]] -version = "0.53.0" -criteria = "safe-to-deploy" - -[[exemptions.winnow]] -version = "0.7.13" -criteria = "safe-to-deploy" - [[exemptions.winsafe]] version = "0.0.19" criteria = "safe-to-deploy" @@ -1586,6 +1086,10 @@ criteria = "safe-to-deploy" version = "1.0.1" criteria = "safe-to-deploy" +[[exemptions.yaml_serde]] +version = "0.10.3" +criteria = "safe-to-deploy" + [[exemptions.yansi]] version = "1.0.1" criteria = "safe-to-run" diff --git a/supply-chain/imports.lock b/supply-chain/imports.lock index a421f461..2e057b9d 100644 --- a/supply-chain/imports.lock +++ b/supply-chain/imports.lock @@ -1,6 +1,68 @@ # cargo-vet imports lock +[[publisher.aho-corasick]] +version = "1.1.3" +when = "2024-03-20" +user-id = 189 +user-login = "BurntSushi" +user-name = "Andrew Gallant" + +[[publisher.anstream]] +version = "0.6.20" +when = "2025-08-05" +user-id = 6743 +user-login = "epage" +user-name = "Ed Page" + +[[publisher.anstyle]] +version = "1.0.11" +when = "2025-06-04" +user-id = 6743 +user-login = "epage" +user-name = "Ed Page" + +[[publisher.anstyle-parse]] +version = "0.2.7" +when = "2025-06-04" +user-id = 6743 +user-login = "epage" +user-name = "Ed Page" + +[[publisher.anstyle-query]] +version = "1.1.4" +when = "2025-08-05" +user-id = 6743 +user-login = "epage" +user-name = "Ed Page" + +[[publisher.anstyle-wincon]] +version = "3.0.10" +when = "2025-08-05" +user-id = 6743 +user-login = "epage" +user-name = "Ed Page" + +[[publisher.async-trait]] +version = "0.1.89" +when = "2025-08-14" +user-id = 3618 +user-login = "dtolnay" +user-name = "David Tolnay" + +[[publisher.backtrace]] +version = "0.3.75" +when = "2025-05-06" +user-id = 55123 +user-login = "rust-lang-owner" + +[[publisher.bstr]] +version = "1.12.0" +when = "2025-04-08" +user-id = 189 +user-login = "BurntSushi" +user-name = "Andrew Gallant" + [[publisher.bumpalo]] version = "3.19.0" when = "2025-06-24" @@ -8,6 +70,69 @@ user-id = 696 user-login = "fitzgen" user-name = "Nick Fitzgerald" +[[publisher.bytes]] +version = "1.10.1" +when = "2025-03-05" +user-id = 6741 +user-login = "Darksonn" +user-name = "Alice Ryhl" + +[[publisher.caseless]] +version = "0.2.2" +when = "2024-12-30" +user-id = 1139 +user-login = "Manishearth" +user-name = "Manish Goregaokar" + +[[publisher.clap]] +version = "4.5.48" +when = "2025-09-19" +user-id = 6743 +user-login = "epage" +user-name = "Ed Page" + +[[publisher.clap_builder]] +version = "4.5.48" +when = "2025-09-19" +user-id = 6743 +user-login = "epage" +user-name = "Ed Page" + +[[publisher.clap_derive]] +version = "4.5.47" +when = "2025-09-02" +user-id = 6743 +user-login = "epage" +user-name = "Ed Page" + +[[publisher.clap_lex]] +version = "0.7.5" +when = "2025-06-09" +user-id = 6743 +user-login = "epage" +user-name = "Ed Page" + +[[publisher.colorchoice]] +version = "1.0.4" +when = "2025-06-04" +user-id = 6743 +user-login = "epage" +user-name = "Ed Page" + +[[publisher.dyn-clone]] +version = "1.0.20" +when = "2025-07-27" +user-id = 3618 +user-login = "dtolnay" +user-name = "David Tolnay" + +[[publisher.dyn-hash]] +version = "0.2.2" +when = "2025-03-03" +user-id = 3618 +user-login = "dtolnay" +user-name = "David Tolnay" + [[publisher.encoding_rs]] version = "0.8.35" when = "2024-10-24" @@ -15,6 +140,556 @@ user-id = 4484 user-login = "hsivonen" user-name = "Henri Sivonen" +[[publisher.encoding_rs_io]] +version = "0.1.7" +when = "2020-02-07" +user-id = 189 +user-login = "BurntSushi" +user-name = "Andrew Gallant" + +[[publisher.erased-serde]] +version = "0.4.8" +when = "2025-09-14" +user-id = 3618 +user-login = "dtolnay" +user-name = "David Tolnay" + +[[publisher.globset]] +version = "0.4.16" +when = "2025-02-27" +user-id = 189 +user-login = "BurntSushi" +user-name = "Andrew Gallant" + +[[publisher.grep-matcher]] +version = "0.1.7" +when = "2023-11-26" +user-id = 189 +user-login = "BurntSushi" +user-name = "Andrew Gallant" + +[[publisher.grep-printer]] +version = "0.2.2" +when = "2024-09-09" +user-id = 189 +user-login = "BurntSushi" +user-name = "Andrew Gallant" + +[[publisher.grep-regex]] +version = "0.1.13" +when = "2024-09-09" +user-id = 189 +user-login = "BurntSushi" +user-name = "Andrew Gallant" + +[[publisher.grep-searcher]] +version = "0.1.14" +when = "2024-09-09" +user-id = 189 +user-login = "BurntSushi" +user-name = "Andrew Gallant" + +[[publisher.h2]] +version = "0.4.12" +when = "2025-08-06" +user-id = 359 +user-login = "seanmonstar" +user-name = "Sean McArthur" + +[[publisher.hashbrown]] +version = "0.15.5" +when = "2025-08-07" +user-id = 55123 +user-login = "rust-lang-owner" + +[[publisher.hashbrown]] +version = "0.16.1" +when = "2025-11-20" +user-id = 55123 +user-login = "rust-lang-owner" + +[[publisher.http]] +version = "1.3.1" +when = "2025-03-11" +user-id = 359 +user-login = "seanmonstar" +user-name = "Sean McArthur" + +[[publisher.http-body-util]] +version = "0.1.3" +when = "2025-03-11" +user-id = 359 +user-login = "seanmonstar" +user-name = "Sean McArthur" + +[[publisher.httparse]] +version = "1.10.1" +when = "2025-03-03" +user-id = 359 +user-login = "seanmonstar" +user-name = "Sean McArthur" + +[[publisher.hyper]] +version = "1.7.0" +when = "2025-08-18" +user-id = 359 +user-login = "seanmonstar" +user-name = "Sean McArthur" + +[[publisher.hyper-util]] +version = "0.1.17" +when = "2025-09-15" +user-id = 359 +user-login = "seanmonstar" +user-name = "Sean McArthur" + +[[publisher.ignore]] +version = "0.4.23" +when = "2024-09-09" +user-id = 189 +user-login = "BurntSushi" +user-name = "Andrew Gallant" + +[[publisher.indexmap]] +version = "2.13.0" +when = "2026-01-07" +user-id = 539 +user-login = "cuviper" +user-name = "Josh Stone" + +[[publisher.indoc]] +version = "2.0.6" +when = "2025-03-03" +user-id = 3618 +user-login = "dtolnay" +user-name = "David Tolnay" + +[[publisher.inventory]] +version = "0.3.21" +when = "2025-08-20" +user-id = 3618 +user-login = "dtolnay" +user-name = "David Tolnay" + +[[publisher.is_terminal_polyfill]] +version = "1.70.1" +when = "2024-07-25" +user-id = 6743 +user-login = "epage" +user-name = "Ed Page" + +[[publisher.libc]] +version = "0.2.175" +when = "2025-08-11" +user-id = 55123 +user-login = "rust-lang-owner" + +[[publisher.linkme]] +version = "0.3.33" +when = "2025-05-17" +user-id = 3618 +user-login = "dtolnay" +user-name = "David Tolnay" + +[[publisher.linkme-impl]] +version = "0.3.33" +when = "2025-05-17" +user-id = 3618 +user-login = "dtolnay" +user-name = "David Tolnay" + +[[publisher.linux-raw-sys]] +version = "0.11.0" +when = "2025-09-09" +user-id = 6825 +user-login = "sunfishcode" +user-name = "Dan Gohman" + +[[publisher.lock_api]] +version = "0.4.13" +when = "2025-05-29" +user-id = 2915 +user-login = "Amanieu" +user-name = "Amanieu d'Antras" + +[[publisher.memchr]] +version = "2.7.5" +when = "2025-06-11" +user-id = 189 +user-login = "BurntSushi" +user-name = "Andrew Gallant" + +[[publisher.mime]] +version = "0.3.17" +when = "2023-03-20" +user-id = 359 +user-login = "seanmonstar" +user-name = "Sean McArthur" + +[[publisher.num]] +version = "0.4.3" +when = "2024-05-08" +user-id = 539 +user-login = "cuviper" +user-name = "Josh Stone" + +[[publisher.num-bigint]] +version = "0.4.6" +when = "2024-06-27" +user-id = 539 +user-login = "cuviper" +user-name = "Josh Stone" + +[[publisher.num-complex]] +version = "0.4.6" +when = "2024-05-07" +user-id = 539 +user-login = "cuviper" +user-name = "Josh Stone" + +[[publisher.once_cell_polyfill]] +version = "1.70.1" +when = "2025-05-22" +user-id = 6743 +user-login = "epage" +user-name = "Ed Page" + +[[publisher.openssl-probe]] +version = "0.1.6" +when = "2025-01-23" +user-id = 1 +user-login = "alexcrichton" +user-name = "Alex Crichton" + +[[publisher.ordered-float]] +version = "5.0.0" +when = "2025-02-17" +user-id = 2017 +user-login = "mbrubeck" +user-name = "Matt Brubeck" + +[[publisher.parking_lot]] +version = "0.12.4" +when = "2025-05-29" +user-id = 2915 +user-login = "Amanieu" +user-name = "Amanieu d'Antras" + +[[publisher.parking_lot_core]] +version = "0.9.11" +when = "2025-05-29" +user-id = 2915 +user-login = "Amanieu" +user-name = "Amanieu d'Antras" + +[[publisher.paste]] +version = "1.0.15" +when = "2024-05-07" +user-id = 3618 +user-login = "dtolnay" +user-name = "David Tolnay" + +[[publisher.potential_utf]] +version = "0.1.3" +when = "2025-08-28" +user-id = 1139 +user-login = "Manishearth" +user-name = "Manish Goregaokar" + +[[publisher.proc-macro2]] +version = "1.0.106" +when = "2026-01-21" +user-id = 3618 +user-login = "dtolnay" +user-name = "David Tolnay" + +[[publisher.quote]] +version = "1.0.44" +when = "2026-01-23" +user-id = 3618 +user-login = "dtolnay" +user-name = "David Tolnay" + +[[publisher.ref-cast]] +version = "1.0.24" +when = "2025-03-03" +user-id = 3618 +user-login = "dtolnay" +user-name = "David Tolnay" + +[[publisher.ref-cast-impl]] +version = "1.0.24" +when = "2025-03-03" +user-id = 3618 +user-login = "dtolnay" +user-name = "David Tolnay" + +[[publisher.regex]] +version = "1.11.2" +when = "2025-08-24" +user-id = 189 +user-login = "BurntSushi" +user-name = "Andrew Gallant" + +[[publisher.regex-automata]] +version = "0.4.10" +when = "2025-08-24" +user-id = 189 +user-login = "BurntSushi" +user-name = "Andrew Gallant" + +[[publisher.regex-syntax]] +version = "0.8.6" +when = "2025-08-24" +user-id = 189 +user-login = "BurntSushi" +user-name = "Andrew Gallant" + +[[publisher.reqwest]] +version = "0.12.23" +when = "2025-08-12" +user-id = 359 +user-login = "seanmonstar" +user-name = "Sean McArthur" + +[[publisher.rustix]] +version = "1.1.2" +when = "2025-09-09" +user-id = 6825 +user-login = "sunfishcode" +user-name = "Dan Gohman" + +[[publisher.ryu]] +version = "1.0.20" +when = "2025-03-04" +user-id = 3618 +user-login = "dtolnay" +user-name = "David Tolnay" + +[[publisher.same-file]] +version = "1.0.6" +when = "2020-01-11" +user-id = 189 +user-login = "BurntSushi" +user-name = "Andrew Gallant" + +[[publisher.scopeguard]] +version = "1.2.0" +when = "2023-07-17" +user-id = 2915 +user-login = "Amanieu" +user-name = "Amanieu d'Antras" + +[[publisher.semver]] +version = "1.0.27" +when = "2025-09-14" +user-id = 3618 +user-login = "dtolnay" +user-name = "David Tolnay" + +[[publisher.serde-untagged]] +version = "0.1.9" +when = "2025-09-14" +user-id = 3618 +user-login = "dtolnay" +user-name = "David Tolnay" + +[[publisher.serde_derive_internals]] +version = "0.29.1" +when = "2024-05-15" +user-id = 3618 +user-login = "dtolnay" +user-name = "David Tolnay" + +[[publisher.serde_json]] +version = "1.0.149" +when = "2026-01-06" +user-id = 3618 +user-login = "dtolnay" +user-name = "David Tolnay" + +[[publisher.serde_path_to_error]] +version = "0.1.20" +when = "2025-09-15" +user-id = 3618 +user-login = "dtolnay" +user-name = "David Tolnay" + +[[publisher.serde_spanned]] +version = "0.6.9" +when = "2025-06-06" +user-id = 6743 +user-login = "epage" +user-name = "Ed Page" + +[[publisher.serde_yaml]] +version = "0.9.34+deprecated" +when = "2024-03-25" +user-id = 3618 +user-login = "dtolnay" +user-name = "David Tolnay" + +[[publisher.slab]] +version = "0.4.11" +when = "2025-08-08" +user-id = 6741 +user-login = "Darksonn" +user-name = "Alice Ryhl" + +[[publisher.syn]] +version = "2.0.114" +when = "2026-01-07" +user-id = 3618 +user-login = "dtolnay" +user-name = "David Tolnay" + +[[publisher.tabwriter]] +version = "1.4.1" +when = "2025-01-05" +user-id = 189 +user-login = "BurntSushi" +user-name = "Andrew Gallant" + +[[publisher.termcolor]] +version = "1.4.1" +when = "2024-01-10" +user-id = 189 +user-login = "BurntSushi" +user-name = "Andrew Gallant" + +[[publisher.thiserror]] +version = "2.0.18" +when = "2026-01-18" +user-id = 3618 +user-login = "dtolnay" +user-name = "David Tolnay" + +[[publisher.thiserror-impl]] +version = "2.0.18" +when = "2026-01-18" +user-id = 3618 +user-login = "dtolnay" +user-name = "David Tolnay" + +[[publisher.tokio]] +version = "1.47.1" +when = "2025-08-01" +user-id = 6741 +user-login = "Darksonn" +user-name = "Alice Ryhl" + +[[publisher.tokio-macros]] +version = "2.5.0" +when = "2025-01-08" +user-id = 6741 +user-login = "Darksonn" +user-name = "Alice Ryhl" + +[[publisher.tokio-util]] +version = "0.7.16" +when = "2025-08-03" +user-id = 6741 +user-login = "Darksonn" +user-name = "Alice Ryhl" + +[[publisher.toml]] +version = "0.5.7" +when = "2020-10-11" +user-id = 1 +user-login = "alexcrichton" +user-name = "Alex Crichton" + +[[publisher.toml]] +version = "0.8.23" +when = "2025-06-06" +user-id = 6743 +user-login = "epage" +user-name = "Ed Page" + +[[publisher.toml]] +version = "0.9.11+spec-1.1.0" +when = "2026-01-09" +user-id = 6743 +user-login = "epage" +user-name = "Ed Page" + +[[publisher.toml_datetime]] +version = "0.6.11" +when = "2025-06-06" +user-id = 6743 +user-login = "epage" +user-name = "Ed Page" + +[[publisher.toml_edit]] +version = "0.22.27" +when = "2025-06-06" +user-id = 6743 +user-login = "epage" +user-name = "Ed Page" + +[[publisher.toml_parser]] +version = "1.0.6+spec-1.1.0" +when = "2025-12-18" +user-id = 6743 +user-login = "epage" +user-name = "Ed Page" + +[[publisher.toml_write]] +version = "0.1.2" +when = "2025-06-06" +user-id = 6743 +user-login = "epage" +user-name = "Ed Page" + +[[publisher.tower]] +version = "0.5.2" +when = "2024-12-11" +user-id = 359 +user-login = "seanmonstar" +user-name = "Sean McArthur" + +[[publisher.tower-http]] +version = "0.6.6" +when = "2025-06-03" +user-id = 359 +user-login = "seanmonstar" +user-name = "Sean McArthur" + +[[publisher.typeid]] +version = "1.0.3" +when = "2025-03-04" +user-id = 3618 +user-login = "dtolnay" +user-name = "David Tolnay" + +[[publisher.typetag]] +version = "0.2.20" +when = "2025-02-28" +user-id = 3618 +user-login = "dtolnay" +user-name = "David Tolnay" + +[[publisher.typetag-impl]] +version = "0.2.20" +when = "2025-02-28" +user-id = 3618 +user-login = "dtolnay" +user-name = "David Tolnay" + +[[publisher.ucd-trie]] +version = "0.1.7" +when = "2024-09-29" +user-id = 189 +user-login = "BurntSushi" +user-name = "Andrew Gallant" + +[[publisher.unicode-ident]] +version = "1.0.19" +when = "2025-09-10" +user-id = 3618 +user-login = "dtolnay" +user-name = "David Tolnay" + [[publisher.unicode-normalization]] version = "0.1.24" when = "2024-09-17" @@ -43,6 +718,20 @@ user-id = 1139 user-login = "Manishearth" user-name = "Manish Goregaokar" +[[publisher.unsafe-libyaml]] +version = "0.2.11" +when = "2024-03-17" +user-id = 3618 +user-login = "dtolnay" +user-name = "David Tolnay" + +[[publisher.url]] +version = "2.5.8" +when = "2026-01-05" +user-id = 1139 +user-login = "Manishearth" +user-name = "Manish Goregaokar" + [[publisher.utf8_iter]] version = "1.0.4" when = "2023-12-01" @@ -50,6 +739,20 @@ user-id = 4484 user-login = "hsivonen" user-name = "Henri Sivonen" +[[publisher.walkdir]] +version = "2.5.0" +when = "2024-03-01" +user-id = 189 +user-login = "BurntSushi" +user-name = "Andrew Gallant" + +[[publisher.wasi]] +version = "0.11.1+wasi-snapshot-preview1" +when = "2025-06-10" +user-id = 1 +user-login = "alexcrichton" +user-name = "Alex Crichton" + [[publisher.wasip2]] version = "1.0.1+wasi-0.2.4" when = "2025-09-15" @@ -57,12 +760,222 @@ user-id = 1 user-login = "alexcrichton" user-name = "Alex Crichton" +[[publisher.winapi-util]] +version = "0.1.11" +when = "2025-09-07" +user-id = 189 +user-login = "BurntSushi" +user-name = "Andrew Gallant" + +[[publisher.windows]] +version = "0.56.0" +when = "2024-04-12" +user-id = 64539 +user-login = "kennykerr" +user-name = "Kenny Kerr" + +[[publisher.windows-core]] +version = "0.56.0" +when = "2024-04-12" +user-id = 64539 +user-login = "kennykerr" +user-name = "Kenny Kerr" + +[[publisher.windows-implement]] +version = "0.56.0" +when = "2024-04-12" +user-id = 64539 +user-login = "kennykerr" +user-name = "Kenny Kerr" + +[[publisher.windows-interface]] +version = "0.56.0" +when = "2024-04-12" +user-id = 64539 +user-login = "kennykerr" +user-name = "Kenny Kerr" + +[[publisher.windows-result]] +version = "0.1.2" +when = "2024-06-07" +user-id = 64539 +user-login = "kennykerr" +user-name = "Kenny Kerr" + +[[publisher.windows-sys]] +version = "0.52.0" +when = "2023-11-15" +user-id = 64539 +user-login = "kennykerr" +user-name = "Kenny Kerr" + +[[publisher.windows-sys]] +version = "0.59.0" +when = "2024-07-30" +user-id = 64539 +user-login = "kennykerr" +user-name = "Kenny Kerr" + +[[publisher.windows-sys]] +version = "0.60.2" +when = "2025-06-12" +user-id = 64539 +user-login = "kennykerr" +user-name = "Kenny Kerr" + +[[publisher.windows-sys]] +version = "0.61.0" +when = "2025-09-04" +user-id = 64539 +user-login = "kennykerr" +user-name = "Kenny Kerr" + +[[publisher.windows-targets]] +version = "0.52.6" +when = "2024-07-03" +user-id = 64539 +user-login = "kennykerr" +user-name = "Kenny Kerr" + +[[publisher.windows-targets]] +version = "0.53.3" +when = "2025-07-28" +user-id = 64539 +user-login = "kennykerr" +user-name = "Kenny Kerr" + +[[publisher.windows_aarch64_gnullvm]] +version = "0.52.6" +when = "2024-07-03" +user-id = 64539 +user-login = "kennykerr" +user-name = "Kenny Kerr" + +[[publisher.windows_aarch64_gnullvm]] +version = "0.53.0" +when = "2025-01-07" +user-id = 64539 +user-login = "kennykerr" +user-name = "Kenny Kerr" + +[[publisher.windows_aarch64_msvc]] +version = "0.52.6" +when = "2024-07-03" +user-id = 64539 +user-login = "kennykerr" +user-name = "Kenny Kerr" + +[[publisher.windows_aarch64_msvc]] +version = "0.53.0" +when = "2025-01-07" +user-id = 64539 +user-login = "kennykerr" +user-name = "Kenny Kerr" + +[[publisher.windows_i686_gnu]] +version = "0.52.6" +when = "2024-07-03" +user-id = 64539 +user-login = "kennykerr" +user-name = "Kenny Kerr" + +[[publisher.windows_i686_gnu]] +version = "0.53.0" +when = "2025-01-07" +user-id = 64539 +user-login = "kennykerr" +user-name = "Kenny Kerr" + +[[publisher.windows_i686_gnullvm]] +version = "0.52.6" +when = "2024-07-03" +user-id = 64539 +user-login = "kennykerr" +user-name = "Kenny Kerr" + +[[publisher.windows_i686_gnullvm]] +version = "0.53.0" +when = "2025-01-07" +user-id = 64539 +user-login = "kennykerr" +user-name = "Kenny Kerr" + +[[publisher.windows_i686_msvc]] +version = "0.52.6" +when = "2024-07-03" +user-id = 64539 +user-login = "kennykerr" +user-name = "Kenny Kerr" + +[[publisher.windows_i686_msvc]] +version = "0.53.0" +when = "2025-01-07" +user-id = 64539 +user-login = "kennykerr" +user-name = "Kenny Kerr" + +[[publisher.windows_x86_64_gnu]] +version = "0.52.6" +when = "2024-07-03" +user-id = 64539 +user-login = "kennykerr" +user-name = "Kenny Kerr" + +[[publisher.windows_x86_64_gnu]] +version = "0.53.0" +when = "2025-01-07" +user-id = 64539 +user-login = "kennykerr" +user-name = "Kenny Kerr" + +[[publisher.windows_x86_64_gnullvm]] +version = "0.52.6" +when = "2024-07-03" +user-id = 64539 +user-login = "kennykerr" +user-name = "Kenny Kerr" + +[[publisher.windows_x86_64_gnullvm]] +version = "0.53.0" +when = "2025-01-07" +user-id = 64539 +user-login = "kennykerr" +user-name = "Kenny Kerr" + +[[publisher.windows_x86_64_msvc]] +version = "0.52.6" +when = "2024-07-03" +user-id = 64539 +user-login = "kennykerr" +user-name = "Kenny Kerr" + +[[publisher.windows_x86_64_msvc]] +version = "0.53.0" +when = "2025-01-07" +user-id = 64539 +user-login = "kennykerr" +user-name = "Kenny Kerr" + +[[publisher.winnow]] +version = "0.7.13" +when = "2025-08-22" +user-id = 6743 +user-login = "epage" +user-name = "Ed Page" + [[publisher.wit-bindgen]] version = "0.43.0" when = "2025-06-24" user-id = 73222 user-login = "wasmtime-publish" +[[publisher.zmij]] +version = "1.0.17" +when = "2026-01-25" +user-id = 3618 +user-login = "dtolnay" +user-name = "David Tolnay" + [[audits.bytecode-alliance.wildcard-audits.bumpalo]] who = "Nick Fitzgerald " criteria = "safe-to-deploy" @@ -101,6 +1014,11 @@ The changes appear to be reasonable updates from Rust's stdlib imported into `allocator-api2`'s copy of this code. """ +[[audits.bytecode-alliance.audits.anyhow]] +who = "Pat Hickey " +criteria = "safe-to-deploy" +delta = "1.0.69 -> 1.0.71" + [[audits.bytecode-alliance.audits.atomic-waker]] who = "Alex Crichton " criteria = "safe-to-deploy" @@ -427,18 +1345,6 @@ criteria = "safe-to-deploy" version = "1.1.4" notes = "uses unsafe to implement thread local storage of objects" -[[audits.bytecode-alliance.audits.tracing-attributes]] -who = "Alex Crichton " -criteria = "safe-to-deploy" -delta = "0.1.28 -> 0.1.30" -notes = "Few code changes, a pretty minor update." - -[[audits.bytecode-alliance.audits.tracing-core]] -who = "Alex Crichton " -criteria = "safe-to-deploy" -delta = "0.1.33 -> 0.1.34" -notes = "Mostly just an update with Rust stylistic conventions changing. Nothing awry." - [[audits.bytecode-alliance.audits.tracing-log]] who = "Alex Crichton " criteria = "safe-to-deploy" @@ -503,6 +1409,11 @@ criteria = "safe-to-deploy" delta = "0.45.1 -> 0.46.0" notes = "The Bytecode Alliance is the author of this crate" +[[audits.embark-studios.audits.anyhow]] +who = "Johan Andersson " +criteria = "safe-to-deploy" +version = "1.0.58" + [[audits.embark-studios.audits.cfg_aliases]] who = "Johan Andersson " criteria = "safe-to-deploy" @@ -849,31 +1760,6 @@ delta = "2.0.0-beta1 -> 2.0.0-beta2" notes = "from_utf8_unchecked unsafe remove, all other unsafe not meaningfully changed" aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" -[[audits.google.audits.indexmap]] -who = "Lukasz Anforowicz " -criteria = "safe-to-deploy" -version = "2.7.1" -notes = ''' -Grepped for `-i cipher`, `-i crypto`, `'\bfs\b'`, `'\bnet\b'` -and there were no hits. - -There is a little bit of `unsafe` Rust code - the audit can be found at -https://chromium-review.googlesource.com/c/chromium/src/+/6187726/2 -''' -aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" - -[[audits.google.audits.indexmap]] -who = "Lukasz Anforowicz " -criteria = "safe-to-deploy" -delta = "2.7.1 -> 2.8.0" -notes = """ -No `unsafe` introduced or affected in: -* `indexmap_with_default!` and `indexset_with_default!` macros -* New `PartialEq` implementations -* `fn slice_eq` in `util.rs` -""" -aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" - [[audits.google.audits.itoa]] who = "Lukasz Anforowicz " criteria = "safe-to-deploy" @@ -1016,56 +1902,6 @@ delta = "0.2.9 -> 0.2.13" notes = "Audited at https://fxrev.dev/946396" aggregated-from = "https://fuchsia.googlesource.com/fuchsia/+/refs/heads/main/third_party/rust_crates/supply-chain/audits.toml?format=TEXT" -[[audits.google.audits.quote]] -who = "Lukasz Anforowicz " -criteria = "safe-to-deploy" -version = "1.0.35" -notes = """ -Grepped for "unsafe", "crypt", "cipher", "fs", "net" - there were no hits -(except for benign "net" hit in tests and "fs" hit in README.md) -""" -aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" - -[[audits.google.audits.quote]] -who = "Adrian Taylor " -criteria = "safe-to-deploy" -delta = "1.0.35 -> 1.0.36" -aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" - -[[audits.google.audits.quote]] -who = "Lukasz Anforowicz " -criteria = "safe-to-deploy" -delta = "1.0.36 -> 1.0.37" -notes = """ -The delta just 1) inlines/expands `impl ToTokens` that used to be handled via -`primitive!` macro and 2) adds `impl ToTokens` for `CStr` and `CString`. -""" -aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" - -[[audits.google.audits.quote]] -who = "Dustin J. Mitchell " -criteria = "safe-to-deploy" -delta = "1.0.37 -> 1.0.38" -notes = "Still no unsafe" -aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" - -[[audits.google.audits.quote]] -who = "Daniel Cheng " -criteria = "safe-to-deploy" -delta = "1.0.38 -> 1.0.39" -notes = "Only minor changes for clippy lints and documentation." -aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" - -[[audits.google.audits.quote]] -who = "Lukasz Anforowicz " -criteria = "safe-to-deploy" -delta = "1.0.39 -> 1.0.40" -notes = """ -The delta is just a simplification of how `tokens.extend(...)` call is made. -Still no `unsafe` anywhere. -""" -aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" - [[audits.google.audits.rand]] who = "Lukasz Anforowicz " criteria = "safe-to-deploy" @@ -1824,6 +2660,43 @@ criteria = "safe-to-deploy" delta = "0.2.20 -> 0.2.21" aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" +[[audits.mozilla.audits.anyhow]] +who = "Mike Hommey " +criteria = "safe-to-deploy" +delta = "1.0.57 -> 1.0.61" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.anyhow]] +who = "Bobby Holley " +criteria = "safe-to-deploy" +delta = "1.0.58 -> 1.0.57" +notes = "No functional differences, just CI config and docs." +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.anyhow]] +who = "Mike Hommey " +criteria = "safe-to-deploy" +delta = "1.0.61 -> 1.0.62" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.anyhow]] +who = "Mike Hommey " +criteria = "safe-to-deploy" +delta = "1.0.62 -> 1.0.68" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.anyhow]] +who = "Mike Hommey " +criteria = "safe-to-deploy" +delta = "1.0.68 -> 1.0.69" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.anyhow]] +who = "Jan-Erik Rediger " +criteria = "safe-to-deploy" +delta = "1.0.71 -> 1.0.95" +aggregated-from = "https://raw.githubusercontent.com/mozilla/glean/main/supply-chain/audits.toml" + [[audits.mozilla.audits.arraydeque]] who = "Lars Eggert " criteria = "safe-to-deploy" @@ -2151,12 +3024,6 @@ criteria = "safe-to-deploy" delta = "1.2.0 -> 1.2.1" aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" -[[audits.mozilla.audits.indexmap]] -who = "Erich Gubler " -criteria = "safe-to-deploy" -delta = "2.8.0 -> 2.11.4" -aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" - [[audits.mozilla.audits.litemap]] who = "Makoto Kato " criteria = "safe-to-deploy" @@ -2305,6 +3172,56 @@ delta = "1.1.0 -> 2.1.1" notes = "Simple hashing crate, no unsafe code." aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" +[[audits.mozilla.audits.serde]] +who = "Erich Gubler " +criteria = "safe-to-deploy" +delta = "1.0.226 -> 1.0.227" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.serde]] +who = "Jan-Erik Rediger " +criteria = "safe-to-deploy" +delta = "1.0.227 -> 1.0.228" +aggregated-from = "https://raw.githubusercontent.com/mozilla/glean/main/supply-chain/audits.toml" + +[[audits.mozilla.audits.serde_core]] +who = "Erich Gubler " +criteria = "safe-to-deploy" +delta = "1.0.226 -> 1.0.227" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.serde_core]] +who = "Jan-Erik Rediger " +criteria = "safe-to-deploy" +delta = "1.0.227 -> 1.0.228" +aggregated-from = "https://raw.githubusercontent.com/mozilla/glean/main/supply-chain/audits.toml" + +[[audits.mozilla.audits.serde_derive]] +who = "Erich Gubler " +criteria = "safe-to-deploy" +delta = "1.0.226 -> 1.0.227" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.serde_derive]] +who = "Jan-Erik Rediger " +criteria = "safe-to-deploy" +delta = "1.0.227 -> 1.0.228" +aggregated-from = "https://raw.githubusercontent.com/mozilla/glean/main/supply-chain/audits.toml" + +[[audits.mozilla.audits.serde_spanned]] +who = "Ben Dean-Kawamura " +criteria = "safe-to-deploy" +version = "1.0.3" +notes = "Relatively simple Serde trait implementations. No IO or unsafe code." +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + +[[audits.mozilla.audits.serde_spanned]] +who = "Jan-Erik Rediger " +criteria = "safe-to-deploy" +delta = "1.0.3 -> 1.0.4" +notes = "Unchanged" +aggregated-from = "https://raw.githubusercontent.com/mozilla/glean/main/supply-chain/audits.toml" + [[audits.mozilla.audits.sha2]] who = "Mike Hommey " criteria = "safe-to-deploy" @@ -2414,52 +3331,36 @@ criteria = "safe-to-deploy" delta = "0.1.0 -> 0.1.1" aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" -[[audits.mozilla.audits.tracing]] -who = "Alex Franchuk " -criteria = "safe-to-deploy" -version = "0.1.37" -notes = """ -There's only one unsafe impl, and its purpose is to ensure correct behavior by -creating a non-Send marker type (it has nothing to do with soundness). All -dependencies make sense, and no side-effectful std functions are used. -""" -aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" - -[[audits.mozilla.audits.tracing]] -who = "Mark Hammond " +[[audits.mozilla.audits.toml]] +who = "Bobby Holley " criteria = "safe-to-deploy" -delta = "0.1.37 -> 0.1.41" +delta = "0.5.7 -> 0.5.9" aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" -[[audits.mozilla.audits.tracing-attributes]] -who = "Alex Franchuk " +[[audits.mozilla.audits.toml]] +who = "Mike Hommey " criteria = "safe-to-deploy" -version = "0.1.24" -notes = "No unsafe code, macros extensively tested and produce reasonable code." +delta = "0.5.9 -> 0.5.10" aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" -[[audits.mozilla.audits.tracing-attributes]] -who = "Mark Hammond " +[[audits.mozilla.audits.toml]] +who = "Mike Hommey " criteria = "safe-to-deploy" -delta = "0.1.24 -> 0.1.28" +delta = "0.5.10 -> 0.5.11" aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" -[[audits.mozilla.audits.tracing-core]] -who = "Alex Franchuk " +[[audits.mozilla.audits.toml_datetime]] +who = "Jan-Erik Rediger " criteria = "safe-to-deploy" -version = "0.1.30" -notes = """ -Most unsafe code is in implementing non-std sync primitives. Unsafe impls are -logically correct and justified in comments, and unsafe code is sound and -justified in comments. -""" -aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" +version = "0.7.5+spec-1.1.0" +notes = "Pure data type crate with some datetime parsing. No unsafe." +aggregated-from = "https://raw.githubusercontent.com/mozilla/glean/main/supply-chain/audits.toml" -[[audits.mozilla.audits.tracing-core]] -who = "Mark Hammond " +[[audits.mozilla.audits.toml_writer]] +who = "Jan-Erik Rediger " criteria = "safe-to-deploy" -delta = "0.1.30 -> 0.1.33" -aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" +version = "1.0.6+spec-1.1.0" +aggregated-from = "https://raw.githubusercontent.com/mozilla/glean/main/supply-chain/audits.toml" [[audits.mozilla.audits.tracing-subscriber]] who = "Mark Hammond " @@ -2480,42 +3381,6 @@ delta = "2.6.0 -> 2.8.1" notes = "Update to Unicode 15.0.0" aggregated-from = "https://raw.githubusercontent.com/mozilla/glean/main/supply-chain/audits.toml" -[[audits.mozilla.audits.url]] -who = "Valentin Gosu " -criteria = "safe-to-deploy" -version = "2.4.0" -aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" - -[[audits.mozilla.audits.url]] -who = "Valentin Gosu " -criteria = "safe-to-deploy" -delta = "2.4.0 -> 2.4.1" -aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" - -[[audits.mozilla.audits.url]] -who = "Valentin Gosu " -criteria = "safe-to-deploy" -delta = "2.4.1 -> 2.5.0" -aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" - -[[audits.mozilla.audits.url]] -who = "Henri Sivonen " -criteria = "safe-to-deploy" -delta = "2.5.0 -> 2.5.1" -aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" - -[[audits.mozilla.audits.url]] -who = "Valentin Gosu " -criteria = "safe-to-deploy" -delta = "2.5.1 -> 2.5.4" -aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" - -[[audits.mozilla.audits.url]] -who = "edgul " -criteria = "safe-to-deploy" -delta = "2.5.4 -> 2.5.7" -aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" - [[audits.mozilla.audits.utf8parse]] who = "Nika Layzell " criteria = "safe-to-deploy" @@ -2660,6 +3525,28 @@ criteria = "safe-to-deploy" delta = "0.10.3 -> 0.11.1" aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" +[[audits.zcash.audits.anyhow]] +who = "Jack Grigg " +criteria = "safe-to-deploy" +delta = "1.0.95 -> 1.0.97" +aggregated-from = "https://raw.githubusercontent.com/zcash/wallet/main/supply-chain/audits.toml" + +[[audits.zcash.audits.anyhow]] +who = "Jack Grigg " +criteria = "safe-to-deploy" +delta = "1.0.97 -> 1.0.100" +notes = """ +Changes to the build script are to enable reusing the probe file within the crate, enable +more features on newer Rust versions, and catch more errors. + +Most of the changes to `unsafe` code are refactors to surrounding safe code, and not +actually altering the `unsafe` blocks. The new instances of `unsafe` are to allow errors +to be converted to `Box` in a way that supports downcasting (at the +cost of backtraces), via a new vtable method. The `unsafe` blocks in the new code appear +to match how boxing and downcasting logic is done in other existing vtable methods. +""" +aggregated-from = "https://raw.githubusercontent.com/zcash/librustzcash/main/supply-chain/audits.toml" + [[audits.zcash.audits.autocfg]] who = "Jack Grigg " criteria = "safe-to-deploy" From 211e17f79ac3d6c3fab892ff562227d2f9d93280 Mon Sep 17 00:00:00 2001 From: rgrant Date: Fri, 13 Feb 2026 23:34:35 +0000 Subject: [PATCH 06/23] 20260213 add cargo vet CI step Vetting Succeeded (269 fully audited, 1 partially audited, 257 exempted) --- .github/workflows/rust.yml | 2 +- justfile | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 9533a79b..bb144231 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -19,7 +19,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - task: [build, lint, fmt, test, docs, coverage, deny, insta, shear] + task: [build, lint, fmt, test, docs, coverage, deny, insta, shear, vet] name: ${{ matrix.task }} steps: - uses: actions/cache/restore@5a3ec84eff668545956fd18022155c47e93e2684 # v4 diff --git a/justfile b/justfile index 229743a4..93132945 100644 --- a/justfile +++ b/justfile @@ -144,7 +144,7 @@ serve-tools CONTEXT TOOL: # Run all ci tasks. [group('ci')] -ci: build-ci lint-ci fmt-ci test-ci docs-ci coverage-ci deny-ci insta-ci shear-ci +ci: build-ci lint-ci fmt-ci test-ci docs-ci coverage-ci deny-ci insta-ci shear-ci vet-ci # Build the code on CI. [group('ci')] @@ -199,6 +199,12 @@ _insta-ci-setup: (_install "cargo-nextest@" + nextest_version + " cargo-insta@" shear-ci: (_install "cargo-expand@" + expand_version) @just shear --expand +# Verify supply-chain audits on CI. +[group('ci')] +vet-ci: _install_ci_matchers + cargo install --locked cargo-vet + cargo vet --locked + @_install_ci_matchers: echo "::add-matcher::.github/matchers.json" From 7937904337a233f97ae501544ae859fc8b7574a7 Mon Sep 17 00:00:00 2001 From: rgrant Date: Fri, 13 Feb 2026 23:43:52 +0000 Subject: [PATCH 07/23] 20260213 update bytes per RUSTSEC-2026-0007 --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 15bcdfc1..d8cac2b7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -432,9 +432,9 @@ checksum = "3995eaeebcdf32f91f980d360f78732ddc061097ab4e39991ae7a6ace9194677" [[package]] name = "bytes" -version = "1.10.1" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" dependencies = [ "serde", ] From 8c1b39fbb3a6fa4ccf22f5304cb59f8a7f76c7c2 Mon Sep 17 00:00:00 2001 From: rgrant Date: Fri, 13 Feb 2026 23:45:55 +0000 Subject: [PATCH 08/23] 20260213 update time per RUSTSEC-2026-0009 --- Cargo.lock | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d8cac2b7..1a679e3e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2849,9 +2849,9 @@ dependencies = [ [[package]] name = "num-conv" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" +checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050" [[package]] name = "num-integer" @@ -4544,9 +4544,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.44" +version = "0.3.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" +checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" dependencies = [ "deranged", "itoa", @@ -4554,22 +4554,22 @@ dependencies = [ "num-conv", "num_threads", "powerfmt", - "serde", + "serde_core", "time-core", "time-macros", ] [[package]] name = "time-core" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" +checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" [[package]] name = "time-macros" -version = "0.2.24" +version = "0.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" +checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" dependencies = [ "num-conv", "time-core", From f776528932ac9c17b907c2f659756c544812b44a Mon Sep 17 00:00:00 2001 From: rgrant Date: Sat, 14 Feb 2026 00:41:15 +0000 Subject: [PATCH 09/23] 20260214 plan to excise time crate --- .agentic-shepherd/plans/excise-time-crate.md | 165 +++++++++++++++++++ supply-chain/audits.toml | 5 +- supply-chain/imports.lock | 4 +- 3 files changed, 171 insertions(+), 3 deletions(-) create mode 100644 .agentic-shepherd/plans/excise-time-crate.md diff --git a/.agentic-shepherd/plans/excise-time-crate.md b/.agentic-shepherd/plans/excise-time-crate.md new file mode 100644 index 00000000..87542938 --- /dev/null +++ b/.agentic-shepherd/plans/excise-time-crate.md @@ -0,0 +1,165 @@ +# Plan: Excise `time` crate, replace with `chrono` + +## Context + +The `time` crate is an unallowed dependency (RUSTSEC-2026-0009 and supply-chain policy). It must be completely removed from `cargo tree`. Currently it appears via: + +- **8 first-party crates** that directly depend on it +- **`bat` -> `plist` -> `time`** (transitive, no feature flag to disable) +- **`octocrab` -> `jsonwebtoken` -> `simple_asn1` -> `time`** (transitive, no feature flag to disable) + +`chrono` is already in the dependency tree transitively (via octocrab, openai_responses, rmcp). + +## Approach + +Three workstreams, all required for `cargo tree` to stop listing `time`: + +### 1. Migrate all first-party code from `time` to `chrono` + +**Type mapping:** + +| `time` | `chrono` | +|--------|----------| +| `UtcDateTime` | `DateTime` | +| `OffsetDateTime` | `DateTime` or `DateTime` | +| `Date` | `NaiveDate` | +| `UtcOffset` | `FixedOffset` or `Local` | +| `time::Duration` | `chrono::Duration` (or `TimeDelta`) | + +**Method mapping:** + +| `time` | `chrono` | +|--------|----------| +| `UtcDateTime::now()` | `Utc::now()` | +| `.unix_timestamp_nanos()` | `.timestamp_nanos_opt().unwrap()` (returns i64, not i128) | +| `UtcDateTime::from_unix_timestamp_nanos(n)` | `DateTime::from_timestamp_nanos(n)` | +| `UtcOffset::current_local_offset()` | `Local::now().offset().clone()` | +| `format_description!("[year]-[month]...")` | `"%Y-%m-..."` strftime strings | +| `.format(&desc)` | `.format("%Y-%m-...").to_string()` | +| `.parse(s, &desc)` | `NaiveDateTime::parse_from_str(s, fmt)` | +| `utc_datetime!(2024-01-01 0:00)` | `Utc.with_ymd_and_hms(2024,1,1,0,0,0).unwrap()` | +| `date!(2024-01-01)` | `NaiveDate::from_ymd_opt(2024,1,1).unwrap()` | +| `datetime!(2024-01-01 0:00 utc)` | `Utc.with_ymd_and_hms(2024,1,1,0,0,0).unwrap()` | +| `#[serde(with = "time::serde::timestamp")]` | `#[serde(with = "chrono::serde::ts_seconds")]` | +| `1.hours()` (NumericalDuration ext) | `chrono::Duration::hours(1)` | +| `.to_offset(offset)` | `.with_timezone(&offset)` | +| `.nanosecond()` | `.nanosecond()` (same) | +| `.replace_nanosecond(n)` | `.with_nanosecond(n).unwrap()` | + +**Crates to modify (Cargo.toml + source):** + +| Crate | Files | Key changes | +|-------|-------|-------------| +| **jp_id** | `Cargo.toml`, `src/lib.rs`, `src/serde.rs` | `UtcDateTime` → `DateTime`, custom serde (decisecond precision — note: chrono `timestamp_nanos_opt()` returns `i64` not `i128`, adjust divisor logic) | +| **jp_conversation** | `Cargo.toml`, `src/event.rs`, `src/conversation.rs`, `src/stream.rs` | `UtcDateTime` → `DateTime`, serde annotations | +| **jp_format** | `Cargo.toml`, `src/datetime.rs`, `src/conversation.rs` | `UtcDateTime`/`UtcOffset` → `DateTime`/`FixedOffset`, format strings, local offset | +| **jp_openrouter** | `Cargo.toml`, `src/types/response.rs` | `OffsetDateTime` → `DateTime`, `time::serde::timestamp` → `chrono::serde::ts_seconds` | +| **jp_llm** | `Cargo.toml`, `src/model.rs`, `src/provider/openai.rs`, `src/provider/anthropic.rs`, `src/test.rs` | `Date` → `NaiveDate`, macro literals → constructor calls | +| **jp_storage** | `Cargo.toml`, `src/lib.rs` | `UtcDateTime` → `DateTime`, format/parse strings | +| **jp_workspace** | `Cargo.toml`, `src/lib.rs` | `UtcDateTime` → `DateTime` | +| **jp_cli** | `Cargo.toml`, `src/cmd/conversation/ls.rs`, `src/editor.rs`, `src/ctx.rs`, `src/cmd/conversation/fork.rs`, `src/cmd/conversation/edit.rs`, `src/cmd/query.rs` | `UtcDateTime`/`UtcOffset` → chrono types | +| **tools** | `.config/jp/tools/Cargo.toml`, `src/github/pulls.rs`, `src/github/issues.rs` | `OffsetDateTime` → `DateTime` or `DateTime` | + +**Workspace root `Cargo.toml`:** Remove `time` from `[workspace.dependencies]`, add `chrono` with needed features (`serde`). + +**Special attention — `jp_id/src/serde.rs`:** The custom decisecond serializer uses `i128` from `unix_timestamp_nanos()`. Chrono's `timestamp_nanos_opt()` returns `Option`. This is fine for dates within ~292 years of epoch. The divisor math stays the same but types change from `i128` to `i64`. + +### 2. Replace `bat` with `syntect` (eliminates `bat` -> `plist` -> `time`) + +**Scope:** bat is used in exactly one place: `crates/jp_term/src/code.rs` via `PrettyPrinter`. It syntax-highlights code blocks for terminal output. + +**Files to modify:** +- `Cargo.toml` (workspace): Remove `bat`, add `syntect` +- `crates/jp_term/Cargo.toml`: Replace `bat` with `syntect` +- `crates/jp_term/src/code.rs`: Rewrite `format()` using syntect directly +- `crates/jp_cli/Cargo.toml`: Remove `bat` dependency (only needed it for error type) +- `crates/jp_cli/src/error.rs`: Remove `Bat` error variant, add syntect equivalent +- `crates/jp_cli/src/cmd.rs`: Remove bat error conversion macro + +**Implementation sketch for `code.rs`:** +```rust +use syntect::highlighting::ThemeSet; +use syntect::parsing::SyntaxSet; +use syntect::html::ClassedHTMLGenerator; // or terminal output +use syntect::util::as_24bit_terminal_escaped; +use syntect::easy::HighlightLines; + +pub fn format(content: &str, buf: &mut String, config: &Config) -> Result { + let ss = SyntaxSet::load_defaults_newlines(); + let ts = ThemeSet::load_defaults(); + let syntax = match config.language.as_deref() { + Some(lang) => match ss.find_syntax_by_token(lang) { + Some(s) => s, + None => return Ok(false), // unknown syntax + }, + None => return Ok(false), + }; + let theme = config.theme.as_deref() + .and_then(|t| ts.themes.get(t)) + .unwrap_or_else(|| &ts.themes["base16-ocean.dark"]); + let mut h = HighlightLines::new(syntax, theme); + for line in LinesWithEndings::from(content) { + let ranges = h.highlight_line(line, &ss)?; + let escaped = as_24bit_terminal_escaped(&ranges, config.theme.is_some()); + buf.push_str(&escaped); + } + Ok(true) +} +``` + +**Note:** Need to check if syntect itself pulls in plist. If it does (for loading .tmTheme/.tmLanguage files), use `syntect` with `default-syntaxes` and `default-themes` features which embed assets and may not need plist at runtime. Will verify during implementation. + +### 3. Replace `octocrab` with raw `reqwest` + `serde` (eliminates `octocrab` -> `jsonwebtoken` -> `simple_asn1` -> `time`) + +**Scope:** octocrab is used only in `.config/jp/tools/src/github/`. reqwest is already a dependency of the tools crate. + +**Files to modify:** +- `Cargo.toml` (workspace): Remove `octocrab` +- `.config/jp/tools/Cargo.toml`: Remove `octocrab` +- `.config/jp/tools/src/github.rs`: Replace auth init with reqwest client setup +- `.config/jp/tools/src/github/pulls.rs`: Replace octocrab calls with reqwest +- `.config/jp/tools/src/github/issues.rs`: Replace octocrab calls with reqwest +- `.config/jp/tools/src/github/create_issue_bug.rs`: Replace octocrab calls with reqwest +- `.config/jp/tools/src/github/create_issue_enhancement.rs`: Replace octocrab calls with reqwest +- `.config/jp/tools/src/github/repo.rs`: Replace octocrab calls with reqwest + GraphQL + +**Approach:** +- Create a thin `GitHubClient` struct wrapping `reqwest::Client` with base URL + auth token +- Implement pagination helper that follows GitHub `Link` headers +- Define minimal serde response structs for: PullRequest, Issue, Label, Collaborator, FileContent, DiffEntry, SearchResult +- Map each octocrab call to its REST endpoint (see table in exploration notes) +- GraphQL: POST to `https://api.github.com/graphql` with JSON body + +**Auth pattern:** +```rust +struct GitHubClient { + client: reqwest::Client, + token: String, +} +impl GitHubClient { + fn get(&self, path: &str) -> reqwest::RequestBuilder { + self.client.get(format!("https://api.github.com{path}")) + .bearer_auth(&self.token) + .header("Accept", "application/vnd.github+json") + .header("User-Agent", "jp-tools") + } +} +``` + +## Verification + +1. `cargo build` — compiles without errors +2. `cargo test` — all tests pass +3. `cargo tree -i time` — **must return nothing** (no crate depends on time) +4. `cargo tree | grep time` — only matches like "timeout" not "time v0.3" +5. `cargo vet` — all new dependencies pass supply-chain audit +6. Manually verify syntax highlighting still works in CLI +7. Verify GitHub tool operations still work (list issues, get PR, etc.) + +## Order of Operations + +1. Migrate first-party `time` → `chrono` (largest, most mechanical change) +2. Replace `bat` → `syntect` (small, isolated) +3. Replace `octocrab` → `reqwest` (moderate, isolated to tools crate) +4. Remove `time` from workspace deps, clean up `Cargo.lock` +5. Run verification steps diff --git a/supply-chain/audits.toml b/supply-chain/audits.toml index 46038059..89be6fcb 100644 --- a/supply-chain/audits.toml +++ b/supply-chain/audits.toml @@ -1,7 +1,10 @@ # cargo-vet audits file -[audits] +[[audits.time-core]] +who = "rgrant " +criteria = "safe-to-deploy" +delta = "0.1.6 -> 0.1.8" [[trusted.aho-corasick]] criteria = "safe-to-deploy" diff --git a/supply-chain/imports.lock b/supply-chain/imports.lock index 2e057b9d..37eefac5 100644 --- a/supply-chain/imports.lock +++ b/supply-chain/imports.lock @@ -71,8 +71,8 @@ user-login = "fitzgen" user-name = "Nick Fitzgerald" [[publisher.bytes]] -version = "1.10.1" -when = "2025-03-05" +version = "1.11.1" +when = "2026-02-03" user-id = 6741 user-login = "Darksonn" user-name = "Alice Ryhl" From 42b8adf9232fca7021ab5e15c553bcde8cd328a7 Mon Sep 17 00:00:00 2001 From: rgrant Date: Mon, 16 Feb 2026 19:26:38 +0000 Subject: [PATCH 10/23] 20260216 excise bat --- .../plans/excise-time-crate-via-features.md | 95 +++++ Cargo.lock | 361 +----------------- Cargo.toml | 7 +- crates/jp_cli/Cargo.toml | 2 +- crates/jp_cli/src/cmd.rs | 4 +- crates/jp_cli/src/error.rs | 4 +- ...ts__partial_app_config_default_values.snap | 2 +- crates/jp_config/src/style/code.rs | 4 +- crates/jp_term/Cargo.toml | 2 +- crates/jp_term/src/code.rs | 56 ++- 10 files changed, 168 insertions(+), 369 deletions(-) create mode 100644 .agentic-shepherd/plans/excise-time-crate-via-features.md diff --git a/.agentic-shepherd/plans/excise-time-crate-via-features.md b/.agentic-shepherd/plans/excise-time-crate-via-features.md new file mode 100644 index 00000000..b10f84ef --- /dev/null +++ b/.agentic-shepherd/plans/excise-time-crate-via-features.md @@ -0,0 +1,95 @@ +# Plan: Excise `bat` and make `octocrab` an optional feature + +## Context + +The `time` crate has a security advisory (RUSTSEC-2026-0009) and is pulled in transitively by both `bat` (via `plist`) and `octocrab` (via `jsonwebtoken` → `simple_asn1`). + +## Part 1: Replace `bat` with `syntect` — DONE + +Rather than making `bat` an optional feature, we replaced it entirely with `syntect` (the library bat itself uses internally). This eliminates bat, plist, onig, and their transitive `time` dependency unconditionally. + +syntect is configured with `default-features = false` and only the features needed for pure-Rust terminal highlighting: `default-syntaxes`, `default-themes`, `parsing`, `regex-fancy`. The `regex-fancy` feature uses `fancy-regex` (pure Rust) instead of `regex-onig` (Oniguruma C library). The `plist-load` feature is excluded, which is what pulled in `plist` → `time`. + +### Changes made + +**`Cargo.toml` (workspace root)** +- Added `syntect` to `[workspace.dependencies]` with features: `default-syntaxes`, `default-themes`, `parsing`, `regex-fancy` +- `bat` entry remains but is now unused — should be removed + +**`crates/jp_term/Cargo.toml`** +- Removed `bat` dependency +- Added `syntect` with workspace features + +**`crates/jp_term/src/code.rs`** +- Rewrote `format()` using syntect's `HighlightLines`, `SyntaxSet::load_defaults_newlines()`, `ThemeSet::load_defaults()`, `as_24_bit_terminal_escaped()` +- `find_syntax_by_token(lang)` replaces bat's `language()` — returns `Ok(false)` for unknown syntaxes (same behavior) +- When theme is `None`, content is pushed unformatted (same as bat's `colored_output(false)`) +- When theme name is not found in syntect's bundled themes, falls back to unformatted output +- Return type changed from `Result` to `Result` + +**`crates/jp_cli/Cargo.toml`** +- Removed `bat` dependency +- Added `syntect = { workspace = true }` (needed for the error type) + +**`crates/jp_cli/src/error.rs`** +- `Bat(#[from] bat::error::Error)` → `SyntaxHighlight(#[from] syntect::Error)` + +**`crates/jp_cli/src/cmd.rs`** +- `Bat(error)` match arm → `SyntaxHighlight(error)` +- `impl_from_error!(bat::error::Error, ...)` → `impl_from_error!(syntect::Error, ...)` + +### Verified + +- `cargo check --workspace` — compiles clean +- `cargo tree -p jp_cli | grep -E 'bat |plist|onig'` — all absent + +**`crates/jp_config/src/style/code.rs`** +- Changed default theme from `"Monokai Extended"` to `"base16-mocha.dark"` (bundled in syntect) +- Updated doc comment to reference syntect instead of bat + +**`crates/jp_config/src/snapshots/jp_config__tests__partial_app_config_default_values.snap`** +- Updated snapshot to reflect new default theme + +**`Cargo.toml` (workspace root)** +- Removed `bat` from `[workspace.dependencies]` + +## Part 2: Make `octocrab` an optional feature — TODO + +All octocrab usage is isolated in `.config/jp/tools/src/github/`. The approach is to feature-gate it. + +### Changes needed + +**`.config/jp/tools/Cargo.toml`** +- Make `octocrab` optional, add a `github` feature (default-enabled): + +```toml +[features] +default = ["github"] +github = ["dep:octocrab"] + +[dependencies] +octocrab = { ..., optional = true } +``` + +**`.config/jp/tools/src/lib.rs`** +- cfg-gate the github module and add a fallback match arm: + +```rust +#[cfg(feature = "github")] +mod github; +``` + +```rust +#[cfg(feature = "github")] +s if s.starts_with("github_") => github::run(ctx, t).await, +#[cfg(not(feature = "github"))] +s if s.starts_with("github_") => Err("GitHub tools require the `github` feature.".into()), +``` + +The `github.rs` module and all submodules need no changes — they are entirely compiled out by the module-level cfg gate. + +### Verification + +1. `cargo check --workspace` — compiles with defaults (github enabled) +2. `cargo check -p tools --no-default-features` — compiles without octocrab +3. `cargo tree -p tools --no-default-features | grep octocrab` — octocrab absent diff --git a/Cargo.lock b/Cargo.lock index 1a679e3e..e9cd40a7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -64,15 +64,6 @@ dependencies = [ "ansitok", ] -[[package]] -name = "ansi_colours" -version = "1.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14eec43e0298190790f41679fe69ef7a829d2a2ddd78c8c00339e84710e435fe" -dependencies = [ - "rgb", -] - [[package]] name = "ansitok" version = "0.3.0" @@ -313,43 +304,6 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" -[[package]] -name = "bat" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab792c2ad113a666f08856c88cdec0a62d732559b1f3982eedf0142571e669a" -dependencies = [ - "ansi_colours", - "anyhow", - "bincode", - "bytesize", - "clircle", - "console 0.15.11", - "content_inspector", - "encoding_rs", - "flate2", - "globset", - "home", - "indexmap", - "itertools 0.13.0", - "nu-ansi-term", - "once_cell", - "path_abs", - "plist", - "regex", - "semver", - "serde", - "serde_derive", - "serde_with", - "serde_yaml", - "syntect", - "terminal-colorsaurus", - "thiserror 1.0.69", - "toml 0.8.23", - "unicode-width 0.1.14", - "walkdir", -] - [[package]] name = "bincode" version = "1.3.3" @@ -374,12 +328,6 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - [[package]] name = "bitflags" version = "2.9.4" @@ -424,12 +372,6 @@ version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "175812e0be2bccb6abe50bb8d566126198344f707e304f45c648fd8f2cc0365e" -[[package]] -name = "bytemuck" -version = "1.23.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3995eaeebcdf32f91f980d360f78732ddc061097ab4e39991ae7a6ace9194677" - [[package]] name = "bytes" version = "1.11.1" @@ -439,12 +381,6 @@ dependencies = [ "serde", ] -[[package]] -name = "bytesize" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e93abca9e28e0a1b9877922aacb20576e05d4679ffa78c3d6dc22a26a216659" - [[package]] name = "camino" version = "1.2.2" @@ -556,16 +492,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aaa6b4b263a5d737e9bf6b7c09b72c41a5480aec4d7219af827f6564e950b6a5" -[[package]] -name = "clircle" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d9334f725b46fb9bed8580b9b47a932587e044fadb344ed7fa98774b067ac1a" -dependencies = [ - "cfg-if", - "windows", -] - [[package]] name = "colorchoice" version = "1.0.4" @@ -616,7 +542,6 @@ dependencies = [ "encode_unicode", "libc", "once_cell", - "unicode-width 0.2.1", "windows-sys 0.59.0", ] @@ -633,15 +558,6 @@ dependencies = [ "windows-sys 0.61.0", ] -[[package]] -name = "content_inspector" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7bda66e858c683005a53a9a60c69a4aca7eeaa45d124526e389f7aec8e62f38" -dependencies = [ - "memchr", -] - [[package]] name = "convert_case" version = "0.7.1" @@ -791,7 +707,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8b9f2e4c67f833b660cdb0a3523065869fb35570177239812ed4c905aeff87b" dependencies = [ - "bitflags 2.9.4", + "bitflags", "crossterm_winapi", "derive_more", "document-features", @@ -832,16 +748,6 @@ dependencies = [ "darling_macro 0.20.11", ] -[[package]] -name = "darling" -version = "0.21.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" -dependencies = [ - "darling_core 0.21.3", - "darling_macro 0.21.3", -] - [[package]] name = "darling" version = "0.23.0" @@ -866,20 +772,6 @@ dependencies = [ "syn", ] -[[package]] -name = "darling_core" -version = "0.21.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn", -] - [[package]] name = "darling_core" version = "0.23.0" @@ -904,17 +796,6 @@ dependencies = [ "syn", ] -[[package]] -name = "darling_macro" -version = "0.21.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" -dependencies = [ - "darling_core 0.21.3", - "quote", - "syn", -] - [[package]] name = "darling_macro" version = "0.23.0" @@ -1580,15 +1461,6 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" -[[package]] -name = "home" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" -dependencies = [ - "windows-sys 0.59.0", -] - [[package]] name = "http" version = "1.3.1" @@ -1931,7 +1803,7 @@ name = "inquire" version = "0.9.1" source = "git+https://github.com/JeanMertz/inquire?branch=merged#c84710515dc4ee176bff9cae28f92d7b35ce310e" dependencies = [ - "bitflags 2.9.4", + "bitflags", "crossterm", "dyn-clone", "unicode-segmentation", @@ -1966,7 +1838,7 @@ version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "046fa2d4d00aea763528b4950358d0ead425372445dc8ff86312b3c69ff7727b" dependencies = [ - "bitflags 2.9.4", + "bitflags", "cfg-if", "libc", ] @@ -1993,15 +1865,6 @@ version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" -[[package]] -name = "itertools" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" -dependencies = [ - "either", -] - [[package]] name = "itertools" version = "0.14.0" @@ -2129,7 +1992,6 @@ version = "0.1.0" dependencies = [ "assert_matches", "async-stream", - "bat", "camino", "camino-tempfile", "clap", @@ -2145,7 +2007,7 @@ dependencies = [ "indoc", "inquire", "insta", - "itertools 0.14.0", + "itertools", "jp_attachment", "jp_attachment_bear_note", "jp_attachment_cmd_output", @@ -2177,6 +2039,7 @@ dependencies = [ "serde_json", "serial_test", "strip-ansi-escapes", + "syntect", "termimad", "test-log", "thiserror 2.0.18", @@ -2414,9 +2277,9 @@ dependencies = [ name = "jp_term" version = "0.1.0" dependencies = [ - "bat", "comfy-table", "serde_json", + "syntect", ] [[package]] @@ -2570,7 +2433,7 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb" dependencies = [ - "bitflags 2.9.4", + "bitflags", "libc", ] @@ -2981,28 +2844,6 @@ version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" -[[package]] -name = "onig" -version = "6.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "336b9c63443aceef14bea841b899035ae3abe89b7c486aaf4c5bd8aafedac3f0" -dependencies = [ - "bitflags 2.9.4", - "libc", - "once_cell", - "onig_sys", -] - -[[package]] -name = "onig_sys" -version = "69.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7f86c6eef3d6df15f23bcfb6af487cbd2fed4e5581d58d5bf1f5f8b7f6727dc" -dependencies = [ - "cc", - "pkg-config", -] - [[package]] name = "open-editor" version = "1.1.0" @@ -3126,15 +2967,6 @@ dependencies = [ "smallvec", ] -[[package]] -name = "path_abs" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05ef02f6342ac01d8a93b65f96db53fe68a92a15f41144f97fb00a9e669633c3" -dependencies = [ - "std_prelude", -] - [[package]] name = "pem" version = "3.0.5" @@ -3233,19 +3065,6 @@ version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" -[[package]] -name = "plist" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "740ebea15c5d1428f910cd1a5f52cebf8d25006245ed8ade92702f4943d91e07" -dependencies = [ - "base64 0.22.1", - "indexmap", - "quick-xml", - "serde", - "time", -] - [[package]] name = "potential_utf" version = "0.1.3" @@ -3352,7 +3171,7 @@ dependencies = [ "once_cell", "socket2", "tracing", - "windows-sys 0.52.0", + "windows-sys 0.60.2", ] [[package]] @@ -3425,7 +3244,7 @@ version = "0.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" dependencies = [ - "bitflags 2.9.4", + "bitflags", ] [[package]] @@ -3573,15 +3392,6 @@ dependencies = [ "thiserror 1.0.69", ] -[[package]] -name = "rgb" -version = "0.8.52" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c6a884d2998352bb4daf0183589aec883f16a6da1f4dde84d8e2e9a5409a1ce" -dependencies = [ - "bytemuck", -] - [[package]] name = "ring" version = "0.17.14" @@ -3632,7 +3442,7 @@ version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "165ca6e57b20e1351573e3729b958bc62f0e48025386970b6e4d29e7a7e71f3f" dependencies = [ - "bitflags 2.9.4", + "bitflags", "fallible-iterator", "fallible-streaming-iterator", "hashlink", @@ -3664,7 +3474,7 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" dependencies = [ - "bitflags 2.9.4", + "bitflags", "errno", "libc", "linux-raw-sys", @@ -3901,7 +3711,7 @@ version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cc198e42d9b7510827939c9a15f5062a0c913f3371d765977e586d2fe6c16f4a" dependencies = [ - "bitflags 2.9.4", + "bitflags", "core-foundation", "core-foundation-sys", "libc", @@ -3918,12 +3728,6 @@ dependencies = [ "libc", ] -[[package]] -name = "semver" -version = "1.0.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" - [[package]] name = "serde" version = "1.0.228" @@ -4032,15 +3836,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_spanned" -version = "0.6.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" -dependencies = [ - "serde", -] - [[package]] name = "serde_spanned" version = "1.0.4" @@ -4062,29 +3857,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_with" -version = "3.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c522100790450cf78eeac1507263d0a350d4d5b30df0c8e1fe051a10c22b376e" -dependencies = [ - "serde", - "serde_derive", - "serde_with_macros", -] - -[[package]] -name = "serde_with_macros" -version = "3.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327ada00f7d64abaac1e55a6911e90cf665aa051b9a561c7006c157f4633135e" -dependencies = [ - "darling 0.21.3", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "serde_yaml" version = "0.9.34+deprecated" @@ -4293,12 +4065,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" -[[package]] -name = "std_prelude" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8207e78455ffdf55661170876f88daf85356e4edd54e0a3dbc79586ca1e50cbe" - [[package]] name = "strict" version = "0.2.0" @@ -4365,21 +4131,19 @@ dependencies = [ [[package]] name = "syntect" -version = "5.2.0" +version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "874dcfa363995604333cf947ae9f751ca3af4522c60886774c4963943b4746b1" +checksum = "656b45c05d95a5704399aeef6bd0ddec7b2b3531b7c9e900abbf7c4d2190c925" dependencies = [ "bincode", - "bitflags 1.3.2", + "fancy-regex", "flate2", "fnv", "once_cell", - "onig", "regex-syntax", "serde", "serde_derive", - "serde_json", - "thiserror 1.0.69", + "thiserror 2.0.18", "walkdir", ] @@ -4430,32 +4194,6 @@ dependencies = [ "unicode-width 0.1.14", ] -[[package]] -name = "terminal-colorsaurus" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7afe4c174a3cbfb52ebcb11b28965daf74fe9111d4e07e40689d05af06e26e8" -dependencies = [ - "cfg-if", - "libc", - "memchr", - "mio", - "terminal-trx", - "windows-sys 0.59.0", - "xterm-color", -] - -[[package]] -name = "terminal-trx" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "975b4233aefa1b02456d5e53b22c61653c743e308c51cf4181191d8ce41753ab" -dependencies = [ - "cfg-if", - "libc", - "windows-sys 0.59.0", -] - [[package]] name = "terminal_size" version = "0.4.3" @@ -4680,19 +4418,6 @@ dependencies = [ "serde", ] -[[package]] -name = "toml" -version = "0.8.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" -dependencies = [ - "indexmap", - "serde", - "serde_spanned 0.6.9", - "toml_datetime 0.6.11", - "toml_edit", -] - [[package]] name = "toml" version = "0.9.11+spec-1.1.0" @@ -4701,22 +4426,13 @@ checksum = "f3afc9a848309fe1aaffaed6e1546a7a14de1f935dc9d89d32afd9a44bab7c46" dependencies = [ "indexmap", "serde_core", - "serde_spanned 1.0.4", - "toml_datetime 0.7.5+spec-1.1.0", + "serde_spanned", + "toml_datetime", "toml_parser", "toml_writer", "winnow", ] -[[package]] -name = "toml_datetime" -version = "0.6.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" -dependencies = [ - "serde", -] - [[package]] name = "toml_datetime" version = "0.7.5+spec-1.1.0" @@ -4726,20 +4442,6 @@ dependencies = [ "serde_core", ] -[[package]] -name = "toml_edit" -version = "0.22.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" -dependencies = [ - "indexmap", - "serde", - "serde_spanned 0.6.9", - "toml_datetime 0.6.11", - "toml_write", - "winnow", -] - [[package]] name = "toml_parser" version = "1.0.6+spec-1.1.0" @@ -4749,12 +4451,6 @@ dependencies = [ "winnow", ] -[[package]] -name = "toml_write" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" - [[package]] name = "toml_writer" version = "1.0.6+spec-1.1.0" @@ -4819,7 +4515,7 @@ version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" dependencies = [ - "bitflags 2.9.4", + "bitflags", "bytes", "futures-util", "http", @@ -5308,16 +5004,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows" -version = "0.56.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1de69df01bdf1ead2f4ac895dc77c9351aefff65b2f3db429a343f9cbf05e132" -dependencies = [ - "windows-core", - "windows-targets 0.52.6", -] - [[package]] name = "windows-core" version = "0.56.0" @@ -5543,9 +5229,6 @@ name = "winnow" version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" -dependencies = [ - "memchr", -] [[package]] name = "winsafe" @@ -5565,12 +5248,6 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" -[[package]] -name = "xterm-color" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4de5f056fb9dc8b7908754867544e26145767187aaac5a98495e88ad7cb8a80f" - [[package]] name = "yaml_serde" version = "0.10.3" diff --git a/Cargo.toml b/Cargo.toml index 3b5a3945..f0689b91 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,7 +35,6 @@ async-stream = { version = "0.3", default-features = false } async-trait = { version = "0.1", default-features = false } backon = { version = "1", default-features = false } base64 = { version = "0.22", default-features = false } -bat = { version = "0.25", default-features = false } camino = { version = "1", default-features = false } camino-tempfile = { version = "1", default-features = false } clap = { version = "4", default-features = false } @@ -99,6 +98,12 @@ sha1 = { version = "0.10", default-features = false } sha2 = { version = "0.10", default-features = false } similar = { version = "2", default-features = false } strip-ansi-escapes = { version = "0.2", default-features = false } +syntect = { version = "5.3", default-features = false, features = [ + "default-syntaxes", + "default-themes", + "parsing", + "regex-fancy", +] } termimad = { version = "0.34", default-features = false } test-log = { version = "0.2", default-features = false, features = ["trace"] } thiserror = { version = "2", default-features = false } diff --git a/crates/jp_cli/Cargo.toml b/crates/jp_cli/Cargo.toml index 92ff64b1..a5784017 100644 --- a/crates/jp_cli/Cargo.toml +++ b/crates/jp_cli/Cargo.toml @@ -37,7 +37,6 @@ jp_tool = { workspace = true } jp_workspace = { workspace = true } async-stream = { workspace = true } -bat = { workspace = true, features = ["regex-onig"] } camino = { workspace = true } clap = { workspace = true, features = [ "color", @@ -69,6 +68,7 @@ schemars = { workspace = true } serde = { workspace = true } serde_json = { workspace = true, features = ["preserve_order"] } strip-ansi-escapes = { workspace = true } +syntect = { workspace = true } termimad = { workspace = true } thiserror = { workspace = true } time = { workspace = true, features = ["local-offset"] } diff --git a/crates/jp_cli/src/cmd.rs b/crates/jp_cli/src/cmd.rs index d1980ea7..ffe3a037 100644 --- a/crates/jp_cli/src/cmd.rs +++ b/crates/jp_cli/src/cmd.rs @@ -301,7 +301,7 @@ impl From for Error { Llm(error) => return error.into(), Io(error) => return error.into(), Url(error) => return error.into(), - Bat(error) => return error.into(), + SyntaxHighlight(error) => return error.into(), Template(error) => return error.into(), Json(error) => return error.into(), Toml(error) => return error.into(), @@ -373,7 +373,7 @@ macro_rules! impl_from_error { }; } -impl_from_error!(bat::error::Error, "Error while formatting code"); +impl_from_error!(syntect::Error, "Error while formatting code"); impl_from_error!( jp_config::assignment::KvAssignmentError, "Key-value assignment error" diff --git a/crates/jp_cli/src/error.rs b/crates/jp_cli/src/error.rs index 69f500ee..de5fdc0c 100644 --- a/crates/jp_cli/src/error.rs +++ b/crates/jp_cli/src/error.rs @@ -52,8 +52,8 @@ pub(crate) enum Error { #[error("Tool error")] Tool(#[from] jp_llm::ToolError), - #[error("Bat error")] - Bat(#[from] bat::error::Error), + #[error("Syntax highlighting error")] + SyntaxHighlight(#[from] syntect::Error), #[error("Attachment error: {0}")] Attachment(String), diff --git a/crates/jp_config/src/snapshots/jp_config__tests__partial_app_config_default_values.snap b/crates/jp_config/src/snapshots/jp_config__tests__partial_app_config_default_values.snap index 6a3a60f2..b112984d 100644 --- a/crates/jp_config/src/snapshots/jp_config__tests__partial_app_config_default_values.snap +++ b/crates/jp_config/src/snapshots/jp_config__tests__partial_app_config_default_values.snap @@ -104,7 +104,7 @@ Ok( style: PartialStyleConfig { code: PartialCodeConfig { theme: Some( - "Monokai Extended", + "base16-mocha.dark", ), color: Some( true, diff --git a/crates/jp_config/src/style/code.rs b/crates/jp_config/src/style/code.rs index eabfd5e8..961a4cc8 100644 --- a/crates/jp_config/src/style/code.rs +++ b/crates/jp_config/src/style/code.rs @@ -15,8 +15,8 @@ use crate::{ pub struct CodeConfig { /// Theme to use for code blocks. /// - /// This uses the [bat](https://github.com/sharkdp/bat) theme names. - #[setting(default = "Monokai Extended")] + /// This uses [syntect](https://github.com/trishume/syntect) theme names. + #[setting(default = "base16-mocha.dark")] pub theme: String, /// Whether to colorize code blocks. diff --git a/crates/jp_term/Cargo.toml b/crates/jp_term/Cargo.toml index b016af6a..059fadf6 100644 --- a/crates/jp_term/Cargo.toml +++ b/crates/jp_term/Cargo.toml @@ -13,9 +13,9 @@ repository.workspace = true version.workspace = true [dependencies] -bat = { workspace = true, features = ["regex-onig"] } comfy-table = { workspace = true } serde_json = { workspace = true, features = ["preserve_order"] } +syntect = { workspace=true} [lints] workspace = true diff --git a/crates/jp_term/src/code.rs b/crates/jp_term/src/code.rs index c85c0ca1..0d150b7d 100644 --- a/crates/jp_term/src/code.rs +++ b/crates/jp_term/src/code.rs @@ -1,4 +1,9 @@ -use bat::PrettyPrinter; +use syntect::{ + easy::HighlightLines, + highlighting::ThemeSet, + parsing::SyntaxSet, + util::{LinesWithEndings, as_24_bit_terminal_escaped}, +}; pub struct Config { /// The language sytax to use for syntax highlighting. @@ -18,24 +23,41 @@ pub struct Config { /// # Errors /// /// Returns an error if the code block could not be formatted. -pub fn format(content: &str, buf: &mut String, config: &Config) -> Result { - let mut printer = PrettyPrinter::new(); - printer - .input_from_bytes(content.as_bytes()) - .line_numbers(false); - - if let Some(language) = config.language.as_deref() { - printer.language(language); - } +pub fn format(content: &str, buf: &mut String, config: &Config) -> Result { + let ss = SyntaxSet::load_defaults_newlines(); + + let syntax = match config.language.as_deref() { + Some(lang) => match ss.find_syntax_by_token(lang) { + Some(s) => s, + None => return Ok(false), + }, + None => ss.find_syntax_plain_text(), + }; - match config.theme.as_deref() { - Some(theme) => printer.theme(theme), - None => printer.colored_output(false), + let theme_name = match config.theme.as_deref() { + Some(name) => name, + None => { + buf.push_str(content); + return Ok(true); + } }; - match printer.print_with_writer(Some(buf)) { - Ok(_) => Ok(true), - Err(bat::error::Error::UnknownSyntax(_)) => Ok(false), - Err(e) => Err(e), + let ts = ThemeSet::load_defaults(); + let theme = match ts.themes.get(theme_name) { + Some(t) => t, + None => { + buf.push_str(content); + return Ok(true); + } + }; + + let mut h = HighlightLines::new(syntax, theme); + for line in LinesWithEndings::from(content) { + let ranges = h.highlight_line(line, &ss)?; + let escaped = as_24_bit_terminal_escaped(&ranges, true); + buf.push_str(&escaped); } + buf.push_str("\x1b[0m"); + + Ok(true) } From 0ec52ecc195d3be8b977ff51dd74cd606bffddfd Mon Sep 17 00:00:00 2001 From: rgrant Date: Mon, 16 Feb 2026 19:50:32 +0000 Subject: [PATCH 11/23] 20260216 make octocrab optional under feature named github --- .../plans/excise-time-crate-via-features.md | 95 ------------------- .config/jp/tools/Cargo.toml | 5 +- .config/jp/tools/src/lib.rs | 5 + supply-chain/audits.toml | 5 + supply-chain/imports.lock | 28 ------ 5 files changed, 14 insertions(+), 124 deletions(-) delete mode 100644 .agentic-shepherd/plans/excise-time-crate-via-features.md diff --git a/.agentic-shepherd/plans/excise-time-crate-via-features.md b/.agentic-shepherd/plans/excise-time-crate-via-features.md deleted file mode 100644 index b10f84ef..00000000 --- a/.agentic-shepherd/plans/excise-time-crate-via-features.md +++ /dev/null @@ -1,95 +0,0 @@ -# Plan: Excise `bat` and make `octocrab` an optional feature - -## Context - -The `time` crate has a security advisory (RUSTSEC-2026-0009) and is pulled in transitively by both `bat` (via `plist`) and `octocrab` (via `jsonwebtoken` → `simple_asn1`). - -## Part 1: Replace `bat` with `syntect` — DONE - -Rather than making `bat` an optional feature, we replaced it entirely with `syntect` (the library bat itself uses internally). This eliminates bat, plist, onig, and their transitive `time` dependency unconditionally. - -syntect is configured with `default-features = false` and only the features needed for pure-Rust terminal highlighting: `default-syntaxes`, `default-themes`, `parsing`, `regex-fancy`. The `regex-fancy` feature uses `fancy-regex` (pure Rust) instead of `regex-onig` (Oniguruma C library). The `plist-load` feature is excluded, which is what pulled in `plist` → `time`. - -### Changes made - -**`Cargo.toml` (workspace root)** -- Added `syntect` to `[workspace.dependencies]` with features: `default-syntaxes`, `default-themes`, `parsing`, `regex-fancy` -- `bat` entry remains but is now unused — should be removed - -**`crates/jp_term/Cargo.toml`** -- Removed `bat` dependency -- Added `syntect` with workspace features - -**`crates/jp_term/src/code.rs`** -- Rewrote `format()` using syntect's `HighlightLines`, `SyntaxSet::load_defaults_newlines()`, `ThemeSet::load_defaults()`, `as_24_bit_terminal_escaped()` -- `find_syntax_by_token(lang)` replaces bat's `language()` — returns `Ok(false)` for unknown syntaxes (same behavior) -- When theme is `None`, content is pushed unformatted (same as bat's `colored_output(false)`) -- When theme name is not found in syntect's bundled themes, falls back to unformatted output -- Return type changed from `Result` to `Result` - -**`crates/jp_cli/Cargo.toml`** -- Removed `bat` dependency -- Added `syntect = { workspace = true }` (needed for the error type) - -**`crates/jp_cli/src/error.rs`** -- `Bat(#[from] bat::error::Error)` → `SyntaxHighlight(#[from] syntect::Error)` - -**`crates/jp_cli/src/cmd.rs`** -- `Bat(error)` match arm → `SyntaxHighlight(error)` -- `impl_from_error!(bat::error::Error, ...)` → `impl_from_error!(syntect::Error, ...)` - -### Verified - -- `cargo check --workspace` — compiles clean -- `cargo tree -p jp_cli | grep -E 'bat |plist|onig'` — all absent - -**`crates/jp_config/src/style/code.rs`** -- Changed default theme from `"Monokai Extended"` to `"base16-mocha.dark"` (bundled in syntect) -- Updated doc comment to reference syntect instead of bat - -**`crates/jp_config/src/snapshots/jp_config__tests__partial_app_config_default_values.snap`** -- Updated snapshot to reflect new default theme - -**`Cargo.toml` (workspace root)** -- Removed `bat` from `[workspace.dependencies]` - -## Part 2: Make `octocrab` an optional feature — TODO - -All octocrab usage is isolated in `.config/jp/tools/src/github/`. The approach is to feature-gate it. - -### Changes needed - -**`.config/jp/tools/Cargo.toml`** -- Make `octocrab` optional, add a `github` feature (default-enabled): - -```toml -[features] -default = ["github"] -github = ["dep:octocrab"] - -[dependencies] -octocrab = { ..., optional = true } -``` - -**`.config/jp/tools/src/lib.rs`** -- cfg-gate the github module and add a fallback match arm: - -```rust -#[cfg(feature = "github")] -mod github; -``` - -```rust -#[cfg(feature = "github")] -s if s.starts_with("github_") => github::run(ctx, t).await, -#[cfg(not(feature = "github"))] -s if s.starts_with("github_") => Err("GitHub tools require the `github` feature.".into()), -``` - -The `github.rs` module and all submodules need no changes — they are entirely compiled out by the module-level cfg gate. - -### Verification - -1. `cargo check --workspace` — compiles with defaults (github enabled) -2. `cargo check -p tools --no-default-features` — compiles without octocrab -3. `cargo tree -p tools --no-default-features | grep octocrab` — octocrab absent diff --git a/.config/jp/tools/Cargo.toml b/.config/jp/tools/Cargo.toml index 76bdd81f..07791605 100644 --- a/.config/jp/tools/Cargo.toml +++ b/.config/jp/tools/Cargo.toml @@ -28,7 +28,7 @@ grep-regex = { workspace = true } grep-searcher = { workspace = true } ignore = { workspace = true } indoc = { workspace = true } -octocrab = { workspace = true, features = [ +octocrab = { workspace = true, optional = true, features = [ "default-client", "follow-redirect", "retry", @@ -52,6 +52,9 @@ time = { workspace = true, features = ["serde-human-readable"] } tokio = { workspace = true, features = ["full"] } url = { workspace = true, features = ["serde", "std"] } +[features] +github = ["dep:octocrab"] + [dev-dependencies] assert_matches = { workspace = true } camino-tempfile = { workspace = true } diff --git a/.config/jp/tools/src/lib.rs b/.config/jp/tools/src/lib.rs index c18f70a0..607c3e8d 100644 --- a/.config/jp/tools/src/lib.rs +++ b/.config/jp/tools/src/lib.rs @@ -4,6 +4,7 @@ mod cargo; mod fs; mod git; +#[cfg(feature = "github")] mod github; mod util; mod web; @@ -18,7 +19,10 @@ type Result = std::result::Result; pub async fn run(ctx: Context, t: Tool) -> util::ToolResult { match t.name.as_str() { s if s.starts_with("cargo_") => cargo::run(ctx, t).await, + #[cfg(feature = "github")] s if s.starts_with("github_") => github::run(ctx, t).await, + #[cfg(not(feature = "github"))] + s if s.starts_with("github_") => Err("GitHub tools require the `github` feature.".into()), s if s.starts_with("fs_") => fs::run(ctx, t).await, s if s.starts_with("web_") => web::run(ctx, t).await.map(Into::into), s if s.starts_with("git_") => git::run(ctx, t).await, @@ -59,6 +63,7 @@ impl Tool { self.req(key).map(Some) } + #[cfg(feature = "github")] fn opt_or_empty(&self, key: &str) -> Result> { match self.opt(key) { opt @ Ok(_) => opt, diff --git a/supply-chain/audits.toml b/supply-chain/audits.toml index 89be6fcb..34f7400d 100644 --- a/supply-chain/audits.toml +++ b/supply-chain/audits.toml @@ -1,6 +1,11 @@ # cargo-vet audits file +[[audits.syntect]] +who = "rgrant " +criteria = "safe-to-deploy" +delta = "5.2.0 -> 5.3.0" + [[audits.time-core]] who = "rgrant " criteria = "safe-to-deploy" diff --git a/supply-chain/imports.lock b/supply-chain/imports.lock index 37eefac5..a4cbdefa 100644 --- a/supply-chain/imports.lock +++ b/supply-chain/imports.lock @@ -480,13 +480,6 @@ user-id = 2915 user-login = "Amanieu" user-name = "Amanieu d'Antras" -[[publisher.semver]] -version = "1.0.27" -when = "2025-09-14" -user-id = 3618 -user-login = "dtolnay" -user-name = "David Tolnay" - [[publisher.serde-untagged]] version = "0.1.9" when = "2025-09-14" @@ -620,13 +613,6 @@ user-id = 6743 user-login = "epage" user-name = "Ed Page" -[[publisher.toml_edit]] -version = "0.22.27" -when = "2025-06-06" -user-id = 6743 -user-login = "epage" -user-name = "Ed Page" - [[publisher.toml_parser]] version = "1.0.6+spec-1.1.0" when = "2025-12-18" @@ -634,13 +620,6 @@ user-id = 6743 user-login = "epage" user-name = "Ed Page" -[[publisher.toml_write]] -version = "0.1.2" -when = "2025-06-06" -user-id = 6743 -user-login = "epage" -user-name = "Ed Page" - [[publisher.tower]] version = "0.5.2" when = "2024-12-11" @@ -767,13 +746,6 @@ user-id = 189 user-login = "BurntSushi" user-name = "Andrew Gallant" -[[publisher.windows]] -version = "0.56.0" -when = "2024-04-12" -user-id = 64539 -user-login = "kennykerr" -user-name = "Kenny Kerr" - [[publisher.windows-core]] version = "0.56.0" when = "2024-04-12" From ad95cb720a35695fcdde37c60e0ab9a9b0c5c65b Mon Sep 17 00:00:00 2001 From: rgrant Date: Mon, 16 Feb 2026 21:13:25 +0000 Subject: [PATCH 12/23] 20260216 replace time with chrono --- crates/jp_cli/Cargo.toml | 2 +- crates/jp_cli/src/cmd/conversation/edit.rs | 4 +- crates/jp_cli/src/cmd/conversation/fork.rs | 78 +++++++++++----------- crates/jp_cli/src/cmd/conversation/ls.rs | 19 +++--- crates/jp_cli/src/cmd/query.rs | 9 ++- crates/jp_cli/src/ctx.rs | 14 ++-- crates/jp_cli/src/editor.rs | 12 ++-- crates/jp_cli/src/lib.rs | 7 +- crates/jp_config/src/util.rs | 2 +- crates/jp_conversation/Cargo.toml | 2 +- crates/jp_conversation/src/conversation.rs | 71 ++++++++++++-------- crates/jp_conversation/src/event.rs | 12 ++-- crates/jp_conversation/src/lib.rs | 55 +++++++++++++++ crates/jp_conversation/src/stream.rs | 38 +++++------ crates/jp_format/Cargo.toml | 2 +- crates/jp_format/src/conversation.rs | 16 ++--- crates/jp_format/src/datetime.rs | 39 ++++++----- crates/jp_id/Cargo.toml | 2 +- crates/jp_id/src/serde.rs | 23 ++++--- crates/jp_llm/Cargo.toml | 2 +- crates/jp_llm/src/model.rs | 8 +-- crates/jp_llm/src/provider/anthropic.rs | 24 +++---- crates/jp_llm/src/provider/openai.rs | 66 +++++++++--------- crates/jp_llm/src/provider/openrouter.rs | 2 +- crates/jp_llm/src/test.rs | 12 ++-- crates/jp_openrouter/Cargo.toml | 7 +- crates/jp_openrouter/src/types/response.rs | 28 ++++++-- crates/jp_storage/Cargo.toml | 2 +- crates/jp_storage/src/lib.rs | 41 +++++++----- crates/jp_workspace/Cargo.toml | 2 +- crates/jp_workspace/src/lib.rs | 20 +++--- 31 files changed, 359 insertions(+), 262 deletions(-) diff --git a/crates/jp_cli/Cargo.toml b/crates/jp_cli/Cargo.toml index a5784017..69d91590 100644 --- a/crates/jp_cli/Cargo.toml +++ b/crates/jp_cli/Cargo.toml @@ -71,7 +71,7 @@ strip-ansi-escapes = { workspace = true } syntect = { workspace = true } termimad = { workspace = true } thiserror = { workspace = true } -time = { workspace = true, features = ["local-offset"] } +chrono = { workspace = true } timeago = { workspace = true } tokio = { workspace = true } toml = { workspace = true, features = ["preserve_order"] } diff --git a/crates/jp_cli/src/cmd/conversation/edit.rs b/crates/jp_cli/src/cmd/conversation/edit.rs index 2f2f73d0..35005372 100644 --- a/crates/jp_cli/src/cmd/conversation/edit.rs +++ b/crates/jp_cli/src/cmd/conversation/edit.rs @@ -1,12 +1,12 @@ use std::time::Duration; +use chrono::Utc; use jp_config::{ AppConfig, PartialAppConfig, ToPartial as _, model::id::PartialModelIdOrAliasConfig, }; use jp_conversation::{ConversationId, ConversationStream}; use jp_llm::{provider, structured}; use jp_printer::PrinterWriter; -use time::UtcDateTime; use crate::{Output, cmd::Success, ctx::Ctx}; @@ -70,7 +70,7 @@ impl Edit { if let Some(ephemeral) = self.expires_at { let mut conversation = ctx.workspace.try_get_conversation_mut(&id)?; let duration = ephemeral.map_or(Duration::ZERO, Into::into); - conversation.expires_at = Some(UtcDateTime::now() + duration); + conversation.expires_at = Some(Utc::now() + duration); } else if self.no_expires_at { ctx.workspace.try_get_conversation_mut(&id)?.expires_at = None; } diff --git a/crates/jp_cli/src/cmd/conversation/fork.rs b/crates/jp_cli/src/cmd/conversation/fork.rs index f01280fb..7e912bd9 100644 --- a/crates/jp_cli/src/cmd/conversation/fork.rs +++ b/crates/jp_cli/src/cmd/conversation/fork.rs @@ -1,7 +1,7 @@ use std::{str::FromStr as _, time::Duration}; +use chrono::{DateTime, Utc}; use jp_conversation::ConversationId; -use time::UtcDateTime; use crate::{Output, cmd::Success, ctx::Ctx}; @@ -20,19 +20,19 @@ pub(crate) struct Fork { /// Timestamp can be relative (5days, 2mins, etc) or absolute. Can be used /// in combination with `--until`. #[arg(long, value_parser = parse_duration)] - from: Option, + from: Option>, /// Ignore all conversation events *after* the specified timestamp. /// /// Timestamp can be relative (5days, 2mins, etc) or absolute. Can be used /// in combination with `--until`. #[arg(long, value_parser = parse_duration)] - until: Option, + until: Option>, } -fn parse_duration(s: &str) -> Result { +fn parse_duration(s: &str) -> Result, String> { humantime::Duration::from_str(s) - .map(|d| UtcDateTime::now() - Duration::from(d)) + .map(|d| Utc::now() - Duration::from(d)) .map_err(|e| e.to_string()) .or_else(|_| { humantime::parse_rfc3339_weak(s) @@ -89,6 +89,7 @@ mod tests { use assert_matches::assert_matches; use camino_tempfile::tempdir; + use chrono::TimeZone as _; use jp_config::AppConfig; use jp_conversation::{ Conversation, ConversationEvent, ConversationStream, @@ -96,7 +97,6 @@ mod tests { }; use jp_printer::Printer; use jp_workspace::Workspace; - use time::macros::utc_datetime; use tokio::runtime::Runtime; use super::*; @@ -141,8 +141,8 @@ mod tests { assert!(convs[0].2.created_at < convs[1].2.created_at); for (_, conv, stream) in &mut convs { - conv.last_activated_at = UtcDateTime::UNIX_EPOCH; - stream.created_at = UtcDateTime::UNIX_EPOCH; + conv.last_activated_at = DateTime::::UNIX_EPOCH; + stream.created_at = DateTime::::UNIX_EPOCH; } assert!(convs[0].0.timestamp() < convs[1].0.timestamp()); @@ -171,11 +171,11 @@ mod tests { ctx.workspace.get_events_mut(&id).unwrap().extend(vec![ ConversationEvent::new( ChatRequest::from("foo"), - utc_datetime!(2020-01-01 0:00), + Utc.with_ymd_and_hms(2020, 1, 1, 0, 0, 0).unwrap(), ), ConversationEvent::new( ChatResponse::message("bar"), - utc_datetime!(2020-01-01 0:01), + Utc.with_ymd_and_hms(2020, 1, 1, 0, 1, 0).unwrap(), ), ]); }, @@ -187,8 +187,8 @@ mod tests { assert!(convs[0].2.created_at < convs[1].2.created_at); for (_, conv, stream) in &mut convs { - conv.last_activated_at = UtcDateTime::UNIX_EPOCH; - stream.created_at = UtcDateTime::UNIX_EPOCH; + conv.last_activated_at = DateTime::::UNIX_EPOCH; + stream.created_at = DateTime::::UNIX_EPOCH; } assert!(convs[0].0.timestamp() < convs[1].0.timestamp()); @@ -216,11 +216,11 @@ mod tests { ctx.workspace.get_events_mut(&id).unwrap().extend(vec![ ConversationEvent::new( ChatRequest::from("foo"), - utc_datetime!(2020-01-01 0:00), + Utc.with_ymd_and_hms(2020, 1, 1, 0, 0, 0).unwrap(), ), ConversationEvent::new( ChatResponse::message("bar"), - utc_datetime!(2020-01-01 0:01), + Utc.with_ymd_and_hms(2020, 1, 1, 0, 1, 0).unwrap(), ), ]); }, @@ -235,8 +235,8 @@ mod tests { assert!(convs[0].2.created_at > convs[1].2.created_at); for (_, conv, stream) in &mut convs { - conv.last_activated_at = UtcDateTime::UNIX_EPOCH; - stream.created_at = UtcDateTime::UNIX_EPOCH; + conv.last_activated_at = DateTime::::UNIX_EPOCH; + stream.created_at = DateTime::::UNIX_EPOCH; } assert!(convs[0].0.timestamp() > convs[1].0.timestamp()); @@ -248,7 +248,7 @@ mod tests { args: Fork { id: None, activate: false, - from: Some(utc_datetime!(2020-01-01 0:01)), + from: Some(Utc.with_ymd_and_hms(2020, 1, 1, 0, 1, 0).unwrap()), until: None, }, setup: |ctx| { @@ -264,15 +264,15 @@ mod tests { ctx.workspace.get_events_mut(&id).unwrap().extend(vec![ ConversationEvent::new( ChatRequest::from("foo"), - utc_datetime!(2020-01-01 0:00), + Utc.with_ymd_and_hms(2020, 1, 1, 0, 0, 0).unwrap(), ), ConversationEvent::new( ChatResponse::message("bar"), - utc_datetime!(2020-01-01 0:01), + Utc.with_ymd_and_hms(2020, 1, 1, 0, 1, 0).unwrap(), ), ConversationEvent::new( ChatResponse::message("baz"), - utc_datetime!(2020-01-01 0:02), + Utc.with_ymd_and_hms(2020, 1, 1, 0, 2, 0).unwrap(), ), ]); }, @@ -283,11 +283,11 @@ mod tests { assert_eq!(convs[1].2.iter().count(), 2); assert_eq!( convs[0].2.first().unwrap().event.timestamp, - utc_datetime!(2020-01-01 0:00) + Utc.with_ymd_and_hms(2020, 1, 1, 0, 0, 0).unwrap() ); assert_eq!( convs[1].2.first().unwrap().event.timestamp, - utc_datetime!(2020-01-01 0:01) + Utc.with_ymd_and_hms(2020, 1, 1, 0, 1, 0).unwrap() ); }, }), @@ -296,7 +296,7 @@ mod tests { id: None, activate: false, from: None, - until: Some(utc_datetime!(2020-01-01 0:01)), + until: Some(Utc.with_ymd_and_hms(2020, 1, 1, 0, 1, 0).unwrap()), }, setup: |ctx| { let id = ConversationId::try_from(ctx.now()).unwrap(); @@ -311,15 +311,15 @@ mod tests { ctx.workspace.get_events_mut(&id).unwrap().extend(vec![ ConversationEvent::new( ChatRequest::from("foo"), - utc_datetime!(2020-01-01 0:00), + Utc.with_ymd_and_hms(2020, 1, 1, 0, 0, 0).unwrap(), ), ConversationEvent::new( ChatResponse::message("bar"), - utc_datetime!(2020-01-01 0:01), + Utc.with_ymd_and_hms(2020, 1, 1, 0, 1, 0).unwrap(), ), ConversationEvent::new( ChatResponse::message("baz"), - utc_datetime!(2020-01-01 0:02), + Utc.with_ymd_and_hms(2020, 1, 1, 0, 2, 0).unwrap(), ), ]); }, @@ -330,11 +330,11 @@ mod tests { assert_eq!(convs[1].2.iter().count(), 2); assert_eq!( convs[0].2.last().unwrap().event.timestamp, - utc_datetime!(2020-01-01 0:02) + Utc.with_ymd_and_hms(2020, 1, 1, 0, 2, 0).unwrap() ); assert_eq!( convs[1].2.last().unwrap().event.timestamp, - utc_datetime!(2020-01-01 0:01) + Utc.with_ymd_and_hms(2020, 1, 1, 0, 1, 0).unwrap() ); }, }), @@ -342,8 +342,8 @@ mod tests { args: Fork { id: None, activate: false, - from: Some(utc_datetime!(2020-01-01 0:01)), - until: Some(utc_datetime!(2020-01-01 0:02)), + from: Some(Utc.with_ymd_and_hms(2020, 1, 1, 0, 1, 0).unwrap()), + until: Some(Utc.with_ymd_and_hms(2020, 1, 1, 0, 2, 0).unwrap()), }, setup: |ctx| { let id = ConversationId::try_from(ctx.now()).unwrap(); @@ -358,19 +358,19 @@ mod tests { ctx.workspace.get_events_mut(&id).unwrap().extend(vec![ ConversationEvent::new( ChatRequest::from("foo"), - utc_datetime!(2020-01-01 0:00), + Utc.with_ymd_and_hms(2020, 1, 1, 0, 0, 0).unwrap(), ), ConversationEvent::new( ChatResponse::message("bar"), - utc_datetime!(2020-01-01 0:01), + Utc.with_ymd_and_hms(2020, 1, 1, 0, 1, 0).unwrap(), ), ConversationEvent::new( ChatResponse::message("baz"), - utc_datetime!(2020-01-01 0:02), + Utc.with_ymd_and_hms(2020, 1, 1, 0, 2, 0).unwrap(), ), ConversationEvent::new( ChatResponse::message("qux"), - utc_datetime!(2020-01-01 0:03), + Utc.with_ymd_and_hms(2020, 1, 1, 0, 3, 0).unwrap(), ), ]); }, @@ -381,19 +381,19 @@ mod tests { assert_eq!(convs[1].2.iter().count(), 2); assert_eq!( convs[0].2.first().unwrap().event.timestamp, - utc_datetime!(2020-01-01 0:00) + Utc.with_ymd_and_hms(2020, 1, 1, 0, 0, 0).unwrap() ); assert_eq!( convs[1].2.first().unwrap().event.timestamp, - utc_datetime!(2020-01-01 0:01) + Utc.with_ymd_and_hms(2020, 1, 1, 0, 1, 0).unwrap() ); assert_eq!( convs[0].2.last().unwrap().event.timestamp, - utc_datetime!(2020-01-01 0:03) + Utc.with_ymd_and_hms(2020, 1, 1, 0, 3, 0).unwrap() ); assert_eq!( convs[1].2.last().unwrap().event.timestamp, - utc_datetime!(2020-01-01 0:02) + Utc.with_ymd_and_hms(2020, 1, 1, 0, 2, 0).unwrap() ); }, }), @@ -419,7 +419,7 @@ mod tests { resume_unwind(panic); } - ctx.set_now(UtcDateTime::UNIX_EPOCH + Duration::from_secs(1)); + ctx.set_now(DateTime::::UNIX_EPOCH + Duration::from_secs(1)); let msg = assert_matches!(case.args.run(&mut ctx).unwrap(), Success::Message(msg) => msg); diff --git a/crates/jp_cli/src/cmd/conversation/ls.rs b/crates/jp_cli/src/cmd/conversation/ls.rs index 4daf2714..439296ea 100644 --- a/crates/jp_cli/src/cmd/conversation/ls.rs +++ b/crates/jp_cli/src/cmd/conversation/ls.rs @@ -1,8 +1,8 @@ +use chrono::{DateTime, FixedOffset, Local, Utc}; use comfy_table::{Cell, CellAlignment, Row}; use crossterm::style::{Color, Stylize as _}; use jp_conversation::{Conversation, ConversationId}; use jp_term::osc::hyperlink; -use time::{UtcDateTime, UtcOffset, macros::format_description}; use crate::{Output, cmd::Success, ctx::Ctx}; @@ -44,8 +44,8 @@ struct Details { id: ConversationId, title: Option, messages: usize, - last_event_at: Option, - expires_at: Option, + last_event_at: Option>, + expires_at: Option>, local: bool, } @@ -161,16 +161,15 @@ impl Ls { let last_message_at_fmt = if self.full { last_message_at .and_then(|t| { - let format = - format_description!("[year]-[month]-[day] [hour]:[minute]:[second]"); - let local_offset = UtcOffset::current_local_offset().unwrap_or(UtcOffset::UTC); + let format = "%Y-%m-%d %H:%M:%S"; + let local_offset: FixedOffset = *Local::now().offset(); - t.to_offset(local_offset).format(&format).ok() + Some(t.with_timezone(&local_offset).format(format).to_string()) }) .unwrap_or_default() } else { last_message_at.map_or_else(String::new, |t| { - let ago = (UtcDateTime::now() - t).try_into().expect("valid duration"); + let ago = (Utc::now() - t).to_std().expect("valid duration"); timeago::Formatter::new().convert(ago) }) }; @@ -182,10 +181,10 @@ impl Ls { if expires_at_column { let expires_at_fmt = expires_at.map_or_else(String::new, |t| { - if t < UtcDateTime::now() { + if t < Utc::now() { "Now".to_string() } else { - let dur = (UtcDateTime::now() - t).unsigned_abs(); + let dur = (Utc::now() - t).abs().to_std().unwrap_or_default(); timeago::Formatter::new().ago("").convert(dur) } }); diff --git a/crates/jp_cli/src/cmd/query.rs b/crates/jp_cli/src/cmd/query.rs index 1a7f74ee..fbe891d2 100644 --- a/crates/jp_cli/src/cmd/query.rs +++ b/crates/jp_cli/src/cmd/query.rs @@ -13,6 +13,7 @@ use std::{ }; use camino::{Utf8Path, Utf8PathBuf}; +use chrono::{DateTime, Utc}; use clap::{ArgAction, builder::TypedValueParser as _}; use event::StreamEventHandler; use futures::StreamExt as _; @@ -44,7 +45,6 @@ use jp_workspace::Workspace; use minijinja::{Environment, UndefinedBehavior}; use response_handler::ResponseHandler; use serde_json::Value; -use time::UtcDateTime; use tracing::{debug, error, info, trace, warn}; use super::{Output, attachment::register_attachment}; @@ -498,7 +498,7 @@ impl Query { &self, ws: &mut Workspace, cfg: Arc, - now: UtcDateTime, + now: DateTime, ) -> Result { // Store the (old) active conversation ID, so that we can restore to it, // if the current conversation is aborted early (e.g. because of an @@ -513,10 +513,9 @@ impl Query { if let Some(duration) = self.expires_in_duration() && let Some(mut conversation) = ws.get_conversation_mut(&id) { - conversation.expires_at = duration - .try_into() + conversation.expires_at = chrono::Duration::from_std(duration) .ok() - .and_then(|v| id.timestamp().checked_add(v)); + .and_then(|v| id.timestamp().checked_add_signed(v)); } debug!( diff --git a/crates/jp_cli/src/ctx.rs b/crates/jp_cli/src/ctx.rs index adb4e608..343b69df 100644 --- a/crates/jp_cli/src/ctx.rs +++ b/crates/jp_cli/src/ctx.rs @@ -4,12 +4,12 @@ use std::{ sync::Arc, }; +use chrono::{DateTime, Utc}; use jp_config::{AppConfig, PartialAppConfig, conversation::tool::ToolSource}; use jp_mcp::id::{McpServerId, McpToolId}; use jp_printer::Printer; use jp_task::TaskHandler; use jp_workspace::Workspace; -use time::UtcDateTime; use tokio::{ runtime::{Handle, Runtime}, task::JoinSet, @@ -41,7 +41,7 @@ pub(crate) struct Ctx { runtime: Runtime, #[cfg(test)] - pub(crate) stubbed_now: UtcDateTime, + pub(crate) stubbed_now: DateTime, } pub(crate) struct Term { @@ -81,23 +81,23 @@ impl Ctx { runtime, #[cfg(test)] - stubbed_now: UtcDateTime::UNIX_EPOCH, + stubbed_now: DateTime::::UNIX_EPOCH, } } #[cfg(not(test))] #[expect(clippy::unused_self)] - pub(crate) fn now(&self) -> UtcDateTime { - UtcDateTime::now() + pub(crate) fn now(&self) -> DateTime { + Utc::now() } #[cfg(test)] - pub(crate) fn now(&self) -> UtcDateTime { + pub(crate) fn now(&self) -> DateTime { self.stubbed_now } #[cfg(test)] - pub(crate) fn set_now(&mut self, now: UtcDateTime) { + pub(crate) fn set_now(&mut self, now: DateTime) { self.stubbed_now = now; } diff --git a/crates/jp_cli/src/editor.rs b/crates/jp_cli/src/editor.rs index 3993fa2b..bd2e1aa3 100644 --- a/crates/jp_cli/src/editor.rs +++ b/crates/jp_cli/src/editor.rs @@ -7,6 +7,7 @@ use std::{ }; use camino::{Utf8Path, Utf8PathBuf}; +use chrono::{FixedOffset, Local}; use duct::Expression; use jp_config::{ AppConfig, PartialAppConfig, ToPartial as _, model::parameters::PartialReasoningConfig, @@ -15,7 +16,6 @@ use jp_conversation::{ ConversationStream, event::{ChatResponse, EventKind}, }; -use time::{UtcOffset, macros::format_description}; use crate::{ editor::parser::QueryDocument, @@ -291,17 +291,17 @@ fn build_history_text(history: &ConversationStream) -> String { text.push_str("\n# Conversation History (last 10 entries)"); } - let local_offset = UtcOffset::current_local_offset().unwrap_or(UtcOffset::UTC); - let format = format_description!("[year]-[month]-[day] [hour]:[minute]:[second]"); + let local_offset: FixedOffset = *Local::now().offset(); + let format = "%Y-%m-%d %H:%M:%S"; let mut messages = vec![]; for event in history.iter().rev().take(10) { let mut buf = String::new(); let timestamp = event .timestamp - .to_offset(local_offset) - .format(&format) - .unwrap_or_else(|_| event.timestamp.to_string()); + .with_timezone(&local_offset) + .format(format) + .to_string(); let options = comrak::Options { render: comrak::options::Render { diff --git a/crates/jp_cli/src/lib.rs b/crates/jp_cli/src/lib.rs index 22ad6661..f7bf6c78 100644 --- a/crates/jp_cli/src/lib.rs +++ b/crates/jp_cli/src/lib.rs @@ -734,12 +734,7 @@ fn run_dhat() -> dhat::Profiler { .and_then(|v| String::from_utf8(v.stdout).ok()) .and_then(|v| PathBuf::from(v).parent().map(|v| v.join("tmp/profiling"))) .and_then(|v| std::fs::create_dir_all(&v).ok().map(|()| v)) - .map(|v| { - v.join(format!( - "heap-{}.json", - time::UtcDateTime::now().unix_timestamp() - )) - }) + .map(|v| v.join(format!("heap-{}.json", chrono::Utc::now().timestamp()))) .map_or_else(dhat::Profiler::new_heap, |v| { dhat::Profiler::builder().file_name(v).build() }) diff --git a/crates/jp_config/src/util.rs b/crates/jp_config/src/util.rs index 35ff2fcd..6a8e22a1 100644 --- a/crates/jp_config/src/util.rs +++ b/crates/jp_config/src/util.rs @@ -790,7 +790,7 @@ mod tests { ), ], path: "foo", - root: None, + root: Some(""), want: Ok(None), }), ("regular extends with string replace", TestCase { diff --git a/crates/jp_conversation/Cargo.toml b/crates/jp_conversation/Cargo.toml index 59bc7cd5..1a23b089 100644 --- a/crates/jp_conversation/Cargo.toml +++ b/crates/jp_conversation/Cargo.toml @@ -23,7 +23,7 @@ quick-xml = { workspace = true, features = ["serialize"] } serde = { workspace = true } serde_json = { workspace = true, features = ["preserve_order"] } thiserror = { workspace = true } -time = { workspace = true, features = ["serde-human-readable"] } +chrono = { workspace = true } tracing = { workspace = true } [dev-dependencies] diff --git a/crates/jp_conversation/src/conversation.rs b/crates/jp_conversation/src/conversation.rs index 0d5ae5a2..aa739865 100644 --- a/crates/jp_conversation/src/conversation.rs +++ b/crates/jp_conversation/src/conversation.rs @@ -2,13 +2,13 @@ use std::{fmt, str::FromStr}; +use chrono::{DateTime, Utc}; use jp_id::{ Id, NANOSECONDS_PER_DECISECOND, parts::{GlobalId, TargetId, Variant}, }; use jp_serde::skip_if; use serde::{Deserialize, Serialize}; -use time::UtcDateTime; use crate::error::{Error, Result}; @@ -20,7 +20,11 @@ pub struct Conversation { pub title: Option, /// The last time the conversation was activated. - pub last_activated_at: UtcDateTime, + #[serde( + serialize_with = "crate::serialize_dt", + deserialize_with = "crate::deserialize_dt" + )] + pub last_activated_at: DateTime, /// Whether the conversation is stored in the user or workspace storage. // TODO: rename to `user_local` @@ -37,12 +41,17 @@ pub struct Conversation { /// is in the future, garbage collection will not occur, if the timestamp is /// *exactly* now, the conversation *might* be garbage collected, but it /// might also happen at a later time, when the timestamp is in the past. - #[serde(default, skip_serializing_if = "Option::is_none")] - pub expires_at: Option, + #[serde( + default, + skip_serializing_if = "Option::is_none", + serialize_with = "crate::serialize_dt_opt", + deserialize_with = "crate::deserialize_dt_opt" + )] + pub expires_at: Option>, /// The time of the last event, or `None` if the conversation is empty. #[serde(skip)] - pub last_event_at: Option, + pub last_event_at: Option>, /// The number of events in the conversation. #[serde(skip)] @@ -52,7 +61,7 @@ pub struct Conversation { impl Default for Conversation { fn default() -> Self { Self { - last_activated_at: UtcDateTime::now(), + last_activated_at: Utc::now(), title: None, user: false, expires_at: None, @@ -81,14 +90,14 @@ impl Conversation { /// Sets whether the conversation is ephemeral. #[must_use] - pub const fn with_ephemeral(mut self, ephemeral: Option) -> Self { + pub const fn with_ephemeral(mut self, ephemeral: Option>) -> Self { self.expires_at = ephemeral; self } /// Sets the last activated at timestamp. #[must_use] - pub const fn with_last_activated_at(mut self, last_activated_at: UtcDateTime) -> Self { + pub const fn with_last_activated_at(mut self, last_activated_at: DateTime) -> Self { self.last_activated_at = last_activated_at; self } @@ -96,7 +105,7 @@ impl Conversation { /// ID wrapper for Conversation #[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)] -pub struct ConversationId(#[serde(with = "jp_id::serde")] UtcDateTime); +pub struct ConversationId(#[serde(with = "jp_id::serde")] DateTime); impl fmt::Debug for ConversationId { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -109,14 +118,17 @@ impl fmt::Debug for ConversationId { impl ConversationId { /// Get the timestamp of the conversation id. #[must_use] - pub const fn timestamp(&self) -> UtcDateTime { + pub const fn timestamp(&self) -> DateTime { self.0 } /// Get the timestamp of the conversation id as deciseconds. #[must_use] - pub fn as_deciseconds(&self) -> i128 { - self.timestamp().unix_timestamp_nanos() / i128::from(NANOSECONDS_PER_DECISECOND) + pub fn as_deciseconds(&self) -> i64 { + self.timestamp() + .timestamp_nanos_opt() + .expect("timestamp in range") + / i64::from(NANOSECONDS_PER_DECISECOND) } /// Try to create a conversation id from deciseconds. @@ -125,11 +137,13 @@ impl ConversationId { /// /// Returns an error if the deciseconds cannot be converted to a valid UTC /// timestamp. - pub fn try_from_deciseconds(deciseconds: i128) -> Result { - let timestamp = UtcDateTime::from_unix_timestamp_nanos( - deciseconds * i128::from(NANOSECONDS_PER_DECISECOND), - ) - .map_err(|e| jp_id::Error::InvalidTimestamp(e.to_string()))?; + pub fn try_from_deciseconds(deciseconds: i64) -> Result { + let nanos = deciseconds + .checked_mul(i64::from(NANOSECONDS_PER_DECISECOND)) + .ok_or_else(|| { + jp_id::Error::InvalidTimestamp("decisecond timestamp overflow".to_owned()) + })?; + let timestamp = DateTime::from_timestamp_nanos(nanos); Ok(Self(timestamp)) } @@ -141,7 +155,7 @@ impl ConversationId { /// Returns an error if the deciseconds cannot be parsed or converted to a /// valid UTC timestamp. pub fn try_from_deciseconds_str(deciseconds: impl AsRef) -> Result { - let deciseconds = deciseconds.as_ref().parse::().map_err(|_| { + let deciseconds = deciseconds.as_ref().parse::().map_err(|_| { Error::InvalidIdFormat(format!("Invalid deciseconds: {}", deciseconds.as_ref())) })?; @@ -192,16 +206,20 @@ impl ConversationId { } } -impl TryFrom for ConversationId { +impl TryFrom> for ConversationId { type Error = Error; - fn try_from(timestamp: UtcDateTime) -> Result { + fn try_from(timestamp: DateTime) -> Result { + use chrono::Timelike as _; + let nanos = timestamp.nanosecond(); let truncated_nanos = (nanos / NANOSECONDS_PER_DECISECOND) * NANOSECONDS_PER_DECISECOND; timestamp - .replace_nanosecond(truncated_nanos) - .map_err(|e| jp_id::Error::InvalidTimestamp(e.to_string()).into()) + .with_nanosecond(truncated_nanos) + .ok_or_else(|| { + jp_id::Error::InvalidTimestamp("invalid nanosecond value".to_owned()).into() + }) .map(Self) } } @@ -239,7 +257,7 @@ impl FromStr for ConversationId { impl Default for ConversationId { fn default() -> Self { - Self::try_from(UtcDateTime::now()).expect("valid timestamp") + Self::try_from(Utc::now()).expect("valid timestamp") } } @@ -271,16 +289,15 @@ impl Default for ConversationsMetadata { #[cfg(test)] mod tests { + use chrono::TimeZone as _; + use super::*; #[test] fn test_conversation_serialization() { let conv = Conversation { title: None, - last_activated_at: UtcDateTime::new( - time::Date::from_calendar_date(2023, time::Month::January, 1).unwrap(), - time::Time::MIDNIGHT, - ), + last_activated_at: Utc.with_ymd_and_hms(2023, 1, 1, 0, 0, 0).unwrap(), user: true, expires_at: None, last_event_at: None, diff --git a/crates/jp_conversation/src/event.rs b/crates/jp_conversation/src/event.rs index cd38760d..f7465772 100644 --- a/crates/jp_conversation/src/event.rs +++ b/crates/jp_conversation/src/event.rs @@ -4,10 +4,10 @@ mod chat; mod inquiry; mod tool_call; +use chrono::{DateTime, Utc}; use indexmap::IndexMap; use serde::{Deserialize, Serialize}; use serde_json::{Map, Value}; -use time::UtcDateTime; pub use self::{ chat::{ChatRequest, ChatResponse}, @@ -19,7 +19,11 @@ pub use self::{ #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct ConversationEvent { /// The timestamp of the event. - pub timestamp: UtcDateTime, + #[serde( + serialize_with = "crate::serialize_dt", + deserialize_with = "crate::deserialize_dt" + )] + pub timestamp: DateTime, /// The kind of event. #[serde(flatten)] @@ -37,7 +41,7 @@ pub struct ConversationEvent { impl ConversationEvent { /// Create a new event with the given timestamp and kind. #[must_use] - pub fn new(event: impl Into, timestamp: impl Into) -> Self { + pub fn new(event: impl Into, timestamp: impl Into>) -> Self { Self { timestamp: timestamp.into(), kind: event.into(), @@ -48,7 +52,7 @@ impl ConversationEvent { /// Create a new event with the current timestamp and kind. #[must_use] pub fn now(event: impl Into) -> Self { - Self::new(event, UtcDateTime::now()) + Self::new(event, Utc::now()) } /// Attaches metadata to the event. diff --git a/crates/jp_conversation/src/lib.rs b/crates/jp_conversation/src/lib.rs index fd9d5c4d..4361a27c 100644 --- a/crates/jp_conversation/src/lib.rs +++ b/crates/jp_conversation/src/lib.rs @@ -37,3 +37,58 @@ pub use conversation::{Conversation, ConversationId, ConversationsMetadata}; pub use error::Error; pub use event::{ConversationEvent, EventKind}; pub use stream::{ConversationStream, StreamError}; + +/// Format `DateTime` like `time`'s human-readable serde: `"2023-01-01 00:00:00.0"`. +fn fmt_dt(dt: &chrono::DateTime) -> String { + if dt.timestamp_subsec_nanos() == 0 { + return dt.format("%Y-%m-%d %H:%M:%S.0").to_string(); + } + dt.format("%Y-%m-%d %H:%M:%S.%9f") + .to_string() + .trim_end_matches('0') + .to_owned() +} + +/// Parse from `time`'s format or RFC 3339. +fn parse_dt(s: &str) -> Result, String> { + chrono::NaiveDateTime::parse_from_str(s, "%Y-%m-%d %H:%M:%S%.f") + .map(|dt| dt.and_utc()) + .or_else(|_| { + chrono::DateTime::parse_from_rfc3339(s).map(|dt| dt.with_timezone(&chrono::Utc)) + }) + .map_err(|e| e.to_string()) +} + +pub(crate) fn serialize_dt( + dt: &chrono::DateTime, + s: S, +) -> Result { + s.serialize_str(&fmt_dt(dt)) +} + +pub(crate) fn deserialize_dt<'de, D: serde::Deserializer<'de>>( + d: D, +) -> Result, D::Error> { + let s = ::deserialize(d)?; + parse_dt(&s).map_err(serde::de::Error::custom) +} + +pub(crate) fn serialize_dt_opt( + dt: &Option>, + s: S, +) -> Result { + match dt { + Some(dt) => s.serialize_some(&fmt_dt(dt)), + None => s.serialize_none(), + } +} + +pub(crate) fn deserialize_dt_opt<'de, D: serde::Deserializer<'de>>( + d: D, +) -> Result>, D::Error> { + let s: Option = serde::Deserialize::deserialize(d)?; + match s { + Some(s) => parse_dt(&s).map(Some).map_err(serde::de::Error::custom), + None => Ok(None), + } +} diff --git a/crates/jp_conversation/src/stream.rs b/crates/jp_conversation/src/stream.rs index dd075819..ebf9807d 100644 --- a/crates/jp_conversation/src/stream.rs +++ b/crates/jp_conversation/src/stream.rs @@ -2,10 +2,10 @@ use std::sync::Arc; +use chrono::{DateTime, TimeZone as _, Utc}; use jp_config::{AppConfig, Config as _, PartialAppConfig, PartialConfig as _}; use serde::{Deserialize, Serialize}; use serde_json::{Map, Value}; -use time::UtcDateTime; use tracing::error; use crate::event::{ @@ -64,7 +64,11 @@ impl InternalEvent { #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct ConfigDelta { /// The timestamp of the event. - pub timestamp: UtcDateTime, + #[serde( + serialize_with = "crate::serialize_dt", + deserialize_with = "crate::deserialize_dt" + )] + pub timestamp: DateTime, /// The configuration delta. pub delta: Box, @@ -107,7 +111,7 @@ impl From for PartialAppConfig { impl From for ConfigDelta { fn from(config: PartialAppConfig) -> Self { Self { - timestamp: UtcDateTime::now(), + timestamp: Utc::now(), delta: Box::new(config), } } @@ -130,7 +134,7 @@ pub struct ConversationStream { events: Vec, /// The timestamp of the creation of the stream. - pub created_at: UtcDateTime, + pub created_at: DateTime, } impl ConversationStream { @@ -140,7 +144,7 @@ impl ConversationStream { Self { base_config, events: Vec::new(), - created_at: UtcDateTime::now(), + created_at: Utc::now(), } } @@ -153,7 +157,7 @@ impl ConversationStream { /// Set the timestamp of the creation of the stream. #[must_use] - pub fn with_created_at(mut self, created_at: impl Into) -> Self { + pub fn with_created_at(mut self, created_at: impl Into>) -> Self { self.created_at = created_at.into(); self } @@ -478,12 +482,10 @@ impl ConversationStream { #[doc(hidden)] #[must_use] pub fn new_test() -> Self { - use time::macros::utc_datetime; - Self { base_config: AppConfig::new_test().into(), events: vec![], - created_at: utc_datetime!(2020-01-01 0:00), + created_at: Utc.with_ymd_and_hms(2020, 1, 1, 0, 0, 0).unwrap(), } } } @@ -896,42 +898,42 @@ impl<'de> Deserialize<'de> for InternalEvent { ConfigDelta(ConfigDelta), ChatRequest { - timestamp: UtcDateTime, + timestamp: DateTime, #[serde(default, with = "jp_serde::repr::base64_json_map")] metadata: Map, #[serde(flatten)] data: ChatRequest, }, ChatResponse { - timestamp: UtcDateTime, + timestamp: DateTime, #[serde(default, with = "jp_serde::repr::base64_json_map")] metadata: Map, #[serde(flatten)] data: ChatResponse, }, ToolCallRequest { - timestamp: UtcDateTime, + timestamp: DateTime, #[serde(default, with = "jp_serde::repr::base64_json_map")] metadata: Map, #[serde(flatten)] data: ToolCallRequest, }, ToolCallResponse { - timestamp: UtcDateTime, + timestamp: DateTime, #[serde(default, with = "jp_serde::repr::base64_json_map")] metadata: Map, #[serde(flatten)] data: ToolCallResponse, }, InquiryRequest { - timestamp: UtcDateTime, + timestamp: DateTime, #[serde(default, with = "jp_serde::repr::base64_json_map")] metadata: Map, #[serde(flatten)] data: InquiryRequest, }, InquiryResponse { - timestamp: UtcDateTime, + timestamp: DateTime, #[serde(default, with = "jp_serde::repr::base64_json_map")] metadata: Map, #[serde(flatten)] @@ -1004,8 +1006,6 @@ impl<'de> Deserialize<'de> for InternalEvent { #[cfg(test)] mod tests { - use time::macros::utc_datetime; - use super::*; #[test] @@ -1018,14 +1018,14 @@ mod tests { .events .push(InternalEvent::Event(Box::new(ConversationEvent::new( ChatRequest::from("foo"), - utc_datetime!(2020-01-01 0:00), + Utc.with_ymd_and_hms(2020, 1, 1, 0, 0, 0).unwrap(), )))); stream .events .push(InternalEvent::Event(Box::new(ConversationEvent::new( ChatResponse::message("bar"), - utc_datetime!(2020-01-02 0:00), + Utc.with_ymd_and_hms(2020, 1, 2, 0, 0, 0).unwrap(), )))); insta::assert_json_snapshot!(&stream); diff --git a/crates/jp_format/Cargo.toml b/crates/jp_format/Cargo.toml index 0d4d3210..1480d3ff 100644 --- a/crates/jp_format/Cargo.toml +++ b/crates/jp_format/Cargo.toml @@ -17,7 +17,7 @@ jp_conversation = { workspace = true } comfy-table = { workspace = true } crossterm = { workspace = true } -time = { workspace = true, features = ["local-offset"] } +chrono = { workspace = true } timeago = { workspace = true } [lints] diff --git a/crates/jp_format/src/conversation.rs b/crates/jp_format/src/conversation.rs index 89e558d9..4bbf43c4 100644 --- a/crates/jp_format/src/conversation.rs +++ b/crates/jp_format/src/conversation.rs @@ -1,9 +1,9 @@ use std::fmt; +use chrono::{DateTime, Utc}; use comfy_table::{Cell, CellAlignment, Row, Table}; use crossterm::style::Stylize as _; use jp_conversation::ConversationId; -use time::UtcDateTime; use crate::datetime::DateTimeFmt; @@ -27,13 +27,13 @@ pub struct DetailsFmt { pub active_conversation: Option, /// Display the timestamp of the last message in the conversation. - pub last_message_at: Option, + pub last_message_at: Option>, /// Display the last time the conversation was activated. - pub last_activated_at: Option, + pub last_activated_at: Option>, /// Display the timestamp of conversation expiration. - pub expires_at: Option, + pub expires_at: Option>, /// Use OSC-8 hyperlinks. pub hyperlinks: bool, @@ -73,19 +73,19 @@ impl DetailsFmt { } #[must_use] - pub fn with_last_message_at(mut self, last_message_at: Option) -> Self { + pub fn with_last_message_at(mut self, last_message_at: Option>) -> Self { self.last_message_at = last_message_at; self } #[must_use] - pub fn with_last_activated_at(mut self, last_activated_at: Option) -> Self { + pub fn with_last_activated_at(mut self, last_activated_at: Option>) -> Self { self.last_activated_at = last_activated_at; self } #[must_use] - pub fn with_expires_at(mut self, expires_at: Option) -> Self { + pub fn with_expires_at(mut self, expires_at: Option>) -> Self { self.expires_at = expires_at; self } @@ -166,7 +166,7 @@ impl DetailsFmt { if let Some(expires_at) = self.expires_at { map.push(( "Expires In".to_owned(), - if expires_at < UtcDateTime::now() { + if expires_at < Utc::now() { "On Deactivation".to_string() } else { DateTimeFmt::new(expires_at).to_string() diff --git a/crates/jp_format/src/datetime.rs b/crates/jp_format/src/datetime.rs index b03524de..b24ace14 100644 --- a/crates/jp_format/src/datetime.rs +++ b/crates/jp_format/src/datetime.rs @@ -1,32 +1,29 @@ use core::fmt; +use chrono::{DateTime, FixedOffset, Local, Utc}; use crossterm::style::Stylize as _; -use time::{ - UtcDateTime, UtcOffset, format_description::BorrowedFormatItem, macros::format_description, -}; -const DEFAULT_TIME_FMT: &[BorrowedFormatItem<'_>] = - format_description!("[year]-[month]-[day] [hour]:[minute]:[second]"); +const DEFAULT_TIME_FMT: &str = "%Y-%m-%d %H:%M:%S"; pub struct DateTimeFmt { - pub timestamp: UtcDateTime, - pub offset: UtcOffset, + pub timestamp: DateTime, + pub offset: FixedOffset, pub timeago: Option, - pub format: &'static [BorrowedFormatItem<'static>], + pub format: &'static str, pub color: bool, } pub enum TimeAgo { Now, - From(UtcDateTime), + From(DateTime), } impl DateTimeFmt { #[must_use] - pub fn new(timestamp: UtcDateTime) -> Self { + pub fn new(timestamp: DateTime) -> Self { Self { timestamp, - offset: UtcOffset::current_local_offset().unwrap_or(UtcOffset::UTC), + offset: *Local::now().offset(), timeago: Some(TimeAgo::Now), format: DEFAULT_TIME_FMT, color: true, @@ -34,7 +31,7 @@ impl DateTimeFmt { } #[must_use] - pub fn with_offset(self, offset: UtcOffset) -> Self { + pub fn with_offset(self, offset: FixedOffset) -> Self { Self { offset, ..self } } @@ -44,17 +41,20 @@ impl DateTimeFmt { } #[must_use] - pub fn with_time_format(self, format: &'static [BorrowedFormatItem<'static>]) -> Self { + pub fn with_time_format(self, format: &'static str) -> Self { Self { format, ..self } } } impl fmt::Display for DateTimeFmt { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let diff = UtcDateTime::now() - self.timestamp; - let is_past = diff.is_negative(); + let diff = Utc::now() - self.timestamp; + let is_past = diff.num_seconds() < 0; - let dur = (UtcDateTime::now() - self.timestamp).unsigned_abs(); + let dur = (Utc::now() - self.timestamp) + .abs() + .to_std() + .unwrap_or_default(); let mut fmt = timeago::Formatter::new(); if is_past { fmt.ago(""); @@ -63,12 +63,11 @@ impl fmt::Display for DateTimeFmt { let ago = fmt.convert(dur); let dt = self .timestamp - .to_offset(self.offset) - .format(&self.format) - .unwrap_or_default(); + .with_timezone(&self.offset) + .format(self.format); if self.color { - write!(f, "{ago} ({})", dt.italic()) + write!(f, "{ago} ({})", dt.to_string().italic()) } else { write!(f, "{ago} ({dt})") } diff --git a/crates/jp_id/Cargo.toml b/crates/jp_id/Cargo.toml index e1be4c3d..024d24bd 100644 --- a/crates/jp_id/Cargo.toml +++ b/crates/jp_id/Cargo.toml @@ -15,7 +15,7 @@ version.workspace = true [dependencies] serde = { workspace = true } thiserror = { workspace = true } -time = { workspace = true, features = ["macros", "formatting", "parsing"] } +chrono = { workspace = true } [dev-dependencies] test-log = { workspace = true } diff --git a/crates/jp_id/src/serde.rs b/crates/jp_id/src/serde.rs index 3c7fc585..d1274137 100644 --- a/crates/jp_id/src/serde.rs +++ b/crates/jp_id/src/serde.rs @@ -1,22 +1,27 @@ +use chrono::{DateTime, Utc}; use serde::{Deserialize, Deserializer, Serialize, Serializer, de}; -use time::UtcDateTime; use crate::NANOSECONDS_PER_DECISECOND; -/// Serialize an `UtcDateTime` as its Unix timestamp with deciseconds. +/// Serialize a `DateTime` as its Unix timestamp with deciseconds. pub fn serialize( - datetime: &UtcDateTime, + datetime: &DateTime, serializer: S, ) -> std::result::Result { - let timestamp = datetime.unix_timestamp_nanos() / i128::from(NANOSECONDS_PER_DECISECOND); + let nanos = datetime.timestamp_nanos_opt().ok_or_else(|| { + serde::ser::Error::custom("timestamp out of range for nanosecond precision") + })?; + let timestamp = nanos / i64::from(NANOSECONDS_PER_DECISECOND); timestamp.serialize(serializer) } -/// Deserialize an `UtcDateTime` from its Unix timestamp with deciseconds. +/// Deserialize a `DateTime` from its Unix timestamp with deciseconds. pub fn deserialize<'a, D: Deserializer<'a>>( deserializer: D, -) -> std::result::Result { - let num = i128::deserialize(deserializer)?; - UtcDateTime::from_unix_timestamp_nanos(num * i128::from(NANOSECONDS_PER_DECISECOND)) - .map_err(de::Error::custom) +) -> std::result::Result, D::Error> { + let num = i64::deserialize(deserializer)?; + let nanos = num + .checked_mul(i64::from(NANOSECONDS_PER_DECISECOND)) + .ok_or_else(|| de::Error::custom("decisecond timestamp overflow"))?; + Ok(DateTime::from_timestamp_nanos(nanos)) } diff --git a/crates/jp_llm/Cargo.toml b/crates/jp_llm/Cargo.toml index ce7dc311..f5a828e5 100644 --- a/crates/jp_llm/Cargo.toml +++ b/crates/jp_llm/Cargo.toml @@ -50,7 +50,7 @@ schemars = { workspace = true } serde = { workspace = true } serde_json = { workspace = true, features = ["preserve_order"] } thiserror = { workspace = true } -time = { workspace = true } +chrono = { workspace = true } tokio = { workspace = true } tokio-stream = { workspace = true } tracing = { workspace = true } diff --git a/crates/jp_llm/src/model.rs b/crates/jp_llm/src/model.rs index 404e031d..137e3249 100644 --- a/crates/jp_llm/src/model.rs +++ b/crates/jp_llm/src/model.rs @@ -1,8 +1,8 @@ +use chrono::NaiveDate; use jp_config::model::{ id::ModelIdConfig, parameters::{CustomReasoningConfig, ReasoningConfig, ReasoningEffort}, }; -use time::Date; use tracing::warn; /// Details about a model for a given provider, as specified by the provider. @@ -25,7 +25,7 @@ pub struct ModelDetails { pub reasoning: Option, /// The knowledge cutoff date, if known. - pub knowledge_cutoff: Option, + pub knowledge_cutoff: Option, /// Deprecation status of the model, if known. pub deprecated: Option, @@ -154,12 +154,12 @@ pub enum ModelDeprecation { note: String, /// The date on which the model will be retired, if known. - retire_at: Option, + retire_at: Option, }, } impl ModelDeprecation { - pub fn deprecated(note: &impl ToString, retire_at: Option) -> Self { + pub fn deprecated(note: &impl ToString, retire_at: Option) -> Self { Self::Deprecated { note: note.to_string(), retire_at, diff --git a/crates/jp_llm/src/provider/anthropic.rs b/crates/jp_llm/src/provider/anthropic.rs index 15664a5d..a5fabe6a 100644 --- a/crates/jp_llm/src/provider/anthropic.rs +++ b/crates/jp_llm/src/provider/anthropic.rs @@ -11,6 +11,7 @@ use async_anthropic::{ }; use async_stream::try_stream; use async_trait::async_trait; +use chrono::NaiveDate; use futures::{StreamExt as _, TryStreamExt as _, pin_mut}; use indexmap::IndexMap; use jp_config::{ @@ -24,7 +25,6 @@ use jp_conversation::{ thread::{Document, Documents, Thread}, }; use serde_json::{Map, Value, json}; -use time::macros::date; use tracing::{debug, info, trace, warn}; use super::Provider; @@ -620,7 +620,7 @@ fn map_model(model: types::Model, beta: &BetaFeatures) -> Result { context_window: Some(200_000), max_output_tokens: Some(64_000), reasoning: Some(ReasoningDetails::budgetted(1024, None)), - knowledge_cutoff: Some(date!(2025 - 7 - 1)), + knowledge_cutoff: Some(NaiveDate::from_ymd_opt(2025, 7, 1).unwrap()), deprecated: Some(ModelDeprecation::Active), features: vec![ "interleaved-thinking", @@ -634,7 +634,7 @@ fn map_model(model: types::Model, beta: &BetaFeatures) -> Result { context_window: Some(200_000), max_output_tokens: Some(64_000), reasoning: Some(ReasoningDetails::budgetted(1024, None)), - knowledge_cutoff: Some(date!(2025 - 7 - 1)), + knowledge_cutoff: Some(NaiveDate::from_ymd_opt(2025, 7, 1).unwrap()), deprecated: Some(ModelDeprecation::Active), features: vec!["interleaved-thinking", "context-editing"], }, @@ -648,7 +648,7 @@ fn map_model(model: types::Model, beta: &BetaFeatures) -> Result { }, max_output_tokens: Some(64_000), reasoning: Some(ReasoningDetails::budgetted(1024, None)), - knowledge_cutoff: Some(date!(2025 - 7 - 1)), + knowledge_cutoff: Some(NaiveDate::from_ymd_opt(2025, 7, 1).unwrap()), deprecated: Some(ModelDeprecation::Active), features: vec![ "interleaved-thinking", @@ -662,7 +662,7 @@ fn map_model(model: types::Model, beta: &BetaFeatures) -> Result { context_window: Some(200_000), max_output_tokens: Some(32_000), reasoning: Some(ReasoningDetails::budgetted(1024, None)), - knowledge_cutoff: Some(date!(2025 - 3 - 1)), + knowledge_cutoff: Some(NaiveDate::from_ymd_opt(2025, 3, 1).unwrap()), deprecated: Some(ModelDeprecation::Active), features: vec![ "interleaved-thinking", @@ -676,7 +676,7 @@ fn map_model(model: types::Model, beta: &BetaFeatures) -> Result { context_window: Some(200_000), max_output_tokens: Some(32_000), reasoning: Some(ReasoningDetails::budgetted(1024, None)), - knowledge_cutoff: Some(date!(2025 - 3 - 1)), + knowledge_cutoff: Some(NaiveDate::from_ymd_opt(2025, 3, 1).unwrap()), deprecated: Some(ModelDeprecation::Active), features: vec!["interleaved-thinking", "context-editing"], }, @@ -690,7 +690,7 @@ fn map_model(model: types::Model, beta: &BetaFeatures) -> Result { }, max_output_tokens: Some(64_000), reasoning: Some(ReasoningDetails::budgetted(1024, None)), - knowledge_cutoff: Some(date!(2025 - 3 - 1)), + knowledge_cutoff: Some(NaiveDate::from_ymd_opt(2025, 3, 1).unwrap()), deprecated: Some(ModelDeprecation::Active), features: vec!["interleaved-thinking", "context-editing"], }, @@ -700,7 +700,7 @@ fn map_model(model: types::Model, beta: &BetaFeatures) -> Result { context_window: Some(200_000), max_output_tokens: Some(64_000), reasoning: Some(ReasoningDetails::budgetted(1024, None)), - knowledge_cutoff: Some(date!(2024 - 11 - 1)), + knowledge_cutoff: Some(NaiveDate::from_ymd_opt(2024, 11, 1).unwrap()), deprecated: Some(ModelDeprecation::Active), features: vec![], }, @@ -710,7 +710,7 @@ fn map_model(model: types::Model, beta: &BetaFeatures) -> Result { context_window: Some(200_000), max_output_tokens: Some(8_192), reasoning: Some(ReasoningDetails::unsupported()), - knowledge_cutoff: Some(date!(2024 - 7 - 1)), + knowledge_cutoff: Some(NaiveDate::from_ymd_opt(2024, 7, 1).unwrap()), deprecated: Some(ModelDeprecation::Active), features: vec![], }, @@ -720,10 +720,10 @@ fn map_model(model: types::Model, beta: &BetaFeatures) -> Result { context_window: Some(200_000), max_output_tokens: Some(4_096), reasoning: Some(ReasoningDetails::unsupported()), - knowledge_cutoff: Some(date!(2023 - 8 - 1)), + knowledge_cutoff: Some(NaiveDate::from_ymd_opt(2023, 8, 1).unwrap()), deprecated: Some(ModelDeprecation::deprecated( &"recommended replacement: claude-opus-4-1-20250805", - Some(date!(2026 - 1 - 5)), + Some(NaiveDate::from_ymd_opt(2026, 1, 5).unwrap()), )), features: vec![], }, @@ -733,7 +733,7 @@ fn map_model(model: types::Model, beta: &BetaFeatures) -> Result { context_window: Some(200_000), max_output_tokens: Some(4_096), reasoning: Some(ReasoningDetails::unsupported()), - knowledge_cutoff: Some(date!(2024 - 8 - 1)), + knowledge_cutoff: Some(NaiveDate::from_ymd_opt(2024, 8, 1).unwrap()), deprecated: Some(ModelDeprecation::Active), features: vec![], }, diff --git a/crates/jp_llm/src/provider/openai.rs b/crates/jp_llm/src/provider/openai.rs index 6a024adc..5b242af8 100644 --- a/crates/jp_llm/src/provider/openai.rs +++ b/crates/jp_llm/src/provider/openai.rs @@ -1,6 +1,7 @@ use std::env; use async_trait::async_trait; +use chrono::NaiveDate; use futures::{FutureExt as _, StreamExt as _, TryStreamExt as _, future, stream}; use indexmap::{IndexMap, IndexSet}; use jp_config::{ @@ -23,7 +24,6 @@ use openai_responses::{ use reqwest::header::{self, HeaderMap, HeaderValue}; use serde::Deserialize; use serde_json::{Map, Value}; -use time::{OffsetDateTime, macros::date}; use tracing::{trace, warn}; use super::{EventStream, ModelDetails, Provider}; @@ -105,8 +105,8 @@ pub(crate) struct ModelResponse { pub id: String, #[serde(rename = "object")] _object: String, - #[serde(rename = "created", with = "time::serde::timestamp")] - _created: OffsetDateTime, + #[serde(rename = "created", with = "chrono::serde::ts_seconds")] + _created: chrono::DateTime, #[serde(rename = "owned_by")] _owned_by: String, } @@ -158,7 +158,7 @@ fn map_model(model: ModelResponse) -> Result { context_window: Some(400_000), max_output_tokens: Some(128_000), reasoning: Some(ReasoningDetails::leveled(false, false, true, true, true)), - knowledge_cutoff: Some(date!(2025 - 9 - 1)), + knowledge_cutoff: Some(NaiveDate::from_ymd_opt(2025, 9, 1).unwrap()), deprecated: Some(ModelDeprecation::Active), features: vec![], }, @@ -168,7 +168,7 @@ fn map_model(model: ModelResponse) -> Result { context_window: Some(400_000), max_output_tokens: Some(128_000), reasoning: Some(ReasoningDetails::budgetted(0, None)), - knowledge_cutoff: Some(date!(2025 - 9 - 1)), + knowledge_cutoff: Some(NaiveDate::from_ymd_opt(2025, 9, 1).unwrap()), deprecated: Some(ModelDeprecation::Active), features: vec![], }, @@ -178,7 +178,7 @@ fn map_model(model: ModelResponse) -> Result { context_window: Some(400_000), max_output_tokens: Some(128_000), reasoning: Some(ReasoningDetails::budgetted(0, None)), - knowledge_cutoff: Some(date!(2024 - 10 - 1)), + knowledge_cutoff: Some(NaiveDate::from_ymd_opt(2024, 10, 1).unwrap()), deprecated: Some(ModelDeprecation::Active), features: vec![], }, @@ -188,7 +188,7 @@ fn map_model(model: ModelResponse) -> Result { context_window: Some(400_000), max_output_tokens: Some(128_000), reasoning: Some(ReasoningDetails::budgetted(0, None)), - knowledge_cutoff: Some(date!(2024 - 10 - 1)), + knowledge_cutoff: Some(NaiveDate::from_ymd_opt(2024, 10, 1).unwrap()), deprecated: Some(ModelDeprecation::Active), features: vec![], }, @@ -198,7 +198,7 @@ fn map_model(model: ModelResponse) -> Result { context_window: Some(400_000), max_output_tokens: Some(128_000), reasoning: Some(ReasoningDetails::budgetted(0, None)), - knowledge_cutoff: Some(date!(2024 - 10 - 1)), + knowledge_cutoff: Some(NaiveDate::from_ymd_opt(2024, 10, 1).unwrap()), deprecated: Some(ModelDeprecation::Active), features: vec![], }, @@ -208,7 +208,7 @@ fn map_model(model: ModelResponse) -> Result { context_window: Some(400_000), max_output_tokens: Some(128_000), reasoning: Some(ReasoningDetails::budgetted(0, None)), - knowledge_cutoff: Some(date!(2024 - 10 - 1)), + knowledge_cutoff: Some(NaiveDate::from_ymd_opt(2024, 10, 1).unwrap()), deprecated: Some(ModelDeprecation::Active), features: vec![], }, @@ -218,7 +218,7 @@ fn map_model(model: ModelResponse) -> Result { context_window: Some(400_000), max_output_tokens: Some(128_000), reasoning: Some(ReasoningDetails::budgetted(0, None)), - knowledge_cutoff: Some(date!(2024 - 10 - 1)), + knowledge_cutoff: Some(NaiveDate::from_ymd_opt(2024, 10, 1).unwrap()), deprecated: Some(ModelDeprecation::Active), features: vec![], }, @@ -228,7 +228,7 @@ fn map_model(model: ModelResponse) -> Result { context_window: Some(400_000), max_output_tokens: Some(128_000), reasoning: Some(ReasoningDetails::budgetted(0, None)), - knowledge_cutoff: Some(date!(2024 - 8 - 30)), + knowledge_cutoff: Some(NaiveDate::from_ymd_opt(2024, 8, 30).unwrap()), deprecated: Some(ModelDeprecation::Active), features: vec![], }, @@ -238,7 +238,7 @@ fn map_model(model: ModelResponse) -> Result { context_window: Some(128_000), max_output_tokens: Some(16_384), reasoning: Some(ReasoningDetails::budgetted(0, None)), - knowledge_cutoff: Some(date!(2024 - 8 - 30)), + knowledge_cutoff: Some(NaiveDate::from_ymd_opt(2024, 8, 30).unwrap()), deprecated: Some(ModelDeprecation::Active), features: vec![], }, @@ -248,7 +248,7 @@ fn map_model(model: ModelResponse) -> Result { context_window: Some(400_000), max_output_tokens: Some(128_000), reasoning: Some(ReasoningDetails::budgetted(0, None)), - knowledge_cutoff: Some(date!(2024 - 8 - 30)), + knowledge_cutoff: Some(NaiveDate::from_ymd_opt(2024, 8, 30).unwrap()), deprecated: Some(ModelDeprecation::Active), features: vec![], }, @@ -258,7 +258,7 @@ fn map_model(model: ModelResponse) -> Result { context_window: Some(400_000), max_output_tokens: Some(128_000), reasoning: Some(ReasoningDetails::budgetted(0, None)), - knowledge_cutoff: Some(date!(2024 - 8 - 30)), + knowledge_cutoff: Some(NaiveDate::from_ymd_opt(2024, 8, 30).unwrap()), deprecated: Some(ModelDeprecation::Active), features: vec![], }, @@ -268,7 +268,7 @@ fn map_model(model: ModelResponse) -> Result { context_window: Some(200_000), max_output_tokens: Some(100_000), reasoning: Some(ReasoningDetails::budgetted(0, None)), - knowledge_cutoff: Some(date!(2024 - 6 - 1)), + knowledge_cutoff: Some(NaiveDate::from_ymd_opt(2024, 6, 1).unwrap()), deprecated: Some(ModelDeprecation::Active), features: vec![], }, @@ -278,7 +278,7 @@ fn map_model(model: ModelResponse) -> Result { context_window: Some(200_000), max_output_tokens: Some(100_000), reasoning: Some(ReasoningDetails::budgetted(0, None)), - knowledge_cutoff: Some(date!(2023 - 10 - 1)), + knowledge_cutoff: Some(NaiveDate::from_ymd_opt(2023, 10, 1).unwrap()), deprecated: Some(ModelDeprecation::Active), features: vec![], }, @@ -288,10 +288,10 @@ fn map_model(model: ModelResponse) -> Result { context_window: Some(128_000), max_output_tokens: Some(65_536), reasoning: Some(ReasoningDetails::budgetted(0, None)), - knowledge_cutoff: Some(date!(2023 - 10 - 1)), + knowledge_cutoff: Some(NaiveDate::from_ymd_opt(2023, 10, 1).unwrap()), deprecated: Some(ModelDeprecation::deprecated( &"recommended replacement: o4-mini", - Some(date!(2025 - 10 - 27)), + Some(NaiveDate::from_ymd_opt(2025, 10, 27).unwrap()), )), features: vec![], }, @@ -301,7 +301,7 @@ fn map_model(model: ModelResponse) -> Result { context_window: Some(200_000), max_output_tokens: Some(100_000), reasoning: Some(ReasoningDetails::budgetted(0, None)), - knowledge_cutoff: Some(date!(2024 - 6 - 1)), + knowledge_cutoff: Some(NaiveDate::from_ymd_opt(2024, 6, 1).unwrap()), deprecated: Some(ModelDeprecation::Active), features: vec![], }, @@ -311,7 +311,7 @@ fn map_model(model: ModelResponse) -> Result { context_window: Some(200_000), max_output_tokens: Some(100_000), reasoning: Some(ReasoningDetails::budgetted(0, None)), - knowledge_cutoff: Some(date!(2024 - 6 - 1)), + knowledge_cutoff: Some(NaiveDate::from_ymd_opt(2024, 6, 1).unwrap()), deprecated: Some(ModelDeprecation::Active), features: vec![], }, @@ -321,7 +321,7 @@ fn map_model(model: ModelResponse) -> Result { context_window: Some(200_000), max_output_tokens: Some(100_000), reasoning: Some(ReasoningDetails::budgetted(0, None)), - knowledge_cutoff: Some(date!(2023 - 10 - 1)), + knowledge_cutoff: Some(NaiveDate::from_ymd_opt(2023, 10, 1).unwrap()), deprecated: Some(ModelDeprecation::Active), features: vec![], }, @@ -331,7 +331,7 @@ fn map_model(model: ModelResponse) -> Result { context_window: Some(200_000), max_output_tokens: Some(100_000), reasoning: Some(ReasoningDetails::budgetted(0, None)), - knowledge_cutoff: Some(date!(2023 - 10 - 1)), + knowledge_cutoff: Some(NaiveDate::from_ymd_opt(2023, 10, 1).unwrap()), deprecated: Some(ModelDeprecation::Active), features: vec![], }, @@ -341,7 +341,7 @@ fn map_model(model: ModelResponse) -> Result { context_window: Some(1_047_576), max_output_tokens: Some(32_768), reasoning: Some(ReasoningDetails::unsupported()), - knowledge_cutoff: Some(date!(2024 - 6 - 1)), + knowledge_cutoff: Some(NaiveDate::from_ymd_opt(2024, 6, 1).unwrap()), deprecated: Some(ModelDeprecation::Active), features: vec![], }, @@ -351,7 +351,7 @@ fn map_model(model: ModelResponse) -> Result { context_window: Some(128_000), max_output_tokens: Some(16_384), reasoning: Some(ReasoningDetails::unsupported()), - knowledge_cutoff: Some(date!(2023 - 10 - 1)), + knowledge_cutoff: Some(NaiveDate::from_ymd_opt(2023, 10, 1).unwrap()), deprecated: Some(ModelDeprecation::Active), features: vec![], }, @@ -361,10 +361,10 @@ fn map_model(model: ModelResponse) -> Result { context_window: Some(128_000), max_output_tokens: Some(16_384), reasoning: Some(ReasoningDetails::unsupported()), - knowledge_cutoff: Some(date!(2023 - 10 - 1)), + knowledge_cutoff: Some(NaiveDate::from_ymd_opt(2023, 10, 1).unwrap()), deprecated: Some(ModelDeprecation::deprecated( &"recommended replacement: gpt-5.1-chat-latest", - Some(date!(2026 - 02 - 11)), + Some(NaiveDate::from_ymd_opt(2026, 2, 11).unwrap()), )), features: vec![], }, @@ -374,7 +374,7 @@ fn map_model(model: ModelResponse) -> Result { context_window: Some(1_047_576), max_output_tokens: Some(32_768), reasoning: Some(ReasoningDetails::unsupported()), - knowledge_cutoff: Some(date!(2024 - 6 - 1)), + knowledge_cutoff: Some(NaiveDate::from_ymd_opt(2024, 6, 1).unwrap()), deprecated: Some(ModelDeprecation::Active), features: vec![], }, @@ -384,7 +384,7 @@ fn map_model(model: ModelResponse) -> Result { context_window: Some(128_000), max_output_tokens: Some(16_384), reasoning: Some(ReasoningDetails::unsupported()), - knowledge_cutoff: Some(date!(2023 - 10 - 1)), + knowledge_cutoff: Some(NaiveDate::from_ymd_opt(2023, 10, 1).unwrap()), deprecated: Some(ModelDeprecation::Active), features: vec![], }, @@ -394,7 +394,7 @@ fn map_model(model: ModelResponse) -> Result { context_window: Some(1_047_576), max_output_tokens: Some(32_768), reasoning: Some(ReasoningDetails::unsupported()), - knowledge_cutoff: Some(date!(2024 - 6 - 1)), + knowledge_cutoff: Some(NaiveDate::from_ymd_opt(2024, 6, 1).unwrap()), deprecated: Some(ModelDeprecation::Active), features: vec![], }, @@ -404,7 +404,7 @@ fn map_model(model: ModelResponse) -> Result { context_window: Some(131_072), max_output_tokens: Some(131_072), reasoning: Some(ReasoningDetails::budgetted(0, None)), - knowledge_cutoff: Some(date!(2024 - 6 - 1)), + knowledge_cutoff: Some(NaiveDate::from_ymd_opt(2024, 6, 1).unwrap()), deprecated: Some(ModelDeprecation::Active), features: vec![], }, @@ -414,7 +414,7 @@ fn map_model(model: ModelResponse) -> Result { context_window: Some(131_072), max_output_tokens: Some(131_072), reasoning: Some(ReasoningDetails::budgetted(0, None)), - knowledge_cutoff: Some(date!(2024 - 6 - 1)), + knowledge_cutoff: Some(NaiveDate::from_ymd_opt(2024, 6, 1).unwrap()), deprecated: Some(ModelDeprecation::Active), features: vec![], }, @@ -424,7 +424,7 @@ fn map_model(model: ModelResponse) -> Result { context_window: Some(200_000), max_output_tokens: Some(100_000), reasoning: Some(ReasoningDetails::budgetted(0, None)), - knowledge_cutoff: Some(date!(2024 - 6 - 1)), + knowledge_cutoff: Some(NaiveDate::from_ymd_opt(2024, 6, 1).unwrap()), deprecated: Some(ModelDeprecation::Active), features: vec![], }, @@ -434,7 +434,7 @@ fn map_model(model: ModelResponse) -> Result { context_window: Some(200_000), max_output_tokens: Some(100_000), reasoning: Some(ReasoningDetails::budgetted(0, None)), - knowledge_cutoff: Some(date!(2024 - 6 - 1)), + knowledge_cutoff: Some(NaiveDate::from_ymd_opt(2024, 6, 1).unwrap()), deprecated: Some(ModelDeprecation::Active), features: vec![], }, diff --git a/crates/jp_llm/src/provider/openrouter.rs b/crates/jp_llm/src/provider/openrouter.rs index 69248066..2cd8b03c 100644 --- a/crates/jp_llm/src/provider/openrouter.rs +++ b/crates/jp_llm/src/provider/openrouter.rs @@ -477,7 +477,7 @@ fn map_model(model: response::Model) -> Result { context_window: Some(model.context_length), max_output_tokens: None, reasoning: None, - knowledge_cutoff: Some(model.created.date()), + knowledge_cutoff: Some(model.created.0.date_naive()), deprecated: None, features: vec![], }) diff --git a/crates/jp_llm/src/test.rs b/crates/jp_llm/src/test.rs index 158d2c5f..32d19b55 100644 --- a/crates/jp_llm/src/test.rs +++ b/crates/jp_llm/src/test.rs @@ -1,5 +1,6 @@ use std::{panic, sync::Arc}; +use chrono::{TimeZone as _, Utc}; use futures::TryStreamExt as _; use jp_config::{ AppConfig, PartialAppConfig, ToPartial as _, @@ -21,7 +22,6 @@ use jp_conversation::{ }; use jp_test::mock::{Snap, Vcr}; use schemars::Schema; -use time::macros::{datetime, utc_datetime}; use crate::{ event::Event, @@ -95,7 +95,7 @@ impl TestRequest { name: "test".parse().unwrap(), }); ConversationStream::new(config.into()) - .with_created_at(utc_datetime!(2020-01-01 0:00)) + .with_created_at(Utc.with_ymd_and_hms(2020, 1, 1, 0, 0, 0).unwrap()) }) .build() .unwrap(), @@ -121,7 +121,7 @@ impl TestRequest { name: "test".parse().unwrap(), }); ConversationStream::new(config.into()) - .with_created_at(utc_datetime!(2020-01-01 0:00)) + .with_created_at(Utc.with_ymd_and_hms(2020, 1, 1, 0, 0, 0).unwrap()) }) .build() .unwrap(), @@ -511,7 +511,8 @@ pub async fn run_chat_completion( .clone() .into_iter() .map(|mut v| { - v.event.timestamp = utc_datetime!(2020-01-01 0:00); + v.event.timestamp = + Utc.with_ymd_and_hms(2020, 1, 1, 0, 0, 0).unwrap(); v }) .collect::>(), @@ -548,7 +549,8 @@ pub async fn run_chat_completion( for mut event in events { if let Event::Part { event, .. } = &mut event { - event.timestamp = datetime!(2020-01-01 0:00 utc).into(); + event.timestamp = + Utc.with_ymd_and_hms(2020, 1, 1, 0, 0, 0).unwrap().into(); } all_events[index].push(event.clone()); diff --git a/crates/jp_openrouter/Cargo.toml b/crates/jp_openrouter/Cargo.toml index bd327981..c53d581e 100644 --- a/crates/jp_openrouter/Cargo.toml +++ b/crates/jp_openrouter/Cargo.toml @@ -26,12 +26,7 @@ reqwest = { workspace = true, features = [ serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true, features = ["preserve_order"] } thiserror = { workspace = true } -time = { workspace = true, features = [ - "serde", - "serde-human-readable", - "serde-well-known", - "std", -] } +chrono = { workspace = true } tokio = { workspace = true } tokio-util = { workspace = true } tracing = { workspace = true } diff --git a/crates/jp_openrouter/src/types/response.rs b/crates/jp_openrouter/src/types/response.rs index 62e3d5f8..87820a14 100644 --- a/crates/jp_openrouter/src/types/response.rs +++ b/crates/jp_openrouter/src/types/response.rs @@ -1,9 +1,29 @@ +use std::fmt; + +use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use serde_json::Value; -use time::OffsetDateTime; use super::tool::ToolCall; +/// Wrapper for `DateTime` that produces `time::OffsetDateTime`-compatible +/// `Debug` output: `2025-12-09 12:51:48.0 +00:00:00`. +#[derive(Clone, Copy, PartialEq, Eq, Deserialize)] +#[serde(transparent)] +pub struct OffsetDateTimeFmt(#[serde(with = "chrono::serde::ts_seconds")] pub DateTime); + +impl fmt::Debug for OffsetDateTimeFmt { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let nanos = self.0.timestamp_subsec_nanos(); + if nanos == 0 { + write!(f, "{} +00:00:00", self.0.format("%Y-%m-%d %H:%M:%S.0")) + } else { + let full = self.0.format("%Y-%m-%d %H:%M:%S.%9f").to_string(); + write!(f, "{} +00:00:00", full.trim_end_matches('0')) + } + } +} + /// A chat completion response. #[derive(Debug, Deserialize)] pub struct ChatCompletion { @@ -25,8 +45,7 @@ pub struct ChatCompletion { pub choices: Vec, /// The time the response was created. - #[serde(with = "time::serde::timestamp")] - pub created: OffsetDateTime, + pub created: OffsetDateTimeFmt, /// The model used to generate the response. pub model: String, @@ -349,7 +368,6 @@ pub struct ModelsResponse { pub struct Model { pub id: String, pub name: String, - #[serde(with = "time::serde::timestamp")] - pub created: OffsetDateTime, + pub created: OffsetDateTimeFmt, pub context_length: u32, } diff --git a/crates/jp_storage/Cargo.toml b/crates/jp_storage/Cargo.toml index 68cc8ad9..751810d6 100644 --- a/crates/jp_storage/Cargo.toml +++ b/crates/jp_storage/Cargo.toml @@ -24,7 +24,7 @@ rayon = { workspace = true } serde = { workspace = true } serde_json = { workspace = true, features = ["preserve_order", "raw_value"] } thiserror = { workspace = true } -time = { workspace = true } +chrono = { workspace = true } toml = { workspace = true, features = ["preserve_order"] } tracing = { workspace = true } diff --git a/crates/jp_storage/src/lib.rs b/crates/jp_storage/src/lib.rs index 2c92e7ca..2b0d2590 100644 --- a/crates/jp_storage/src/lib.rs +++ b/crates/jp_storage/src/lib.rs @@ -5,12 +5,12 @@ use std::{cell::OnceCell, fs, io::BufReader, iter}; use ahash::{HashMap, HashMapExt}; use camino::{Utf8DirEntry, Utf8Path, Utf8PathBuf}; +use chrono::{DateTime, NaiveDateTime, Utc}; pub use error::Error; use jp_conversation::{Conversation, ConversationId, ConversationStream, ConversationsMetadata}; use jp_id::Id as _; use jp_tombmap::TombMap; use rayon::iter::{IntoParallelIterator as _, IntoParallelRefIterator as _, ParallelIterator as _}; -use time::{UtcDateTime, macros::format_description}; use tracing::{trace, warn}; use crate::{ @@ -401,7 +401,7 @@ impl Storage { let path = entry.into_path(); let expiring_ts = get_expiring_timestamp(&path)?; - if expiring_ts > UtcDateTime::now() { + if expiring_ts > Utc::now() { return None; } @@ -420,12 +420,22 @@ impl Storage { } } -fn load_count_and_timestamp_events(root: &Utf8Path) -> Option<(usize, Option)> { +fn parse_datetime(s: &str) -> Option> { + DateTime::parse_from_rfc3339(s) + .map(|dt| dt.with_timezone(&Utc)) + .ok() + .or_else(|| { + NaiveDateTime::parse_from_str(s, "%Y-%m-%d %H:%M:%S%.f") + .ok() + .map(|dt| dt.and_utc()) + }) +} + +fn load_count_and_timestamp_events(root: &Utf8Path) -> Option<(usize, Option>)> { #[derive(serde::Deserialize)] struct RawEvent { timestamp: Box, } - let fmt = format_description!("[year]-[month]-[day] [hour]:[minute]:[second].[subsecond]"); let path = root.join(EVENTS_FILE); let file = fs::File::open(&path).ok()?; let reader = BufReader::new(file); @@ -448,7 +458,7 @@ fn load_count_and_timestamp_events(root: &Utf8Path) -> Option<(usize, Option= 2 && ts.starts_with('"') && ts.ends_with('"') { - last_timestamp = UtcDateTime::parse(&ts[1..ts.len() - 1], &fmt).ok(); + last_timestamp = parse_datetime(&ts[1..ts.len() - 1]); } } @@ -460,12 +470,11 @@ fn load_count_and_timestamp_events(root: &Utf8Path) -> Option<(usize, Option Option { +fn get_expiring_timestamp(root: &Utf8Path) -> Option> { #[derive(serde::Deserialize)] struct RawConversation { expires_at: Option>, } - let fmt = format_description!("[year]-[month]-[day] [hour]:[minute]:[second].[subsecond]"); let path = root.join(METADATA_FILE); let file = fs::File::open(&path).ok()?; let reader = BufReader::new(file); @@ -488,7 +497,7 @@ fn get_expiring_timestamp(root: &Utf8Path) -> Option { return None; } - UtcDateTime::parse(&ts[1..ts.len() - 1], &fmt).ok() + parse_datetime(&ts[1..ts.len() - 1]) } fn dir_entries(path: &Utf8Path) -> impl Iterator { @@ -633,10 +642,10 @@ mod tests { }; use camino_tempfile::tempdir; + use chrono::TimeZone as _; use jp_conversation::ConversationId; use serde_json::json; use test_log::test; - use time::macros::utc_datetime; use super::*; @@ -733,8 +742,6 @@ mod tests { #[test] fn test_remove_ephemeral_conversations() { - use time::ext::NumericalDuration; - let storage_dir = tempdir().unwrap(); let path = storage_dir.path(); let convs = path.join(CONVERSATIONS_DIR); @@ -750,8 +757,8 @@ mod tests { write_json( &dir1.join("metadata.json"), &json!({ - "last_activated_at": utc_datetime!(2023-01-01 00:00:00), - "expires_at": UtcDateTime::now().saturating_sub(1.hours()) + "last_activated_at": Utc.with_ymd_and_hms(2023, 1, 1, 0, 0, 0).unwrap(), + "expires_at": Utc::now() - chrono::Duration::hours(1) }), ) .unwrap(); @@ -764,8 +771,8 @@ mod tests { &dir2.join("metadata.json"), &json!({ "title": title, - "last_activated_at": utc_datetime!(2023-01-01 00:00:00), - "expires_at": UtcDateTime::now().saturating_add(1.hours()) + "last_activated_at": Utc.with_ymd_and_hms(2023, 1, 1, 0, 0, 0).unwrap(), + "expires_at": Utc::now() + chrono::Duration::hours(1) }), ) .unwrap(); @@ -777,8 +784,8 @@ mod tests { &dir3.join("metadata.json"), &json!({ "title": title, - "last_activated_at": utc_datetime!(2023-01-01 00:00:00), - "expires_at": UtcDateTime::now().saturating_sub(1.hours()) + "last_activated_at": Utc.with_ymd_and_hms(2023, 1, 1, 0, 0, 0).unwrap(), + "expires_at": Utc::now() - chrono::Duration::hours(1) }), ) .unwrap(); diff --git a/crates/jp_workspace/Cargo.toml b/crates/jp_workspace/Cargo.toml index e7bfb70a..7a477fb0 100644 --- a/crates/jp_workspace/Cargo.toml +++ b/crates/jp_workspace/Cargo.toml @@ -24,7 +24,7 @@ camino-tempfile = { workspace = true } directories = { workspace = true } serde = { workspace = true } thiserror = { workspace = true } -time = { workspace = true } +chrono = { workspace = true } tracing = { workspace = true } [dev-dependencies] diff --git a/crates/jp_workspace/src/lib.rs b/crates/jp_workspace/src/lib.rs index 7a95c93c..e1a4b983 100644 --- a/crates/jp_workspace/src/lib.rs +++ b/crates/jp_workspace/src/lib.rs @@ -11,6 +11,7 @@ mod state; use std::{cell::OnceCell, iter, sync::Arc}; use camino::{FromPathBufError, Utf8Path, Utf8PathBuf}; +use chrono::{DateTime, Utc}; pub use error::Error; use error::Result; pub use id::Id; @@ -19,7 +20,6 @@ use jp_conversation::{Conversation, ConversationId, ConversationStream}; use jp_storage::Storage; use jp_tombmap::{Mut, TombMap}; use state::{LocalState, State, UserState}; -use time::UtcDateTime; use tracing::{debug, info, trace, warn}; const APPLICATION: &str = "jp"; @@ -316,7 +316,7 @@ impl Workspace { pub fn set_active_conversation_id( &mut self, id: ConversationId, - activation_timestamp: UtcDateTime, + activation_timestamp: DateTime, ) -> Result<()> { // Remove the new active conversation from the list of conversations, // returning an error if it doesn't exist. @@ -671,9 +671,9 @@ mod tests { use std::{collections::HashMap, fs, time::Duration}; use camino_tempfile::tempdir; + use chrono::TimeZone as _; use jp_storage::{CONVERSATIONS_DIR, METADATA_FILE, value::read_json}; use test_log::test; - use time::{UtcDateTime, macros::utc_datetime}; use super::*; @@ -780,7 +780,7 @@ mod tests { let id = workspace.create_conversation(Conversation::default(), config.into()); workspace - .set_active_conversation_id(id, UtcDateTime::UNIX_EPOCH) + .set_active_conversation_id(id, DateTime::::UNIX_EPOCH) .unwrap(); assert!(!storage.exists()); @@ -825,7 +825,7 @@ mod tests { let mut workspace = Workspace::new(Utf8PathBuf::new()); assert!(workspace.state.local.conversations.is_empty()); - let id = ConversationId::try_from(UtcDateTime::now() - Duration::from_secs(1)).unwrap(); + let id = ConversationId::try_from(Utc::now() - Duration::from_secs(1)).unwrap(); assert_eq!(workspace.get_conversation(&id), None); let conversation = Conversation::default(); @@ -865,7 +865,7 @@ mod tests { let mut workspace = Workspace::new(Utf8PathBuf::new()); assert!(workspace.state.local.conversations.is_empty()); - let id = ConversationId::try_from(UtcDateTime::now() - Duration::from_secs(1)).unwrap(); + let id = ConversationId::try_from(Utc::now() - Duration::from_secs(1)).unwrap(); let conversation = Conversation::default(); workspace .state @@ -912,13 +912,15 @@ mod tests { let mut workspace = Workspace::new(&root).persisted_at(&storage).unwrap(); let config = Arc::new(AppConfig::new_test()); - let id1 = ConversationId::try_from(utc_datetime!(2023-01-01 0:00)).unwrap(); - let id2 = ConversationId::try_from(utc_datetime!(2023-01-02 0:00)).unwrap(); + let id1 = + ConversationId::try_from(Utc.with_ymd_and_hms(2023, 1, 1, 0, 0, 0).unwrap()).unwrap(); + let id2 = + ConversationId::try_from(Utc.with_ymd_and_hms(2023, 1, 2, 0, 0, 0).unwrap()).unwrap(); workspace.create_conversation_with_id(id1, Conversation::default(), config.clone()); workspace.create_conversation_with_id(id2, Conversation::default(), config.clone()); workspace - .set_active_conversation_id(id1, UtcDateTime::UNIX_EPOCH) + .set_active_conversation_id(id1, DateTime::::UNIX_EPOCH) .unwrap(); workspace.persist_active_conversation().unwrap(); From 44a290ab74bd743501295ec138ef9ee65551e41d Mon Sep 17 00:00:00 2001 From: rgrant Date: Mon, 16 Feb 2026 22:50:57 +0000 Subject: [PATCH 13/23] 20260216 missed files for time->chrono commit --- .config/jp/tools/Cargo.toml | 2 +- .config/jp/tools/src/github/issues.rs | 46 ++++++---------- .config/jp/tools/src/github/pulls.rs | 78 +++++++++------------------ Cargo.lock | 30 ++++------- Cargo.toml | 2 +- 5 files changed, 54 insertions(+), 104 deletions(-) diff --git a/.config/jp/tools/Cargo.toml b/.config/jp/tools/Cargo.toml index 07791605..47aecc8e 100644 --- a/.config/jp/tools/Cargo.toml +++ b/.config/jp/tools/Cargo.toml @@ -48,7 +48,7 @@ serde = { workspace = true, features = ["std", "derive", "alloc"] } serde_json = { workspace = true, features = ["std", "preserve_order", "alloc"] } similar = { workspace = true, features = ["text", "unicode", "inline"] } strip-ansi-escapes = { workspace = true } -time = { workspace = true, features = ["serde-human-readable"] } +chrono = { workspace = true } tokio = { workspace = true, features = ["full"] } url = { workspace = true, features = ["serde", "std"] } diff --git a/.config/jp/tools/src/github/issues.rs b/.config/jp/tools/src/github/issues.rs index bf9f798f..fb5c2eb5 100644 --- a/.config/jp/tools/src/github/issues.rs +++ b/.config/jp/tools/src/github/issues.rs @@ -1,4 +1,4 @@ -use time::OffsetDateTime; +use chrono::{DateTime, Utc}; use url::Url; use super::auth; @@ -26,10 +26,8 @@ async fn get_issue(number: u64) -> Result { url: Url, labels: Vec, author: String, - #[serde(with = "time::serde::rfc3339")] - created_at: OffsetDateTime, - #[serde(with = "time::serde::rfc3339::option")] - closed_at: Option, + created_at: DateTime, + closed_at: Option>, linked_pull_request: Option, } @@ -46,11 +44,8 @@ async fn get_issue(number: u64) -> Result { url: issue.html_url, labels: issue.labels.into_iter().map(|label| label.name).collect(), author: issue.user.login, - created_at: OffsetDateTime::from_unix_timestamp(issue.created_at.timestamp())?, - closed_at: issue - .closed_at - .map(|t| OffsetDateTime::from_unix_timestamp(t.timestamp())) - .transpose()?, + created_at: issue.created_at, + closed_at: issue.closed_at, linked_pull_request: issue.pull_request.map(|pr| pr.html_url), }) } @@ -68,10 +63,8 @@ async fn get_issues() -> Result { url: Url, labels: Vec, author: String, - #[serde(with = "time::serde::rfc3339")] - created_at: OffsetDateTime, - #[serde(with = "time::serde::rfc3339::option")] - closed_at: Option, + created_at: DateTime, + closed_at: Option>, linked_pull_request: Option, } @@ -86,22 +79,17 @@ async fn get_issues() -> Result { .all_pages(page) .await? .into_iter() - .map(|issue| { - Ok(Issue { - number: issue.number, - title: issue.title, - url: issue.html_url, - labels: issue.labels.into_iter().map(|label| label.name).collect(), - author: issue.user.login, - created_at: OffsetDateTime::from_unix_timestamp(issue.created_at.timestamp())?, - closed_at: issue - .closed_at - .map(|t| OffsetDateTime::from_unix_timestamp(t.timestamp())) - .transpose()?, - linked_pull_request: issue.pull_request.map(|pr| pr.html_url), - }) + .map(|issue| Issue { + number: issue.number, + title: issue.title, + url: issue.html_url, + labels: issue.labels.into_iter().map(|label| label.name).collect(), + author: issue.user.login, + created_at: issue.created_at, + closed_at: issue.closed_at, + linked_pull_request: issue.pull_request.map(|pr| pr.html_url), }) - .collect::>()?; + .collect(); to_xml(Issues { issue }) } diff --git a/.config/jp/tools/src/github/pulls.rs b/.config/jp/tools/src/github/pulls.rs index a3ec5275..aaef414e 100644 --- a/.config/jp/tools/src/github/pulls.rs +++ b/.config/jp/tools/src/github/pulls.rs @@ -1,5 +1,5 @@ +use chrono::{DateTime, Utc}; use octocrab::{models::repos::DiffEntryStatus, params}; -use time::OffsetDateTime; use url::Url; use super::auth; @@ -53,12 +53,9 @@ async fn get(number: u64) -> Result { url: Option, labels: Vec, author: Option, - #[serde(with = "time::serde::rfc3339::option")] - created_at: Option, - #[serde(with = "time::serde::rfc3339::option")] - closed_at: Option, - #[serde(with = "time::serde::rfc3339::option")] - merged_at: Option, + created_at: Option>, + closed_at: Option>, + merged_at: Option>, merge_commit_sha: Option, changed_files: Vec, } @@ -101,18 +98,9 @@ async fn get(number: u64) -> Result { .map(|label| label.name) .collect(), author: pull.user.map(|user| user.login), - created_at: pull - .created_at - .map(|v| OffsetDateTime::from_unix_timestamp(v.timestamp())) - .transpose()?, - closed_at: pull - .closed_at - .map(|v| OffsetDateTime::from_unix_timestamp(v.timestamp())) - .transpose()?, - merged_at: pull - .merged_at - .map(|v| OffsetDateTime::from_unix_timestamp(v.timestamp())) - .transpose()?, + created_at: pull.created_at, + closed_at: pull.closed_at, + merged_at: pull.merged_at, merge_commit_sha: pull.merge_commit_sha, changed_files, }) @@ -168,12 +156,9 @@ async fn list(state: Option) -> Result { url: Option, labels: Vec, author: Option, - #[serde(with = "time::serde::rfc3339::option")] - created_at: Option, - #[serde(with = "time::serde::rfc3339::option")] - closed_at: Option, - #[serde(with = "time::serde::rfc3339::option")] - merged_at: Option, + created_at: Option>, + closed_at: Option>, + merged_at: Option>, merge_commit_sha: Option, } @@ -195,34 +180,23 @@ async fn list(state: Option) -> Result { .all_pages(page) .await? .into_iter() - .map(|pull| { - Ok(Pull { - number: pull.number, - title: pull.title, - url: pull.html_url, - labels: pull - .labels - .into_iter() - .flatten() - .map(|label| label.name) - .collect(), - author: pull.user.map(|user| user.login), - created_at: pull - .created_at - .map(|v| OffsetDateTime::from_unix_timestamp(v.timestamp())) - .transpose()?, - closed_at: pull - .closed_at - .map(|v| OffsetDateTime::from_unix_timestamp(v.timestamp())) - .transpose()?, - merged_at: pull - .merged_at - .map(|v| OffsetDateTime::from_unix_timestamp(v.timestamp())) - .transpose()?, - merge_commit_sha: pull.merge_commit_sha, - }) + .map(|pull| Pull { + number: pull.number, + title: pull.title, + url: pull.html_url, + labels: pull + .labels + .into_iter() + .flatten() + .map(|label| label.name) + .collect(), + author: pull.user.map(|user| user.login), + created_at: pull.created_at, + closed_at: pull.closed_at, + merged_at: pull.merged_at, + merge_commit_sha: pull.merge_commit_sha, }) - .collect::>()?; + .collect(); to_xml(Pulls { pull }) } diff --git a/Cargo.lock b/Cargo.lock index e9cd40a7..b158816b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -820,7 +820,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d630bccd429a5bb5a64b5e94f693bfc48c9f8566418fda4c494cc94f911f87cc" dependencies = [ "powerfmt", - "serde", ] [[package]] @@ -1994,6 +1993,7 @@ dependencies = [ "async-stream", "camino", "camino-tempfile", + "chrono", "clap", "clean-path", "comfy-table", @@ -2043,7 +2043,6 @@ dependencies = [ "termimad", "test-log", "thiserror 2.0.18", - "time", "timeago", "tokio", "toml 0.9.11+spec-1.1.0", @@ -2092,6 +2091,7 @@ dependencies = [ name = "jp_conversation" version = "0.1.0" dependencies = [ + "chrono", "indexmap", "insta", "jp_attachment", @@ -2103,7 +2103,6 @@ dependencies = [ "serde_json", "test-log", "thiserror 2.0.18", - "time", "tracing", ] @@ -2111,10 +2110,10 @@ dependencies = [ name = "jp_format" version = "0.1.0" dependencies = [ + "chrono", "comfy-table", "crossterm", "jp_conversation", - "time", "timeago", ] @@ -2122,10 +2121,10 @@ dependencies = [ name = "jp_id" version = "0.1.0" dependencies = [ + "chrono", "serde", "test-log", "thiserror 2.0.18", - "time", ] [[package]] @@ -2143,6 +2142,7 @@ dependencies = [ "async-stream", "async-trait", "camino", + "chrono", "crossterm", "duct", "duct_sh", @@ -2172,7 +2172,6 @@ dependencies = [ "serde_json", "test-log", "thiserror 2.0.18", - "time", "tokio", "tokio-stream", "tracing", @@ -2206,6 +2205,7 @@ version = "0.1.0" dependencies = [ "async-stream", "backon 1.5.2", + "chrono", "futures", "jp_test", "reqwest", @@ -2213,7 +2213,6 @@ dependencies = [ "serde_json", "test-log", "thiserror 2.0.18", - "time", "tokio", "tokio-util", "tracing", @@ -2243,6 +2242,7 @@ dependencies = [ "ahash", "camino", "camino-tempfile", + "chrono", "jp_config", "jp_conversation", "jp_id", @@ -2252,7 +2252,6 @@ dependencies = [ "serde_json", "test-log", "thiserror 2.0.18", - "time", "toml 0.9.11+spec-1.1.0", "tracing", ] @@ -2318,6 +2317,7 @@ version = "0.1.0" dependencies = [ "camino", "camino-tempfile", + "chrono", "directories", "jp_config", "jp_conversation", @@ -2327,7 +2327,6 @@ dependencies = [ "serde", "test-log", "thiserror 2.0.18", - "time", "tracing", ] @@ -2756,15 +2755,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "num_threads" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" -dependencies = [ - "libc", -] - [[package]] name = "object" version = "0.36.7" @@ -4288,9 +4278,7 @@ checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" dependencies = [ "deranged", "itoa", - "libc", "num-conv", - "num_threads", "powerfmt", "serde_core", "time-core", @@ -4465,6 +4453,7 @@ dependencies = [ "base64 0.22.1", "camino", "camino-tempfile", + "chrono", "convert_case 0.10.0", "crossbeam-channel", "crossterm", @@ -4487,7 +4476,6 @@ dependencies = [ "similar", "strip-ansi-escapes", "test-log", - "time", "tokio", "url", ] diff --git a/Cargo.toml b/Cargo.toml index f0689b91..fd31f206 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,6 +36,7 @@ async-trait = { version = "0.1", default-features = false } backon = { version = "1", default-features = false } base64 = { version = "0.22", default-features = false } camino = { version = "1", default-features = false } +chrono = { version = "0.4", default-features = false, features = ["clock", "serde"] } camino-tempfile = { version = "1", default-features = false } clap = { version = "4", default-features = false } clean-path = { version = "0.2", default-features = false } @@ -107,7 +108,6 @@ syntect = { version = "5.3", default-features = false, features = [ termimad = { version = "0.34", default-features = false } test-log = { version = "0.2", default-features = false, features = ["trace"] } thiserror = { version = "2", default-features = false } -time = { version = "0.3", default-features = false } timeago = { version = "0.5", default-features = false } tokio = { version = "1", default-features = false, features = ["full"] } tokio-stream = { version = "0.1", default-features = false } From ab606e93e1dfae2482e8179b6ae0e2d05e2e3c9f Mon Sep 17 00:00:00 2001 From: rgrant Date: Wed, 18 Feb 2026 17:25:06 +0000 Subject: [PATCH 14/23] 20260218 serialize conversation stream dates correctly, too --- crates/jp_conversation/src/stream.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/crates/jp_conversation/src/stream.rs b/crates/jp_conversation/src/stream.rs index ebf9807d..59432558 100644 --- a/crates/jp_conversation/src/stream.rs +++ b/crates/jp_conversation/src/stream.rs @@ -898,6 +898,7 @@ impl<'de> Deserialize<'de> for InternalEvent { ConfigDelta(ConfigDelta), ChatRequest { + #[serde(deserialize_with = "crate::deserialize_dt")] timestamp: DateTime, #[serde(default, with = "jp_serde::repr::base64_json_map")] metadata: Map, @@ -905,6 +906,7 @@ impl<'de> Deserialize<'de> for InternalEvent { data: ChatRequest, }, ChatResponse { + #[serde(deserialize_with = "crate::deserialize_dt")] timestamp: DateTime, #[serde(default, with = "jp_serde::repr::base64_json_map")] metadata: Map, @@ -912,6 +914,7 @@ impl<'de> Deserialize<'de> for InternalEvent { data: ChatResponse, }, ToolCallRequest { + #[serde(deserialize_with = "crate::deserialize_dt")] timestamp: DateTime, #[serde(default, with = "jp_serde::repr::base64_json_map")] metadata: Map, @@ -919,6 +922,7 @@ impl<'de> Deserialize<'de> for InternalEvent { data: ToolCallRequest, }, ToolCallResponse { + #[serde(deserialize_with = "crate::deserialize_dt")] timestamp: DateTime, #[serde(default, with = "jp_serde::repr::base64_json_map")] metadata: Map, @@ -926,6 +930,7 @@ impl<'de> Deserialize<'de> for InternalEvent { data: ToolCallResponse, }, InquiryRequest { + #[serde(deserialize_with = "crate::deserialize_dt")] timestamp: DateTime, #[serde(default, with = "jp_serde::repr::base64_json_map")] metadata: Map, @@ -933,6 +938,7 @@ impl<'de> Deserialize<'de> for InternalEvent { data: InquiryRequest, }, InquiryResponse { + #[serde(deserialize_with = "crate::deserialize_dt")] timestamp: DateTime, #[serde(default, with = "jp_serde::repr::base64_json_map")] metadata: Map, From 87a0e043d27824c1ce4e28f437bd6f69eb532555 Mon Sep 17 00:00:00 2001 From: rgrant Date: Wed, 18 Feb 2026 18:52:00 +0000 Subject: [PATCH 15/23] 20260218 apply serialization rule to Debug as well --- .agentic-shepherd/plans/excise-time-crate.md | 25 ++++++++++++++--- crates/jp_conversation/src/event.rs | 14 +++++++++- crates/jp_conversation/src/lib.rs | 29 ++++++++++++++++++++ 3 files changed, 63 insertions(+), 5 deletions(-) diff --git a/.agentic-shepherd/plans/excise-time-crate.md b/.agentic-shepherd/plans/excise-time-crate.md index 87542938..260fcfb7 100644 --- a/.agentic-shepherd/plans/excise-time-crate.md +++ b/.agentic-shepherd/plans/excise-time-crate.md @@ -115,9 +115,10 @@ pub fn format(content: &str, buf: &mut String, config: &Config) -> Result Result, } +impl fmt::Debug for ConversationEvent { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("ConversationEvent") + .field("timestamp", &crate::DebugDt(&self.timestamp)) + .field("kind", &self.kind) + .field("metadata", &self.metadata) + .finish() + } +} + impl ConversationEvent { /// Create a new event with the given timestamp and kind. #[must_use] diff --git a/crates/jp_conversation/src/lib.rs b/crates/jp_conversation/src/lib.rs index 4361a27c..615bde57 100644 --- a/crates/jp_conversation/src/lib.rs +++ b/crates/jp_conversation/src/lib.rs @@ -38,6 +38,35 @@ pub use error::Error; pub use event::{ConversationEvent, EventKind}; pub use stream::{ConversationStream, StreamError}; +/// A wrapper around `DateTime` that implements `Debug` to match `time`'s +/// `OffsetDateTime` format (e.g. `2020-01-01 0:00:00.0 +00`). +pub(crate) struct DebugDt<'a>(pub &'a chrono::DateTime); + +impl std::fmt::Debug for DebugDt<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + use chrono::{Datelike as _, Timelike as _}; + let dt = self.0; + let nanos = dt.nanosecond() % 1_000_000_000; + write!( + f, + "{}-{:02}-{:02} {}:{:02}:{:02}", + dt.year(), + dt.month(), + dt.day(), + dt.hour(), + dt.minute(), + dt.second(), + )?; + if nanos == 0 { + write!(f, ".0")?; + } else { + let s = format!("{nanos:09}"); + write!(f, ".{}", s.trim_end_matches('0'))?; + } + write!(f, " +00") + } +} + /// Format `DateTime` like `time`'s human-readable serde: `"2023-01-01 00:00:00.0"`. fn fmt_dt(dt: &chrono::DateTime) -> String { if dt.timestamp_subsec_nanos() == 0 { From 6391b8e340b46c8c78827ca7f47f538180be71c2 Mon Sep 17 00:00:00 2001 From: rgrant Date: Wed, 18 Feb 2026 18:58:26 +0000 Subject: [PATCH 16/23] 20260218 clippy fixes --- .config/jp/tools/src/lib.rs | 1 - crates/jp_cli/src/cmd/conversation/ls.rs | 4 +- crates/jp_conversation/src/conversation.rs | 4 + crates/jp_conversation/src/lib.rs | 10 +- crates/jp_llm/src/test.rs | 2 +- crates/jp_term/src/code.rs | 18 +- .../example-code/gargoyle-snaps/Cargo.toml | 20 + .../example-code/gargoyle-snaps/README.md | 111 +++ .../gargoyle-snaps/src/gargoyle_snaps.rs | 673 ++++++++++++++++++ 9 files changed, 823 insertions(+), 20 deletions(-) create mode 100644 crates/jp_test/example-code/gargoyle-snaps/Cargo.toml create mode 100644 crates/jp_test/example-code/gargoyle-snaps/README.md create mode 100644 crates/jp_test/example-code/gargoyle-snaps/src/gargoyle_snaps.rs diff --git a/.config/jp/tools/src/lib.rs b/.config/jp/tools/src/lib.rs index 607c3e8d..e27da3c0 100644 --- a/.config/jp/tools/src/lib.rs +++ b/.config/jp/tools/src/lib.rs @@ -1,4 +1,3 @@ -#![expect(clippy::too_many_arguments)] #![allow(clippy::print_stdout, clippy::print_stderr)] mod cargo; diff --git a/crates/jp_cli/src/cmd/conversation/ls.rs b/crates/jp_cli/src/cmd/conversation/ls.rs index 439296ea..6a1b5caa 100644 --- a/crates/jp_cli/src/cmd/conversation/ls.rs +++ b/crates/jp_cli/src/cmd/conversation/ls.rs @@ -160,11 +160,11 @@ impl Ls { let last_message_at_fmt = if self.full { last_message_at - .and_then(|t| { + .map(|t| { let format = "%Y-%m-%d %H:%M:%S"; let local_offset: FixedOffset = *Local::now().offset(); - Some(t.with_timezone(&local_offset).format(format).to_string()) + t.with_timezone(&local_offset).format(format).to_string() }) .unwrap_or_default() } else { diff --git a/crates/jp_conversation/src/conversation.rs b/crates/jp_conversation/src/conversation.rs index aa739865..b61aa294 100644 --- a/crates/jp_conversation/src/conversation.rs +++ b/crates/jp_conversation/src/conversation.rs @@ -123,6 +123,10 @@ impl ConversationId { } /// Get the timestamp of the conversation id as deciseconds. + /// + /// # Panics + /// + /// Panics if the timestamp is out of range for nanosecond conversion. #[must_use] pub fn as_deciseconds(&self) -> i64 { self.timestamp() diff --git a/crates/jp_conversation/src/lib.rs b/crates/jp_conversation/src/lib.rs index 615bde57..5d604c0e 100644 --- a/crates/jp_conversation/src/lib.rs +++ b/crates/jp_conversation/src/lib.rs @@ -88,6 +88,7 @@ fn parse_dt(s: &str) -> Result, String> { .map_err(|e| e.to_string()) } +/// Serialize a `DateTime` in `time`'s human-readable format. pub(crate) fn serialize_dt( dt: &chrono::DateTime, s: S, @@ -95,6 +96,7 @@ pub(crate) fn serialize_dt( s.serialize_str(&fmt_dt(dt)) } +/// Deserialize a `DateTime` from `time`'s format or RFC 3339. pub(crate) fn deserialize_dt<'de, D: serde::Deserializer<'de>>( d: D, ) -> Result, D::Error> { @@ -102,6 +104,8 @@ pub(crate) fn deserialize_dt<'de, D: serde::Deserializer<'de>>( parse_dt(&s).map_err(serde::de::Error::custom) } +/// Serialize an optional `DateTime` in `time`'s human-readable format. +#[expect(clippy::ref_option, reason = "serde serialize_with requires &Option")] pub(crate) fn serialize_dt_opt( dt: &Option>, s: S, @@ -112,12 +116,10 @@ pub(crate) fn serialize_dt_opt( } } +/// Deserialize an optional `DateTime` from `time`'s format or RFC 3339. pub(crate) fn deserialize_dt_opt<'de, D: serde::Deserializer<'de>>( d: D, ) -> Result>, D::Error> { let s: Option = serde::Deserialize::deserialize(d)?; - match s { - Some(s) => parse_dt(&s).map(Some).map_err(serde::de::Error::custom), - None => Ok(None), - } + s.map_or_else(|| Ok(None), |s| parse_dt(&s).map(Some).map_err(serde::de::Error::custom)) } diff --git a/crates/jp_llm/src/test.rs b/crates/jp_llm/src/test.rs index 32d19b55..3d812646 100644 --- a/crates/jp_llm/src/test.rs +++ b/crates/jp_llm/src/test.rs @@ -550,7 +550,7 @@ pub async fn run_chat_completion( for mut event in events { if let Event::Part { event, .. } = &mut event { event.timestamp = - Utc.with_ymd_and_hms(2020, 1, 1, 0, 0, 0).unwrap().into(); + Utc.with_ymd_and_hms(2020, 1, 1, 0, 0, 0).unwrap(); } all_events[index].push(event.clone()); diff --git a/crates/jp_term/src/code.rs b/crates/jp_term/src/code.rs index 0d150b7d..06d1daab 100644 --- a/crates/jp_term/src/code.rs +++ b/crates/jp_term/src/code.rs @@ -34,21 +34,15 @@ pub fn format(content: &str, buf: &mut String, config: &Config) -> Result ss.find_syntax_plain_text(), }; - let theme_name = match config.theme.as_deref() { - Some(name) => name, - None => { - buf.push_str(content); - return Ok(true); - } + let Some(theme_name) = config.theme.as_deref() else { + buf.push_str(content); + return Ok(true); }; let ts = ThemeSet::load_defaults(); - let theme = match ts.themes.get(theme_name) { - Some(t) => t, - None => { - buf.push_str(content); - return Ok(true); - } + let Some(theme) = ts.themes.get(theme_name) else { + buf.push_str(content); + return Ok(true); }; let mut h = HighlightLines::new(syntax, theme); diff --git a/crates/jp_test/example-code/gargoyle-snaps/Cargo.toml b/crates/jp_test/example-code/gargoyle-snaps/Cargo.toml new file mode 100644 index 00000000..0d07c2ff --- /dev/null +++ b/crates/jp_test/example-code/gargoyle-snaps/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "gargoyle-snaps" +version = "0.1.5+1196a84" +edition = "2021" +description = "Always-on snapshot testing utilities with path normalization filters" +license = "MPL-2.0" +repository = "local" +readme = "README.md" +keywords = ["testing", "snapshot", "insta"] +categories = ["development-tools::testing"] + +[lib] +path = "src/gargoyle_snaps.rs" + +[dependencies] +insta = { version = "1", features = ["json", "filters", "redactions"] } +inventory = "0.3.21" +onlyerror = "0.1" +serde = "1" +serde_json = "1" diff --git a/crates/jp_test/example-code/gargoyle-snaps/README.md b/crates/jp_test/example-code/gargoyle-snaps/README.md new file mode 100644 index 00000000..2c51ad3d --- /dev/null +++ b/crates/jp_test/example-code/gargoyle-snaps/README.md @@ -0,0 +1,111 @@ +# gargoyle-snaps + +Always-on snapshot testing utilities with path normalization filters. + +## Overview + +gargoyle-snaps wraps [insta](https://insta.rs) snapshot testing with: + +- **Standardized documentation** - Every snapshot requires `desc`, `test_purpose`, and `expected_output` parameters +- **Path normalization filters** - Timestamps and temp paths are replaced with placeholders for reproducible snapshots +- **Fixture concurrency checking** - Detect read/write conflicts when multiple tests share fixtures + +## The Independent Verification Principle + +**Accepting a snapshot must be an independent verification.** + +The `expected_output` parameter must be a human-written statement of what correctness looks like, based on your understanding of the requirements—NOT derived from the code being tested. + +Why this matters: If `expected_output` is generated from the code (e.g., by echoing computed results), and the code has a bug, then the guidance will also be wrong. The reviewer has no independent reference point. + +## Usage + +```rust +use gargoyle_snaps::{assert_snapshot_json, assert_snapshot_text, assert_snapshot_debug}; + +#[test] +fn test_issue_parsing() { + let issue = parse_issue(input); + + assert_snapshot_json!( + "parsed_issue", // snapshot name + "Parse issue #42 from markdown.", // desc: WHAT is this test about? + "Section boundaries must be respected.", // test_purpose: WHY does this test exist? + "issue_id=42, description has 2 items", // expected_output: WHAT to verify + &issue, + ); +} +``` + +## Macros + +### `assert_snapshot_json!` +For types implementing `Serialize`. Produces JSON snapshots. + +### `assert_snapshot_text!` +For string content. Produces plain text snapshots. + +### `assert_snapshot_debug!` +For types implementing `Debug` but not `Serialize`. Produces Debug-formatted snapshots. + +## Filters + +### `timestamp_filters()` +Normalizes various timestamp formats: +- ISO 8601 (`2025-01-17T14:30:00Z`) +- SQL datetime (`2025-01-17 14:30:00`) +- Issue timestamps (`[claude 20250117 14:30 UTC]`) + +### `temp_path_filters()` +Normalizes temporary directory paths: +- macOS: `/var/folders/...` and `/private/var/folders/...` +- Linux: `/tmp.*/` +- Claude Code sandbox: `/tmp/claude/...` + +### `usual_filters()` +Combines all filters for typical usage. + +## Concurrency Checking + +Declare file access patterns for fixture-sharing tests: + +```rust +use gargoyle_snaps::{ConcurrencyInfo, Fixture, TestName, CommitHashShort, AccessMode}; + +inventory::submit! { + ConcurrencyInfo { + test_name: TestName("test_read_only"), + fixture: Fixture { + name: "shared_fixture", + commit: CommitHashShort("abc1234"), + path: fixture_path.clone(), + }, + files: vec![ + (PathBuf::from("config.toml"), AccessMode::Read), + ], + } +} +``` + +Then verify no conflicts: + +```rust +#[test] +fn verify_fixture_safety() { + gargoyle_snaps::verify_no_conflicts().unwrap(); +} +``` + +## Snapshot Storage + +Snapshots are stored in `$CARGO_MANIFEST_DIR/snapshots/` with names derived from the test file: + +``` +test file: tests/integration/issue_test.rs +snapshot name: "parsed" +result: snapshots/issue__parsed.snap +``` + +## License + +MPL-2.0 diff --git a/crates/jp_test/example-code/gargoyle-snaps/src/gargoyle_snaps.rs b/crates/jp_test/example-code/gargoyle-snaps/src/gargoyle_snaps.rs new file mode 100644 index 00000000..930e5b33 --- /dev/null +++ b/crates/jp_test/example-code/gargoyle-snaps/src/gargoyle_snaps.rs @@ -0,0 +1,673 @@ +//! Always-on snapshot testing utilities with path normalization filters. +//! +//! This crate provides filters for normalizing paths and timestamps in +//! insta snapshots, ensuring reproducible tests across different environments. +//! +//! # The Independent Verification Principle +//! +//! **Accepting a snapshot must be an independent verification.** +//! +//! The `expected_output` parameter must be a human-written statement of what +//! correctness looks like, based on your understanding of the requirements—NOT +//! derived from the code being tested. +//! +//! Why this matters: If `expected_output` is generated from the code (e.g., by +//! echoing computed results), and the code has a bug, then the guidance will +//! also be wrong. The reviewer has no independent reference point. +//! +//! When a reviewer accepts a snapshot, they're checking: "Does the actual +//! output match what we independently know should be correct?" This only +//! works if `expected_output` comes from human understanding of requirements, +//! not from the code under test. + +use insta::Settings; +use insta::_macro_support::{assert_snapshot as insta_assert_snapshot, SnapshotValue}; +use onlyerror::Error; +use serde_json::{json, Map, Value}; +use std::borrow::Cow; +use std::collections::{BTreeMap, HashMap}; +use std::fmt::Debug; +use std::path::{Path, PathBuf}; + +/// Identifies a test by its fn name. +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct TestName(pub &'static str); + +/// First 7 of a Git commit hash. +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct CommitHashShort(pub &'static str); + +/// A single file conflict within a fixture. +#[derive(Debug, Clone)] +pub struct FileConflict { + pub fixture: Fixture, + pub file: PathBuf, + pub readers: Vec, + pub writers: Vec, +} + +/// All conflicts found during verification. +#[derive(Debug, Error)] +pub enum ConflictError { + #[error("File access conflicts: {0:?}")] + Conflicts(Vec), +} + +/// File access mode for concurrency checking. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum AccessMode { + /// Test only reads this file. + Read, + + /// Test reads and writes this file. + ReadWrite, +} + +/// Identifies a test fixture (shared test environment). +#[derive(Debug, Clone)] +pub struct Fixture { + pub name: &'static str, + pub commit: CommitHashShort, + pub path: PathBuf, +} + +/// Declares which files a test accesses within a fixture. +#[derive(Debug, Clone)] +pub struct ConcurrencyInfo { + pub test_name: TestName, + pub fixture: Fixture, + pub files: Vec<(PathBuf, AccessMode)>, +} + +inventory::collect!(ConcurrencyInfo); + +/// Checks for conflicts between tests accessing the same fixture files. +/// Returns Ok(()) if no conflicts, or Err with all conflicts found. +pub fn verify_no_conflicts() -> Result<(), ConflictError> { + let mut by_fixture: HashMap<&str, Vec<&ConcurrencyInfo>> = HashMap::new(); + + for info in inventory::iter:: { + by_fixture.entry(info.fixture.name).or_default().push(info); + } + + let mut conflicts = Vec::new(); + + for (_fixture_name, tests) in by_fixture { + let mut file_accesses: HashMap> = + HashMap::new(); + + for test in &tests { + for (file, access) in &test.files { + file_accesses + .entry(file.clone()) + .or_default() + .push((test, *access)); + } + } + + for (file, accesses) in file_accesses { + if accesses.len() > 1 { + let has_write = accesses.iter().any(|(_, a)| *a == AccessMode::ReadWrite); + if has_write { + let readers: Vec = accesses + .iter() + .filter(|(_, a)| *a == AccessMode::Read) + .map(|(info, _)| info.test_name.clone()) + .collect(); + let writers: Vec = accesses + .iter() + .filter(|(_, a)| *a == AccessMode::ReadWrite) + .map(|(info, _)| info.test_name.clone()) + .collect(); + let fixture = accesses[0].0.fixture.clone(); + conflicts.push(FileConflict { + fixture, + file, + readers, + writers, + }); + } + } + } + } + + if conflicts.is_empty() { + Ok(()) + } else { + Err(ConflictError::Conflicts(conflicts)) + } +} + +/// Returns the snapshots directory for the calling crate. +#[macro_export] +macro_rules! snapshots_dir { + () => { + concat!(env!("CARGO_MANIFEST_DIR"), "/snapshots") + }; +} + +/// JSON snapshot with filters, using caller's snapshots directory. +/// +/// Wraps insta's snapshot with path/timestamp normalization filters. +/// Snapshots are stored in `$CARGO_MANIFEST_DIR/snapshots/`. +/// +/// # Arguments +/// +/// * `name` - Unique identifier for this snapshot within the test file. +/// Combined with the test file stem to form the full snapshot filename. +/// Example: `"parsed_issue"` in `issue_test.rs` → `issue__parsed_issue.snap` +/// +/// The purposes of `desc`, `test_purpose`, and `expected_output` do not overlap. +/// To use any of them correctly, you must understand all three and ensure your +/// content belongs in exactly one. +/// +/// * `desc` - Brief sentence answering "WHAT is this test about?" +/// Name the functionality being tested, not the data format. +/// Keep it laconic - under 10 words. Don't say "Test" - they know it's a test. +/// Example: `"Prioritize-issue moves #3 to top."` NOT `"prioritize-issue JSON response"` +/// +/// * `test_purpose` - Complete sentence explaining WHY this test exists. +/// State the invariant or requirement being verified. +/// Be concise - no "This test verifies that" boilerplate. +/// Example: `"Nested continuations must survive round-trip parsing."` +/// +/// * `expected_output` - Concrete field values that indicate correctness. +/// **Must be human-written, independent of the code under test.** +/// Tells the reviewer exactly what to check in the snapshot data. +/// Be specific: name fields, expected values, structural properties. +/// NEVER generate this dynamically from test inputs or code—if the code +/// is wrong, dynamic guidance will be wrong too. +/// Example: `"issue_id=42, title contains 'test', description has 2 items, +/// first continuation has 3 subitems"` +/// +/// * `result` - The value to snapshot (must be serializable) +/// +/// # Reviewer Flow +/// +/// When someone reviews a snapshot, they read in order: +/// 1. `desc` → "What am I looking at?" +/// 2. `test_purpose` → "Why does this matter? Where should I look?" +/// 3. `expected_output` → "What specific values should I verify?" +/// 4. Compare against actual snapshot content +/// +/// # Example +/// +/// ```ignore +/// assert_snapshot_json!( +/// "parsed_issue", +/// "Parse issue #42 from markdown.", +/// "Section boundaries must be respected. \ +/// Check Analysis section is separate from description.", +/// "issue_id=42, description has 1 item, analysis_section is Some", +/// &parsed_issue, +/// ); +/// ``` +#[macro_export] +macro_rules! assert_snapshot_json { + ($name:expr, $desc:expr, $test_purpose:expr, $expected_output:expr, $result:expr $(,)?) => { + $crate::assert_snapshot_impl_json( + env!("CARGO_MANIFEST_DIR"), + file!(), + module_path!(), + line!(), + $name, + $desc, + $test_purpose, + $expected_output, + stringify!($result), + $result, + ) + }; +} + +/// Text snapshot with filters, using caller's snapshots directory. +/// +/// Wraps insta's snapshot with path/timestamp normalization filters. +/// Snapshots are stored in `$CARGO_MANIFEST_DIR/snapshots/`. +/// +/// # Arguments +/// +/// * `name` - Unique identifier for this snapshot within the test file. +/// Combined with the test file stem to form the full snapshot filename. +/// Example: `"formatted_output"` in `format_test.rs` → `format__formatted_output.snap` +/// +/// The purposes of `desc`, `test_purpose`, and `expected_output` do not overlap. +/// To use any of them correctly, you must understand all three and ensure your +/// content belongs in exactly one. +/// +/// * `desc` - Brief sentence answering "WHAT is this test about?" +/// Name the functionality being tested, not the data format. +/// Keep it laconic - under 10 words. Don't say "Test" - they know it's a test. +/// Example: `"Prettyprint issue with catharsis section."` +/// +/// * `test_purpose` - Complete sentence explaining WHY this test exists. +/// State the invariant or requirement being verified. +/// Be concise - no "This test verifies that" boilerplate. +/// Example: `"Lines must wrap at 99 chars with proper continuation indentation."` +/// +/// * `expected_output` - Concrete field values that indicate correctness. +/// **Must be human-written, independent of the code under test.** +/// Tells the reviewer exactly what to check in the snapshot data. +/// Be specific: name fields, expected values, structural properties. +/// NEVER generate this dynamically from test inputs or code—if the code +/// is wrong, dynamic guidance will be wrong too. +/// Example: `"No line exceeds 99 chars, continuation lines start with 4 spaces, +/// timestamp appears on first line"` +/// +/// * `result` - The string value to snapshot +/// +/// # Reviewer Flow +/// +/// When someone reviews a snapshot, they read in order: +/// 1. `desc` → "What am I looking at?" +/// 2. `test_purpose` → "Why does this matter? Where should I look?" +/// 3. `expected_output` → "What specific values should I verify?" +/// 4. Compare against actual snapshot content +/// +/// # Example +/// +/// ```ignore +/// assert_snapshot_text!( +/// "wrapped_output", +/// "Line wrapping for long description item.", +/// "Autowrap must preserve content while respecting line limits. \ +/// Check continuation line indentation.", +/// "Lines under 99 chars, continuations indented 4 spaces", +/// &formatted_text, +/// ); +/// ``` +#[macro_export] +macro_rules! assert_snapshot_text { + ($name:expr, $desc:expr, $test_purpose:expr, $expected_output:expr, $result:expr $(,)?) => { + $crate::assert_snapshot_impl_text( + env!("CARGO_MANIFEST_DIR"), + file!(), + module_path!(), + line!(), + $name, + $desc, + $test_purpose, + $expected_output, + stringify!($result), + $result, + ) + }; +} + +/// Debug snapshot with filters, using caller's snapshots directory. +/// +/// Wraps insta's debug snapshot with path/timestamp normalization filters. +/// Snapshots are stored in `$CARGO_MANIFEST_DIR/snapshots/`. +/// +/// Use this for types that implement `Debug` but not `Serialize`. +/// +/// # Arguments +/// +/// * `name` - Unique identifier for this snapshot within the test file. +/// Combined with the test file stem to form the full snapshot filename. +/// Example: `"parsed_struct"` in `parser_test.rs` → `parser__parsed_struct.snap` +/// +/// The purposes of `desc`, `test_purpose`, and `expected_output` do not overlap. +/// To use any of them correctly, you must understand all three and ensure your +/// content belongs in exactly one. +/// +/// * `desc` - Brief sentence answering "WHAT is this test about?" +/// Name the functionality being tested, not the data format. +/// Keep it laconic - under 10 words. Don't say "Test" - they know it's a test. +/// Example: `"Parse nested bullets into Issue struct."` +/// +/// * `test_purpose` - Complete sentence explaining WHY this test exists. +/// State the invariant or requirement being verified. +/// Be concise - no "This test verifies that" boilerplate. +/// Example: `"Continuations must parse into nested structure."` +/// +/// * `expected_output` - Concrete field values that indicate correctness. +/// **Must be human-written, independent of the code under test.** +/// Tells the reviewer exactly what to check in the snapshot data. +/// Be specific: name fields, expected values, structural properties. +/// NEVER generate this dynamically from test inputs or code—if the code +/// is wrong, dynamic guidance will be wrong too. +/// Example: `"description.len()=2, first item has 1 continuation, +/// continuation contains 3 subitems"` +/// +/// * `result` - The value to snapshot (must implement Debug) +/// +/// # Reviewer Flow +/// +/// When someone reviews a snapshot, they read in order: +/// 1. `desc` → "What am I looking at?" +/// 2. `test_purpose` → "Why does this matter? Where should I look?" +/// 3. `expected_output` → "What specific values should I verify?" +/// 4. Compare against actual snapshot content +/// +/// # Example +/// +/// ```ignore +/// assert_snapshot_debug!( +/// "nested_issue", +/// "Deeply nested continuation structure.", +/// "Three levels of nesting must be preserved. \ +/// Check continuations at each level.", +/// "description[0].continuations.len()=1, sublist has 2 items, \ +/// second subitem has its own continuations", +/// &parsed_issue, +/// ); +/// ``` +#[macro_export] +macro_rules! assert_snapshot_debug { + ($name:expr, $desc:expr, $test_purpose:expr, $expected_output:expr, $result:expr $(,)?) => { + $crate::assert_snapshot_impl_debug( + env!("CARGO_MANIFEST_DIR"), + file!(), + module_path!(), + line!(), + $name, + $desc, + $test_purpose, + $expected_output, + stringify!($result), + $result, + ) + }; +} + +/// Standard timestamp filters for snapshot tests. +/// +/// This function provides regex filters to replace timestamps with a placeholder +/// so snapshots remain stable across test runs. +pub fn timestamp_filters() -> Vec<(&'static str, &'static str)> { + vec![ + // ISO 8601 with Z timezone + ( + r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z", + "[timestamp]", + ), + // ISO 8601 with timezone offset + ( + r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?[+-]\d{2}:\d{2}", + "[timestamp]", + ), + // ISO 8601 without timezone (local time, no Z or offset) + ( + r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?", + "[timestamp]", + ), + // SQL datetime format (common in SQLite) + ( + r"\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}(?:\.\d+)?", + "[timestamp]", + ), + // Full timestamped prefix with username (e.g., [claude 20251108 14:30 UTC]) + // NOTE: Must come before the plain timestamp pattern to match correctly + ( + r"\[[\w-]+ \d{8} \d{2}:\d{2} UTC\]", + "[USERNAME YYYYMMDD HH:MM UTC]", + ), + // Issue timestamp format (YYYYMMDD HH:MM UTC) + (r"\d{8} \d{2}:\d{2} UTC", "YYYYMMDD HH:MM UTC"), + ] +} + +/// Filters for normalizing temporary directory paths in snapshots. +pub fn temp_path_filters() -> Vec<(&'static str, &'static str)> { + vec![ + // macOS temp directories (with optional /private prefix) + (r"/private/var/folders/[^/]+/[^/]+/[^/]+/[^/]+/", "[tmp]/"), + (r"/var/folders/[^/]+/[^/]+/[^/]+/[^/]+/", "[tmp]/"), + // Claude Code sandbox temp directories (with optional /private prefix) + (r"/private/tmp/claude/[^/]+/", "[tmp]/"), + (r"/tmp/claude/[^/]+/", "[tmp]/"), + // Linux/generic temp directories + (r"/tmp\.[^/]+/", "[tmp]/"), + // Generic .tmp* patterns + (r"\.tmp[A-Za-z0-9]+/", "[tmp]/"), + ] +} + +/// Filters for normalizing Debug struct datetime fields. +/// +/// These handle the `datetime: "..."` pattern that appears in Debug output +/// of structs containing DateTime fields. +pub fn debug_datetime_filters() -> Vec<(&'static str, &'static str)> { + vec![ + // Debug struct datetime format (datetime: "2025-01-01T...") + (r#"datetime: "[^"]+""#, r#"datetime: "[DATETIME]""#), + ] +} + +/// Filters for normalizing home directory paths in snapshots. +/// +/// Replaces `/Users/username/` or `/home/username/` with `[HOME]/` +/// so snapshots are portable across machines. +pub fn home_path_filters() -> Vec<(&'static str, &'static str)> { + vec![ + // macOS home directories (/Users/username/) + (r"/Users/[^/]+/", "[HOME]/"), + // Linux home directories (/home/username/) + (r"/home/[^/]+/", "[HOME]/"), + ] +} + +/// Combined filters for typical snapshot testing needs. +/// +/// Includes timestamp, temporary path, debug datetime, and home path normalization. +pub fn usual_filters() -> Vec<(&'static str, &'static str)> { + let mut filters = timestamp_filters(); + filters.extend(temp_path_filters()); + filters.extend(debug_datetime_filters()); + filters.extend(home_path_filters()); + filters +} + +/// Recursively sorts all object keys in a JSON value alphabetically. +/// +/// This ensures deterministic JSON output regardless of the order in which +/// keys were inserted into serde_json::Value objects. +fn sort_json_keys(value: Value) -> Value { + match value { + Value::Object(map) => { + let sorted: BTreeMap = map + .into_iter() + .map(|(k, v)| (k, sort_json_keys(v))) + .collect(); + Value::Object(sorted.into_iter().collect::>()) + } + Value::Array(arr) => Value::Array(arr.into_iter().map(sort_json_keys).collect()), + other => other, + } +} + +/// Serializes a value to pretty-printed JSON with sorted keys. +fn serialize_json_sorted(value: &T) -> String { + let json_value: Value = + serde_json::to_value(value).expect("Failed to convert to serde_json::Value"); + let sorted = sort_json_keys(json_value); + serde_json::to_string_pretty(&sorted).expect("Failed to serialize sorted JSON") +} + +/// Runs snapshot assertion with standardized insta settings and correct source attribution. +/// +/// Builds snapshot name from source_file (e.g., "tests/integration/json_execution_test.rs" +/// becomes "json_execution") and combines with snapshot_name. +/// +/// Calls insta's internal `assert_snapshot` directly to pass the correct source_file, +/// ensuring snapshot metadata shows the actual test file, not this library. +#[allow(clippy::too_many_arguments, clippy::absolute_paths)] +fn run_snapshot_assertion( + manifest_dir: &'static str, + source_file: &'static str, + module_path: &'static str, + line: u32, + snapshot_name: &str, + desc: &str, + test_purpose: &str, + expected_output: &str, + expression: &str, + content: &str, +) { + assert!( + test_purpose.len() > 4, + "test_purpose must be more than 4 characters" + ); + assert!( + expected_output.len() > 4, + "expected_output must be more than 4 characters" + ); + + let stem = Path::new(source_file) + .file_stem() + .and_then(|s| s.to_str()) + .expect("source_file should have a valid file stem"); + let prefix = stem.strip_suffix("_test").unwrap_or(stem); + let full_name = format!("{prefix}__{snapshot_name}"); + + let snapshot_path = format!("{manifest_dir}/snapshots"); + + let info_value = json!({ + "test_purpose": test_purpose, + "expected_output": expected_output + }); + + let mut settings = Settings::clone_current(); + settings.set_description(desc); + settings.set_info(&info_value); + settings.set_snapshot_path(&snapshot_path); + settings.set_prepend_module_to_snapshot(false); + for (pattern, replacement) in usual_filters() { + settings.add_filter(pattern, replacement); + } + + settings.bind(|| { + let snapshot_value = SnapshotValue::FileText { + name: Some(Cow::Borrowed(&full_name)), + content, + }; + + // Get workspace root (same logic as insta's _get_workspace_root! macro) + let workspace = insta::_macro_support::get_cargo_workspace( + insta::_macro_support::Workspace::DetectWithCargo(manifest_dir), + ); + + insta_assert_snapshot( + snapshot_value, + workspace.as_path(), + module_path, // function_name - insta uses module_path for this + module_path, + source_file, // This is the key fix - pass actual test file + line, + expression, + ) + .unwrap(); + }); +} + +#[doc(hidden)] +#[allow(clippy::too_many_arguments)] +pub fn assert_snapshot_impl_json( + manifest_dir: &'static str, + source_file: &'static str, + module_path: &'static str, + line: u32, + snapshot_name: &str, + desc: &str, + test_purpose: &str, + expected_output: &str, + expression: &str, + result: T, +) { + let content = serialize_json_sorted(&result); + run_snapshot_assertion( + manifest_dir, + source_file, + module_path, + line, + snapshot_name, + desc, + test_purpose, + expected_output, + expression, + &content, + ); +} + +#[doc(hidden)] +#[allow(clippy::too_many_arguments)] +pub fn assert_snapshot_impl_text( + manifest_dir: &'static str, + source_file: &'static str, + module_path: &'static str, + line: u32, + snapshot_name: &str, + desc: &str, + test_purpose: &str, + expected_output: &str, + expression: &str, + result: impl AsRef, +) { + run_snapshot_assertion( + manifest_dir, + source_file, + module_path, + line, + snapshot_name, + desc, + test_purpose, + expected_output, + expression, + result.as_ref(), + ); +} + +#[doc(hidden)] +#[allow(clippy::too_many_arguments)] +pub fn assert_snapshot_impl_debug( + manifest_dir: &'static str, + source_file: &'static str, + module_path: &'static str, + line: u32, + snapshot_name: &str, + desc: &str, + test_purpose: &str, + expected_output: &str, + expression: &str, + result: T, +) { + let content = format!("{:#?}", result); + run_snapshot_assertion( + manifest_dir, + source_file, + module_path, + line, + snapshot_name, + desc, + test_purpose, + expected_output, + expression, + &content, + ); +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_filters_not_empty() { + assert!(!timestamp_filters().is_empty()); + assert!(!temp_path_filters().is_empty()); + assert!(!usual_filters().is_empty()); + } + + #[test] + fn test_usual_filters_combines_all() { + let usual = usual_filters(); + let timestamps = timestamp_filters(); + let temps = temp_path_filters(); + let debug_dt = debug_datetime_filters(); + let home = home_path_filters(); + assert_eq!( + usual.len(), + timestamps.len() + temps.len() + debug_dt.len() + home.len() + ); + } +} From a341b8955cd44cbe5696c31377f6f268c50edd20 Mon Sep 17 00:00:00 2001 From: rgrant Date: Wed, 18 Feb 2026 19:00:02 +0000 Subject: [PATCH 17/23] 20260218 cargo fmt --- crates/jp_conversation/src/lib.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/crates/jp_conversation/src/lib.rs b/crates/jp_conversation/src/lib.rs index 5d604c0e..ce253f6e 100644 --- a/crates/jp_conversation/src/lib.rs +++ b/crates/jp_conversation/src/lib.rs @@ -105,7 +105,10 @@ pub(crate) fn deserialize_dt<'de, D: serde::Deserializer<'de>>( } /// Serialize an optional `DateTime` in `time`'s human-readable format. -#[expect(clippy::ref_option, reason = "serde serialize_with requires &Option")] +#[expect( + clippy::ref_option, + reason = "serde serialize_with requires &Option" +)] pub(crate) fn serialize_dt_opt( dt: &Option>, s: S, @@ -121,5 +124,8 @@ pub(crate) fn deserialize_dt_opt<'de, D: serde::Deserializer<'de>>( d: D, ) -> Result>, D::Error> { let s: Option = serde::Deserialize::deserialize(d)?; - s.map_or_else(|| Ok(None), |s| parse_dt(&s).map(Some).map_err(serde::de::Error::custom)) + s.map_or_else( + || Ok(None), + |s| parse_dt(&s).map(Some).map_err(serde::de::Error::custom), + ) } From 879fedc930ed10ea89df92cc42f234e4ee547cc9 Mon Sep 17 00:00:00 2001 From: Jay Oster Date: Wed, 18 Feb 2026 11:31:34 -0800 Subject: [PATCH 18/23] Replace octocrab with jp_github --- .config/jp/tools/Cargo.toml | 11 +- .config/jp/tools/src/github.rs | 10 +- .../jp/tools/src/github/create_issue_bug.rs | 11 +- .../src/github/create_issue_enhancement.rs | 10 +- .config/jp/tools/src/github/issues.rs | 6 +- .config/jp/tools/src/github/pulls.rs | 16 +- .config/jp/tools/src/github/repo.rs | 10 +- Cargo.lock | 208 +--------- Cargo.toml | 2 +- crates/jp_github/Cargo.toml | 28 ++ crates/jp_github/src/client.rs | 284 +++++++++++++ crates/jp_github/src/error.rs | 53 +++ crates/jp_github/src/handlers.rs | 387 ++++++++++++++++++ crates/jp_github/src/lib.rs | 13 + crates/jp_github/src/models.rs | 124 ++++++ crates/jp_github/src/page.rs | 10 + crates/jp_github/src/params.rs | 17 + crates/jp_github/src/tests.rs | 319 +++++++++++++++ crates/jp_test/src/mock.rs | 6 +- supply-chain/config.toml | 136 ------ supply-chain/imports.lock | 70 ---- 21 files changed, 1290 insertions(+), 441 deletions(-) create mode 100644 crates/jp_github/Cargo.toml create mode 100644 crates/jp_github/src/client.rs create mode 100644 crates/jp_github/src/error.rs create mode 100644 crates/jp_github/src/handlers.rs create mode 100644 crates/jp_github/src/lib.rs create mode 100644 crates/jp_github/src/models.rs create mode 100644 crates/jp_github/src/page.rs create mode 100644 crates/jp_github/src/params.rs create mode 100644 crates/jp_github/src/tests.rs diff --git a/.config/jp/tools/Cargo.toml b/.config/jp/tools/Cargo.toml index 47aecc8e..679d0a41 100644 --- a/.config/jp/tools/Cargo.toml +++ b/.config/jp/tools/Cargo.toml @@ -28,14 +28,7 @@ grep-regex = { workspace = true } grep-searcher = { workspace = true } ignore = { workspace = true } indoc = { workspace = true } -octocrab = { workspace = true, optional = true, features = [ - "default-client", - "follow-redirect", - "retry", - "rustls", - "rustls-ring", - "timeout", -] } +jp_github = { workspace = true, optional = true } quick-xml = { workspace = true, features = ["encoding", "serialize"] } reqwest = { workspace = true, features = [ "charset", @@ -53,7 +46,7 @@ tokio = { workspace = true, features = ["full"] } url = { workspace = true, features = ["serde", "std"] } [features] -github = ["dep:octocrab"] +github = ["dep:jp_github"] [dev-dependencies] assert_matches = { workspace = true } diff --git a/.config/jp/tools/src/github.rs b/.config/jp/tools/src/github.rs index 667db5d7..b5e8b5c2 100644 --- a/.config/jp/tools/src/github.rs +++ b/.config/jp/tools/src/github.rs @@ -82,14 +82,14 @@ async fn auth() -> Result<(), Box "unable to get auth token. Set `JP_GITHUB_TOKEN` or `GITHUB_TOKEN` to a valid token." })?; - let octocrab = octocrab::Octocrab::builder() + let octocrab = jp_github::Octocrab::builder() .personal_token(token) .build() .map_err(|err| format!("unable to create github client: {err:#}"))?; - octocrab::initialise(octocrab); + jp_github::initialise(octocrab); - if octocrab::instance().current().user().await.is_err() { + if jp_github::instance().current().user().await.is_err() { return Err( "Unable to authenticate with github. This might be because the token is expired. \ Either set `JP_GITHUB_TOKEN` or `GITHUB_TOKEN` to a valid token." @@ -100,9 +100,9 @@ async fn auth() -> Result<(), Box Ok(()) } -fn handle_404(error: octocrab::Error, msg: impl Into) -> Error { +fn handle_404(error: jp_github::Error, msg: impl Into) -> Error { match error { - octocrab::Error::GitHub { source, .. } if source.status_code.as_u16() == 404 => { + jp_github::Error::GitHub { source, .. } if source.status_code.as_u16() == 404 => { msg.into().into() } _ => Box::new(error) as Error, diff --git a/.config/jp/tools/src/github/create_issue_bug.rs b/.config/jp/tools/src/github/create_issue_bug.rs index b26b831f..09adb053 100644 --- a/.config/jp/tools/src/github/create_issue_bug.rs +++ b/.config/jp/tools/src/github/create_issue_bug.rs @@ -9,6 +9,7 @@ use crate::{ util::OneOrMany, }; +#[allow(clippy::too_many_arguments)] pub(crate) async fn github_create_issue_bug( title: String, description: String, @@ -94,7 +95,7 @@ pub(crate) async fn github_create_issue_bug( _ => return Err("Invalid complexity, must be one of `low`, `medium`, or `high`.".into()), } - let issue = octocrab::instance() + let issue = jp_github::instance() .issues(ORG, REPO) .create(&title) .body(&body) @@ -109,13 +110,13 @@ pub(crate) async fn github_create_issue_bug( } async fn check_labels(as_ref: Option<&[String]>) -> Result<()> { - let page = octocrab::instance() + let page = jp_github::instance() .issues(ORG, REPO) .list_labels_for_repo() .send() .await?; - let labels = octocrab::instance().all_pages(page).await?; + let labels = jp_github::instance().all_pages(page).await?; let mut invalid_labels = vec![]; for label in as_ref.into_iter().flatten() { @@ -161,13 +162,13 @@ async fn check_labels(as_ref: Option<&[String]>) -> Result<()> { } async fn check_assignees(assignees: Option<&[String]>) -> Result<()> { - let page = octocrab::instance() + let page = jp_github::instance() .repos(ORG, REPO) .list_collaborators() .send() .await?; - let collaborators = octocrab::instance().all_pages(page).await?; + let collaborators = jp_github::instance().all_pages(page).await?; let mut invalid_assignees = vec![]; for assignee in assignees.into_iter().flatten() { diff --git a/.config/jp/tools/src/github/create_issue_enhancement.rs b/.config/jp/tools/src/github/create_issue_enhancement.rs index 7f4fda38..2c70fc18 100644 --- a/.config/jp/tools/src/github/create_issue_enhancement.rs +++ b/.config/jp/tools/src/github/create_issue_enhancement.rs @@ -89,7 +89,7 @@ pub(crate) async fn github_create_issue_enhancement( _ => return Err("Invalid complexity, must be one of `low`, `medium`, or `high`.".into()), } - let issue = octocrab::instance() + let issue = jp_github::instance() .issues(ORG, REPO) .create(&title) .body(&body) @@ -104,13 +104,13 @@ pub(crate) async fn github_create_issue_enhancement( } async fn check_labels(as_ref: Option<&[String]>) -> Result<()> { - let page = octocrab::instance() + let page = jp_github::instance() .issues(ORG, REPO) .list_labels_for_repo() .send() .await?; - let labels = octocrab::instance().all_pages(page).await?; + let labels = jp_github::instance().all_pages(page).await?; let mut invalid_labels = vec![]; for label in as_ref.into_iter().flatten() { @@ -156,13 +156,13 @@ async fn check_labels(as_ref: Option<&[String]>) -> Result<()> { } async fn check_assignees(assignees: Option<&[String]>) -> Result<()> { - let page = octocrab::instance() + let page = jp_github::instance() .repos(ORG, REPO) .list_collaborators() .send() .await?; - let collaborators = octocrab::instance().all_pages(page).await?; + let collaborators = jp_github::instance().all_pages(page).await?; let mut invalid_assignees = vec![]; for assignee in assignees.into_iter().flatten() { diff --git a/.config/jp/tools/src/github/issues.rs b/.config/jp/tools/src/github/issues.rs index fb5c2eb5..e4b87470 100644 --- a/.config/jp/tools/src/github/issues.rs +++ b/.config/jp/tools/src/github/issues.rs @@ -31,7 +31,7 @@ async fn get_issue(number: u64) -> Result { linked_pull_request: Option, } - let issue = octocrab::instance() + let issue = jp_github::instance() .issues(ORG, REPO) .get(number) .await @@ -68,14 +68,14 @@ async fn get_issues() -> Result { linked_pull_request: Option, } - let page = octocrab::instance() + let page = jp_github::instance() .issues(ORG, REPO) .list() .per_page(100) .send() .await?; - let issue = octocrab::instance() + let issue = jp_github::instance() .all_pages(page) .await? .into_iter() diff --git a/.config/jp/tools/src/github/pulls.rs b/.config/jp/tools/src/github/pulls.rs index aaef414e..1c4298b3 100644 --- a/.config/jp/tools/src/github/pulls.rs +++ b/.config/jp/tools/src/github/pulls.rs @@ -1,5 +1,5 @@ use chrono::{DateTime, Utc}; -use octocrab::{models::repos::DiffEntryStatus, params}; +use jp_github::{models::repos::DiffEntryStatus, params}; use url::Url; use super::auth; @@ -60,19 +60,19 @@ async fn get(number: u64) -> Result { changed_files: Vec, } - let pull = octocrab::instance() + let pull = jp_github::instance() .pulls(ORG, REPO) .get(number) .await .map_err(|e| handle_404(e, format!("Pull #{number} not found in {ORG}/{REPO}")))?; - let page = octocrab::instance() + let page = jp_github::instance() .pulls(ORG, REPO) .list_files(number) .await .map_err(|e| handle_404(e, format!("Pull #{number} not found in {ORG}/{REPO}")))?; - let changed_files = octocrab::instance() + let changed_files = jp_github::instance() .all_pages(page) .await? .into_iter() @@ -118,13 +118,13 @@ async fn diff(number: u64, file_diffs: Vec) -> Result { patch: Option, } - let page = octocrab::instance() + let page = jp_github::instance() .pulls(ORG, REPO) .list_files(number) .await .map_err(|e| handle_404(e, format!("Pull #{number} not found in {ORG}/{REPO}")))?; - let changed_files: Vec<_> = octocrab::instance() + let changed_files: Vec<_> = jp_github::instance() .all_pages(page) .await? .into_iter() @@ -168,7 +168,7 @@ async fn list(state: Option) -> Result { None => params::State::All, }; - let page = octocrab::instance() + let page = jp_github::instance() .pulls(ORG, REPO) .list() .state(state) @@ -176,7 +176,7 @@ async fn list(state: Option) -> Result { .send() .await?; - let pull = octocrab::instance() + let pull = jp_github::instance() .all_pages(page) .await? .into_iter() diff --git a/.config/jp/tools/src/github/repo.rs b/.config/jp/tools/src/github/repo.rs index 2d1d7295..302639a3 100644 --- a/.config/jp/tools/src/github/repo.rs +++ b/.config/jp/tools/src/github/repo.rs @@ -27,13 +27,13 @@ pub(crate) async fn github_code_search( auth().await?; let repository = repository.unwrap_or_else(|| format!("{ORG}/{REPO}")); - let page = octocrab::instance() + let page = jp_github::instance() .search() .code(&format!("{query} repo:{repository}")) .send() .await?; - let matches = octocrab::instance() + let matches = jp_github::instance() .all_pages(page) .await? .into_iter() @@ -72,7 +72,7 @@ pub(crate) async fn github_read_file( .split_once('/') .ok_or("`repository` must be in the form of /")?; - let client = octocrab::instance(); + let client = jp_github::instance(); let files = client.repos(org, repo); let mut files = files.get_content().path(path); @@ -84,7 +84,7 @@ pub(crate) async fn github_read_file( .send() .await .map_err(|err| match err { - octocrab::Error::GitHub { source, .. } if source.status_code == 404 => { + jp_github::Error::GitHub { source, .. } if source.status_code == 404 => { "file does not exist for the provided repository".to_owned() } _ => format!("failed to fetch file: {err:?}"), @@ -155,7 +155,7 @@ pub(crate) async fn github_list_files( } "}; - let result: Value = octocrab::instance() + let result: Value = jp_github::instance() .graphql(&json!({ "query": query, "variables": { diff --git a/Cargo.lock b/Cargo.lock index b158816b..ce6aaa49 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -130,12 +130,6 @@ version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" -[[package]] -name = "arc-swap" -version = "1.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" - [[package]] name = "arraydeque" version = "0.5.1" @@ -813,15 +807,6 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" -[[package]] -name = "deranged" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d630bccd429a5bb5a64b5e94f693bfc48c9f8566418fda4c494cc94f911f87cc" -dependencies = [ - "powerfmt", -] - [[package]] name = "derive_builder" version = "0.20.2" @@ -1589,19 +1574,6 @@ dependencies = [ "webpki-roots", ] -[[package]] -name = "hyper-timeout" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0" -dependencies = [ - "hyper", - "hyper-util", - "pin-project-lite", - "tokio", - "tower-service", -] - [[package]] name = "hyper-util" version = "0.1.17" @@ -2117,6 +2089,20 @@ dependencies = [ "timeago", ] +[[package]] +name = "jp_github" +version = "0.1.0" +dependencies = [ + "chrono", + "jp_test", + "reqwest", + "serde", + "serde_json", + "thiserror 2.0.18", + "tokio", + "url", +] + [[package]] name = "jp_id" version = "0.1.0" @@ -2376,21 +2362,6 @@ dependencies = [ "uuid-simd", ] -[[package]] -name = "jsonwebtoken" -version = "9.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a87cc7a48537badeae96744432de36f4be2b4a34a05a5ef32e9dd8a1c169dde" -dependencies = [ - "base64 0.22.1", - "js-sys", - "pem", - "ring", - "serde", - "serde_json", - "simple_asn1", -] - [[package]] name = "lazy-regex" version = "3.4.1" @@ -2709,12 +2680,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "num-conv" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050" - [[package]] name = "num-integer" version = "0.1.46" @@ -2764,45 +2729,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "octocrab" -version = "0.45.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9142159757f166a7b20e3dcd410a5af008a63747c73e836a01fa4f7af84d2c4" -dependencies = [ - "arc-swap", - "async-trait", - "base64 0.22.1", - "bytes", - "cfg-if", - "chrono", - "either", - "futures", - "futures-util", - "http", - "http-body", - "http-body-util", - "hyper", - "hyper-rustls", - "hyper-timeout", - "hyper-util", - "jsonwebtoken", - "once_cell", - "percent-encoding", - "pin-project", - "secrecy", - "serde", - "serde_json", - "serde_path_to_error", - "serde_urlencoded", - "snafu", - "tokio", - "tower", - "tower-http", - "url", - "web-time", -] - [[package]] name = "ollama-rs" version = "0.3.2" @@ -2957,16 +2883,6 @@ dependencies = [ "smallvec", ] -[[package]] -name = "pem" -version = "3.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38af38e8470ac9dee3ce1bae1af9c1671fffc44ddfd8bd1d0a3445bf349a8ef3" -dependencies = [ - "base64 0.22.1", - "serde", -] - [[package]] name = "percent-encoding" version = "2.3.2" @@ -3017,26 +2933,6 @@ dependencies = [ "sha2", ] -[[package]] -name = "pin-project" -version = "1.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "pin-project-lite" version = "0.2.16" @@ -3064,12 +2960,6 @@ dependencies = [ "zerovec", ] -[[package]] -name = "powerfmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" - [[package]] name = "ppv-lite86" version = "0.2.21" @@ -3988,18 +3878,6 @@ dependencies = [ "unicode-segmentation", ] -[[package]] -name = "simple_asn1" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "297f631f50729c8c99b84667867963997ec0b50f32b2a7dbcab828ef0541e8bb" -dependencies = [ - "num-bigint", - "num-traits", - "thiserror 2.0.18", - "time", -] - [[package]] name = "slab" version = "0.4.11" @@ -4012,27 +3890,6 @@ version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" -[[package]] -name = "snafu" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e84b3f4eacbf3a1ce05eac6763b4d629d60cbc94d632e4092c54ade71f1e1a2" -dependencies = [ - "snafu-derive", -] - -[[package]] -name = "snafu-derive" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1c97747dbf44bb1ca44a561ece23508e99cb592e862f22222dcf42f51d1e451" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "socket2" version = "0.6.0" @@ -4270,37 +4127,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "time" -version = "0.3.47" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" -dependencies = [ - "deranged", - "itoa", - "num-conv", - "powerfmt", - "serde_core", - "time-core", - "time-macros", -] - -[[package]] -name = "time-core" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" - -[[package]] -name = "time-macros" -version = "0.2.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" -dependencies = [ - "num-conv", - "time-core", -] - [[package]] name = "timeago" version = "0.5.0" @@ -4466,8 +4292,8 @@ dependencies = [ "ignore", "indoc", "insta", + "jp_github", "jp_tool", - "octocrab", "pretty_assertions", "quick-xml", "reqwest", @@ -4491,10 +4317,8 @@ dependencies = [ "pin-project-lite", "sync_wrapper", "tokio", - "tokio-util", "tower-layer", "tower-service", - "tracing", ] [[package]] @@ -4513,7 +4337,6 @@ dependencies = [ "tower", "tower-layer", "tower-service", - "tracing", ] [[package]] @@ -4937,7 +4760,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" dependencies = [ "js-sys", - "serde", "wasm-bindgen", ] diff --git a/Cargo.toml b/Cargo.toml index fd31f206..04ee422d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ jp_attachment_mcp_resources = { path = "crates/jp_attachment_mcp_resources" } jp_config = { path = "crates/jp_config" } jp_conversation = { path = "crates/jp_conversation" } jp_format = { path = "crates/jp_format" } +jp_github = { path = "crates/jp_github" } jp_id = { path = "crates/jp_id" } jp_inquire = { path = "crates/jp_inquire" } jp_llm = { path = "crates/jp_llm" } @@ -69,7 +70,6 @@ itertools = { version = "0.14", default-features = false } jsonschema = { version = "0.37", default-features = false } linkme = { version = "0.3", default-features = false } minijinja = { version = "2", default-features = false } -octocrab = { version = "0.45", default-features = false } ollama-rs = { version = "0.3", default-features = false } open-editor = { version = "1", default-features = false } openai = { git = "https://github.com/JeanMertz/openai", branch = "tmp", default-features = false } # diff --git a/crates/jp_github/Cargo.toml b/crates/jp_github/Cargo.toml new file mode 100644 index 00000000..e324b8f1 --- /dev/null +++ b/crates/jp_github/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "jp_github" + +authors.workspace = true +description.workspace = true +documentation.workspace = true +edition.workspace = true +homepage.workspace = true +license-file.workspace = true +publish.workspace = true +readme.workspace = true +repository.workspace = true +version.workspace = true + +[dependencies] +chrono = { workspace = true, features = ["serde"] } +reqwest = { workspace = true, features = ["json", "rustls-tls", "http2"] } +serde = { workspace = true, features = ["derive"] } +serde_json = { workspace = true } +thiserror = { workspace = true } +url = { workspace = true, features = ["serde"] } + +[dev-dependencies] +jp_test = { workspace = true } +tokio = { workspace = true, features = ["macros", "rt-multi-thread"] } + +[lints] +workspace = true diff --git a/crates/jp_github/src/client.rs b/crates/jp_github/src/client.rs new file mode 100644 index 00000000..a5c58f90 --- /dev/null +++ b/crates/jp_github/src/client.rs @@ -0,0 +1,284 @@ +use std::sync::{Arc, Mutex, OnceLock}; + +use reqwest::{ + Client, + header::{ACCEPT, AUTHORIZATION, HeaderMap, HeaderName, HeaderValue, USER_AGENT}, +}; +use serde::{Serialize, de::DeserializeOwned}; +use serde_json::Value; + +use crate::{ + Error, GitHubError, Page, Result, StatusCode, + handlers::{CurrentHandler, IssuesHandler, PullsHandler, ReposHandler, SearchHandler}, +}; + +#[derive(Clone)] +pub struct Octocrab { + pub(crate) inner: Arc, +} + +pub(crate) struct Inner { + pub(crate) client: Client, + pub(crate) api_base: String, + pub(crate) graphql_url: String, +} + +pub struct OctocrabBuilder { + token: Option, +} + +impl Octocrab { + #[must_use] + pub fn builder() -> OctocrabBuilder { + OctocrabBuilder { token: None } + } + + #[must_use] + pub fn current(&self) -> CurrentHandler { + CurrentHandler { + client: self.clone(), + } + } + + #[must_use] + pub fn issues(&self, owner: impl Into, repo: impl Into) -> IssuesHandler { + IssuesHandler { + client: self.clone(), + owner: owner.into(), + repo: repo.into(), + } + } + + #[must_use] + pub fn pulls(&self, owner: impl Into, repo: impl Into) -> PullsHandler { + PullsHandler { + client: self.clone(), + owner: owner.into(), + repo: repo.into(), + } + } + + #[must_use] + pub fn repos(&self, owner: impl Into, repo: impl Into) -> ReposHandler { + ReposHandler { + client: self.clone(), + owner: owner.into(), + repo: repo.into(), + } + } + + #[must_use] + pub fn search(&self) -> SearchHandler { + SearchHandler { + client: self.clone(), + } + } + + pub async fn graphql(&self, body: &Value) -> Result { + let request = self.inner.client.post(&self.inner.graphql_url).json(body); + self.send_json(request).await + } + + #[allow(clippy::unused_async)] // Keep async for octocrab API compatibility at callsites. + pub async fn all_pages(&self, page: Page) -> Result> { + Ok(page.items) + } + + pub(crate) async fn get_json( + &self, + path: &str, + query: &[(String, String)], + ) -> Result { + let request = self + .inner + .client + .get(format!("{}{}", self.inner.api_base, path)) + .query(query); + + self.send_json(request).await + } + + pub(crate) async fn post_json( + &self, + path: &str, + body: &B, + ) -> Result { + let request = self + .inner + .client + .post(format!("{}{}", self.inner.api_base, path)) + .json(body); + + self.send_json(request).await + } + + pub(crate) async fn get_paginated( + &self, + path: &str, + mut query: Vec<(String, String)>, + per_page: u8, + ) -> Result> { + let mut page = 1_u64; + let mut out = vec![]; + + loop { + query.retain(|(key, _)| key != "page" && key != "per_page"); + query.push(("per_page".to_owned(), per_page.to_string())); + query.push(("page".to_owned(), page.to_string())); + + let items: Vec = self.get_json(path, &query).await?; + let count = items.len(); + out.extend(items); + + if count == 0 || count < usize::from(per_page) { + break; + } + + page += 1; + } + + Ok(out) + } + + pub(crate) async fn get_search_paginated( + &self, + path: &str, + mut query: Vec<(String, String)>, + per_page: u8, + ) -> Result> { + #[derive(serde::Deserialize)] + struct SearchResponse { + items: Vec, + } + + let mut page = 1_u64; + let mut out = vec![]; + + loop { + query.retain(|(key, _)| key != "page" && key != "per_page"); + query.push(("per_page".to_owned(), per_page.to_string())); + query.push(("page".to_owned(), page.to_string())); + + let response: SearchResponse = self.get_json(path, &query).await?; + let count = response.items.len(); + out.extend(response.items); + + if count == 0 || count < usize::from(per_page) { + break; + } + + page += 1; + } + + Ok(out) + } + + async fn send_json(&self, request: reqwest::RequestBuilder) -> Result { + let response = request.send().await?; + let status = response.status(); + let body = response.text().await?; + + if !status.is_success() { + let message = serde_json::from_str::(&body) + .ok() + .and_then(|value| { + value + .get("message") + .and_then(Value::as_str) + .map(str::to_owned) + }) + .unwrap_or_else(|| format!("request failed with status {}", status.as_u16())); + + return Err(Error::GitHub { + source: GitHubError { + status_code: StatusCode::new(status.as_u16()), + message, + }, + body: Some(body), + }); + } + + serde_json::from_str(&body).map_err(Into::into) + } + + #[cfg(test)] + pub(crate) fn with_base_url(base_url: &str, token: Option<&str>) -> Self { + let client = build_http_client(token).expect("test client to build"); + + Self { + inner: Arc::new(Inner { + client, + api_base: base_url.to_owned(), + graphql_url: format!("{base_url}/graphql"), + }), + } + } +} + +impl OctocrabBuilder { + #[must_use] + pub fn personal_token(mut self, token: impl Into) -> Self { + self.token = Some(token.into()); + self + } + + pub fn build(self) -> Result { + let client = build_http_client(self.token.as_deref())?; + + Ok(Octocrab { + inner: Arc::new(Inner { + client, + api_base: "https://api.github.com".to_owned(), + graphql_url: "https://api.github.com/graphql".to_owned(), + }), + }) + } +} + +fn build_http_client(token: Option<&str>) -> Result { + let mut headers = HeaderMap::new(); + headers.insert(USER_AGENT, HeaderValue::from_static("jp-github")); + headers.insert( + ACCEPT, + HeaderValue::from_static("application/vnd.github+json"), + ); + headers.insert( + HeaderName::from_static("x-github-api-version"), + HeaderValue::from_static("2022-11-28"), + ); + + if let Some(token) = token { + let token = format!("Bearer {token}"); + headers.insert(AUTHORIZATION, HeaderValue::from_str(&token)?); + } + + Client::builder() + .default_headers(headers) + .build() + .map_err(|error| Error::Build(format!("{error:#}"))) +} + +static INSTANCE: OnceLock>> = OnceLock::new(); + +pub fn initialise(client: Octocrab) { + let mutex = INSTANCE.get_or_init(|| Mutex::new(None)); + if let Ok(mut lock) = mutex.lock() { + *lock = Some(client); + } +} + +#[must_use] +/// Returns the globally initialized GitHub client. +/// +/// # Panics +/// +/// Panics if [`initialise`] has not been called successfully. +pub fn instance() -> Octocrab { + let mutex = INSTANCE.get_or_init(|| Mutex::new(None)); + let lock = mutex.lock().ok(); + + match lock.and_then(|guard| guard.as_ref().cloned()) { + Some(client) => client, + None => panic!("jp_github client not initialized"), + } +} diff --git a/crates/jp_github/src/error.rs b/crates/jp_github/src/error.rs new file mode 100644 index 00000000..6dad2d12 --- /dev/null +++ b/crates/jp_github/src/error.rs @@ -0,0 +1,53 @@ +pub type Result = std::result::Result; + +#[derive(Debug, thiserror::Error)] +pub enum Error { + #[error("GitHub API error: {source}")] + GitHub { + source: GitHubError, + body: Option, + }, + + #[error("HTTP client error: {0}")] + Http(#[from] reqwest::Error), + + #[error("JSON parse error: {0}")] + Json(#[from] serde_json::Error), + + #[error("invalid HTTP header value: {0}")] + InvalidHeader(#[from] reqwest::header::InvalidHeaderValue), + + #[error("failed to build github client: {0}")] + Build(String), + + #[error("github client not initialized")] + NotInitialized, +} + +#[derive(Debug, Clone, thiserror::Error)] +#[error("{} ({})", message, status_code.as_u16())] +pub struct GitHubError { + pub status_code: StatusCode, + pub message: String, +} + +#[derive(Debug, Clone, Copy, Eq, PartialEq)] +pub struct StatusCode(u16); + +impl StatusCode { + #[must_use] + pub const fn as_u16(self) -> u16 { + self.0 + } + + #[must_use] + pub(crate) const fn new(value: u16) -> Self { + Self(value) + } +} + +impl PartialEq for StatusCode { + fn eq(&self, other: &u16) -> bool { + self.0 == *other + } +} diff --git a/crates/jp_github/src/handlers.rs b/crates/jp_github/src/handlers.rs new file mode 100644 index 00000000..9775df29 --- /dev/null +++ b/crates/jp_github/src/handlers.rs @@ -0,0 +1,387 @@ +use serde::Serialize; +use serde_json::Value; + +use crate::{Octocrab, Page, Result, models, params}; + +pub struct CurrentHandler { + pub(crate) client: Octocrab, +} + +impl CurrentHandler { + pub async fn user(&self) -> Result { + self.client.get_json("/user", &[]).await + } +} + +pub struct IssuesHandler { + pub(crate) client: Octocrab, + pub(crate) owner: String, + pub(crate) repo: String, +} + +impl IssuesHandler { + pub async fn get(&self, number: u64) -> Result { + self.client + .get_json( + &format!("/repos/{}/{}/issues/{number}", self.owner, self.repo), + &[], + ) + .await + } + + #[must_use] + pub fn list(&self) -> IssueListBuilder { + IssueListBuilder { + client: self.client.clone(), + owner: self.owner.clone(), + repo: self.repo.clone(), + per_page: 30, + } + } + + #[must_use] + pub fn create(&self, title: &str) -> IssueCreateBuilder { + IssueCreateBuilder { + client: self.client.clone(), + owner: self.owner.clone(), + repo: self.repo.clone(), + title: title.to_owned(), + body: None, + labels: None, + assignees: None, + } + } + + #[must_use] + pub fn list_labels_for_repo(&self) -> RepoLabelsListBuilder { + RepoLabelsListBuilder { + client: self.client.clone(), + owner: self.owner.clone(), + repo: self.repo.clone(), + per_page: 100, + } + } +} + +pub struct IssueListBuilder { + pub(crate) client: Octocrab, + pub(crate) owner: String, + pub(crate) repo: String, + pub(crate) per_page: u8, +} + +impl IssueListBuilder { + #[must_use] + pub const fn per_page(mut self, per_page: u8) -> Self { + self.per_page = per_page; + self + } + + pub async fn send(self) -> Result> { + let items = self + .client + .get_paginated( + &format!("/repos/{}/{}/issues", self.owner, self.repo), + vec![], + self.per_page, + ) + .await?; + + Ok(Page::new(items)) + } +} + +pub struct IssueCreateBuilder { + pub(crate) client: Octocrab, + pub(crate) owner: String, + pub(crate) repo: String, + pub(crate) title: String, + pub(crate) body: Option, + pub(crate) labels: Option>, + pub(crate) assignees: Option>, +} + +impl IssueCreateBuilder { + #[must_use] + pub fn body(mut self, body: &str) -> Self { + self.body = Some(body.to_owned()); + self + } + + #[must_use] + pub fn labels(mut self, labels: Option>) -> Self { + self.labels = labels; + self + } + + #[must_use] + pub fn assignees(mut self, assignees: Option>) -> Self { + self.assignees = assignees; + self + } + + pub async fn send(self) -> Result { + #[derive(Serialize)] + struct CreateIssueBody { + title: String, + #[serde(skip_serializing_if = "Option::is_none")] + body: Option, + #[serde(skip_serializing_if = "Option::is_none")] + labels: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + assignees: Option>, + } + + let body = CreateIssueBody { + title: self.title, + body: self.body, + labels: self.labels, + assignees: self.assignees, + }; + + self.client + .post_json( + &format!("/repos/{}/{}/issues", self.owner, self.repo), + &body, + ) + .await + } +} + +pub struct RepoLabelsListBuilder { + pub(crate) client: Octocrab, + pub(crate) owner: String, + pub(crate) repo: String, + pub(crate) per_page: u8, +} + +impl RepoLabelsListBuilder { + pub async fn send(self) -> Result> { + let items = self + .client + .get_paginated( + &format!("/repos/{}/{}/labels", self.owner, self.repo), + vec![], + self.per_page, + ) + .await?; + + Ok(Page::new(items)) + } +} + +pub struct PullsHandler { + pub(crate) client: Octocrab, + pub(crate) owner: String, + pub(crate) repo: String, +} + +impl PullsHandler { + pub async fn get(&self, number: u64) -> Result { + self.client + .get_json( + &format!("/repos/{}/{}/pulls/{number}", self.owner, self.repo), + &[], + ) + .await + } + + pub async fn list_files(&self, number: u64) -> Result> { + let items = self + .client + .get_paginated( + &format!("/repos/{}/{}/pulls/{number}/files", self.owner, self.repo), + vec![], + 100, + ) + .await?; + + Ok(Page::new(items)) + } + + #[must_use] + pub fn list(&self) -> PullListBuilder { + PullListBuilder { + client: self.client.clone(), + owner: self.owner.clone(), + repo: self.repo.clone(), + state: params::State::Open, + per_page: 30, + } + } +} + +pub struct PullListBuilder { + pub(crate) client: Octocrab, + pub(crate) owner: String, + pub(crate) repo: String, + pub(crate) state: params::State, + pub(crate) per_page: u8, +} + +impl PullListBuilder { + #[must_use] + pub const fn state(mut self, state: params::State) -> Self { + self.state = state; + self + } + + #[must_use] + pub const fn per_page(mut self, per_page: u8) -> Self { + self.per_page = per_page; + self + } + + pub async fn send(self) -> Result> { + let query = vec![("state".to_owned(), self.state.as_str().to_owned())]; + let items = self + .client + .get_paginated( + &format!("/repos/{}/{}/pulls", self.owner, self.repo), + query, + self.per_page, + ) + .await?; + + Ok(Page::new(items)) + } +} + +pub struct ReposHandler { + pub(crate) client: Octocrab, + pub(crate) owner: String, + pub(crate) repo: String, +} + +impl ReposHandler { + #[must_use] + pub fn get_content(&self) -> RepoContentBuilder { + RepoContentBuilder { + client: self.client.clone(), + owner: self.owner.clone(), + repo: self.repo.clone(), + path: String::new(), + reference: None, + } + } + + #[must_use] + pub fn list_collaborators(&self) -> RepoCollaboratorListBuilder { + RepoCollaboratorListBuilder { + client: self.client.clone(), + owner: self.owner.clone(), + repo: self.repo.clone(), + per_page: 100, + } + } +} + +pub struct RepoContentBuilder { + pub(crate) client: Octocrab, + pub(crate) owner: String, + pub(crate) repo: String, + pub(crate) path: String, + pub(crate) reference: Option, +} + +impl RepoContentBuilder { + #[must_use] + pub fn path(mut self, path: impl Into) -> Self { + self.path = path.into(); + self + } + + #[must_use] + pub fn r#ref(mut self, reference: impl Into) -> Self { + self.reference = Some(reference.into()); + self + } + + pub async fn send(self) -> Result { + let path = if self.path.is_empty() { + format!("/repos/{}/{}/contents", self.owner, self.repo) + } else { + format!("/repos/{}/{}/contents/{}", self.owner, self.repo, self.path) + }; + + let mut query = vec![]; + if let Some(reference) = self.reference { + query.push(("ref".to_owned(), reference)); + } + + let value: Value = self.client.get_json(&path, &query).await?; + + let items = match value { + Value::Array(array) => array, + value => vec![value], + } + .into_iter() + .map(serde_json::from_value) + .collect::, _>>()?; + + Ok(models::repos::ContentItems::new(items)) + } +} + +pub struct RepoCollaboratorListBuilder { + pub(crate) client: Octocrab, + pub(crate) owner: String, + pub(crate) repo: String, + pub(crate) per_page: u8, +} + +impl RepoCollaboratorListBuilder { + pub async fn send(self) -> Result> { + let users: Vec = self + .client + .get_paginated( + &format!("/repos/{}/{}/collaborators", self.owner, self.repo), + vec![], + self.per_page, + ) + .await?; + + let items = users + .into_iter() + .map(|author| models::repos::Collaborator { author }) + .collect(); + + Ok(Page::new(items)) + } +} + +pub struct SearchHandler { + pub(crate) client: Octocrab, +} + +impl SearchHandler { + #[must_use] + pub fn code(&self, query: &str) -> CodeSearchBuilder { + CodeSearchBuilder { + client: self.client.clone(), + query: query.to_owned(), + per_page: 100, + } + } +} + +pub struct CodeSearchBuilder { + pub(crate) client: Octocrab, + pub(crate) query: String, + pub(crate) per_page: u8, +} + +impl CodeSearchBuilder { + pub async fn send(self) -> Result> { + let items = self + .client + .get_search_paginated( + "/search/code", + vec![("q".to_owned(), self.query)], + self.per_page, + ) + .await?; + + Ok(Page::new(items)) + } +} diff --git a/crates/jp_github/src/lib.rs b/crates/jp_github/src/lib.rs new file mode 100644 index 00000000..a958087b --- /dev/null +++ b/crates/jp_github/src/lib.rs @@ -0,0 +1,13 @@ +mod client; +mod error; +mod handlers; +pub mod models; +mod page; +pub mod params; + +pub use client::{Octocrab, OctocrabBuilder, initialise, instance}; +pub use error::{Error, GitHubError, Result, StatusCode}; +pub use page::Page; + +#[cfg(test)] +mod tests; diff --git a/crates/jp_github/src/models.rs b/crates/jp_github/src/models.rs new file mode 100644 index 00000000..e7b4f239 --- /dev/null +++ b/crates/jp_github/src/models.rs @@ -0,0 +1,124 @@ +use chrono::{DateTime, Utc}; +use serde::{Deserialize, Serialize}; +use url::Url; + +#[derive(Debug, Clone, Deserialize, Serialize)] +pub struct User { + pub login: String, +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +pub struct Label { + pub name: String, + pub description: Option, +} + +pub mod issues { + use super::{DateTime, Deserialize, Label, Serialize, Url, User, Utc}; + + #[derive(Debug, Clone, Deserialize, Serialize)] + pub struct PullRequestLink { + pub html_url: Url, + } + + #[derive(Debug, Clone, Deserialize, Serialize)] + pub struct Issue { + pub number: u64, + pub title: String, + pub body: Option, + pub html_url: Url, + pub labels: Vec