From 0aaf6fa19cc1aa1955a7813519d1874c69cf9099 Mon Sep 17 00:00:00 2001 From: Matthew Jackson <1085847+MattJackson@users.noreply.github.com> Date: Tue, 14 Jul 2026 21:47:08 -0700 Subject: [PATCH 1/2] Restructure into a crates/ workspace layout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All Rust crates now live under crates/ (busbar, api, auth-tokens, auth-admin-tokens, hooks-ranking), so code is cleanly separated from non-code (examples/, scripts/, docs/, bench/, config). No behavior change — the binary and every crate are functionally identical; only paths move. - crates/busbar/ holds the engine + binary (was root src/ + the root package). The root Cargo.toml is now a virtual workspace manifest; [profile.release] stays there (Cargo reads profiles only from the workspace root). - Plugin path deps rewired (../api); the four CARGO_MANIFEST_DIR test reads gain ../../ to reach the repo-root providers.yaml/config.yaml. - scripts/structure-lint.sh scans crates/; docs/code-layout.md documents the workspace layout. Verified: cargo test, clippy -D warnings, fmt, structure-lint, and the --no-default-features build all pass. No version bump / no changelog entry — internal reorganization, invisible to users. --- Cargo.toml | 173 +----------------- {api => crates/api}/Cargo.toml | 0 {api => crates/api}/src/auth.rs | 0 {api => crates/api}/src/hooks.rs | 0 {api => crates/api}/src/lib.rs | 0 .../auth-admin-tokens}/Cargo.toml | 2 +- .../auth-admin-tokens}/src/lib.rs | 0 .../tokens => crates/auth-tokens}/Cargo.toml | 2 +- .../tokens => crates/auth-tokens}/src/lib.rs | 0 crates/busbar/Cargo.toml | 163 +++++++++++++++++ {src => crates/busbar/src}/admin/audit.rs | 0 {src => crates/busbar/src}/admin/mod.rs | 0 {src => crates/busbar/src}/admin/rate.rs | 0 .../busbar/src}/admin/tests/tests.rs | 0 {src => crates/busbar/src}/admin/transport.rs | 0 .../busbar/src}/admin/v1/contract/mod.rs | 0 .../admin/v1/contract/tests/cursor_tests.rs | 0 .../src}/admin/v1/contract/tests/tests.rs | 0 .../busbar/src}/admin/v1/json/handlers.rs | 0 .../busbar/src}/admin/v1/json/mod.rs | 0 .../busbar/src}/admin/v1/json/tests/tests.rs | 0 {src => crates/busbar/src}/admin/v1/mod.rs | 0 .../busbar/src}/admin/v1/service.rs | 0 {src => crates/busbar/src}/admin/versions.rs | 0 {src => crates/busbar/src}/auth/mod.rs | 0 .../busbar/src}/auth/tests/tests.rs | 0 {src => crates/busbar/src}/auth_cache.rs | 0 {src => crates/busbar/src}/billing.rs | 0 {src => crates/busbar/src}/breaker.rs | 0 {src => crates/busbar/src}/config/mod.rs | 0 {src => crates/busbar/src}/config/overlay.rs | 0 .../busbar/src}/config/tests/tests.rs | 8 +- .../busbar/src}/config_validate/mod.rs | 0 .../src}/config_validate/tests/tests.rs | 0 {src => crates/busbar/src}/endpoints.rs | 0 {src => crates/busbar/src}/eventstream.rs | 0 {src => crates/busbar/src}/governance/mod.rs | 0 .../busbar/src}/governance/state.rs | 0 .../busbar/src}/governance/tests/tests.rs | 0 .../busbar/src}/handlers/anthropic.rs | 0 .../busbar/src}/handlers/bedrock.rs | 0 {src => crates/busbar/src}/handlers/chat.rs | 0 {src => crates/busbar/src}/handlers/cohere.rs | 0 {src => crates/busbar/src}/handlers/gemini.rs | 0 {src => crates/busbar/src}/handlers/mod.rs | 0 {src => crates/busbar/src}/handlers/openai.rs | 0 .../busbar/src}/handlers/responses.rs | 0 .../src}/handlers/tests/contract_tests.rs | 0 .../src}/handlers/tests/dispatch_tests.rs | 0 .../src}/handlers/tests/registry_tests.rs | 0 {src => crates/busbar/src}/health.rs | 0 {src => crates/busbar/src}/hooks/mod.rs | 0 {src => crates/busbar/src}/hooks/scrape.rs | 0 {src => crates/busbar/src}/hooks/socket.rs | 0 .../busbar/src}/hooks/tests/scrape_tests.rs | 0 .../busbar/src}/hooks/tests/tests.rs | 0 {src => crates/busbar/src}/hooks/webhook.rs | 0 {src => crates/busbar/src}/hooks/wire.rs | 0 .../busbar/src}/ingress/dispatch.rs | 0 {src => crates/busbar/src}/ingress/mod.rs | 0 .../busbar/src}/ingress/tests/tests.rs | 0 {src => crates/busbar/src}/ir/audio.rs | 0 {src => crates/busbar/src}/ir/embeddings.rs | 0 {src => crates/busbar/src}/ir/image.rs | 0 {src => crates/busbar/src}/ir/mod.rs | 0 {src => crates/busbar/src}/ir/moderation.rs | 0 {src => crates/busbar/src}/ir/rerank.rs | 0 {src => crates/busbar/src}/ir/tests/tests.rs | 0 {src => crates/busbar/src}/ir/variant.rs | 0 {src => crates/busbar/src}/json.rs | 0 {src => crates/busbar/src}/limits.rs | 0 {src => crates/busbar/src}/lossless.rs | 0 {src => crates/busbar/src}/main.rs | 0 {src => crates/busbar/src}/media.rs | 0 {src => crates/busbar/src}/metrics.rs | 0 {src => crates/busbar/src}/net_guard.rs | 0 {src => crates/busbar/src}/observability.rs | 0 {src => crates/busbar/src}/operation.rs | 0 .../busbar/src}/proto/anthropic/mod.rs | 0 .../busbar/src}/proto/anthropic/reader.rs | 0 .../tests/anthropic_hardening_tests.rs | 0 .../anthropic/tests/reasoning_carry_tests.rs | 0 .../tests/user_and_parallelism_carry_tests.rs | 0 .../busbar/src}/proto/anthropic/writer.rs | 0 .../busbar/src}/proto/bedrock/mod.rs | 0 .../busbar/src}/proto/bedrock/reader.rs | 0 .../busbar/src}/proto/bedrock/tests/tests.rs | 0 .../busbar/src}/proto/bedrock/writer.rs | 0 .../busbar/src}/proto/cohere/mod.rs | 0 .../busbar/src}/proto/cohere/reader.rs | 0 .../busbar/src}/proto/cohere/tests/tests.rs | 0 .../busbar/src}/proto/cohere/writer.rs | 0 {src => crates/busbar/src}/proto/detect.rs | 0 .../busbar/src}/proto/gemini/mod.rs | 0 .../busbar/src}/proto/gemini/reader.rs | 0 .../gemini/tests/logprobs_carry_tests.rs | 0 .../busbar/src}/proto/gemini/tests/tests.rs | 0 .../busbar/src}/proto/gemini/writer.rs | 0 {src => crates/busbar/src}/proto/mod.rs | 0 .../busbar/src}/proto/openai_chat/mod.rs | 0 .../busbar/src}/proto/openai_chat/reader.rs | 0 .../src}/proto/openai_chat/tests/tests.rs | 0 .../busbar/src}/proto/openai_chat/writer.rs | 0 .../busbar/src}/proto/openai_family.rs | 0 .../busbar/src}/proto/openai_responses/mod.rs | 0 .../src}/proto/openai_responses/reader.rs | 0 .../proto/openai_responses/tests/tests.rs | 0 .../src}/proto/openai_responses/writer.rs | 0 {src => crates/busbar/src}/proto/stream.rs | 0 .../src}/proto/tests/context_length_tests.rs | 0 .../proto/tests/gemini_integration_tests.rs | 0 .../busbar/src}/proto/tests/gemini_tests.rs | 0 .../proto/tests/image_source_matrix_tests.rs | 0 .../tests/response_format_matrix_tests.rs | 0 .../proto/tests/same_proto_fidelity_tests.rs | 0 .../proto/tests/stop_reason_matrix_tests.rs | 0 .../src}/proto/tests/stream_fanout_tests.rs | 0 .../proto/tests/stream_translate_tests.rs | 0 .../busbar/src}/proto/tests/tests.rs | 0 {src => crates/busbar/src}/proxy/egress.rs | 0 .../busbar/src}/proxy/engine/mod.rs | 0 .../busbar/src}/proxy/engine/walk.rs | 0 {src => crates/busbar/src}/proxy/hooks.rs | 0 {src => crates/busbar/src}/proxy/mod.rs | 0 .../busbar/src}/proxy/response_body.rs | 0 {src => crates/busbar/src}/proxy/select.rs | 0 .../tests/attempt_timeout_precedence_tests.rs | 0 .../src}/proxy/tests/auth_style_tests.rs | 0 .../proxy/tests/bedrock_eventstream_tests.rs | 0 .../src}/proxy/tests/billing_parity_tests.rs | 0 .../proxy/tests/cross_protocol_extra_tests.rs | 0 .../tests/forward_once_pool_cell_tests.rs | 0 .../tests/hook_opt_in_projection_tests.rs | 0 .../src}/proxy/tests/hook_seam_tests.rs | 0 .../ingress_indistinguishability_tests.rs | 0 .../tests/max_tokens_precedence_tests.rs | 0 .../proxy/tests/mid_stream_error_tests.rs | 0 .../src}/proxy/tests/on_exhausted_tests.rs | 0 .../src}/proxy/tests/ordered_walk_tests.rs | 0 .../src}/proxy/tests/probe_guard_tests.rs | 0 .../tests/request_short_circuit_tests.rs | 0 .../src}/proxy/tests/usage_tap_tests.rs | 0 {src => crates/busbar/src}/proxy/usage.rs | 0 {src => crates/busbar/src}/proxy/wire.rs | 0 {src => crates/busbar/src}/sigv4.rs | 0 {src => crates/busbar/src}/state.rs | 0 {src => crates/busbar/src}/state_persist.rs | 0 {src => crates/busbar/src}/store/in_memory.rs | 0 {src => crates/busbar/src}/store/mod.rs | 0 .../busbar/src}/store/tests/tests.rs | 0 .../busbar/src}/test_support/mod.rs | 0 .../busbar/src}/test_support/tests/tests.rs | 0 {src => crates/busbar/src}/tests/tests.rs | 0 {src => crates/busbar/src}/tls.rs | 0 .../hooks-ranking}/Cargo.toml | 2 +- .../hooks-ranking}/src/lib.rs | 0 docs/code-layout.md | 23 +++ scripts/structure-lint.sh | 6 +- 158 files changed, 204 insertions(+), 175 deletions(-) rename {api => crates/api}/Cargo.toml (100%) rename {api => crates/api}/src/auth.rs (100%) rename {api => crates/api}/src/hooks.rs (100%) rename {api => crates/api}/src/lib.rs (100%) rename {auth/admin-tokens => crates/auth-admin-tokens}/Cargo.toml (91%) rename {auth/admin-tokens => crates/auth-admin-tokens}/src/lib.rs (100%) rename {auth/tokens => crates/auth-tokens}/Cargo.toml (90%) rename {auth/tokens => crates/auth-tokens}/src/lib.rs (100%) create mode 100644 crates/busbar/Cargo.toml rename {src => crates/busbar/src}/admin/audit.rs (100%) rename {src => crates/busbar/src}/admin/mod.rs (100%) rename {src => crates/busbar/src}/admin/rate.rs (100%) rename {src => crates/busbar/src}/admin/tests/tests.rs (100%) rename {src => crates/busbar/src}/admin/transport.rs (100%) rename {src => crates/busbar/src}/admin/v1/contract/mod.rs (100%) rename {src => crates/busbar/src}/admin/v1/contract/tests/cursor_tests.rs (100%) rename {src => crates/busbar/src}/admin/v1/contract/tests/tests.rs (100%) rename {src => crates/busbar/src}/admin/v1/json/handlers.rs (100%) rename {src => crates/busbar/src}/admin/v1/json/mod.rs (100%) rename {src => crates/busbar/src}/admin/v1/json/tests/tests.rs (100%) rename {src => crates/busbar/src}/admin/v1/mod.rs (100%) rename {src => crates/busbar/src}/admin/v1/service.rs (100%) rename {src => crates/busbar/src}/admin/versions.rs (100%) rename {src => crates/busbar/src}/auth/mod.rs (100%) rename {src => crates/busbar/src}/auth/tests/tests.rs (100%) rename {src => crates/busbar/src}/auth_cache.rs (100%) rename {src => crates/busbar/src}/billing.rs (100%) rename {src => crates/busbar/src}/breaker.rs (100%) rename {src => crates/busbar/src}/config/mod.rs (100%) rename {src => crates/busbar/src}/config/overlay.rs (100%) rename {src => crates/busbar/src}/config/tests/tests.rs (99%) rename {src => crates/busbar/src}/config_validate/mod.rs (100%) rename {src => crates/busbar/src}/config_validate/tests/tests.rs (100%) rename {src => crates/busbar/src}/endpoints.rs (100%) rename {src => crates/busbar/src}/eventstream.rs (100%) rename {src => crates/busbar/src}/governance/mod.rs (100%) rename {src => crates/busbar/src}/governance/state.rs (100%) rename {src => crates/busbar/src}/governance/tests/tests.rs (100%) rename {src => crates/busbar/src}/handlers/anthropic.rs (100%) rename {src => crates/busbar/src}/handlers/bedrock.rs (100%) rename {src => crates/busbar/src}/handlers/chat.rs (100%) rename {src => crates/busbar/src}/handlers/cohere.rs (100%) rename {src => crates/busbar/src}/handlers/gemini.rs (100%) rename {src => crates/busbar/src}/handlers/mod.rs (100%) rename {src => crates/busbar/src}/handlers/openai.rs (100%) rename {src => crates/busbar/src}/handlers/responses.rs (100%) rename {src => crates/busbar/src}/handlers/tests/contract_tests.rs (100%) rename {src => crates/busbar/src}/handlers/tests/dispatch_tests.rs (100%) rename {src => crates/busbar/src}/handlers/tests/registry_tests.rs (100%) rename {src => crates/busbar/src}/health.rs (100%) rename {src => crates/busbar/src}/hooks/mod.rs (100%) rename {src => crates/busbar/src}/hooks/scrape.rs (100%) rename {src => crates/busbar/src}/hooks/socket.rs (100%) rename {src => crates/busbar/src}/hooks/tests/scrape_tests.rs (100%) rename {src => crates/busbar/src}/hooks/tests/tests.rs (100%) rename {src => crates/busbar/src}/hooks/webhook.rs (100%) rename {src => crates/busbar/src}/hooks/wire.rs (100%) rename {src => crates/busbar/src}/ingress/dispatch.rs (100%) rename {src => crates/busbar/src}/ingress/mod.rs (100%) rename {src => crates/busbar/src}/ingress/tests/tests.rs (100%) rename {src => crates/busbar/src}/ir/audio.rs (100%) rename {src => crates/busbar/src}/ir/embeddings.rs (100%) rename {src => crates/busbar/src}/ir/image.rs (100%) rename {src => crates/busbar/src}/ir/mod.rs (100%) rename {src => crates/busbar/src}/ir/moderation.rs (100%) rename {src => crates/busbar/src}/ir/rerank.rs (100%) rename {src => crates/busbar/src}/ir/tests/tests.rs (100%) rename {src => crates/busbar/src}/ir/variant.rs (100%) rename {src => crates/busbar/src}/json.rs (100%) rename {src => crates/busbar/src}/limits.rs (100%) rename {src => crates/busbar/src}/lossless.rs (100%) rename {src => crates/busbar/src}/main.rs (100%) rename {src => crates/busbar/src}/media.rs (100%) rename {src => crates/busbar/src}/metrics.rs (100%) rename {src => crates/busbar/src}/net_guard.rs (100%) rename {src => crates/busbar/src}/observability.rs (100%) rename {src => crates/busbar/src}/operation.rs (100%) rename {src => crates/busbar/src}/proto/anthropic/mod.rs (100%) rename {src => crates/busbar/src}/proto/anthropic/reader.rs (100%) rename {src => crates/busbar/src}/proto/anthropic/tests/anthropic_hardening_tests.rs (100%) rename {src => crates/busbar/src}/proto/anthropic/tests/reasoning_carry_tests.rs (100%) rename {src => crates/busbar/src}/proto/anthropic/tests/user_and_parallelism_carry_tests.rs (100%) rename {src => crates/busbar/src}/proto/anthropic/writer.rs (100%) rename {src => crates/busbar/src}/proto/bedrock/mod.rs (100%) rename {src => crates/busbar/src}/proto/bedrock/reader.rs (100%) rename {src => crates/busbar/src}/proto/bedrock/tests/tests.rs (100%) rename {src => crates/busbar/src}/proto/bedrock/writer.rs (100%) rename {src => crates/busbar/src}/proto/cohere/mod.rs (100%) rename {src => crates/busbar/src}/proto/cohere/reader.rs (100%) rename {src => crates/busbar/src}/proto/cohere/tests/tests.rs (100%) rename {src => crates/busbar/src}/proto/cohere/writer.rs (100%) rename {src => crates/busbar/src}/proto/detect.rs (100%) rename {src => crates/busbar/src}/proto/gemini/mod.rs (100%) rename {src => crates/busbar/src}/proto/gemini/reader.rs (100%) rename {src => crates/busbar/src}/proto/gemini/tests/logprobs_carry_tests.rs (100%) rename {src => crates/busbar/src}/proto/gemini/tests/tests.rs (100%) rename {src => crates/busbar/src}/proto/gemini/writer.rs (100%) rename {src => crates/busbar/src}/proto/mod.rs (100%) rename {src => crates/busbar/src}/proto/openai_chat/mod.rs (100%) rename {src => crates/busbar/src}/proto/openai_chat/reader.rs (100%) rename {src => crates/busbar/src}/proto/openai_chat/tests/tests.rs (100%) rename {src => crates/busbar/src}/proto/openai_chat/writer.rs (100%) rename {src => crates/busbar/src}/proto/openai_family.rs (100%) rename {src => crates/busbar/src}/proto/openai_responses/mod.rs (100%) rename {src => crates/busbar/src}/proto/openai_responses/reader.rs (100%) rename {src => crates/busbar/src}/proto/openai_responses/tests/tests.rs (100%) rename {src => crates/busbar/src}/proto/openai_responses/writer.rs (100%) rename {src => crates/busbar/src}/proto/stream.rs (100%) rename {src => crates/busbar/src}/proto/tests/context_length_tests.rs (100%) rename {src => crates/busbar/src}/proto/tests/gemini_integration_tests.rs (100%) rename {src => crates/busbar/src}/proto/tests/gemini_tests.rs (100%) rename {src => crates/busbar/src}/proto/tests/image_source_matrix_tests.rs (100%) rename {src => crates/busbar/src}/proto/tests/response_format_matrix_tests.rs (100%) rename {src => crates/busbar/src}/proto/tests/same_proto_fidelity_tests.rs (100%) rename {src => crates/busbar/src}/proto/tests/stop_reason_matrix_tests.rs (100%) rename {src => crates/busbar/src}/proto/tests/stream_fanout_tests.rs (100%) rename {src => crates/busbar/src}/proto/tests/stream_translate_tests.rs (100%) rename {src => crates/busbar/src}/proto/tests/tests.rs (100%) rename {src => crates/busbar/src}/proxy/egress.rs (100%) rename {src => crates/busbar/src}/proxy/engine/mod.rs (100%) rename {src => crates/busbar/src}/proxy/engine/walk.rs (100%) rename {src => crates/busbar/src}/proxy/hooks.rs (100%) rename {src => crates/busbar/src}/proxy/mod.rs (100%) rename {src => crates/busbar/src}/proxy/response_body.rs (100%) rename {src => crates/busbar/src}/proxy/select.rs (100%) rename {src => crates/busbar/src}/proxy/tests/attempt_timeout_precedence_tests.rs (100%) rename {src => crates/busbar/src}/proxy/tests/auth_style_tests.rs (100%) rename {src => crates/busbar/src}/proxy/tests/bedrock_eventstream_tests.rs (100%) rename {src => crates/busbar/src}/proxy/tests/billing_parity_tests.rs (100%) rename {src => crates/busbar/src}/proxy/tests/cross_protocol_extra_tests.rs (100%) rename {src => crates/busbar/src}/proxy/tests/forward_once_pool_cell_tests.rs (100%) rename {src => crates/busbar/src}/proxy/tests/hook_opt_in_projection_tests.rs (100%) rename {src => crates/busbar/src}/proxy/tests/hook_seam_tests.rs (100%) rename {src => crates/busbar/src}/proxy/tests/ingress_indistinguishability_tests.rs (100%) rename {src => crates/busbar/src}/proxy/tests/max_tokens_precedence_tests.rs (100%) rename {src => crates/busbar/src}/proxy/tests/mid_stream_error_tests.rs (100%) rename {src => crates/busbar/src}/proxy/tests/on_exhausted_tests.rs (100%) rename {src => crates/busbar/src}/proxy/tests/ordered_walk_tests.rs (100%) rename {src => crates/busbar/src}/proxy/tests/probe_guard_tests.rs (100%) rename {src => crates/busbar/src}/proxy/tests/request_short_circuit_tests.rs (100%) rename {src => crates/busbar/src}/proxy/tests/usage_tap_tests.rs (100%) rename {src => crates/busbar/src}/proxy/usage.rs (100%) rename {src => crates/busbar/src}/proxy/wire.rs (100%) rename {src => crates/busbar/src}/sigv4.rs (100%) rename {src => crates/busbar/src}/state.rs (100%) rename {src => crates/busbar/src}/state_persist.rs (100%) rename {src => crates/busbar/src}/store/in_memory.rs (100%) rename {src => crates/busbar/src}/store/mod.rs (100%) rename {src => crates/busbar/src}/store/tests/tests.rs (100%) rename {src => crates/busbar/src}/test_support/mod.rs (100%) rename {src => crates/busbar/src}/test_support/tests/tests.rs (100%) rename {src => crates/busbar/src}/tests/tests.rs (100%) rename {src => crates/busbar/src}/tls.rs (100%) rename {hooks/ranking => crates/hooks-ranking}/Cargo.toml (94%) rename {hooks/ranking => crates/hooks-ranking}/src/lib.rs (100%) diff --git a/Cargo.toml b/Cargo.toml index 99eb3b8e..8b1a65eb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,169 +1,12 @@ [workspace] -members = ["api", "auth/tokens", "auth/admin-tokens", "hooks/ranking"] - -[package] -name = "busbar" -version = "1.3.2" -publish = false # internal workspace crate; never goes to crates.io -edition = "2021" -# Effective MSRV: governance.rs uses `u32::is_multiple_of` (stabilized in Rust 1.87), and clippy's -# `manual_is_multiple_of` lint rewrites `% N == 0` back to it, so 1.87 is the genuine minimum. Declare -# it so a build on an older toolchain fails fast with a clear message instead of a cryptic -# "method not found", and so MSRV-aware tooling resolves compatible deps. -rust-version = "1.87" -description = "Native-protocol LLM gateway: lossless cross-protocol translation, weighted pools, per-(pool,lane) circuit breaking, and governance — in one static Rust binary." -license = "Apache-2.0" - -[[bin]] -name = "busbar" -path = "src/main.rs" - -[dependencies] -# The plugin CONTRACTS (auth-module trait, routing-policy trait, projections) — the one crate both -# the engine and every plugin build against. See api/. -busbar-api = { path = "api" } -# The built-in plugins, each its own workspace crate under auth// or hooks// — optional -# so the matching feature (below) compiles each IN or OUT of the binary. -busbar-auth-tokens = { path = "auth/tokens", optional = true } -busbar-auth-admin-tokens = { path = "auth/admin-tokens", optional = true } -busbar-hooks-ranking = { path = "hooks/ranking", optional = true } -axum = "0.8" -# Already present transitively (axum's middleware stack). Pulled in directly ONLY for -# `GlobalConcurrencyLimitLayer` — the OUTERMOST inbound-concurrency cap applied when the operator -# sets `limits.max_inbound_concurrent > 0` (the `0` default adds NO layer). `limit` is the sole -# feature needed. -tower = { version = "0.5", features = ["limit"] } -# Only the subsystems busbar actually touches: the multi-thread runtime (#[tokio::main], -# spawn/JoinHandle), macros (main/test), net (TcpListener), time (sleep/interval), sync -# (Semaphore/OwnedSemaphorePermit), and signal (graceful-shutdown ctrl_c/SIGTERM, so OTLP spans -# flush on exit). The "full" meta-feature additionally pulls fs/process/io-util/io-std/test-util — -# none referenced in src/ — so it is dropped to shrink the request-path binary's compile + attack -# surface. -tokio = { version = "1", features = ["rt-multi-thread", "macros", "net", "time", "sync", "signal"] } -reqwest = { version = "0.12", default-features = false, features = ["rustls-tls", "stream"] } -serde = { version = "1", features = ["derive"] } -serde_json = "1" -# SIMD JSON (NEON on arm64, AVX2/SSE on x86): used for the hot request/response parse+serialize on -# the translate path, where its SIMD escape-scanning is ~5× serde_json on the large string-heavy -# bodies LLM traffic carries. `serde_json` is retained for the cold/config/error paths and as the -# `Value` type; sonic-rs serializes/deserializes that same `serde_json::Value` at the hot boundaries. -sonic-rs = "0.5" -# `serde_yaml` (dtolnay) is archived/deprecated — the locked 0.9 is literally `0.9.34+deprecated`. -# `serde_yaml_ng` is the maintained, API-compatible fork (still backed by `unsafe-libyaml`, but at a -# maintained, patched version); the `package` rename keeps every `serde_yaml::from_str` call site unchanged. -serde_yaml = { package = "serde_yaml_ng", version = "0.10" } -futures = "0.3" -bytes = "1" -http-body-util = "0.1" -metrics = "0.24.6" -# busbar uses this purely as an in-process recorder: `PrometheusBuilder::new().install_recorder()` -# plus `handle.render()` (src/metrics.rs), serving the text exposition from its own axum /metrics -# admin route. The crate's `default` feature enables `http-listener` and `push-gateway`, which drag -# in hyper/hyper-rustls/hyper-util/rustls (an HTTP server + push client busbar never invokes) and a -# second crypto backend (aws-lc-rs). Dropped for the same reason tokio/reqwest/otlp are hand-trimmed: -# shrink the request-path binary's compile + attack surface. -metrics-exporter-prometheus = { version = "0.18.3", default-features = false } -opentelemetry = "0.32.0" -opentelemetry_sdk = "0.32.1" -# Pin OTLP to the HTTP/proto trace path busbar uses (`SpanExporter::builder().with_http()`). The -# default bundled client is dropped; busbar injects its OWN HTTP client via `with_http_client` (see -# observability::build_otlp) so trace export shares busbar's hyper/rustls stack and — critically — -# does NOT follow redirects (a redirect-following exporter is a runtime SSRF vector: a validated OTLP -# endpoint that 3xx-redirects to an internal/metadata target would be followed). Dropping default -# features also removes `reqwest-blocking-client` and the OTLP metrics/logs paths (busbar exports -# metrics via Prometheus, not OTLP). -# -# SINGLE CLIENT STACK: by dropping the `reqwest-rustls` feature and supplying a hyper-based -# `opentelemetry_http::HyperClient` over a hyper-rustls connector (all already in the graph for the -# axum server), the SECOND reqwest major (0.13) that the bundled OTLP client used to pull is gone — -# `cargo tree -d` no longer lists a duplicate reqwest. The request path's reqwest 0.12 is the only -# reqwest major. -opentelemetry-otlp = { version = "0.32.0", default-features = false, features = [ - "trace", - "http-proto", -] } -opentelemetry-http = { version = "0.32.0", default-features = false, features = [ - "hyper", -] } -# HTTPS connector for the OTLP HyperClient (rustls, http/1.1). Already in the graph via the server -# stack; named directly so build_otlp can construct a redirect-free TLS client. -hyper-rustls = { version = "0.27", default-features = false, features = [ - "http1", - "ring", - "webpki-tokio", -] } -tracing = "0.1.44" -tracing-subscriber = "0.3.23" -tracing-opentelemetry = "0.33.0" -sha2 = "0.11.0" -hmac = "0.13.0" -hex = "0.4.3" -rusqlite = { version = "0.40.0", features = ["bundled"] } -getrandom = "0.4" -# CRC32 for the AWS `application/vnd.amazon.eventstream` encoder (Bedrock ingress streaming): AWS -# SDK clients validate both the prelude and message CRC32 on every frame, so the encoder needs a -# correct, fast CRC32. `crc32fast` is small, dependency-light, and the de-facto standard. -crc32fast = "1" -# The pluggable routing-policy contract (`RoutingPolicy`) is an async trait so the webhook transport -# can do I/O; native/socket policies return immediately. `async-trait` is the standard, zero-runtime -# (compile-time desugar to boxed futures) way to express object-safe async traits on stable Rust. It -# is only ever entered for NON-default pools — a `route: weighted` (default) pool never constructs a -# `RoutingPolicy` and never touches this boxing, preserving the zero-cost default. -async-trait = "0.1" -# Native inbound TLS termination (+ optional mTLS). `tokio-rustls` wraps the accepted TcpStream in a -# rustls server handshake; it pins the `ring` crypto provider (already the only provider in the graph -# via reqwest/hyper-rustls), so the process holds exactly one CryptoProvider — no aws-lc-rs. -# `rustls-pki-types`' built-in PEM API parses the operator's PEM cert chain + private key -# (PKCS#8 / PKCS#1 / SEC1). It's already in the graph via rustls/tokio-rustls; named here as a direct -# dep so src/tls.rs can call its `PemObject` API (replacing the unmaintained `rustls-pemfile`). -# axum 0.7's `serve` is hardwired to a `TcpListener` (the generic `Listener` trait only landed in -# axum 0.8). To terminate TLS without bumping axum — which would churn the routing hot path's -# Router/Service types this feature must NOT touch — the TLS branch drives hyper directly: it accepts -# on the TcpListener, runs the rustls handshake, then serves each connection with hyper-util's -# auto::Builder, mirroring exactly what `axum::serve` does internally. `GracefulShutdown` reproduces -# `.with_graceful_shutdown(...)`'s drain semantics. Both crates are already in the graph (axum/server -# stack); they're named here only to pull the `server-auto`/`server-graceful` surface directly. -hyper = { version = "1", default-features = false, features = ["server", "http1"] } -hyper-util = { version = "0.1", default-features = false, features = [ - "server-auto", - "server-graceful", - "service", - "tokio", -] } -tokio-rustls = { version = "0.26", default-features = false, features = ["ring"] } -# `ServerConfig`/`WebPkiClientVerifier`/`crypto::ring` are referenced directly in src/tls.rs. Pinned -# to the version already resolved in the graph (server stack) with only the `ring` provider feature, -# so no second crypto backend is introduced. -rustls = { version = "0.23", default-features = false, features = ["ring", "std", "tls12"] } -rustls-pki-types = { version = "1", default-features = false, features = ["std"] } - -[features] -# The built-in `tokens` auth plugin is a DEFAULT-ON, REMOVABLE feature — compliance by compilation. -# A `--no-default-features` build contains NO client-token auth code at all (the module, its -# constant-time fold, and the allowlist are absent from the binary, provable by attestation + -# symbols). `auth.chain: [tokens]` then BOOT-ERRORS instead of silently opening. A regulated -# deployment ships tokens OUT and wires its own auth module (SAML/AD/OIDC) in the private repo. -default = ["auth-tokens", "auth-admin-tokens", "hooks-ranking"] -auth-tokens = ["dep:busbar-auth-tokens"] -# The built-in `admin-tokens` ADMIN auth plugin (the single operator admin token) — same -# default-on, removable, compliance-by-compilation stance. Removed, `admin_auth: [admin-tokens]` -# (the default) boot-errors and an external admin module must be wired. -auth-admin-tokens = ["dep:busbar-auth-admin-tokens"] -# The built-in RANKING hooks (cheapest/fastest/least_busy/usage) are also a default-on, removable -# feature. `--no-default-features` drops them; `weighted` stays (it's the engine's inline SWRR floor, -# not a plugin). A pool `policy: cheapest` (etc.) is then a boot error. -hooks-ranking = ["dep:busbar-hooks-ranking"] - -[dev-dependencies] -# In-crate #[cfg(test)] harness needs reqwest's json feature + axum http1 server. -reqwest = { version = "0.12", default-features = false, features = ["rustls-tls", "stream", "json"] } -axum = { version = "0.8", features = ["http1"] } -http-body-util = "0.1" -futures = "0.3" -bytes = "1" -# Generates self-signed server certs + a CA/leaf pair at test runtime so the TLS/mTLS integration -# tests exercise a real rustls handshake without checked-in key material. -rcgen = "0.14" +resolver = "2" +members = [ + "crates/busbar", + "crates/api", + "crates/auth-tokens", + "crates/auth-admin-tokens", + "crates/hooks-ranking", +] [profile.release] # Tuned for the shipped "deploy-and-done" binary: max optimization and smallest size, diff --git a/api/Cargo.toml b/crates/api/Cargo.toml similarity index 100% rename from api/Cargo.toml rename to crates/api/Cargo.toml diff --git a/api/src/auth.rs b/crates/api/src/auth.rs similarity index 100% rename from api/src/auth.rs rename to crates/api/src/auth.rs diff --git a/api/src/hooks.rs b/crates/api/src/hooks.rs similarity index 100% rename from api/src/hooks.rs rename to crates/api/src/hooks.rs diff --git a/api/src/lib.rs b/crates/api/src/lib.rs similarity index 100% rename from api/src/lib.rs rename to crates/api/src/lib.rs diff --git a/auth/admin-tokens/Cargo.toml b/crates/auth-admin-tokens/Cargo.toml similarity index 91% rename from auth/admin-tokens/Cargo.toml rename to crates/auth-admin-tokens/Cargo.toml index f5f96e33..c8b3ee8c 100644 --- a/auth/admin-tokens/Cargo.toml +++ b/crates/auth-admin-tokens/Cargo.toml @@ -8,4 +8,4 @@ description = "The built-in `admin-tokens` admin-auth plugin for busbar: the sin license = "Apache-2.0" [dependencies] -busbar-api = { path = "../../api" } +busbar-api = { path = "../api" } diff --git a/auth/admin-tokens/src/lib.rs b/crates/auth-admin-tokens/src/lib.rs similarity index 100% rename from auth/admin-tokens/src/lib.rs rename to crates/auth-admin-tokens/src/lib.rs diff --git a/auth/tokens/Cargo.toml b/crates/auth-tokens/Cargo.toml similarity index 90% rename from auth/tokens/Cargo.toml rename to crates/auth-tokens/Cargo.toml index 9e93410d..f059273b 100644 --- a/auth/tokens/Cargo.toml +++ b/crates/auth-tokens/Cargo.toml @@ -8,4 +8,4 @@ description = "The built-in `tokens` auth plugin for busbar: a static client-tok license = "Apache-2.0" [dependencies] -busbar-api = { path = "../../api" } +busbar-api = { path = "../api" } diff --git a/auth/tokens/src/lib.rs b/crates/auth-tokens/src/lib.rs similarity index 100% rename from auth/tokens/src/lib.rs rename to crates/auth-tokens/src/lib.rs diff --git a/crates/busbar/Cargo.toml b/crates/busbar/Cargo.toml new file mode 100644 index 00000000..a6bb8733 --- /dev/null +++ b/crates/busbar/Cargo.toml @@ -0,0 +1,163 @@ +[package] +name = "busbar" +version = "1.3.2" +publish = false # internal workspace crate; never goes to crates.io +edition = "2021" +# Effective MSRV: governance.rs uses `u32::is_multiple_of` (stabilized in Rust 1.87), and clippy's +# `manual_is_multiple_of` lint rewrites `% N == 0` back to it, so 1.87 is the genuine minimum. Declare +# it so a build on an older toolchain fails fast with a clear message instead of a cryptic +# "method not found", and so MSRV-aware tooling resolves compatible deps. +rust-version = "1.87" +description = "Native-protocol LLM gateway: lossless cross-protocol translation, weighted pools, per-(pool,lane) circuit breaking, and governance — in one static Rust binary." +license = "Apache-2.0" + +[[bin]] +name = "busbar" +path = "src/main.rs" + +[dependencies] +# The plugin CONTRACTS (auth-module trait, routing-policy trait, projections) — the one crate both +# the engine and every plugin build against. See api/. +busbar-api = { path = "../api" } +# The built-in plugins, each its own workspace crate under auth// or hooks// — optional +# so the matching feature (below) compiles each IN or OUT of the binary. +busbar-auth-tokens = { path = "../auth-tokens", optional = true } +busbar-auth-admin-tokens = { path = "../auth-admin-tokens", optional = true } +busbar-hooks-ranking = { path = "../hooks-ranking", optional = true } +axum = "0.8" +# Already present transitively (axum's middleware stack). Pulled in directly ONLY for +# `GlobalConcurrencyLimitLayer` — the OUTERMOST inbound-concurrency cap applied when the operator +# sets `limits.max_inbound_concurrent > 0` (the `0` default adds NO layer). `limit` is the sole +# feature needed. +tower = { version = "0.5", features = ["limit"] } +# Only the subsystems busbar actually touches: the multi-thread runtime (#[tokio::main], +# spawn/JoinHandle), macros (main/test), net (TcpListener), time (sleep/interval), sync +# (Semaphore/OwnedSemaphorePermit), and signal (graceful-shutdown ctrl_c/SIGTERM, so OTLP spans +# flush on exit). The "full" meta-feature additionally pulls fs/process/io-util/io-std/test-util — +# none referenced in src/ — so it is dropped to shrink the request-path binary's compile + attack +# surface. +tokio = { version = "1", features = ["rt-multi-thread", "macros", "net", "time", "sync", "signal"] } +reqwest = { version = "0.12", default-features = false, features = ["rustls-tls", "stream"] } +serde = { version = "1", features = ["derive"] } +serde_json = "1" +# SIMD JSON (NEON on arm64, AVX2/SSE on x86): used for the hot request/response parse+serialize on +# the translate path, where its SIMD escape-scanning is ~5× serde_json on the large string-heavy +# bodies LLM traffic carries. `serde_json` is retained for the cold/config/error paths and as the +# `Value` type; sonic-rs serializes/deserializes that same `serde_json::Value` at the hot boundaries. +sonic-rs = "0.5" +# `serde_yaml` (dtolnay) is archived/deprecated — the locked 0.9 is literally `0.9.34+deprecated`. +# `serde_yaml_ng` is the maintained, API-compatible fork (still backed by `unsafe-libyaml`, but at a +# maintained, patched version); the `package` rename keeps every `serde_yaml::from_str` call site unchanged. +serde_yaml = { package = "serde_yaml_ng", version = "0.10" } +futures = "0.3" +bytes = "1" +http-body-util = "0.1" +metrics = "0.24.6" +# busbar uses this purely as an in-process recorder: `PrometheusBuilder::new().install_recorder()` +# plus `handle.render()` (src/metrics.rs), serving the text exposition from its own axum /metrics +# admin route. The crate's `default` feature enables `http-listener` and `push-gateway`, which drag +# in hyper/hyper-rustls/hyper-util/rustls (an HTTP server + push client busbar never invokes) and a +# second crypto backend (aws-lc-rs). Dropped for the same reason tokio/reqwest/otlp are hand-trimmed: +# shrink the request-path binary's compile + attack surface. +metrics-exporter-prometheus = { version = "0.18.3", default-features = false } +opentelemetry = "0.32.0" +opentelemetry_sdk = "0.32.1" +# Pin OTLP to the HTTP/proto trace path busbar uses (`SpanExporter::builder().with_http()`). The +# default bundled client is dropped; busbar injects its OWN HTTP client via `with_http_client` (see +# observability::build_otlp) so trace export shares busbar's hyper/rustls stack and — critically — +# does NOT follow redirects (a redirect-following exporter is a runtime SSRF vector: a validated OTLP +# endpoint that 3xx-redirects to an internal/metadata target would be followed). Dropping default +# features also removes `reqwest-blocking-client` and the OTLP metrics/logs paths (busbar exports +# metrics via Prometheus, not OTLP). +# +# SINGLE CLIENT STACK: by dropping the `reqwest-rustls` feature and supplying a hyper-based +# `opentelemetry_http::HyperClient` over a hyper-rustls connector (all already in the graph for the +# axum server), the SECOND reqwest major (0.13) that the bundled OTLP client used to pull is gone — +# `cargo tree -d` no longer lists a duplicate reqwest. The request path's reqwest 0.12 is the only +# reqwest major. +opentelemetry-otlp = { version = "0.32.0", default-features = false, features = [ + "trace", + "http-proto", +] } +opentelemetry-http = { version = "0.32.0", default-features = false, features = [ + "hyper", +] } +# HTTPS connector for the OTLP HyperClient (rustls, http/1.1). Already in the graph via the server +# stack; named directly so build_otlp can construct a redirect-free TLS client. +hyper-rustls = { version = "0.27", default-features = false, features = [ + "http1", + "ring", + "webpki-tokio", +] } +tracing = "0.1.44" +tracing-subscriber = "0.3.23" +tracing-opentelemetry = "0.33.0" +sha2 = "0.11.0" +hmac = "0.13.0" +hex = "0.4.3" +rusqlite = { version = "0.40.0", features = ["bundled"] } +getrandom = "0.4" +# CRC32 for the AWS `application/vnd.amazon.eventstream` encoder (Bedrock ingress streaming): AWS +# SDK clients validate both the prelude and message CRC32 on every frame, so the encoder needs a +# correct, fast CRC32. `crc32fast` is small, dependency-light, and the de-facto standard. +crc32fast = "1" +# The pluggable routing-policy contract (`RoutingPolicy`) is an async trait so the webhook transport +# can do I/O; native/socket policies return immediately. `async-trait` is the standard, zero-runtime +# (compile-time desugar to boxed futures) way to express object-safe async traits on stable Rust. It +# is only ever entered for NON-default pools — a `route: weighted` (default) pool never constructs a +# `RoutingPolicy` and never touches this boxing, preserving the zero-cost default. +async-trait = "0.1" +# Native inbound TLS termination (+ optional mTLS). `tokio-rustls` wraps the accepted TcpStream in a +# rustls server handshake; it pins the `ring` crypto provider (already the only provider in the graph +# via reqwest/hyper-rustls), so the process holds exactly one CryptoProvider — no aws-lc-rs. +# `rustls-pki-types`' built-in PEM API parses the operator's PEM cert chain + private key +# (PKCS#8 / PKCS#1 / SEC1). It's already in the graph via rustls/tokio-rustls; named here as a direct +# dep so src/tls.rs can call its `PemObject` API (replacing the unmaintained `rustls-pemfile`). +# axum 0.7's `serve` is hardwired to a `TcpListener` (the generic `Listener` trait only landed in +# axum 0.8). To terminate TLS without bumping axum — which would churn the routing hot path's +# Router/Service types this feature must NOT touch — the TLS branch drives hyper directly: it accepts +# on the TcpListener, runs the rustls handshake, then serves each connection with hyper-util's +# auto::Builder, mirroring exactly what `axum::serve` does internally. `GracefulShutdown` reproduces +# `.with_graceful_shutdown(...)`'s drain semantics. Both crates are already in the graph (axum/server +# stack); they're named here only to pull the `server-auto`/`server-graceful` surface directly. +hyper = { version = "1", default-features = false, features = ["server", "http1"] } +hyper-util = { version = "0.1", default-features = false, features = [ + "server-auto", + "server-graceful", + "service", + "tokio", +] } +tokio-rustls = { version = "0.26", default-features = false, features = ["ring"] } +# `ServerConfig`/`WebPkiClientVerifier`/`crypto::ring` are referenced directly in src/tls.rs. Pinned +# to the version already resolved in the graph (server stack) with only the `ring` provider feature, +# so no second crypto backend is introduced. +rustls = { version = "0.23", default-features = false, features = ["ring", "std", "tls12"] } +rustls-pki-types = { version = "1", default-features = false, features = ["std"] } + +[features] +# The built-in `tokens` auth plugin is a DEFAULT-ON, REMOVABLE feature — compliance by compilation. +# A `--no-default-features` build contains NO client-token auth code at all (the module, its +# constant-time fold, and the allowlist are absent from the binary, provable by attestation + +# symbols). `auth.chain: [tokens]` then BOOT-ERRORS instead of silently opening. A regulated +# deployment ships tokens OUT and wires its own auth module (SAML/AD/OIDC) in the private repo. +default = ["auth-tokens", "auth-admin-tokens", "hooks-ranking"] +auth-tokens = ["dep:busbar-auth-tokens"] +# The built-in `admin-tokens` ADMIN auth plugin (the single operator admin token) — same +# default-on, removable, compliance-by-compilation stance. Removed, `admin_auth: [admin-tokens]` +# (the default) boot-errors and an external admin module must be wired. +auth-admin-tokens = ["dep:busbar-auth-admin-tokens"] +# The built-in RANKING hooks (cheapest/fastest/least_busy/usage) are also a default-on, removable +# feature. `--no-default-features` drops them; `weighted` stays (it's the engine's inline SWRR floor, +# not a plugin). A pool `policy: cheapest` (etc.) is then a boot error. +hooks-ranking = ["dep:busbar-hooks-ranking"] + +[dev-dependencies] +# In-crate #[cfg(test)] harness needs reqwest's json feature + axum http1 server. +reqwest = { version = "0.12", default-features = false, features = ["rustls-tls", "stream", "json"] } +axum = { version = "0.8", features = ["http1"] } +http-body-util = "0.1" +futures = "0.3" +bytes = "1" +# Generates self-signed server certs + a CA/leaf pair at test runtime so the TLS/mTLS integration +# tests exercise a real rustls handshake without checked-in key material. +rcgen = "0.14" diff --git a/src/admin/audit.rs b/crates/busbar/src/admin/audit.rs similarity index 100% rename from src/admin/audit.rs rename to crates/busbar/src/admin/audit.rs diff --git a/src/admin/mod.rs b/crates/busbar/src/admin/mod.rs similarity index 100% rename from src/admin/mod.rs rename to crates/busbar/src/admin/mod.rs diff --git a/src/admin/rate.rs b/crates/busbar/src/admin/rate.rs similarity index 100% rename from src/admin/rate.rs rename to crates/busbar/src/admin/rate.rs diff --git a/src/admin/tests/tests.rs b/crates/busbar/src/admin/tests/tests.rs similarity index 100% rename from src/admin/tests/tests.rs rename to crates/busbar/src/admin/tests/tests.rs diff --git a/src/admin/transport.rs b/crates/busbar/src/admin/transport.rs similarity index 100% rename from src/admin/transport.rs rename to crates/busbar/src/admin/transport.rs diff --git a/src/admin/v1/contract/mod.rs b/crates/busbar/src/admin/v1/contract/mod.rs similarity index 100% rename from src/admin/v1/contract/mod.rs rename to crates/busbar/src/admin/v1/contract/mod.rs diff --git a/src/admin/v1/contract/tests/cursor_tests.rs b/crates/busbar/src/admin/v1/contract/tests/cursor_tests.rs similarity index 100% rename from src/admin/v1/contract/tests/cursor_tests.rs rename to crates/busbar/src/admin/v1/contract/tests/cursor_tests.rs diff --git a/src/admin/v1/contract/tests/tests.rs b/crates/busbar/src/admin/v1/contract/tests/tests.rs similarity index 100% rename from src/admin/v1/contract/tests/tests.rs rename to crates/busbar/src/admin/v1/contract/tests/tests.rs diff --git a/src/admin/v1/json/handlers.rs b/crates/busbar/src/admin/v1/json/handlers.rs similarity index 100% rename from src/admin/v1/json/handlers.rs rename to crates/busbar/src/admin/v1/json/handlers.rs diff --git a/src/admin/v1/json/mod.rs b/crates/busbar/src/admin/v1/json/mod.rs similarity index 100% rename from src/admin/v1/json/mod.rs rename to crates/busbar/src/admin/v1/json/mod.rs diff --git a/src/admin/v1/json/tests/tests.rs b/crates/busbar/src/admin/v1/json/tests/tests.rs similarity index 100% rename from src/admin/v1/json/tests/tests.rs rename to crates/busbar/src/admin/v1/json/tests/tests.rs diff --git a/src/admin/v1/mod.rs b/crates/busbar/src/admin/v1/mod.rs similarity index 100% rename from src/admin/v1/mod.rs rename to crates/busbar/src/admin/v1/mod.rs diff --git a/src/admin/v1/service.rs b/crates/busbar/src/admin/v1/service.rs similarity index 100% rename from src/admin/v1/service.rs rename to crates/busbar/src/admin/v1/service.rs diff --git a/src/admin/versions.rs b/crates/busbar/src/admin/versions.rs similarity index 100% rename from src/admin/versions.rs rename to crates/busbar/src/admin/versions.rs diff --git a/src/auth/mod.rs b/crates/busbar/src/auth/mod.rs similarity index 100% rename from src/auth/mod.rs rename to crates/busbar/src/auth/mod.rs diff --git a/src/auth/tests/tests.rs b/crates/busbar/src/auth/tests/tests.rs similarity index 100% rename from src/auth/tests/tests.rs rename to crates/busbar/src/auth/tests/tests.rs diff --git a/src/auth_cache.rs b/crates/busbar/src/auth_cache.rs similarity index 100% rename from src/auth_cache.rs rename to crates/busbar/src/auth_cache.rs diff --git a/src/billing.rs b/crates/busbar/src/billing.rs similarity index 100% rename from src/billing.rs rename to crates/busbar/src/billing.rs diff --git a/src/breaker.rs b/crates/busbar/src/breaker.rs similarity index 100% rename from src/breaker.rs rename to crates/busbar/src/breaker.rs diff --git a/src/config/mod.rs b/crates/busbar/src/config/mod.rs similarity index 100% rename from src/config/mod.rs rename to crates/busbar/src/config/mod.rs diff --git a/src/config/overlay.rs b/crates/busbar/src/config/overlay.rs similarity index 100% rename from src/config/overlay.rs rename to crates/busbar/src/config/overlay.rs diff --git a/src/config/tests/tests.rs b/crates/busbar/src/config/tests/tests.rs similarity index 99% rename from src/config/tests/tests.rs rename to crates/busbar/src/config/tests/tests.rs index 9cc1cf2f..091a5e99 100644 --- a/src/config/tests/tests.rs +++ b/crates/busbar/src/config/tests/tests.rs @@ -303,12 +303,12 @@ fn test_shipped_example_config_resolves() { std::env::set_var("BUSBAR_CLIENT_TOKEN", "example-token"); std::env::remove_var("BUSBAR_ADMIN_TOKEN"); let providers_raw = - std::fs::read_to_string(concat!(env!("CARGO_MANIFEST_DIR"), "/providers.yaml")).unwrap(); + std::fs::read_to_string(concat!(env!("CARGO_MANIFEST_DIR"), "/../../providers.yaml")).unwrap(); let defs: HashMap = serde_yaml::from_str(&providers_raw).expect("parse providers.yaml"); let config_raw = - std::fs::read_to_string(concat!(env!("CARGO_MANIFEST_DIR"), "/config.yaml")).unwrap(); + std::fs::read_to_string(concat!(env!("CARGO_MANIFEST_DIR"), "/../../config.yaml")).unwrap(); let expanded = interpolate_env(&config_raw).expect("expand ${ENV} in example config.yaml"); let deploy: DeployCfg = serde_yaml::from_str(&expanded).expect("parse example config.yaml"); @@ -341,7 +341,7 @@ fn test_default_config_boots_without_admin_token_env() { std::env::remove_var("BUSBAR_ADMIN_TOKEN"); let config_raw = - std::fs::read_to_string(concat!(env!("CARGO_MANIFEST_DIR"), "/config.yaml")).unwrap(); + std::fs::read_to_string(concat!(env!("CARGO_MANIFEST_DIR"), "/../../config.yaml")).unwrap(); // No active OR commented `${...}` token in the shipped config may reference an admin token: // the only legitimate brace-form interpolation is the active client-tokens entry. @@ -591,7 +591,7 @@ fn test_budget_on_store_error_parses() { /// The shipped providers.yaml catalog must parse, name only known protocols, and use HTTPS. #[test] fn test_shipped_providers_catalog_valid() { - let path = concat!(env!("CARGO_MANIFEST_DIR"), "/providers.yaml"); + let path = concat!(env!("CARGO_MANIFEST_DIR"), "/../../providers.yaml"); let raw = std::fs::read_to_string(path).expect("read providers.yaml"); let defs: HashMap = serde_yaml::from_str(&raw).expect("parse providers.yaml"); diff --git a/src/config_validate/mod.rs b/crates/busbar/src/config_validate/mod.rs similarity index 100% rename from src/config_validate/mod.rs rename to crates/busbar/src/config_validate/mod.rs diff --git a/src/config_validate/tests/tests.rs b/crates/busbar/src/config_validate/tests/tests.rs similarity index 100% rename from src/config_validate/tests/tests.rs rename to crates/busbar/src/config_validate/tests/tests.rs diff --git a/src/endpoints.rs b/crates/busbar/src/endpoints.rs similarity index 100% rename from src/endpoints.rs rename to crates/busbar/src/endpoints.rs diff --git a/src/eventstream.rs b/crates/busbar/src/eventstream.rs similarity index 100% rename from src/eventstream.rs rename to crates/busbar/src/eventstream.rs diff --git a/src/governance/mod.rs b/crates/busbar/src/governance/mod.rs similarity index 100% rename from src/governance/mod.rs rename to crates/busbar/src/governance/mod.rs diff --git a/src/governance/state.rs b/crates/busbar/src/governance/state.rs similarity index 100% rename from src/governance/state.rs rename to crates/busbar/src/governance/state.rs diff --git a/src/governance/tests/tests.rs b/crates/busbar/src/governance/tests/tests.rs similarity index 100% rename from src/governance/tests/tests.rs rename to crates/busbar/src/governance/tests/tests.rs diff --git a/src/handlers/anthropic.rs b/crates/busbar/src/handlers/anthropic.rs similarity index 100% rename from src/handlers/anthropic.rs rename to crates/busbar/src/handlers/anthropic.rs diff --git a/src/handlers/bedrock.rs b/crates/busbar/src/handlers/bedrock.rs similarity index 100% rename from src/handlers/bedrock.rs rename to crates/busbar/src/handlers/bedrock.rs diff --git a/src/handlers/chat.rs b/crates/busbar/src/handlers/chat.rs similarity index 100% rename from src/handlers/chat.rs rename to crates/busbar/src/handlers/chat.rs diff --git a/src/handlers/cohere.rs b/crates/busbar/src/handlers/cohere.rs similarity index 100% rename from src/handlers/cohere.rs rename to crates/busbar/src/handlers/cohere.rs diff --git a/src/handlers/gemini.rs b/crates/busbar/src/handlers/gemini.rs similarity index 100% rename from src/handlers/gemini.rs rename to crates/busbar/src/handlers/gemini.rs diff --git a/src/handlers/mod.rs b/crates/busbar/src/handlers/mod.rs similarity index 100% rename from src/handlers/mod.rs rename to crates/busbar/src/handlers/mod.rs diff --git a/src/handlers/openai.rs b/crates/busbar/src/handlers/openai.rs similarity index 100% rename from src/handlers/openai.rs rename to crates/busbar/src/handlers/openai.rs diff --git a/src/handlers/responses.rs b/crates/busbar/src/handlers/responses.rs similarity index 100% rename from src/handlers/responses.rs rename to crates/busbar/src/handlers/responses.rs diff --git a/src/handlers/tests/contract_tests.rs b/crates/busbar/src/handlers/tests/contract_tests.rs similarity index 100% rename from src/handlers/tests/contract_tests.rs rename to crates/busbar/src/handlers/tests/contract_tests.rs diff --git a/src/handlers/tests/dispatch_tests.rs b/crates/busbar/src/handlers/tests/dispatch_tests.rs similarity index 100% rename from src/handlers/tests/dispatch_tests.rs rename to crates/busbar/src/handlers/tests/dispatch_tests.rs diff --git a/src/handlers/tests/registry_tests.rs b/crates/busbar/src/handlers/tests/registry_tests.rs similarity index 100% rename from src/handlers/tests/registry_tests.rs rename to crates/busbar/src/handlers/tests/registry_tests.rs diff --git a/src/health.rs b/crates/busbar/src/health.rs similarity index 100% rename from src/health.rs rename to crates/busbar/src/health.rs diff --git a/src/hooks/mod.rs b/crates/busbar/src/hooks/mod.rs similarity index 100% rename from src/hooks/mod.rs rename to crates/busbar/src/hooks/mod.rs diff --git a/src/hooks/scrape.rs b/crates/busbar/src/hooks/scrape.rs similarity index 100% rename from src/hooks/scrape.rs rename to crates/busbar/src/hooks/scrape.rs diff --git a/src/hooks/socket.rs b/crates/busbar/src/hooks/socket.rs similarity index 100% rename from src/hooks/socket.rs rename to crates/busbar/src/hooks/socket.rs diff --git a/src/hooks/tests/scrape_tests.rs b/crates/busbar/src/hooks/tests/scrape_tests.rs similarity index 100% rename from src/hooks/tests/scrape_tests.rs rename to crates/busbar/src/hooks/tests/scrape_tests.rs diff --git a/src/hooks/tests/tests.rs b/crates/busbar/src/hooks/tests/tests.rs similarity index 100% rename from src/hooks/tests/tests.rs rename to crates/busbar/src/hooks/tests/tests.rs diff --git a/src/hooks/webhook.rs b/crates/busbar/src/hooks/webhook.rs similarity index 100% rename from src/hooks/webhook.rs rename to crates/busbar/src/hooks/webhook.rs diff --git a/src/hooks/wire.rs b/crates/busbar/src/hooks/wire.rs similarity index 100% rename from src/hooks/wire.rs rename to crates/busbar/src/hooks/wire.rs diff --git a/src/ingress/dispatch.rs b/crates/busbar/src/ingress/dispatch.rs similarity index 100% rename from src/ingress/dispatch.rs rename to crates/busbar/src/ingress/dispatch.rs diff --git a/src/ingress/mod.rs b/crates/busbar/src/ingress/mod.rs similarity index 100% rename from src/ingress/mod.rs rename to crates/busbar/src/ingress/mod.rs diff --git a/src/ingress/tests/tests.rs b/crates/busbar/src/ingress/tests/tests.rs similarity index 100% rename from src/ingress/tests/tests.rs rename to crates/busbar/src/ingress/tests/tests.rs diff --git a/src/ir/audio.rs b/crates/busbar/src/ir/audio.rs similarity index 100% rename from src/ir/audio.rs rename to crates/busbar/src/ir/audio.rs diff --git a/src/ir/embeddings.rs b/crates/busbar/src/ir/embeddings.rs similarity index 100% rename from src/ir/embeddings.rs rename to crates/busbar/src/ir/embeddings.rs diff --git a/src/ir/image.rs b/crates/busbar/src/ir/image.rs similarity index 100% rename from src/ir/image.rs rename to crates/busbar/src/ir/image.rs diff --git a/src/ir/mod.rs b/crates/busbar/src/ir/mod.rs similarity index 100% rename from src/ir/mod.rs rename to crates/busbar/src/ir/mod.rs diff --git a/src/ir/moderation.rs b/crates/busbar/src/ir/moderation.rs similarity index 100% rename from src/ir/moderation.rs rename to crates/busbar/src/ir/moderation.rs diff --git a/src/ir/rerank.rs b/crates/busbar/src/ir/rerank.rs similarity index 100% rename from src/ir/rerank.rs rename to crates/busbar/src/ir/rerank.rs diff --git a/src/ir/tests/tests.rs b/crates/busbar/src/ir/tests/tests.rs similarity index 100% rename from src/ir/tests/tests.rs rename to crates/busbar/src/ir/tests/tests.rs diff --git a/src/ir/variant.rs b/crates/busbar/src/ir/variant.rs similarity index 100% rename from src/ir/variant.rs rename to crates/busbar/src/ir/variant.rs diff --git a/src/json.rs b/crates/busbar/src/json.rs similarity index 100% rename from src/json.rs rename to crates/busbar/src/json.rs diff --git a/src/limits.rs b/crates/busbar/src/limits.rs similarity index 100% rename from src/limits.rs rename to crates/busbar/src/limits.rs diff --git a/src/lossless.rs b/crates/busbar/src/lossless.rs similarity index 100% rename from src/lossless.rs rename to crates/busbar/src/lossless.rs diff --git a/src/main.rs b/crates/busbar/src/main.rs similarity index 100% rename from src/main.rs rename to crates/busbar/src/main.rs diff --git a/src/media.rs b/crates/busbar/src/media.rs similarity index 100% rename from src/media.rs rename to crates/busbar/src/media.rs diff --git a/src/metrics.rs b/crates/busbar/src/metrics.rs similarity index 100% rename from src/metrics.rs rename to crates/busbar/src/metrics.rs diff --git a/src/net_guard.rs b/crates/busbar/src/net_guard.rs similarity index 100% rename from src/net_guard.rs rename to crates/busbar/src/net_guard.rs diff --git a/src/observability.rs b/crates/busbar/src/observability.rs similarity index 100% rename from src/observability.rs rename to crates/busbar/src/observability.rs diff --git a/src/operation.rs b/crates/busbar/src/operation.rs similarity index 100% rename from src/operation.rs rename to crates/busbar/src/operation.rs diff --git a/src/proto/anthropic/mod.rs b/crates/busbar/src/proto/anthropic/mod.rs similarity index 100% rename from src/proto/anthropic/mod.rs rename to crates/busbar/src/proto/anthropic/mod.rs diff --git a/src/proto/anthropic/reader.rs b/crates/busbar/src/proto/anthropic/reader.rs similarity index 100% rename from src/proto/anthropic/reader.rs rename to crates/busbar/src/proto/anthropic/reader.rs diff --git a/src/proto/anthropic/tests/anthropic_hardening_tests.rs b/crates/busbar/src/proto/anthropic/tests/anthropic_hardening_tests.rs similarity index 100% rename from src/proto/anthropic/tests/anthropic_hardening_tests.rs rename to crates/busbar/src/proto/anthropic/tests/anthropic_hardening_tests.rs diff --git a/src/proto/anthropic/tests/reasoning_carry_tests.rs b/crates/busbar/src/proto/anthropic/tests/reasoning_carry_tests.rs similarity index 100% rename from src/proto/anthropic/tests/reasoning_carry_tests.rs rename to crates/busbar/src/proto/anthropic/tests/reasoning_carry_tests.rs diff --git a/src/proto/anthropic/tests/user_and_parallelism_carry_tests.rs b/crates/busbar/src/proto/anthropic/tests/user_and_parallelism_carry_tests.rs similarity index 100% rename from src/proto/anthropic/tests/user_and_parallelism_carry_tests.rs rename to crates/busbar/src/proto/anthropic/tests/user_and_parallelism_carry_tests.rs diff --git a/src/proto/anthropic/writer.rs b/crates/busbar/src/proto/anthropic/writer.rs similarity index 100% rename from src/proto/anthropic/writer.rs rename to crates/busbar/src/proto/anthropic/writer.rs diff --git a/src/proto/bedrock/mod.rs b/crates/busbar/src/proto/bedrock/mod.rs similarity index 100% rename from src/proto/bedrock/mod.rs rename to crates/busbar/src/proto/bedrock/mod.rs diff --git a/src/proto/bedrock/reader.rs b/crates/busbar/src/proto/bedrock/reader.rs similarity index 100% rename from src/proto/bedrock/reader.rs rename to crates/busbar/src/proto/bedrock/reader.rs diff --git a/src/proto/bedrock/tests/tests.rs b/crates/busbar/src/proto/bedrock/tests/tests.rs similarity index 100% rename from src/proto/bedrock/tests/tests.rs rename to crates/busbar/src/proto/bedrock/tests/tests.rs diff --git a/src/proto/bedrock/writer.rs b/crates/busbar/src/proto/bedrock/writer.rs similarity index 100% rename from src/proto/bedrock/writer.rs rename to crates/busbar/src/proto/bedrock/writer.rs diff --git a/src/proto/cohere/mod.rs b/crates/busbar/src/proto/cohere/mod.rs similarity index 100% rename from src/proto/cohere/mod.rs rename to crates/busbar/src/proto/cohere/mod.rs diff --git a/src/proto/cohere/reader.rs b/crates/busbar/src/proto/cohere/reader.rs similarity index 100% rename from src/proto/cohere/reader.rs rename to crates/busbar/src/proto/cohere/reader.rs diff --git a/src/proto/cohere/tests/tests.rs b/crates/busbar/src/proto/cohere/tests/tests.rs similarity index 100% rename from src/proto/cohere/tests/tests.rs rename to crates/busbar/src/proto/cohere/tests/tests.rs diff --git a/src/proto/cohere/writer.rs b/crates/busbar/src/proto/cohere/writer.rs similarity index 100% rename from src/proto/cohere/writer.rs rename to crates/busbar/src/proto/cohere/writer.rs diff --git a/src/proto/detect.rs b/crates/busbar/src/proto/detect.rs similarity index 100% rename from src/proto/detect.rs rename to crates/busbar/src/proto/detect.rs diff --git a/src/proto/gemini/mod.rs b/crates/busbar/src/proto/gemini/mod.rs similarity index 100% rename from src/proto/gemini/mod.rs rename to crates/busbar/src/proto/gemini/mod.rs diff --git a/src/proto/gemini/reader.rs b/crates/busbar/src/proto/gemini/reader.rs similarity index 100% rename from src/proto/gemini/reader.rs rename to crates/busbar/src/proto/gemini/reader.rs diff --git a/src/proto/gemini/tests/logprobs_carry_tests.rs b/crates/busbar/src/proto/gemini/tests/logprobs_carry_tests.rs similarity index 100% rename from src/proto/gemini/tests/logprobs_carry_tests.rs rename to crates/busbar/src/proto/gemini/tests/logprobs_carry_tests.rs diff --git a/src/proto/gemini/tests/tests.rs b/crates/busbar/src/proto/gemini/tests/tests.rs similarity index 100% rename from src/proto/gemini/tests/tests.rs rename to crates/busbar/src/proto/gemini/tests/tests.rs diff --git a/src/proto/gemini/writer.rs b/crates/busbar/src/proto/gemini/writer.rs similarity index 100% rename from src/proto/gemini/writer.rs rename to crates/busbar/src/proto/gemini/writer.rs diff --git a/src/proto/mod.rs b/crates/busbar/src/proto/mod.rs similarity index 100% rename from src/proto/mod.rs rename to crates/busbar/src/proto/mod.rs diff --git a/src/proto/openai_chat/mod.rs b/crates/busbar/src/proto/openai_chat/mod.rs similarity index 100% rename from src/proto/openai_chat/mod.rs rename to crates/busbar/src/proto/openai_chat/mod.rs diff --git a/src/proto/openai_chat/reader.rs b/crates/busbar/src/proto/openai_chat/reader.rs similarity index 100% rename from src/proto/openai_chat/reader.rs rename to crates/busbar/src/proto/openai_chat/reader.rs diff --git a/src/proto/openai_chat/tests/tests.rs b/crates/busbar/src/proto/openai_chat/tests/tests.rs similarity index 100% rename from src/proto/openai_chat/tests/tests.rs rename to crates/busbar/src/proto/openai_chat/tests/tests.rs diff --git a/src/proto/openai_chat/writer.rs b/crates/busbar/src/proto/openai_chat/writer.rs similarity index 100% rename from src/proto/openai_chat/writer.rs rename to crates/busbar/src/proto/openai_chat/writer.rs diff --git a/src/proto/openai_family.rs b/crates/busbar/src/proto/openai_family.rs similarity index 100% rename from src/proto/openai_family.rs rename to crates/busbar/src/proto/openai_family.rs diff --git a/src/proto/openai_responses/mod.rs b/crates/busbar/src/proto/openai_responses/mod.rs similarity index 100% rename from src/proto/openai_responses/mod.rs rename to crates/busbar/src/proto/openai_responses/mod.rs diff --git a/src/proto/openai_responses/reader.rs b/crates/busbar/src/proto/openai_responses/reader.rs similarity index 100% rename from src/proto/openai_responses/reader.rs rename to crates/busbar/src/proto/openai_responses/reader.rs diff --git a/src/proto/openai_responses/tests/tests.rs b/crates/busbar/src/proto/openai_responses/tests/tests.rs similarity index 100% rename from src/proto/openai_responses/tests/tests.rs rename to crates/busbar/src/proto/openai_responses/tests/tests.rs diff --git a/src/proto/openai_responses/writer.rs b/crates/busbar/src/proto/openai_responses/writer.rs similarity index 100% rename from src/proto/openai_responses/writer.rs rename to crates/busbar/src/proto/openai_responses/writer.rs diff --git a/src/proto/stream.rs b/crates/busbar/src/proto/stream.rs similarity index 100% rename from src/proto/stream.rs rename to crates/busbar/src/proto/stream.rs diff --git a/src/proto/tests/context_length_tests.rs b/crates/busbar/src/proto/tests/context_length_tests.rs similarity index 100% rename from src/proto/tests/context_length_tests.rs rename to crates/busbar/src/proto/tests/context_length_tests.rs diff --git a/src/proto/tests/gemini_integration_tests.rs b/crates/busbar/src/proto/tests/gemini_integration_tests.rs similarity index 100% rename from src/proto/tests/gemini_integration_tests.rs rename to crates/busbar/src/proto/tests/gemini_integration_tests.rs diff --git a/src/proto/tests/gemini_tests.rs b/crates/busbar/src/proto/tests/gemini_tests.rs similarity index 100% rename from src/proto/tests/gemini_tests.rs rename to crates/busbar/src/proto/tests/gemini_tests.rs diff --git a/src/proto/tests/image_source_matrix_tests.rs b/crates/busbar/src/proto/tests/image_source_matrix_tests.rs similarity index 100% rename from src/proto/tests/image_source_matrix_tests.rs rename to crates/busbar/src/proto/tests/image_source_matrix_tests.rs diff --git a/src/proto/tests/response_format_matrix_tests.rs b/crates/busbar/src/proto/tests/response_format_matrix_tests.rs similarity index 100% rename from src/proto/tests/response_format_matrix_tests.rs rename to crates/busbar/src/proto/tests/response_format_matrix_tests.rs diff --git a/src/proto/tests/same_proto_fidelity_tests.rs b/crates/busbar/src/proto/tests/same_proto_fidelity_tests.rs similarity index 100% rename from src/proto/tests/same_proto_fidelity_tests.rs rename to crates/busbar/src/proto/tests/same_proto_fidelity_tests.rs diff --git a/src/proto/tests/stop_reason_matrix_tests.rs b/crates/busbar/src/proto/tests/stop_reason_matrix_tests.rs similarity index 100% rename from src/proto/tests/stop_reason_matrix_tests.rs rename to crates/busbar/src/proto/tests/stop_reason_matrix_tests.rs diff --git a/src/proto/tests/stream_fanout_tests.rs b/crates/busbar/src/proto/tests/stream_fanout_tests.rs similarity index 100% rename from src/proto/tests/stream_fanout_tests.rs rename to crates/busbar/src/proto/tests/stream_fanout_tests.rs diff --git a/src/proto/tests/stream_translate_tests.rs b/crates/busbar/src/proto/tests/stream_translate_tests.rs similarity index 100% rename from src/proto/tests/stream_translate_tests.rs rename to crates/busbar/src/proto/tests/stream_translate_tests.rs diff --git a/src/proto/tests/tests.rs b/crates/busbar/src/proto/tests/tests.rs similarity index 100% rename from src/proto/tests/tests.rs rename to crates/busbar/src/proto/tests/tests.rs diff --git a/src/proxy/egress.rs b/crates/busbar/src/proxy/egress.rs similarity index 100% rename from src/proxy/egress.rs rename to crates/busbar/src/proxy/egress.rs diff --git a/src/proxy/engine/mod.rs b/crates/busbar/src/proxy/engine/mod.rs similarity index 100% rename from src/proxy/engine/mod.rs rename to crates/busbar/src/proxy/engine/mod.rs diff --git a/src/proxy/engine/walk.rs b/crates/busbar/src/proxy/engine/walk.rs similarity index 100% rename from src/proxy/engine/walk.rs rename to crates/busbar/src/proxy/engine/walk.rs diff --git a/src/proxy/hooks.rs b/crates/busbar/src/proxy/hooks.rs similarity index 100% rename from src/proxy/hooks.rs rename to crates/busbar/src/proxy/hooks.rs diff --git a/src/proxy/mod.rs b/crates/busbar/src/proxy/mod.rs similarity index 100% rename from src/proxy/mod.rs rename to crates/busbar/src/proxy/mod.rs diff --git a/src/proxy/response_body.rs b/crates/busbar/src/proxy/response_body.rs similarity index 100% rename from src/proxy/response_body.rs rename to crates/busbar/src/proxy/response_body.rs diff --git a/src/proxy/select.rs b/crates/busbar/src/proxy/select.rs similarity index 100% rename from src/proxy/select.rs rename to crates/busbar/src/proxy/select.rs diff --git a/src/proxy/tests/attempt_timeout_precedence_tests.rs b/crates/busbar/src/proxy/tests/attempt_timeout_precedence_tests.rs similarity index 100% rename from src/proxy/tests/attempt_timeout_precedence_tests.rs rename to crates/busbar/src/proxy/tests/attempt_timeout_precedence_tests.rs diff --git a/src/proxy/tests/auth_style_tests.rs b/crates/busbar/src/proxy/tests/auth_style_tests.rs similarity index 100% rename from src/proxy/tests/auth_style_tests.rs rename to crates/busbar/src/proxy/tests/auth_style_tests.rs diff --git a/src/proxy/tests/bedrock_eventstream_tests.rs b/crates/busbar/src/proxy/tests/bedrock_eventstream_tests.rs similarity index 100% rename from src/proxy/tests/bedrock_eventstream_tests.rs rename to crates/busbar/src/proxy/tests/bedrock_eventstream_tests.rs diff --git a/src/proxy/tests/billing_parity_tests.rs b/crates/busbar/src/proxy/tests/billing_parity_tests.rs similarity index 100% rename from src/proxy/tests/billing_parity_tests.rs rename to crates/busbar/src/proxy/tests/billing_parity_tests.rs diff --git a/src/proxy/tests/cross_protocol_extra_tests.rs b/crates/busbar/src/proxy/tests/cross_protocol_extra_tests.rs similarity index 100% rename from src/proxy/tests/cross_protocol_extra_tests.rs rename to crates/busbar/src/proxy/tests/cross_protocol_extra_tests.rs diff --git a/src/proxy/tests/forward_once_pool_cell_tests.rs b/crates/busbar/src/proxy/tests/forward_once_pool_cell_tests.rs similarity index 100% rename from src/proxy/tests/forward_once_pool_cell_tests.rs rename to crates/busbar/src/proxy/tests/forward_once_pool_cell_tests.rs diff --git a/src/proxy/tests/hook_opt_in_projection_tests.rs b/crates/busbar/src/proxy/tests/hook_opt_in_projection_tests.rs similarity index 100% rename from src/proxy/tests/hook_opt_in_projection_tests.rs rename to crates/busbar/src/proxy/tests/hook_opt_in_projection_tests.rs diff --git a/src/proxy/tests/hook_seam_tests.rs b/crates/busbar/src/proxy/tests/hook_seam_tests.rs similarity index 100% rename from src/proxy/tests/hook_seam_tests.rs rename to crates/busbar/src/proxy/tests/hook_seam_tests.rs diff --git a/src/proxy/tests/ingress_indistinguishability_tests.rs b/crates/busbar/src/proxy/tests/ingress_indistinguishability_tests.rs similarity index 100% rename from src/proxy/tests/ingress_indistinguishability_tests.rs rename to crates/busbar/src/proxy/tests/ingress_indistinguishability_tests.rs diff --git a/src/proxy/tests/max_tokens_precedence_tests.rs b/crates/busbar/src/proxy/tests/max_tokens_precedence_tests.rs similarity index 100% rename from src/proxy/tests/max_tokens_precedence_tests.rs rename to crates/busbar/src/proxy/tests/max_tokens_precedence_tests.rs diff --git a/src/proxy/tests/mid_stream_error_tests.rs b/crates/busbar/src/proxy/tests/mid_stream_error_tests.rs similarity index 100% rename from src/proxy/tests/mid_stream_error_tests.rs rename to crates/busbar/src/proxy/tests/mid_stream_error_tests.rs diff --git a/src/proxy/tests/on_exhausted_tests.rs b/crates/busbar/src/proxy/tests/on_exhausted_tests.rs similarity index 100% rename from src/proxy/tests/on_exhausted_tests.rs rename to crates/busbar/src/proxy/tests/on_exhausted_tests.rs diff --git a/src/proxy/tests/ordered_walk_tests.rs b/crates/busbar/src/proxy/tests/ordered_walk_tests.rs similarity index 100% rename from src/proxy/tests/ordered_walk_tests.rs rename to crates/busbar/src/proxy/tests/ordered_walk_tests.rs diff --git a/src/proxy/tests/probe_guard_tests.rs b/crates/busbar/src/proxy/tests/probe_guard_tests.rs similarity index 100% rename from src/proxy/tests/probe_guard_tests.rs rename to crates/busbar/src/proxy/tests/probe_guard_tests.rs diff --git a/src/proxy/tests/request_short_circuit_tests.rs b/crates/busbar/src/proxy/tests/request_short_circuit_tests.rs similarity index 100% rename from src/proxy/tests/request_short_circuit_tests.rs rename to crates/busbar/src/proxy/tests/request_short_circuit_tests.rs diff --git a/src/proxy/tests/usage_tap_tests.rs b/crates/busbar/src/proxy/tests/usage_tap_tests.rs similarity index 100% rename from src/proxy/tests/usage_tap_tests.rs rename to crates/busbar/src/proxy/tests/usage_tap_tests.rs diff --git a/src/proxy/usage.rs b/crates/busbar/src/proxy/usage.rs similarity index 100% rename from src/proxy/usage.rs rename to crates/busbar/src/proxy/usage.rs diff --git a/src/proxy/wire.rs b/crates/busbar/src/proxy/wire.rs similarity index 100% rename from src/proxy/wire.rs rename to crates/busbar/src/proxy/wire.rs diff --git a/src/sigv4.rs b/crates/busbar/src/sigv4.rs similarity index 100% rename from src/sigv4.rs rename to crates/busbar/src/sigv4.rs diff --git a/src/state.rs b/crates/busbar/src/state.rs similarity index 100% rename from src/state.rs rename to crates/busbar/src/state.rs diff --git a/src/state_persist.rs b/crates/busbar/src/state_persist.rs similarity index 100% rename from src/state_persist.rs rename to crates/busbar/src/state_persist.rs diff --git a/src/store/in_memory.rs b/crates/busbar/src/store/in_memory.rs similarity index 100% rename from src/store/in_memory.rs rename to crates/busbar/src/store/in_memory.rs diff --git a/src/store/mod.rs b/crates/busbar/src/store/mod.rs similarity index 100% rename from src/store/mod.rs rename to crates/busbar/src/store/mod.rs diff --git a/src/store/tests/tests.rs b/crates/busbar/src/store/tests/tests.rs similarity index 100% rename from src/store/tests/tests.rs rename to crates/busbar/src/store/tests/tests.rs diff --git a/src/test_support/mod.rs b/crates/busbar/src/test_support/mod.rs similarity index 100% rename from src/test_support/mod.rs rename to crates/busbar/src/test_support/mod.rs diff --git a/src/test_support/tests/tests.rs b/crates/busbar/src/test_support/tests/tests.rs similarity index 100% rename from src/test_support/tests/tests.rs rename to crates/busbar/src/test_support/tests/tests.rs diff --git a/src/tests/tests.rs b/crates/busbar/src/tests/tests.rs similarity index 100% rename from src/tests/tests.rs rename to crates/busbar/src/tests/tests.rs diff --git a/src/tls.rs b/crates/busbar/src/tls.rs similarity index 100% rename from src/tls.rs rename to crates/busbar/src/tls.rs diff --git a/hooks/ranking/Cargo.toml b/crates/hooks-ranking/Cargo.toml similarity index 94% rename from hooks/ranking/Cargo.toml rename to crates/hooks-ranking/Cargo.toml index 7de5756f..f32341d4 100644 --- a/hooks/ranking/Cargo.toml +++ b/crates/hooks-ranking/Cargo.toml @@ -8,7 +8,7 @@ description = "The built-in ranking hooks for busbar: cheapest / fastest / least license = "Apache-2.0" [dependencies] -busbar-api = { path = "../../api" } +busbar-api = { path = "../api" } async-trait = "0.1" [dev-dependencies] diff --git a/hooks/ranking/src/lib.rs b/crates/hooks-ranking/src/lib.rs similarity index 100% rename from hooks/ranking/src/lib.rs rename to crates/hooks-ranking/src/lib.rs diff --git a/docs/code-layout.md b/docs/code-layout.md index e6c68d37..9f281551 100644 --- a/docs/code-layout.md +++ b/docs/code-layout.md @@ -7,6 +7,29 @@ true by construction. Size reduction is a side effect of getting that right, not Four invariants, all mechanically enforced by `scripts/structure-lint.sh` (run in CI). If they hold, the tree cannot drift back into giant, inconsistent files. +## 0. Workspace layout — all Rust lives under `crates/` + +The repo is a Cargo workspace. Every crate lives under `crates/`, and nothing else at the root is +Rust — so "code vs not-code" is obvious at a glance: + +``` +crates/ + busbar/ the engine + binary (src/main.rs, the request path, admin plane, protocols) + api/ the plugin CONTRACT crate — traits/types both the engine and every plugin build against + auth-tokens/ built-in `tokens` auth plugin (default-on, removable feature) + auth-admin-tokens/ built-in `admin-tokens` admin plugin (default-on, removable feature) + hooks-ranking/ built-in cheapest/fastest/… policies (default-on, removable feature) +``` + +Dependency direction is one-way: `busbar` → `api` ← plugins. A plugin depends only on `api`, never on +the engine — so a built-in is structured exactly like a third-party plugin would be (no privileged +access). Each plugin is an `optional` dependency gated by a feature, so `--no-default-features` compiles +it out entirely. Non-Rust lives at the root: `examples/`, `scripts/`, `docs/`, `bench/`, `config.yaml`, +`providers.yaml`, `Dockerfile`. The `[profile.release]` and `[workspace]` table are in the root +`Cargo.toml`; each crate's `[package]` is in its own `crates//Cargo.toml`. + +The invariants below govern module layout *within* each crate's `src/`. + ## 1. A module is a file *or* a folder — never both `foo.rs` and `foo/` must not coexist. The moment a module needs a second file, the parent `foo.rs` diff --git a/scripts/structure-lint.sh b/scripts/structure-lint.sh index b8a770e6..56995f1b 100755 --- a/scripts/structure-lint.sh +++ b/scripts/structure-lint.sh @@ -23,7 +23,7 @@ while IFS= read -r d; do note "HYBRID: ${base}.rs coexists with ${base}/ — fold ${base}.rs into ${base}/mod.rs" fail=1 fi -done < <(find src -type d) +done < <(find crates -type d) [ "$fail" -eq 0 ] && note "ok" # ── Invariant 2: no monster impl files — split by area. Test files (under a tests/ dir) are exempt. ─ @@ -33,7 +33,7 @@ while IFS= read -r f; do case "$f" in */tests/*) continue ;; esac # test files are name-navigated → exempt from the cap n=$(wc -l < "$f") if [ "$n" -gt "$MAX_LINES_IMPL" ]; then note "OVERSIZED: $f ($n lines)"; fail=1; big=1; fi -done < <(find src -name '*.rs') +done < <(find crates -name '*.rs') [ "$big" -eq 0 ] && note "ok" # ── Invariant 3: tests live in foo/tests/. The trigger is an inline test module BODY — a @@ -59,7 +59,7 @@ while IFS= read -r f; do note "MULTI-TEST-MOD: $f has ${bodies} inline test bodies — give each its own tests/.rs" fail=1; loc=1 fi -done < <(find src -name '*.rs') +done < <(find crates -name '*.rs') [ "$loc" -eq 0 ] && note "ok" hdr "result" From 46e4d71bdc888d11436512fdb0d02fbd4c520b73 Mon Sep 17 00:00:00 2001 From: Matthew Jackson <1085847+MattJackson@users.noreply.github.com> Date: Tue, 14 Jul 2026 21:49:25 -0700 Subject: [PATCH 2/2] fmt: wrap the over-width providers.yaml test read The ../../ path fix pushed the concat! read past rustfmt's 100-col limit; stable rustfmt breaks .unwrap() onto its own line. --- crates/busbar/src/config/tests/tests.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/busbar/src/config/tests/tests.rs b/crates/busbar/src/config/tests/tests.rs index 091a5e99..21073041 100644 --- a/crates/busbar/src/config/tests/tests.rs +++ b/crates/busbar/src/config/tests/tests.rs @@ -303,7 +303,8 @@ fn test_shipped_example_config_resolves() { std::env::set_var("BUSBAR_CLIENT_TOKEN", "example-token"); std::env::remove_var("BUSBAR_ADMIN_TOKEN"); let providers_raw = - std::fs::read_to_string(concat!(env!("CARGO_MANIFEST_DIR"), "/../../providers.yaml")).unwrap(); + std::fs::read_to_string(concat!(env!("CARGO_MANIFEST_DIR"), "/../../providers.yaml")) + .unwrap(); let defs: HashMap = serde_yaml::from_str(&providers_raw).expect("parse providers.yaml");