From 892dd9257e3c7d073b1d08d21bc8ebc3f62c97de Mon Sep 17 00:00:00 2001 From: seniorswe <57962648+seniorswe@users.noreply.github.com> Date: Sat, 26 Sep 2026 20:53:20 -0400 Subject: [PATCH 1/6] Rust migration --- .github/workflows/ci.yml | 2 + Makefile | 7 +- gateway-rs/Cargo.lock | 32 + gateway-rs/Cargo.toml | 3 +- gateway-rs/src/app.rs | 40 +- gateway-rs/src/config.rs | 3 + gateway-rs/src/constants.rs | 66 + gateway-rs/src/demo_seed.rs | 572 + gateway-rs/src/error_codes.rs | 183 + gateway-rs/src/gateway/transforms.rs | 42 +- gateway-rs/src/lib.rs | 3 + gateway-rs/src/main.rs | 235 +- gateway-rs/src/middleware/chaos.rs | 40 + gateway-rs/src/middleware/mod.rs | 1 + gateway-rs/src/middleware/security_headers.rs | 23 +- gateway-rs/src/middleware/websocket_reject.rs | 73 + .../src/observability/analytics_aggregator.rs | 83 +- gateway-rs/src/observability/audit.rs | 52 +- gateway-rs/src/observability/email.rs | 27 + gateway-rs/src/observability/logging.rs | 44 +- gateway-rs/src/observability/mod.rs | 1 + gateway-rs/src/platform_contract.rs | 18 +- gateway-rs/src/policy/auth.rs | 52 +- gateway-rs/src/policy/credits.rs | 13 +- gateway-rs/src/policy/evaluator.rs | 104 +- gateway-rs/src/policy/geo.rs | 284 + gateway-rs/src/policy/ip.rs | 13 +- gateway-rs/src/policy/mod.rs | 2 + gateway-rs/src/policy/quota.rs | 35 +- gateway-rs/src/policy/simulator.rs | 351 + gateway-rs/src/policy/subscription.rs | 2 +- gateway-rs/src/routes/platform.rs | 2643 +- gateway-rs/src/routes/rest.rs | 126 +- gateway-rs/src/storage/cache.rs | 6 +- gateway-rs/src/storage/field_encryption.rs | 48 + gateway-rs/src/storage/mod.rs | 1 + gateway-rs/src/storage/runtime.rs | 110 +- gateway-rs/src/storage/snapshot.rs | 83 +- gateway-rs/src/storage/vault.rs | 22 + gateway-rs/src/validation/graphql.rs | 69 +- gateway-rs/src/validation/json.rs | 250 +- gateway-rs/src/validation/mod.rs | 1 + gateway-rs/src/validation/sanitize.rs | 85 + gateway-rs/tests/live_tests_parity.rs | 2 +- gateway-rs/tests/memory_routes_parity.rs | 11 + gateway-rs/tests/platform_native.rs | 835 +- gateway-rs/tests/python_parity_suite.rs | 5 +- gateway-rs/tests/roles_groups_parity.rs | 218 +- gateway-rs/tests/user_lifecycle_parity.rs | 18 +- parity/README.md | 23 + parity/source_coverage_ledger.json | 50918 ++++++++++++++++ parity/source_coverage_overrides.json | 2420 + scripts/generate_source_coverage_ledger.py | 276 + scripts/release_check.py | 1 + scripts/run_e2e.py | 8 +- user-docs/TESTS.md | 3 +- 56 files changed, 59678 insertions(+), 910 deletions(-) create mode 100644 gateway-rs/src/constants.rs create mode 100644 gateway-rs/src/demo_seed.rs create mode 100644 gateway-rs/src/error_codes.rs create mode 100644 gateway-rs/src/middleware/websocket_reject.rs create mode 100644 gateway-rs/src/observability/email.rs create mode 100644 gateway-rs/src/policy/geo.rs create mode 100644 gateway-rs/src/policy/simulator.rs create mode 100644 gateway-rs/src/storage/field_encryption.rs create mode 100644 gateway-rs/src/validation/sanitize.rs create mode 100644 parity/source_coverage_ledger.json create mode 100644 parity/source_coverage_overrides.json create mode 100644 scripts/generate_source_coverage_ledger.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e56ddea1..fbbbd05c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -36,6 +36,8 @@ jobs: python3 scripts/check_parity_reference.py - name: Verify Python-to-Rust test coverage ledger run: python3 scripts/generate_test_coverage_ledger.py --check + - name: Verify Python-to-Rust source coverage ledger + run: python3 scripts/generate_source_coverage_ledger.py --check - name: Test release tooling run: python3 -m unittest discover -s scripts -p 'test_*.py' - name: Run Clippy diff --git a/Makefile b/Makefile index 2967e4b9..0a8ac2f9 100644 --- a/Makefile +++ b/Makefile @@ -6,11 +6,11 @@ ADMIN_PASSWORD ?= $(shell grep '^DOORMAN_ADMIN_PASSWORD=' .env 2>/dev/null | cut BASE_URL ?= http://localhost:$(PORT) GATEWAY_LOAD_BASE_URL ?= http://localhost:3001 -.PHONY: check test unit unitq rust-test rust-clippy rust-fmt-check web-audit web-build parity parity-reference parity-ledger parity-contracts parity-differential parity-performance release-check local-e2e test-e2e release-e2e e2e-plan system-e2e-smoke system-e2e system-e2e-soak system-e2e-plan system-e2e-check system-e2e-clean test-live-tcp smoke preflight live liveq gateway-load external-storage-test clean clean-deep +.PHONY: check test unit unitq rust-test rust-clippy rust-fmt-check web-audit web-build parity parity-reference parity-ledger parity-source-ledger parity-contracts parity-differential parity-performance release-check local-e2e test-e2e release-e2e e2e-plan system-e2e-smoke system-e2e system-e2e-soak system-e2e-plan system-e2e-check system-e2e-clean test-live-tcp smoke preflight live liveq gateway-load external-storage-test clean clean-deep check: rust-fmt-check rust-clippy test -parity: parity-reference parity-ledger parity-contracts +parity: parity-reference parity-ledger parity-source-ledger parity-contracts parity-reference: python3 scripts/check_parity_reference.py @@ -18,6 +18,9 @@ parity-reference: parity-ledger: python3 scripts/generate_test_coverage_ledger.py --check +parity-source-ledger: + python3 scripts/generate_source_coverage_ledger.py --check + parity-contracts: cargo test --manifest-path gateway-rs/Cargo.toml --locked --test parity_contracts --test openapi_parity --test auth_rate_parity diff --git a/gateway-rs/Cargo.lock b/gateway-rs/Cargo.lock index eafc3df5..faa9d46e 100644 --- a/gateway-rs/Cargo.lock +++ b/gateway-rs/Cargo.lock @@ -134,6 +134,7 @@ checksum = "31b698c5f9a010f6573133b09e0de5408834d0c82f8d7475a89fc1867a71cd90" dependencies = [ "axum-core", "axum-macros", + "base64 0.22.1", "bytes", "form_urlencoded", "futures-util", @@ -152,8 +153,10 @@ dependencies = [ "serde_json", "serde_path_to_error", "serde_urlencoded", + "sha1", "sync_wrapper", "tokio", + "tokio-tungstenite", "tower", "tower-layer", "tower-service", @@ -694,6 +697,7 @@ dependencies = [ "prost-types", "protoc-bin-vendored", "quick-xml", + "rand 0.9.5", "redis", "regex", "reqwest", @@ -2692,6 +2696,18 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-tungstenite" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f72a05e828585856dacd553fba484c242c46e391fb0e58917c942ee9202915c" +dependencies = [ + "futures-util", + "log", + "tokio", + "tungstenite", +] + [[package]] name = "tokio-util" version = "0.7.19" @@ -2873,6 +2889,22 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" +[[package]] +name = "tungstenite" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c01152af293afb9c7c2a57e4b559c5620b421f6d133261c60dd2d0cdb38e6b8" +dependencies = [ + "bytes", + "data-encoding", + "http", + "httparse", + "log", + "rand 0.9.5", + "sha1", + "thiserror", +] + [[package]] name = "typed-builder" version = "0.22.0" diff --git a/gateway-rs/Cargo.toml b/gateway-rs/Cargo.toml index b60d3173..81706071 100644 --- a/gateway-rs/Cargo.toml +++ b/gateway-rs/Cargo.toml @@ -14,7 +14,7 @@ name = "doorman-gateway" path = "src/main.rs" [dependencies] -axum = { version = "0.8.9", features = ["http2", "macros"] } +axum = { version = "0.8.9", features = ["http2", "macros", "ws"] } base64 = "0.22" bytes = "1.10" futures-util = "0.3" @@ -25,6 +25,7 @@ mongodb = "3" prost = "0.14" prost-reflect = { version = "0.16", features = ["serde"] } quick-xml = "0.38" +rand = "0.9.5" redis = { version = "0.32", features = ["aio", "tokio-comp", "connection-manager"] } regex = "1" ryu = "1" diff --git a/gateway-rs/src/app.rs b/gateway-rs/src/app.rs index b02fcc32..2f0cd2df 100644 --- a/gateway-rs/src/app.rs +++ b/gateway-rs/src/app.rs @@ -4,6 +4,7 @@ use axum::{ routing::{any, get}, }; use http::StatusCode; +use std::any::Any; use tower_http::{ catch_panic::CatchPanicLayer, compression::{CompressionLayer, CompressionLevel, predicate::SizeAbove}, @@ -13,11 +14,12 @@ use tower_http::{ use crate::{ middleware::{ activity::track_active_requests, - chaos::chaos_middleware, + chaos::{chaos_middleware, latency_injection}, platform_cors::{force_platform_vary, platform_cors}, request_id::request_id, response_compat::response_compat, security_headers::security_headers, + websocket_reject::reject_disabled_websockets, }, policy::PolicyErrorBody, routes::{ @@ -84,7 +86,7 @@ pub fn build_router(state: AppState) -> Router { .collect::>(), ), ) - .layer(CatchPanicLayer::new()); + .layer(CatchPanicLayer::custom(handle_panic)); let platform = Router::new() .route("/", any(platform_dispatch)) .route("/{*path}", any(platform_dispatch)) @@ -119,7 +121,7 @@ pub fn build_router(state: AppState) -> Router { .collect::>(), ), ) - .layer(CatchPanicLayer::new()); + .layer(CatchPanicLayer::custom(handle_panic)); Router::new() .nest("/api", api) @@ -130,10 +132,15 @@ pub fn build_router(state: AppState) -> Router { ) .route("/metrics", get(metrics)) .fallback(not_found) + .layer(axum_middleware::from_fn(latency_injection)) .layer(axum_middleware::from_fn_with_state( state.clone(), track_active_requests, )) + .layer(axum_middleware::from_fn_with_state( + state.clone(), + reject_disabled_websockets, + )) .layer(compression) .layer(axum_middleware::from_fn(force_platform_vary)) .with_state(state) @@ -150,6 +157,17 @@ async fn gateway_route_not_found() -> Response { .into_response() } +fn handle_panic(_panic: Box) -> Response { + ( + StatusCode::INTERNAL_SERVER_ERROR, + Json(PolicyErrorBody { + error_code: "ISE001".to_owned(), + error_message: "Internal Server Error".to_owned(), + }), + ) + .into_response() +} + async fn not_found(request: axum::extract::Request) -> Response { let request_id = request .headers() @@ -174,6 +192,22 @@ async fn not_found(request: axum::extract::Request) -> Response { mod tests { use std::io::Read; + #[tokio::test] + async fn panic_handler_matches_python_internal_error_envelope() { + use http_body_util::BodyExt; + + let response = handle_panic(Box::new("boom")); + assert_eq!(response.status(), StatusCode::INTERNAL_SERVER_ERROR); + let body = response.into_body().collect().await.unwrap().to_bytes(); + assert_eq!( + serde_json::from_slice::(&body).unwrap(), + serde_json::json!({ + "error_code": "ISE001", + "error_message": "Internal Server Error" + }) + ); + } + use axum::{ body::{Body, to_bytes}, http::{Method, Request, header}, diff --git a/gateway-rs/src/config.rs b/gateway-rs/src/config.rs index dbddb9c8..0c2c3346 100644 --- a/gateway-rs/src/config.rs +++ b/gateway-rs/src/config.rs @@ -14,6 +14,7 @@ pub struct Config { pub compression_level: i32, pub compression_minimum_size: u16, pub strict_response_envelope: bool, + pub websockets_enabled: bool, pub logs_dir: Option, pub security_settings_file: Option, pub shared_storage: SharedStorageConfig, @@ -211,6 +212,7 @@ impl Config { compression_level, compression_minimum_size, strict_response_envelope: env_bool("STRICT_RESPONSE_ENVELOPE", false), + websockets_enabled: env_bool("WEBSOCKETS_ENABLED", false), logs_dir: env_non_empty("LOGS_DIR").map(PathBuf::from).or_else(|| { let path = PathBuf::from("/app/logs"); path.exists().then_some(path) @@ -245,6 +247,7 @@ impl Config { compression_level: 6, compression_minimum_size: 500, strict_response_envelope: false, + websockets_enabled: false, logs_dir: None, // Tests opt into an isolated path when exercising file persistence. security_settings_file: None, diff --git a/gateway-rs/src/constants.rs b/gateway-rs/src/constants.rs new file mode 100644 index 00000000..50dc2386 --- /dev/null +++ b/gateway-rs/src/constants.rs @@ -0,0 +1,66 @@ +//! Shared platform constants retained from the Python backend. + +pub struct Headers; +impl Headers { + pub const REQUEST_ID: &str = "request_id"; +} + +pub struct Defaults; +impl Defaults { + pub const PAGE: usize = 1; + pub const PAGE_SIZE: usize = 10; + pub const MAX_PAGE_SIZE_ENV: &str = "MAX_PAGE_SIZE"; + pub const MAX_PAGE_SIZE_DEFAULT: usize = 200; + pub const MAX_MULTIPART_SIZE_BYTES_ENV: &str = "MAX_MULTIPART_SIZE_BYTES"; + pub const MAX_MULTIPART_SIZE_BYTES_DEFAULT: usize = 5_242_880; +} + +pub struct Roles; +impl Roles { + pub const MANAGE_USERS: &str = "manage_users"; + pub const MANAGE_APIS: &str = "manage_apis"; + pub const MANAGE_GROUPS: &str = "manage_groups"; + pub const MANAGE_ENDPOINTS: &str = "manage_endpoints"; + pub const VIEW_LOGS: &str = "view_logs"; + pub const EXPORT_LOGS: &str = "export_logs"; + pub const MANAGE_ROLES: &str = "manage_roles"; +} + +pub struct ErrorCodes; +impl ErrorCodes { + pub const UNEXPECTED: &str = "GTW999"; + pub const HTTP_EXCEPTION: &str = "GTW998"; + pub const GRPC_GENERATION_FAILED: &str = "GTW012"; + pub const PATH_VALIDATION: &str = "GTW013"; + pub const API_NOT_FOUND: &str = "API002"; + pub const AUTH_REQUIRED: &str = "AUTH001"; + pub const REQUEST_TOO_LARGE: &str = "REQ002"; + pub const REQUEST_FILE_TYPE: &str = "REQ003"; + pub const PAGE_SIZE: &str = "PAG001"; +} + +pub struct Messages; +impl Messages { + pub const UNEXPECTED: &str = "An unexpected error occurred"; + pub const FILE_TOO_LARGE: &str = "Uploaded file too large"; + pub const ONLY_PROTO_ALLOWED: &str = "Only .proto files are allowed"; + pub const PERMISSION_MANAGE_APIS: &str = "User does not have permission to manage APIs"; + pub const GRPC_GEN_FAILED: &str = "Failed to generate gRPC code"; + pub const PAGE_TOO_LARGE: &str = "Page size exceeds maximum limit"; + pub const INVALID_PAGING: &str = "Invalid page or page size"; +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn preserves_python_defaults_and_wire_constants() { + assert_eq!(Headers::REQUEST_ID, "request_id"); + assert_eq!(Defaults::PAGE_SIZE, 10); + assert_eq!(Defaults::MAX_PAGE_SIZE_DEFAULT, 200); + assert_eq!(Defaults::MAX_MULTIPART_SIZE_BYTES_DEFAULT, 5_242_880); + assert_eq!(ErrorCodes::HTTP_EXCEPTION, "GTW998"); + assert_eq!(Messages::FILE_TOO_LARGE, "Uploaded file too large"); + } +} diff --git a/gateway-rs/src/demo_seed.rs b/gateway-rs/src/demo_seed.rs new file mode 100644 index 00000000..5be67bf0 --- /dev/null +++ b/gateway-rs/src/demo_seed.rs @@ -0,0 +1,572 @@ +use std::{ + collections::BTreeSet, + fs::{self, OpenOptions}, + io::Write, + path::Path, + time::{SystemTime, UNIX_EPOCH}, +}; + +use rand::{Rng, SeedableRng, prelude::SliceRandom, rngs::StdRng}; +use serde_json::{Value, json}; +use time::{Duration, OffsetDateTime}; +use uuid::Uuid; + +use crate::{ + observability::analytics_aggregator::global_analytics, + storage::{field_encryption::encrypt_value, runtime::SharedStorage}, +}; + +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct SeedOptions { + pub users: usize, + pub apis: usize, + pub endpoints: usize, + pub groups: usize, + pub protos: usize, + pub logs: usize, + pub seed: Option, +} + +impl Default for SeedOptions { + fn default() -> Self { + Self { + users: 60, + apis: 20, + endpoints: 6, + groups: 10, + protos: 6, + logs: 2_000, + seed: None, + } + } +} + +pub async fn run_seed( + storage: &SharedStorage, + options: &SeedOptions, +) -> Result> { + let mut rng = options + .seed + .map(StdRng::seed_from_u64) + .unwrap_or_else(StdRng::from_os_rng); + let roles = ensure_roles(storage).await?; + let apis = seed_apis(storage, options.apis, &roles, &mut rng).await?; + let api_keys = apis + .iter() + .map(|(name, version)| format!("{name}/{version}")) + .collect::>(); + let groups = seed_groups(storage, options.groups, &api_keys, &mut rng).await?; + let users = seed_users(storage, options.users, &roles, &groups, &mut rng).await?; + seed_endpoints(storage, &apis, options.endpoints, &mut rng).await?; + let credit_groups = seed_credits(storage, &mut rng).await?; + seed_user_credits(storage, &users, &credit_groups, &mut rng).await?; + seed_subscriptions(storage, &users, &api_keys, &mut rng).await?; + seed_logs(options.logs, &users, &apis, &mut rng)?; + seed_protos(options.protos, &apis, &mut rng)?; + seed_metrics(&users, &apis, &mut rng); + + let mut result = serde_json::Map::new(); + for (name, collection) in [ + ("users", "users"), + ("apis", "apis"), + ("endpoints", "endpoints"), + ("groups", "groups"), + ("roles", "roles"), + ("subscriptions", "subscriptions"), + ("credit_defs", "credit_defs"), + ("user_credits", "user_credits"), + ] { + result.insert( + name.to_owned(), + json!(storage.find_many(collection, &json!({})).await?.len()), + ); + } + Ok(Value::Object(result)) +} + +async fn ensure_roles(storage: &SharedStorage) -> Result, Box> { + let roles = [ + ( + "developer", + json!({"manage_apis": true, "manage_endpoints": true, "manage_subscriptions": true, "manage_credits": true, "view_logs": true}), + ), + ("analyst", json!({"view_logs": true, "export_logs": true})), + ("viewer", json!({"view_logs": true})), + ( + "ops", + json!({"manage_gateway": true, "view_logs": true, "export_logs": true, "manage_security": true}), + ), + ]; + for (name, extra) in roles { + if storage + .find_one("roles", &json!({"role_name": name})) + .await? + .is_none() + { + let mut value = json!({"role_name": name, "role_description": format!("{name} role")}); + if let (Some(target), Some(extra)) = (value.as_object_mut(), extra.as_object()) { + target.extend(extra.clone()); + } + storage.insert_one("roles", value).await?; + } + } + Ok(["admin", "developer", "analyst", "viewer", "ops"] + .into_iter() + .map(str::to_owned) + .collect()) +} + +async fn seed_apis( + storage: &SharedStorage, + count: usize, + roles: &[String], + rng: &mut StdRng, +) -> Result, Box> { + let bases = [ + "customers", + "orders", + "billing", + "weather", + "news", + "crypto", + "search", + "inventory", + "shipping", + "payments", + "alerts", + "metrics", + "recommendations", + ]; + let versions = ["v1", "v2", "v3"]; + let mut result = Vec::new(); + for _ in 0..count { + let name = format!("{}-{}", choose(&bases, rng), random_word(3, 6, rng)); + let version = choose(&versions, rng).to_string(); + if storage + .find_one("apis", &json!({"api_name": name, "api_version": version})) + .await? + .is_none() + { + storage + .insert_one( + "apis", + json!({ + "api_name": name, "api_version": version, + "api_description": format!("Auto API {name}/{version}"), + "api_allowed_roles": sample(roles, rng.random_range(1..=roles.len().min(3)), rng), + "api_allowed_groups": ["ALL", "admin"], + "api_servers": [format!("http://localhost:{}", 8_000 + rng.random_range(0..1_000))], + "api_type": "REST", "api_allowed_retry_count": rng.random_range(0..=3), + "api_id": Uuid::new_v4().to_string(), "api_path": format!("/{name}/{version}") + }), + ) + .await?; + } + result.push((name, version)); + } + Ok(result) +} + +async fn seed_groups( + storage: &SharedStorage, + count: usize, + api_keys: &[String], + rng: &mut StdRng, +) -> Result, Box> { + let mut result = Vec::new(); + for index in 0..count { + let name = format!("team-{}-{index}", random_word(3, 6, rng)); + if storage + .find_one("groups", &json!({"group_name": name})) + .await? + .is_none() + { + let access = if api_keys.is_empty() { + Vec::new() + } else { + let maximum = (api_keys.len() / 3).max(1); + sample(api_keys, rng.random_range(1..=maximum), rng) + }; + storage.insert_one("groups", json!({"group_name": name, "group_description": format!("Auto group {name}"), "api_access": access})).await?; + } + result.push(name); + } + for name in ["ALL", "admin"] { + if storage + .find_one("groups", &json!({"group_name": name})) + .await? + .is_none() + { + storage.insert_one("groups", json!({"group_name": name, "group_description": format!("{name} group"), "api_access": []})).await?; + } + if !result.iter().any(|item| item == name) { + result.push(name.to_owned()); + } + } + Ok(result) +} + +async fn seed_users( + storage: &SharedStorage, + count: usize, + roles: &[String], + groups: &[String], + rng: &mut StdRng, +) -> Result, Box> { + let firsts = [ + "alex", "casey", "morgan", "sam", "taylor", "riley", "jamie", "jordan", "drew", "quinn", + "kyle", "parker", "blake", "devon", + ]; + let lasts = [ + "lee", "kim", "patel", "garcia", "nguyen", "williams", "brown", "davis", "miller", + "wilson", "moore", "taylor", "thomas", + ]; + let domains = ["example.com", "acme.io", "contoso.net", "demo.dev"]; + let mut result = Vec::new(); + for index in 0..count { + let username = format!("{}.{}_{}", choose(&firsts, rng), choose(&lasts, rng), index); + if storage + .find_one("users", &json!({"username": username})) + .await? + .is_none() + { + let password = bcrypt::hash(random_password(rng), bcrypt::DEFAULT_COST)?; + let group_count = rng.random_range(1..=groups.len().min(3)); + storage.insert_one("users", json!({ + "username": username, "email": format!("{}@{}", username.replace('.', "_"), choose(&domains, rng)), + "password": password, "role": choose(roles, rng), "groups": sample(groups, group_count, rng), + "rate_limit_duration": rng.random_range(100..=10_000), "rate_limit_duration_type": choose(&["minute", "hour", "day"], rng), + "throttle_duration": rng.random_range(1_000..=100_000), "throttle_duration_type": choose(&["second", "minute"], rng), + "throttle_wait_duration": rng.random_range(100..=10_000), "throttle_wait_duration_type": choose(&["seconds", "minutes"], rng), + "custom_attributes": {"dept": choose(&["sales", "eng", "support", "ops"], rng)}, "active": true, + "ui_access": rng.random_bool(0.5) + })).await?; + } + result.push(username); + } + Ok(result) +} + +async fn seed_endpoints( + storage: &SharedStorage, + apis: &[(String, String)], + per_api: usize, + rng: &mut StdRng, +) -> Result<(), Box> { + let methods = ["GET", "POST", "PUT", "DELETE", "PATCH"]; + let uris = [ + "/status", + "/health", + "/items", + "/items/{id}", + "/search", + "/reports", + "/export", + "/metrics", + "/list", + "/detail/{id}", + ]; + for (name, version) in apis { + let api = storage + .find_one("apis", &json!({"api_name": name, "api_version": version})) + .await?; + let api_id = api + .as_ref() + .and_then(|value| value.get("api_id")) + .and_then(Value::as_str) + .unwrap_or_default(); + let mut created = BTreeSet::new(); + for _ in 0..per_api { + let method = choose(&methods, rng); + let uri = choose(&uris, rng); + if !created.insert((method, uri)) || storage.find_one("endpoints", &json!({"api_name": name, "api_version": version, "endpoint_method": method, "endpoint_uri": uri})).await?.is_some() { continue; } + storage.insert_one("endpoints", json!({"api_name": name, "api_version": version, "endpoint_method": method, "endpoint_uri": uri, "endpoint_description": format!("{method} {uri} for {name}"), "api_id": api_id, "endpoint_id": Uuid::new_v4().to_string()})).await?; + } + } + Ok(()) +} + +async fn seed_credits( + storage: &SharedStorage, + rng: &mut StdRng, +) -> Result, Box> { + let groups = [ + "ai-basic", + "ai-pro", + "maps-basic", + "maps-pro", + "news-tier", + "weather-tier", + ]; + let catalog = [ + json!({"tier_name":"basic","credits":100,"input_limit":100,"output_limit":100,"reset_frequency":"monthly"}), + json!({"tier_name":"pro","credits":1000,"input_limit":500,"output_limit":500,"reset_frequency":"monthly"}), + json!({"tier_name":"enterprise","credits":10000,"input_limit":2000,"output_limit":2000,"reset_frequency":"monthly"}), + ]; + for group in groups { + if storage + .find_one("credit_defs", &json!({"api_credit_group": group})) + .await? + .is_none() + { + let tiers = sample(&catalog, rng.random_range(1..=3), rng); + storage.insert_one("credit_defs", json!({"api_credit_group": group, "api_key": encrypt_value(Some(&Uuid::new_v4().simple().to_string())), "api_key_header": choose(&["x-api-key", "authorization", "x-token"], rng), "credit_tiers": tiers})).await?; + } + } + Ok(groups.into_iter().map(str::to_owned).collect()) +} + +async fn seed_user_credits( + storage: &SharedStorage, + users: &[String], + groups: &[String], + rng: &mut StdRng, +) -> Result<(), Box> { + let selected = sample(users, (users.len() / 2).max(1).min(users.len()), rng); + for username in selected { + let mut credits = serde_json::Map::new(); + for group in sample(groups, rng.random_range(1..=groups.len().min(3)), rng) { + let days = rng.random_range(1..=30); + credits.insert(group, json!({"tier_name": choose(&["basic", "pro", "enterprise"], rng), "available_credits": rng.random_range(10..=10_000), "reset_date": date_after(days), "user_api_key": encrypt_value(Some(&Uuid::new_v4().simple().to_string()))})); + } + let value = json!({"users_credits": credits}); + if storage + .find_one("user_credits", &json!({"username": username})) + .await? + .is_some() + { + storage + .update_one("user_credits", &json!({"username": username}), &value) + .await?; + } else { + storage + .insert_one( + "user_credits", + json!({"username": username, "users_credits": credits}), + ) + .await?; + } + } + Ok(()) +} + +async fn seed_subscriptions( + storage: &SharedStorage, + users: &[String], + api_keys: &[String], + rng: &mut StdRng, +) -> Result<(), Box> { + for username in users { + let subscriptions = if api_keys.is_empty() { + Vec::new() + } else { + sample(api_keys, rng.random_range(1..=api_keys.len().min(5)), rng) + }; + if storage + .find_one("subscriptions", &json!({"username": username})) + .await? + .is_some() + { + storage + .update_one( + "subscriptions", + &json!({"username": username}), + &json!({"apis": subscriptions}), + ) + .await?; + } else { + storage + .insert_one( + "subscriptions", + json!({"username": username, "apis": subscriptions}), + ) + .await?; + } + } + Ok(()) +} + +fn seed_logs( + count: usize, + users: &[String], + apis: &[(String, String)], + rng: &mut StdRng, +) -> Result<(), Box> { + let directory = std::env::var_os("LOGS_DIR") + .map(std::path::PathBuf::from) + .unwrap_or_else(|| "logs".into()); + fs::create_dir_all(&directory)?; + let mut file = OpenOptions::new() + .create(true) + .append(true) + .open(directory.join("doorman.log"))?; + for _ in 0..count { + let (api, version) = apis + .get(rng.random_range(0..apis.len().max(1))) + .cloned() + .unwrap_or_else(|| ("demo".to_owned(), "v1".to_owned())); + let user = users + .get(rng.random_range(0..users.len().max(1))) + .map(String::as_str) + .unwrap_or("admin"); + writeln!( + file, + "{} - doorman.gateway - INFO - {} | Username: {user} | From: 127.0.0.1:{} | Endpoint: {} /{api}/{version}{} | Total time: {}ms", + timestamp(), + Uuid::new_v4(), + rng.random_range(10_000..=65_000), + choose(&["GET", "POST", "PUT", "DELETE", "PATCH"], rng), + choose( + &[ + "/status", + "/list", + "/items", + "/items/123", + "/search?q=test", + "/export", + "/metrics" + ], + rng + ), + rng.random_range(5..=500) + )?; + } + Ok(()) +} + +fn seed_protos( + count: usize, + apis: &[(String, String)], + rng: &mut StdRng, +) -> Result<(), Box> { + fs::create_dir_all("proto")?; + fs::create_dir_all("generated")?; + for (name, version) in sample(apis, count.min(apis.len()), rng) { + let key = format!("{name}_{version}").replace('-', "_"); + let service = name.split('-').map(capitalize).collect::(); + let content = format!( + "syntax = \"proto3\";\n\npackage {key};\n\nservice {service}Service {{\n rpc GetStatus (StatusRequest) returns (StatusReply) {{}}\n}}\n\nmessage StatusRequest {{\n string id = 1;\n}}\n\nmessage StatusReply {{\n string status = 1;\n string message = 2;\n}}\n" + ); + fs::write(Path::new("proto").join(format!("{key}.proto")), content)?; + } + Ok(()) +} + +fn seed_metrics(users: &[String], apis: &[(String, String)], rng: &mut StdRng) { + for _ in 0..400 { + for _ in 0..rng.random_range(0..=50) { + let status = *choose(&[200_u16, 200, 200, 201, 204, 400, 401, 403, 404, 500], rng); + let api = apis + .get(rng.random_range(0..apis.len().max(1))) + .map(|item| format!("rest:{}", item.0)); + let user = users + .get(rng.random_range(0..users.len().max(1))) + .map(String::as_str); + global_analytics().record_request( + api.as_deref(), + user, + None, + status, + rng.random_range(10.0..400.0), + 0, + 0, + ); + } + } +} + +fn choose<'a, T>(values: &'a [T], rng: &mut StdRng) -> &'a T { + &values[rng.random_range(0..values.len())] +} + +fn sample(values: &[T], count: usize, rng: &mut StdRng) -> Vec { + let mut values = values.to_vec(); + values.shuffle(rng); + values.truncate(count.min(values.len())); + values +} + +fn random_word(minimum: usize, maximum: usize, rng: &mut StdRng) -> String { + (0..rng.random_range(minimum..=maximum)) + .map(|_| char::from(rng.random_range(b'a'..=b'z'))) + .collect() +} + +fn random_password(rng: &mut StdRng) -> String { + let mut bytes = Vec::new(); + bytes.push(*choose(b"ABCDEFGHIJKLMNOPQRSTUVWXYZ", rng)); + bytes.extend((0..8).map(|_| *choose(b"abcdefghijklmnopqrstuvwxyz", rng))); + bytes.extend((0..4).map(|_| *choose(b"0123456789", rng))); + bytes.push(*choose(b"!@#$%^&*()-_=+[]{};:,.<>?/", rng)); + bytes.extend((0..6).map(|_| { + *choose( + b"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", + rng, + ) + })); + bytes.shuffle(rng); + String::from_utf8(bytes).expect("ASCII password") +} + +fn date_after(days: i64) -> String { + let date = (OffsetDateTime::now_utc() + Duration::days(days)).date(); + format!( + "{:04}-{:02}-{:02}", + date.year(), + date.month() as u8, + date.day() + ) +} + +fn timestamp() -> String { + let seconds = SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap_or_default() + .as_secs() as i64; + OffsetDateTime::from_unix_timestamp(seconds) + .unwrap_or(OffsetDateTime::UNIX_EPOCH) + .to_string() +} + +fn capitalize(value: &str) -> String { + let mut characters = value.chars(); + characters + .next() + .map(char::to_uppercase) + .into_iter() + .flatten() + .chain(characters) + .collect() +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn defaults_match_the_python_seed_command() { + assert_eq!( + SeedOptions::default(), + SeedOptions { + users: 60, + apis: 20, + endpoints: 6, + groups: 10, + protos: 6, + logs: 2_000, + seed: None + } + ); + } + + #[test] + fn seeded_generators_are_reproducible() { + let mut first = StdRng::seed_from_u64(17); + let mut second = StdRng::seed_from_u64(17); + assert_eq!( + random_word(4, 10, &mut first), + random_word(4, 10, &mut second) + ); + assert_eq!(random_password(&mut first), random_password(&mut second)); + } +} diff --git a/gateway-rs/src/error_codes.rs b/gateway-rs/src/error_codes.rs new file mode 100644 index 00000000..df28dd1c --- /dev/null +++ b/gateway-rs/src/error_codes.rs @@ -0,0 +1,183 @@ +//! Central error-code registry retained from the Python API. + +pub struct ErrorCode; + +impl ErrorCode { + pub const AUTH_MISSING_CREDENTIALS: &str = "AUTH001"; + pub const AUTH_INVALID_CREDENTIALS: &str = "AUTH002"; + pub const AUTH_TOKEN_INVALID: &str = "AUTH003"; + pub const AUTH_TOKEN_MISSING: &str = "AUTH004"; + pub const AUTH_TOKEN_EXPIRED: &str = "AUTH005"; + pub const AUTH_USER_INACTIVE: &str = "AUTH007"; + pub const AUTH_UNEXPECTED_ERROR: &str = "AUTH900"; + pub const USR_ALREADY_EXISTS: &str = "USR001"; + pub const USR_NOT_FOUND: &str = "USR002"; + pub const USR_DELETE_FAILED: &str = "USR003"; + pub const USR_UPDATE_FAILED: &str = "USR004"; + pub const USR_WEAK_PASSWORD: &str = "USR005"; + pub const USR_UNAUTHORIZED_ACCESS: &str = "USR006"; + pub const USR_INVALID_OPERATION: &str = "USR007"; + pub const USR_PERMISSION_DENIED: &str = "USR008"; + pub const USR_USERNAME_INVALID: &str = "USR013"; + pub const USR_EMAIL_INVALID: &str = "USR015"; + pub const USR_TOO_MANY_ATTRIBUTES: &str = "USR016"; + pub const API_ALREADY_EXISTS: &str = "API001"; + pub const API_CREATE_FAILED: &str = "API002"; + pub const API_NOT_FOUND: &str = "API003"; + pub const API_UPDATE_NAME_FORBIDDEN: &str = "API005"; + pub const API_NO_DATA_TO_UPDATE: &str = "API006"; + pub const API_PERMISSION_DENIED: &str = "API007"; + pub const API_INVALID_REQUEST: &str = "API008"; + pub const API_PROTO_INVALID: &str = "API009"; + pub const API_PUBLIC_CREDITS_CONFLICT: &str = "API013"; + pub const END_ALREADY_EXISTS: &str = "END001"; + pub const END_CREATE_FAILED: &str = "END002"; + pub const END_NOT_FOUND: &str = "END003"; + pub const END_UPDATE_FAILED: &str = "END004"; + pub const END_DELETE_FAILED: &str = "END005"; + pub const END_INVALID_TYPE: &str = "END006"; + pub const END_VALIDATION_FAILED: &str = "END007"; + pub const END_SERVERS_REQUIRED: &str = "END008"; + pub const END_CIRCULAR_DEPENDENCY: &str = "END009"; + pub const END_PERMISSION_DENIED: &str = "END010"; + pub const END_INVALID_REQUEST: &str = "END011"; + pub const END_MISSING_PROTO: &str = "END012"; + pub const END_PATH_CONFLICT: &str = "END013"; + pub const END_METHOD_CONFLICT: &str = "END014"; + pub const END_SERVER_INVALID: &str = "END015"; + pub const END_TIMEOUT_INVALID: &str = "END016"; + pub const END_RETRIES_INVALID: &str = "END017"; + pub const END_HEADERS_INVALID: &str = "END018"; + pub const END_BODY_TRANSFORM_INVALID: &str = "END019"; + pub const END_RESPONSE_TRANSFORM_INVALID: &str = "END020"; + pub const END_LOAD_BALANCER_INVALID: &str = "END021"; + pub const END_CIRCUIT_BREAKER_INVALID: &str = "END022"; + pub const END_RATE_LIMIT_INVALID: &str = "END023"; + pub const ROLE_ALREADY_EXISTS: &str = "ROLE001"; + pub const ROLE_CREATE_FAILED: &str = "ROLE002"; + pub const ROLE_NOT_FOUND: &str = "ROLE004"; + pub const ROLE_NAME_IMMUTABLE: &str = "ROLE005"; + pub const ROLE_UPDATE_FAILED: &str = "ROLE006"; + pub const ROLE_NO_DATA_TO_UPDATE: &str = "ROLE007"; + pub const ROLE_DELETE_FAILED: &str = "ROLE008"; + pub const ROLE_PERMISSION_DENIED: &str = "ROLE009"; + pub const ROLE_INVALID_REQUEST: &str = "ROLE010"; + pub const ROLE_IN_USE: &str = "ROLE011"; + pub const ROLE_PERMISSION_INVALID: &str = "ROLE013"; + pub const ROLE_NAME_INVALID: &str = "ROLE014"; + pub const ROLE_RESERVED_NAME: &str = "ROLE015"; + pub const ROLE_DESCRIPTION_REQUIRED: &str = "ROLE016"; + pub const GRP_ALREADY_EXISTS: &str = "GRP001"; + pub const GRP_CREATE_FAILED: &str = "GRP002"; + pub const GRP_NOT_FOUND: &str = "GRP003"; + pub const GRP_UPDATE_FAILED: &str = "GRP004"; + pub const GRP_DELETE_FAILED: &str = "GRP005"; + pub const GRP_NAME_IMMUTABLE: &str = "GRP006"; + pub const GRP_NO_DATA_TO_UPDATE: &str = "GRP007"; + pub const GRP_PERMISSION_DENIED: &str = "GRP008"; + pub const GRP_INVALID_REQUEST: &str = "GRP009"; + pub const GRP_IN_USE: &str = "GRP010"; + pub const SUB_INVALID_API: &str = "SUB003"; + pub const SUB_ALREADY_EXISTS: &str = "SUB004"; + pub const SUB_NOT_FOUND: &str = "SUB005"; + pub const SUB_CREATE_FAILED: &str = "SUB006"; + pub const SUB_PERMISSION_DENIED: &str = "SUB007"; + pub const SUB_INVALID_REQUEST: &str = "SUB008"; + pub const SUB_DELETE_FAILED: &str = "SUB009"; + pub const RTG_ALREADY_EXISTS: &str = "RTG001"; + pub const RTG_CREATE_FAILED: &str = "RTG002"; + pub const RTG_NOT_FOUND: &str = "RTG004"; + pub const RTG_UPDATE_FAILED: &str = "RTG005"; + pub const RTG_DELETE_FAILED: &str = "RTG006"; + pub const RTG_NO_DATA_TO_UPDATE: &str = "RTG007"; + pub const RTG_NAME_IMMUTABLE: &str = "RTG008"; + pub const RTG_PERMISSION_DENIED: &str = "RTG009"; + pub const RTG_INVALID_REQUEST: &str = "RTG010"; + pub const RTG_PRIORITY_CONFLICT: &str = "RTG011"; + pub const RTG_PATH_INVALID: &str = "RTG012"; + pub const RTG_CONDITION_INVALID: &str = "RTG013"; + pub const CRD_GROUP_EXISTS: &str = "CRD001"; + pub const CRD_CREATE_FAILED: &str = "CRD002"; + pub const CRD_GROUP_IMMUTABLE: &str = "CRD003"; + pub const CRD_NOT_FOUND: &str = "CRD004"; + pub const CRD_UPDATE_FAILED: &str = "CRD005"; + pub const CRD_NO_DATA_TO_UPDATE: &str = "CRD006"; + pub const CRD_DELETE_NOT_FOUND: &str = "CRD007"; + pub const CRD_DELETE_FAILED: &str = "CRD008"; + pub const CRD_GROUP_NAME_REQUIRED: &str = "CRD009"; + pub const CRD_API_KEY_REQUIRED: &str = "CRD010"; + pub const CRD_DATABASE_ERROR: &str = "CRD011"; + pub const CRD_DATABASE_ERROR_UPDATE: &str = "CRD012"; + pub const CRD_DATABASE_ERROR_DELETE: &str = "CRD013"; + pub const CRD_USERNAME_MISMATCH: &str = "CRD014"; + pub const CRD_USER_CREDITS_ERROR: &str = "CRD015"; + pub const CRD_GET_ALL_ERROR: &str = "CRD016"; + pub const CRD_USER_NOT_FOUND: &str = "CRD017"; + pub const CRD_GET_USER_ERROR: &str = "CRD018"; + pub const CRD_LIST_ERROR: &str = "CRD020"; + pub const CRD_FETCH_ERROR: &str = "CRD021"; + pub const CRD_RETRIEVE_ERROR: &str = "CRD022"; + pub const GTW_UPSTREAM_ERROR: &str = "GTW001"; + pub const GTW_TIMEOUT: &str = "GTW002"; + pub const GTW_NO_AVAILABLE_SERVERS: &str = "GTW003"; + pub const GTW_INVALID_REQUEST: &str = "GTW004"; + pub const GTW_RATE_LIMIT_EXCEEDED: &str = "GTW005"; + pub const GTW_SERVICE_UNAVAILABLE: &str = "GTW006"; + pub const GTW_AUTHENTICATION_REQUIRED: &str = "GTW007"; + pub const GTW_SUBSCRIPTION_REQUIRED: &str = "GTW008"; + pub const GTW_CIRCUIT_BREAKER_OPEN: &str = "GTW010"; + pub const GTW_INVALID_ENDPOINT: &str = "GTW011"; + pub const GTW_PROTO_DECODE_ERROR: &str = "GTW013"; + pub const GTW_UNEXPECTED_ERROR: &str = "GTW999"; + pub const CFG_PERMISSION_DENIED: &str = "CFG001"; + pub const CFG_API_PERMISSION_DENIED: &str = "CFG002"; + pub const CFG_ENDPOINT_PERMISSION_DENIED: &str = "CFG003"; + pub const CFG_GROUP_PERMISSION_DENIED: &str = "CFG004"; + pub const CFG_ROLE_PERMISSION_DENIED: &str = "CFG005"; + pub const CFG_ROUTING_PERMISSION_DENIED: &str = "CFG006"; + pub const CFG_SUBSCRIPTION_PERMISSION_DENIED: &str = "CFG007"; + pub const CFG_NOT_FOUND: &str = "CFG404"; + pub const SEC_PERMISSION_DENIED: &str = "SEC001"; + pub const SEC_UPDATE_FAILED: &str = "SEC002"; + pub const SEC_INVALID_IP: &str = "SEC003"; + pub const SEC_INVALID_SETTING: &str = "SEC004"; + pub const SEC_PROTECTED_SETTING: &str = "SEC005"; + pub const LOG_PERMISSION_DENIED: &str = "LOG001"; + pub const LOG_INVALID_LEVEL: &str = "LOG002"; + pub const LOG_UPDATE_FAILED: &str = "LOG003"; + pub const LOG_QUERY_FAILED: &str = "LOG004"; + pub const LOG_EXPORT_FAILED: &str = "LOG005"; + pub const MON_PERMISSION_DENIED: &str = "MON001"; + pub const MON_QUERY_FAILED: &str = "MON002"; + pub const MON_UNEXPECTED_ERROR: &str = "MON003"; + pub const MEM_PERMISSION_DENIED: &str = "MEM001"; + pub const MEM_DUMP_FAILED: &str = "MEM002"; + pub const MEM_OPERATION_FAILED: &str = "MEM003"; + pub const DEMO_ALREADY_SEEDED: &str = "DEMO001"; + pub const DEMO_SEED_FAILED: &str = "DEMO999"; + pub const TLS_PERMISSION_DENIED: &str = "TLS001"; + pub const TLS_UNEXPECTED_ERROR: &str = "TLS999"; + pub const GEN_INVALID_REQUEST: &str = "GEN001"; + pub const GEN_VALIDATION_ERROR: &str = "GEN002"; + pub const ISE_INTERNAL_ERROR: &str = "ISE001"; + pub const REQ_BODY_TOO_LARGE: &str = "REQ001"; + pub const VAL_INVALID_JSON: &str = "VAL001"; + pub const JWT_DECODE_ERROR: &str = "JWT001"; + pub const RATE_LIMIT_EXCEEDED: &str = "RATE_LIMIT_EXCEEDED"; +} + +pub type ErrorCodes = ErrorCode; + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn preserves_representative_python_error_code_values() { + assert_eq!(ErrorCode::AUTH_MISSING_CREDENTIALS, "AUTH001"); + assert_eq!(ErrorCode::END_RATE_LIMIT_INVALID, "END023"); + assert_eq!(ErrorCode::CRD_RETRIEVE_ERROR, "CRD022"); + assert_eq!(ErrorCodes::GTW_UNEXPECTED_ERROR, "GTW999"); + assert_eq!(ErrorCode::RATE_LIMIT_EXCEEDED, "RATE_LIMIT_EXCEEDED"); + } +} diff --git a/gateway-rs/src/gateway/transforms.rs b/gateway-rs/src/gateway/transforms.rs index 05bc9c9b..21136c4b 100644 --- a/gateway-rs/src/gateway/transforms.rs +++ b/gateway-rs/src/gateway/transforms.rs @@ -38,7 +38,11 @@ pub fn transform_response( let status = direction .get("status_map") .and_then(|mapping| mapping.get(status.as_u16().to_string())) - .and_then(Value::as_u64) + .and_then(|value| { + value + .as_u64() + .or_else(|| value.as_str().and_then(|value| value.parse().ok())) + }) .and_then(|value| u16::try_from(value).ok()) .and_then(|value| StatusCode::from_u16(value).ok()) .unwrap_or(status); @@ -71,7 +75,7 @@ fn transform_headers(mut headers: HeaderMap, config: Option<&Value>) -> HeaderMa for (name, value) in add { let (Ok(name), Ok(value)) = ( HeaderName::try_from(name), - HeaderValue::from_str(value.as_str().unwrap_or(&value.to_string())), + HeaderValue::from_str(&python_string(value)), ) else { continue; }; @@ -134,15 +138,22 @@ fn transform_query(query: Option<&str>, config: Option<&Value>) -> String { if let Some(add) = config.get("add").and_then(Value::as_object) { for (name, value) in add { pairs.retain(|(existing, _)| existing != name); - pairs.push(( - name.clone(), - value.as_str().unwrap_or(&value.to_string()).to_owned(), - )); + pairs.push((name.clone(), python_string(value))); } } encode_query(&pairs) } +fn python_string(value: &Value) -> String { + match value { + Value::String(value) => value.clone(), + Value::Bool(true) => "True".to_owned(), + Value::Bool(false) => "False".to_owned(), + Value::Null => "None".to_owned(), + value => value.to_string(), + } +} + fn encode_query(pairs: &[(String, String)]) -> String { let mut serializer = url::form_urlencoded::Serializer::new(String::new()); serializer.extend_pairs(pairs.iter().map(|(key, value)| (key, value))); @@ -296,6 +307,25 @@ mod tests { Some(&config), ); assert_eq!(status, StatusCode::BAD_GATEWAY); + + let config = serde_json::json!({"request": { + "headers": {"add": {"x-enabled": true, "x-empty": null}}, + "query": {"add": {"enabled": false}} + }}); + let (headers, _, query) = + transform_request(HeaderMap::new(), Vec::new(), None, Some(&config)); + assert_eq!(headers["x-enabled"], "True"); + assert_eq!(headers["x-empty"], "None"); + assert_eq!(query, "enabled=False"); + + let config = serde_json::json!({"response": {"status_map": {"500": "502"}}}); + let (_, _, status) = transform_response( + HeaderMap::new(), + Vec::new(), + StatusCode::INTERNAL_SERVER_ERROR, + Some(&config), + ); + assert_eq!(status, StatusCode::BAD_GATEWAY); } #[test] diff --git a/gateway-rs/src/lib.rs b/gateway-rs/src/lib.rs index 180f7864..3519988a 100644 --- a/gateway-rs/src/lib.rs +++ b/gateway-rs/src/lib.rs @@ -1,6 +1,9 @@ pub mod app; pub mod config; +pub mod constants; +pub mod demo_seed; pub mod error; +pub mod error_codes; pub mod gateway; pub mod hot_reload; pub mod middleware; diff --git a/gateway-rs/src/main.rs b/gateway-rs/src/main.rs index 5f898e17..d2b7fa84 100644 --- a/gateway-rs/src/main.rs +++ b/gateway-rs/src/main.rs @@ -1,12 +1,15 @@ use std::{ - env, - path::PathBuf, + env, fs, + path::{Path, PathBuf}, + process::{Command, Stdio}, sync::{Arc, atomic::Ordering}, + thread, time::Duration, }; use doorman_gateway::{ AppState, Config, build_router, + demo_seed::{SeedOptions, run_seed}, hot_reload::HotReloadConfig, observability::analytics_aggregator::global_analytics, routes::platform::backfill_grpc_descriptors, @@ -19,6 +22,20 @@ use tracing::{error, info, warn}; #[tokio::main] async fn main() -> Result<(), Box> { doorman_gateway::observability::init(); + + match env::args().nth(1).as_deref() { + Some("start") => return start_process(), + Some("stop") => return stop_process(), + Some("restart") => { + stop_process()?; + thread::sleep(Duration::from_secs(1)); + return start_process(); + } + Some("seed") => return seed_command(env::args().skip(2)).await, + Some("run") | None => {} + Some(command) => return Err(format!("unknown command: {command}").into()), + } + restore_metrics(); let config = Config::from_env()?; @@ -130,6 +147,160 @@ async fn main() -> Result<(), Box> { Ok(()) } +async fn seed_command( + arguments: impl Iterator, +) -> Result<(), Box> { + let arguments = arguments.collect::>(); + if arguments + .iter() + .any(|argument| argument == "--help" || argument == "-h") + { + print_seed_help(); + return Ok(()); + } + let options = parse_seed_options(arguments.into_iter())?; + println!("Starting demo seed with:"); + println!(" Users: {}", options.users); + println!(" APIs: {}", options.apis); + println!(" Endpoints per API: {}", options.endpoints); + println!(" Groups: {}", options.groups); + println!(" Protos: {}", options.protos); + println!(" Logs: {}", options.logs); + if let Some(seed) = options.seed { + println!(" Random Seed: {seed}"); + } + println!(); + + let config = Config::from_env()?; + let storage = SharedStorage::connect(&config.shared_storage).await?; + storage.initialize_core().await?; + let result = run_seed(&storage, &options).await?; + println!("\n✓ Seeding completed successfully!"); + println!("Result: {result}"); + Ok(()) +} + +fn parse_seed_options( + arguments: impl Iterator, +) -> Result> { + let mut options = SeedOptions::default(); + let mut arguments = arguments.peekable(); + while let Some(argument) = arguments.next() { + let (name, inline_value) = argument + .split_once('=') + .map_or((argument.as_str(), None), |(name, value)| { + (name, Some(value.to_owned())) + }); + let value = inline_value + .or_else(|| arguments.next()) + .ok_or_else(|| format!("{name} requires an integer value"))?; + match name { + "--users" => options.users = value.parse()?, + "--apis" => options.apis = value.parse()?, + "--endpoints" => options.endpoints = value.parse()?, + "--groups" => options.groups = value.parse()?, + "--protos" => options.protos = value.parse()?, + "--logs" => options.logs = value.parse()?, + "--seed" => options.seed = Some(value.parse()?), + _ => return Err(format!("unknown seed option: {name}").into()), + } + } + Ok(options) +} + +fn print_seed_help() { + println!( + "Seed the database with demo data\n\n --users N Number of users (default: 60)\n --apis N Number of APIs (default: 20)\n --endpoints N Endpoints per API (default: 6)\n --groups N Number of groups (default: 10)\n --protos N Number of proto files (default: 6)\n --logs N Number of log entries (default: 2000)\n --seed N Random seed for reproducibility" + ); +} + +fn pid_file_path() -> PathBuf { + env::var_os("PID_FILE") + .or_else(|| env::var_os("DOORMAN_PID_FILE")) + .map(PathBuf::from) + .unwrap_or_else(|| PathBuf::from("doorman.pid")) +} + +fn start_process() -> Result<(), Box> { + let pid_file = pid_file_path(); + if pid_file.exists() { + info!(path = %pid_file.display(), "doorman is already running"); + return Ok(()); + } + + let executable = env::current_exe()?; + let mut command = Command::new(executable); + command + .arg("run") + .stdin(Stdio::null()) + .stdout(Stdio::null()) + .stderr(Stdio::null()); + #[cfg(unix)] + { + use std::os::unix::process::CommandExt; + command.process_group(0); + } + let child = command.spawn()?; + fs::write(&pid_file, child.id().to_string())?; + info!(pid = child.id(), "starting doorman"); + Ok(()) +} + +fn stop_process() -> Result<(), Box> { + let pid_file = pid_file_path(); + if !pid_file.exists() { + info!("no running instance found"); + return Ok(()); + } + let pid = read_pid(&pid_file)?; + + #[cfg(unix)] + stop_unix_process_group(pid); + #[cfg(windows)] + { + let _ = Command::new("taskkill") + .args(["/F", "/PID", &pid.to_string()]) + .status(); + } + + if pid_file.exists() { + fs::remove_file(&pid_file)?; + } + info!(pid, "stopping doorman"); + Ok(()) +} + +fn read_pid(path: &Path) -> Result> { + let pid = fs::read_to_string(path)?.trim().parse::()?; + if pid == 0 { + return Err("PID file must contain a positive process ID".into()); + } + Ok(pid) +} + +#[cfg(unix)] +fn stop_unix_process_group(pid: u32) { + let group = format!("-{pid}"); + let status = Command::new("kill").args(["-TERM", "--", &group]).status(); + if !status.is_ok_and(|status| status.success()) { + return; + } + + let deadline = std::time::Instant::now() + Duration::from_secs(15); + while std::time::Instant::now() < deadline { + let running = Command::new("kill") + .args(["-0", "--", &pid.to_string()]) + .stdout(Stdio::null()) + .stderr(Stdio::null()) + .status() + .is_ok_and(|status| status.success()); + if !running { + break; + } + thread::sleep(Duration::from_millis(500)); + } +} + #[cfg(unix)] fn spawn_sighup_reload(config: Arc) { tokio::spawn(async move { @@ -323,3 +494,63 @@ fn spawn_metrics_autosave(runtime: Arc) { } }); } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn pid_files_require_a_positive_integer() { + let directory = env::temp_dir().join(format!("doorman-pid-test-{}", uuid::Uuid::new_v4())); + fs::create_dir_all(&directory).unwrap(); + let path = directory.join("doorman.pid"); + + fs::write(&path, "1234\n").unwrap(); + assert_eq!(read_pid(&path).unwrap(), 1234); + fs::write(&path, "0").unwrap(); + assert!(read_pid(&path).is_err()); + fs::write(&path, "invalid").unwrap(); + assert!(read_pid(&path).is_err()); + + fs::remove_dir_all(directory).unwrap(); + } + + #[test] + fn seed_options_match_python_cli_names_and_defaults() { + assert_eq!( + parse_seed_options(std::iter::empty()).unwrap(), + SeedOptions::default() + ); + assert_eq!( + parse_seed_options( + [ + "--users=2", + "--apis", + "3", + "--endpoints", + "4", + "--groups", + "5", + "--protos", + "6", + "--logs", + "7", + "--seed", + "8", + ] + .into_iter() + .map(str::to_owned), + ) + .unwrap(), + SeedOptions { + users: 2, + apis: 3, + endpoints: 4, + groups: 5, + protos: 6, + logs: 7, + seed: Some(8), + } + ); + } +} diff --git a/gateway-rs/src/middleware/chaos.rs b/gateway-rs/src/middleware/chaos.rs index 41b9dded..7a53fea8 100644 --- a/gateway-rs/src/middleware/chaos.rs +++ b/gateway-rs/src/middleware/chaos.rs @@ -4,6 +4,7 @@ use axum::{ response::{IntoResponse, Response}, }; use http::StatusCode; +use std::env; use std::sync::atomic::{AtomicBool, AtomicU32, AtomicU64, Ordering}; use std::time::Duration; @@ -36,3 +37,42 @@ pub async fn chaos_middleware(req: Request, next: Next) -> Response { next.run(req).await } + +pub async fn latency_injection(req: Request, next: Next) -> Response { + let enabled = env::var("ENABLE_LATENCY_INJECTION") + .ok() + .is_some_and(|value| value.eq_ignore_ascii_case("true")); + if let Some(delay) = injected_latency_ms( + enabled, + req.headers() + .get("x-doorman-latency") + .and_then(|value| value.to_str().ok()), + ) { + tokio::time::sleep(Duration::from_millis(delay)).await; + } + next.run(req).await +} + +fn injected_latency_ms(enabled: bool, value: Option<&str>) -> Option { + if !enabled { + return None; + } + let delay = value?.trim().parse::().ok()?.clamp(0, 5_000); + (delay > 0).then_some(delay as u64) +} + +#[cfg(test)] +mod tests { + use super::injected_latency_ms; + + #[test] + fn legacy_header_latency_matches_python_bounds_and_parsing() { + assert_eq!(injected_latency_ms(false, Some("100")), None); + assert_eq!(injected_latency_ms(true, None), None); + assert_eq!(injected_latency_ms(true, Some("bad")), None); + assert_eq!(injected_latency_ms(true, Some("-1")), None); + assert_eq!(injected_latency_ms(true, Some("0")), None); + assert_eq!(injected_latency_ms(true, Some(" 125 ")), Some(125)); + assert_eq!(injected_latency_ms(true, Some("9000")), Some(5_000)); + } +} diff --git a/gateway-rs/src/middleware/mod.rs b/gateway-rs/src/middleware/mod.rs index eb7ef98b..f2cbd8e6 100644 --- a/gateway-rs/src/middleware/mod.rs +++ b/gateway-rs/src/middleware/mod.rs @@ -8,3 +8,4 @@ pub mod platform_cors; pub mod request_id; pub mod response_compat; pub mod security_headers; +pub mod websocket_reject; diff --git a/gateway-rs/src/middleware/security_headers.rs b/gateway-rs/src/middleware/security_headers.rs index 80fb1963..818298dc 100644 --- a/gateway-rs/src/middleware/security_headers.rs +++ b/gateway-rs/src/middleware/security_headers.rs @@ -12,32 +12,31 @@ pub async fn security_headers( request: Request, next: Next, ) -> Response { - let docs = matches!(request.uri().path(), "/platform/docs" | "/platform/redoc"); + let docs = matches!( + request.uri().path(), + "/docs" | "/redoc" | "/platform/docs" | "/platform/redoc" + ); let mut response = next.run(request).await; let headers = response.headers_mut(); insert_default(headers, "x-content-type-options", "nosniff"); - insert_default( - headers, - "x-frame-options", - if docs { "SAMEORIGIN" } else { "DENY" }, - ); + insert_default(headers, "x-frame-options", "DENY"); insert_default(headers, "referrer-policy", "no-referrer"); insert_default( headers, "permissions-policy", "geolocation=(), microphone=(), camera=()", ); + let custom_csp = state.config.content_security_policy.as_deref(); let default_csp = if docs { - "default-src 'self'; script-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net; img-src 'self' data: https://cdn.jsdelivr.net; font-src 'self' data: https://cdn.jsdelivr.net; connect-src 'self'; frame-ancestors 'self'; base-uri 'self';" + "default-src 'self'; script-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net; img-src 'self' data: https://cdn.jsdelivr.net; font-src 'self' data: https://cdn.jsdelivr.net; connect-src 'self'; frame-ancestors *; base-uri 'self';" } else { "default-src 'none'; frame-ancestors 'none'; base-uri 'none'; form-action 'self'; img-src 'self' data:; connect-src 'self';" }; - let csp = state - .config - .content_security_policy - .as_deref() - .unwrap_or(default_csp); + if docs && custom_csp.is_none() { + headers.remove("x-frame-options"); + } + let csp = custom_csp.unwrap_or(default_csp); insert_value_default(headers, "content-security-policy", csp); if state.config.https_only { insert_default( diff --git a/gateway-rs/src/middleware/websocket_reject.rs b/gateway-rs/src/middleware/websocket_reject.rs new file mode 100644 index 00000000..0aa247d1 --- /dev/null +++ b/gateway-rs/src/middleware/websocket_reject.rs @@ -0,0 +1,73 @@ +use axum::{ + extract::{ + FromRequestParts, Request, State, + ws::{CloseFrame, Message, WebSocketUpgrade}, + }, + middleware::Next, + response::{IntoResponse, Response}, +}; +use http::header; + +use crate::state::AppState; + +pub async fn reject_disabled_websockets( + State(state): State, + request: Request, + next: Next, +) -> Response { + if state.config.websockets_enabled || !is_websocket_upgrade(&request) { + return next.run(request).await; + } + + let (mut parts, body) = request.into_parts(); + match WebSocketUpgrade::from_request_parts(&mut parts, &state).await { + Ok(upgrade) => upgrade + .on_upgrade(|mut socket| async move { + let _ = socket + .send(Message::Close(Some(CloseFrame { + code: 1008, + reason: "".into(), + }))) + .await; + }) + .into_response(), + Err(_) => next.run(Request::from_parts(parts, body)).await, + } +} + +fn is_websocket_upgrade(request: &Request) -> bool { + request + .headers() + .get(header::UPGRADE) + .and_then(|value| value.to_str().ok()) + .is_some_and(|value| value.eq_ignore_ascii_case("websocket")) + && request + .headers() + .get(header::CONNECTION) + .and_then(|value| value.to_str().ok()) + .is_some_and(|value| { + value + .split(',') + .any(|token| token.trim().eq_ignore_ascii_case("upgrade")) + }) +} + +#[cfg(test)] +mod tests { + use axum::body::Body; + + use super::*; + + #[test] + fn recognizes_websocket_upgrade_headers_case_insensitively() { + let request = Request::builder() + .header(header::CONNECTION, "keep-alive, Upgrade") + .header(header::UPGRADE, "WebSocket") + .body(Body::empty()) + .unwrap(); + assert!(is_websocket_upgrade(&request)); + + let request = Request::builder().body(Body::empty()).unwrap(); + assert!(!is_websocket_upgrade(&request)); + } +} diff --git a/gateway-rs/src/observability/analytics_aggregator.rs b/gateway-rs/src/observability/analytics_aggregator.rs index 32320e47..cd7e0e90 100644 --- a/gateway-rs/src/observability/analytics_aggregator.rs +++ b/gateway-rs/src/observability/analytics_aggregator.rs @@ -97,7 +97,7 @@ pub struct AnalyticsAggregator { impl AnalyticsAggregator { pub fn new() -> Self { Self { - points: RwLock::new(VecDeque::with_capacity(1440)), + points: RwLock::new(VecDeque::with_capacity(43_200)), api_counters: RwLock::new(HashMap::new()), api_error_counters: RwLock::new(HashMap::new()), user_counters: RwLock::new(HashMap::new()), @@ -155,7 +155,7 @@ impl AnalyticsAggregator { ((last.latency_ms * previous as f64) + duration_ms) / last.requests as f64; return; } - if points.len() >= 1440 { + if points.len() >= 43_200 { points.pop_front(); } points.push_back(AggregatedPoint { @@ -177,10 +177,18 @@ impl AnalyticsAggregator { } pub fn get_timeseries_range(&self, start_ts: u64, end_ts: u64) -> Vec { - self.get_timeseries() - .into_iter() - .filter(|point| point.timestamp >= start_ts && point.timestamp <= end_ts) - .collect() + let interval = match end_ts.saturating_sub(start_ts) { + seconds if seconds <= 86_400 => 300, + seconds if seconds <= 604_800 => 3_600, + _ => 86_400, + }; + aggregate_points( + self.get_timeseries() + .into_iter() + .filter(|point| point.timestamp >= start_ts && point.timestamp <= end_ts) + .collect(), + interval, + ) } pub fn get_status_distribution(&self) -> HashMap { @@ -305,7 +313,7 @@ impl AnalyticsAggregator { bytes_out: bucket.bytes_out, }) .collect::>(); - while points.len() > 1440 { + while points.len() > 43_200 { points.pop_front(); } @@ -329,6 +337,28 @@ impl AnalyticsAggregator { } } +fn aggregate_points(points: Vec, interval: u64) -> Vec { + let mut buckets = std::collections::BTreeMap::::new(); + for point in points { + let timestamp = (point.timestamp / interval) * interval; + let bucket = buckets.entry(timestamp).or_insert_with(|| AggregatedPoint { + timestamp, + ..AggregatedPoint::default() + }); + let previous_requests = bucket.requests; + bucket.requests = bucket.requests.saturating_add(point.requests); + bucket.errors = bucket.errors.saturating_add(point.errors); + bucket.bytes_in = bucket.bytes_in.saturating_add(point.bytes_in); + bucket.bytes_out = bucket.bytes_out.saturating_add(point.bytes_out); + if bucket.requests > 0 { + bucket.latency_ms = ((bucket.latency_ms * previous_requests as f64) + + (point.latency_ms * point.requests as f64)) + / bucket.requests as f64; + } + } + buckets.into_values().collect() +} + impl Default for AnalyticsAggregator { fn default() -> Self { Self::new() @@ -449,4 +479,43 @@ mod tests { fs::remove_dir_all(directory).unwrap(); } + + #[test] + fn range_queries_use_python_aggregation_levels() { + let points = vec![ + AggregatedPoint { + timestamp: 301, + requests: 2, + errors: 1, + latency_ms: 10.0, + bytes_in: 3, + bytes_out: 4, + }, + AggregatedPoint { + timestamp: 599, + requests: 1, + errors: 0, + latency_ms: 40.0, + bytes_in: 5, + bytes_out: 6, + }, + AggregatedPoint { + timestamp: 601, + requests: 1, + errors: 1, + latency_ms: 20.0, + bytes_in: 7, + bytes_out: 8, + }, + ]; + let five_minute = aggregate_points(points.clone(), 300); + assert_eq!(five_minute.len(), 2); + assert_eq!(five_minute[0].timestamp, 300); + assert_eq!(five_minute[0].requests, 3); + assert_eq!(five_minute[0].errors, 1); + assert_eq!(five_minute[0].latency_ms, 20.0); + assert_eq!(five_minute[0].bytes_in, 8); + assert_eq!(aggregate_points(points.clone(), 3_600).len(), 1); + assert_eq!(aggregate_points(points, 86_400).len(), 1); + } } diff --git a/gateway-rs/src/observability/audit.rs b/gateway-rs/src/observability/audit.rs index df7afc82..2acd3c4c 100644 --- a/gateway-rs/src/observability/audit.rs +++ b/gateway-rs/src/observability/audit.rs @@ -28,6 +28,19 @@ static SENSITIVE_LOG_AUTH_SCHEME: LazyLock = LazyLock::new(|| { regex::Regex::new(r"(?i)\b(bearer|basic)\s+[A-Za-z0-9._~+/-]+={0,2}") .expect("sensitive authorization scheme expression is valid") }); +static SENSITIVE_VALUE: LazyLock> = LazyLock::new(|| { + [ + r"^eyJ[a-zA-Z0-9_-]+\.eyJ[a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+$", + r"(?i)^Bearer\s+", + r"(?i)^Basic\s+[a-zA-Z0-9+/=]+$", + r"^sk-[a-zA-Z0-9]{32,}$", + r"^[a-fA-F0-9]{32,}$", + r"(?s)^-----BEGIN[A-Z\s]+PRIVATE KEY-----", + ] + .into_iter() + .map(|pattern| regex::Regex::new(pattern).expect("sensitive value expression is valid")) + .collect() +}); /// Sanitize a free-form log message before it reaches a non-structured sink. /// Structured audit records should use `redacted_headers` or `redacted_value` instead. @@ -56,6 +69,9 @@ pub fn redact_record(value: &mut serde_json::Value) { } } serde_json::Value::Array(values) => values.iter_mut().for_each(redact_record), + serde_json::Value::String(raw) if is_sensitive_value(raw) => { + *raw = REDACTED.to_owned(); + } _ => {} } } @@ -123,23 +139,35 @@ pub fn config_export(actor: &str, section: Option<&str>) { } fn is_sensitive_name(name: &str) -> bool { - let normalized = name.to_ascii_lowercase().replace('_', "-"); + let normalized = name.to_ascii_lowercase().replace('-', "_"); + if matches!( + normalized.as_str(), + "api_authorization_field_swap" | "authorization_field_swap" + ) { + return false; + } matches!( normalized.as_str(), - "authorization" | "proxy-authorization" | "cookie" | "set-cookie" + "authorization" | "proxy_authorization" | "cookie" | "set_cookie" ) || normalized.contains("password") || normalized.contains("secret") || normalized.contains("token") - || normalized.contains("api-key") + || normalized.contains("key") || normalized.contains("apikey") - || normalized.contains("credential") + || normalized.contains("auth") +} + +fn is_sensitive_value(value: &str) -> bool { + SENSITIVE_VALUE + .iter() + .any(|pattern| pattern.is_match(value)) } #[cfg(test)] mod tests { use http::{HeaderMap, HeaderValue, header}; - use super::{REDACTED, redacted_headers, redacted_log_message, redacted_value}; + use super::{REDACTED, redact_record, redacted_headers, redacted_log_message, redacted_value}; #[test] fn audit_header_redaction_never_exposes_credentials() { @@ -188,4 +216,18 @@ mod tests { assert!(redacted.contains(expected), "{redacted}"); } } + + #[test] + fn structured_records_match_python_key_and_value_redaction() { + let mut record = serde_json::json!({ + "signing_key": "secret", + "api_authorization_field_swap": "x-auth", + "nested": ["Bearer secret", "safe"] + }); + redact_record(&mut record); + assert_eq!(record["signing_key"], REDACTED); + assert_eq!(record["api_authorization_field_swap"], "x-auth"); + assert_eq!(record["nested"][0], REDACTED); + assert_eq!(record["nested"][1], "safe"); + } } diff --git a/gateway-rs/src/observability/email.rs b/gateway-rs/src/observability/email.rs new file mode 100644 index 00000000..7c05f1f7 --- /dev/null +++ b/gateway-rs/src/observability/email.rs @@ -0,0 +1,27 @@ +use serde_json::Value; +use tracing::info; + +/// Log the legacy mock-email payload and report successful delivery. +pub async fn send_email( + to_email: &str, + subject: &str, + body: &str, + metadata: Option<&Value>, +) -> bool { + info!(to = to_email, subject, "📧 [MOCK EMAIL]"); + info!(body, "mock email body"); + if let Some(metadata) = metadata { + info!(metadata = %metadata, "mock email metadata"); + } + true +} + +#[cfg(test)] +mod tests { + use super::*; + + #[tokio::test] + async fn mock_email_always_succeeds() { + assert!(send_email("user@example.com", "Subject", "Body", None).await); + } +} diff --git a/gateway-rs/src/observability/logging.rs b/gateway-rs/src/observability/logging.rs index 6203cc1a..e87b994b 100644 --- a/gateway-rs/src/observability/logging.rs +++ b/gateway-rs/src/observability/logging.rs @@ -1,4 +1,8 @@ -use std::fmt; +use std::{ + collections::VecDeque, + fmt, + sync::{LazyLock, Mutex}, +}; use tracing::{ Event, Subscriber, @@ -15,6 +19,26 @@ use tracing_subscriber::{ use crate::observability::audit::redact_record; +const MEMORY_LOG_CAPACITY: usize = 50_000; +static MEMORY_LOGS: LazyLock>> = + LazyLock::new(|| Mutex::new(VecDeque::with_capacity(MEMORY_LOG_CAPACITY))); + +pub fn memory_log_snapshot() -> Vec { + MEMORY_LOGS + .lock() + .map(|logs| logs.iter().cloned().collect()) + .unwrap_or_default() +} + +fn remember_log(entry: &str) { + if let Ok(mut logs) = MEMORY_LOGS.lock() { + if logs.len() == MEMORY_LOG_CAPACITY { + logs.pop_front(); + } + logs.push_back(entry.to_owned()); + } +} + /// Formats complete tracing events as JSON only after recursively removing secrets. /// /// The formatter is deliberately applied at the sink boundary so a future @@ -46,6 +70,18 @@ where }); redact_record(&mut record); let encoded = serde_json::to_string(&record).map_err(|_| fmt::Error)?; + let memory_time = record + .get("timestamp") + .and_then(serde_json::Value::as_str) + .and_then(|timestamp| timestamp.get(..19)) + .unwrap_or_default(); + let memory_record = serde_json::json!({ + "time": memory_time, + "name": event.metadata().target(), + "level": event.metadata().level().to_string(), + "message": record.pointer("/fields/message").cloned().unwrap_or(serde_json::Value::String(String::new())), + }); + remember_log(&serde_json::to_string(&memory_record).map_err(|_| fmt::Error)?); writer.write_str(&encoded)?; writer.write_char('\n') } @@ -108,7 +144,7 @@ mod tests { use tracing_subscriber::fmt::MakeWriter; - use super::RedactingJsonEvent; + use super::{RedactingJsonEvent, memory_log_snapshot}; #[derive(Clone, Default)] struct CapturedLog(Arc>>); @@ -158,5 +194,9 @@ mod tests { event["fields"]["message"], "Authorization: [REDACTED]; Cookie: [REDACTED]; Set-Cookie: [REDACTED]; X-API-Key: [REDACTED]; X-CSRF-Token: [REDACTED]; access_token=[REDACTED]; refresh_token=[REDACTED]; Basic [REDACTED]" ); + assert!(memory_log_snapshot().iter().any(|line| { + serde_json::from_str::(line) + .is_ok_and(|entry| entry["message"] == event["fields"]["message"]) + })); } } diff --git a/gateway-rs/src/observability/mod.rs b/gateway-rs/src/observability/mod.rs index 0228385c..56168612 100644 --- a/gateway-rs/src/observability/mod.rs +++ b/gateway-rs/src/observability/mod.rs @@ -1,5 +1,6 @@ pub mod analytics_aggregator; pub mod audit; +pub mod email; pub mod logging; pub mod metrics; diff --git a/gateway-rs/src/platform_contract.rs b/gateway-rs/src/platform_contract.rs index 1758c062..77f1474c 100644 --- a/gateway-rs/src/platform_contract.rs +++ b/gateway-rs/src/platform_contract.rs @@ -46,9 +46,10 @@ const BOOL_FIELDS: &[&str] = &[ "api_graphql_subscriptions", "api_grpc_web_enabled", "api_is_crud", - "enforce_admin_subscription", ]; +const RUST_EXTENSION_BOOL_FIELDS: &[&str] = &["enforce_admin_subscription"]; + const INT_FIELDS: &[&str] = &["api_allowed_retry_count", "api_graphql_max_depth"]; const OBJECT_FIELDS: &[&str] = &[ @@ -177,6 +178,9 @@ fn normalize_api_fields(payload: &Value, update: bool) -> Result, key: Option, public_key: Option, + public_key_path: Option, verification_key: Option, - active: Option, } pub fn extract_token(headers: &HeaderMap) -> Option { @@ -107,6 +107,7 @@ fn extract_cookie(headers: &HeaderMap, name: &str) -> Option { #[derive(Clone, Debug)] struct VerificationKey { + kid: Option, algorithm: String, secret: String, rsa: bool, @@ -137,6 +138,7 @@ fn select_key(config: &SharedStorageConfig, kid: Option<&str>) -> Option) -> Option return None, }; - configs + let keys = configs .into_iter() .filter_map(|value| serde_json::from_value::(value).ok()) - .filter(|config| config.active.unwrap_or(true)) - .find_map(|config| { - if let Some(expected) = kid { - if config.kid.as_deref() != Some(expected) { - return None; - } - } + .filter_map(|config| { let algorithm = config.algorithm.unwrap_or_else(|| "HS256".to_owned()); let secret = if algorithm.eq_ignore_ascii_case("RS256") { - config.public_key.or(config.verification_key) + config + .public_key_path + .and_then(|path| std::fs::read_to_string(path).ok()) + .or(config.public_key) + .or(config.verification_key) } else { config.secret.or(config.key).or(config.verification_key) }?; Some(VerificationKey { + kid: config.kid, rsa: algorithm.eq_ignore_ascii_case("RS256"), algorithm, secret, }) }) + .collect::>(); + if let Some(kid) = kid { + return keys.into_iter().find(|key| key.kid.as_deref() == Some(kid)); + } + if keys.len() == 1 { + return keys.into_iter().next(); + } + keys.into_iter() + .find(|key| key.kid.as_deref() == Some("legacy-key")) } pub fn unauthorized(message: &str) -> PolicyFailure { @@ -224,4 +234,26 @@ mod tests { headers.insert(header::AUTHORIZATION, HeaderValue::from_static("raw-token")); assert_eq!(extract_token(&headers), Some("raw-token".to_owned())); } + + #[test] + fn configured_verification_key_selection_matches_legacy_kid_rules() { + let keys = r#"[ + {"kid":"one","algorithm":"HS256","secret":"first","active":false}, + {"kid":"two","algorithm":"HS256","secret":"second"} + ]"#; + assert!(select_configured_key(keys, None).is_none()); + assert_eq!( + select_configured_key(keys, Some("one")).unwrap().secret, + "first" + ); + + let legacy = r#"[ + {"kid":"one","algorithm":"HS256","secret":"first"}, + {"kid":"legacy-key","algorithm":"HS256","secret":"legacy"} + ]"#; + assert_eq!( + select_configured_key(legacy, None).unwrap().secret, + "legacy" + ); + } } diff --git a/gateway-rs/src/policy/credits.rs b/gateway-rs/src/policy/credits.rs index 7e8fe46e..a2bf8c34 100644 --- a/gateway-rs/src/policy/credits.rs +++ b/gateway-rs/src/policy/credits.rs @@ -3,7 +3,10 @@ use serde_json::Value; use time::{OffsetDateTime, format_description::well_known::Rfc3339}; use super::{PolicyFailure, PolicyStage}; -use crate::storage::models::{bool_field_default, object_field, string_field, u64_field}; +use crate::storage::{ + field_encryption::decrypt_value, + models::{bool_field_default, object_field, string_field, u64_field}, +}; #[derive(Clone, Debug, Default, Eq, PartialEq)] pub struct CreditDecision { @@ -18,8 +21,10 @@ pub fn credit_header_values( now: OffsetDateTime, ) -> Option<(String, Vec)> { let header = string_field(definition, "api_key_header")?.to_owned(); - let old = string_field(definition, "api_key").map(str::to_owned); - let new = string_field(definition, "api_key_new").map(str::to_owned); + let old_encrypted = string_field(definition, "api_key"); + let old = decrypt_value(old_encrypted).or_else(|| old_encrypted.map(str::to_owned)); + let new_encrypted = string_field(definition, "api_key_new"); + let new = decrypt_value(new_encrypted).or_else(|| new_encrypted.map(str::to_owned)); let expires = string_field(definition, "api_key_rotation_expires") .and_then(|value| OffsetDateTime::parse(value, &Rfc3339).ok()); let values = match (old, new, expires) { @@ -83,7 +88,7 @@ pub fn evaluate_credits( .and_then(|doc| object_field(doc, "users_credits")) .and_then(|credits| credits.get(group)) .and_then(|credit| string_field(credit, "user_api_key")) - .map(str::to_owned); + .and_then(|value| decrypt_value(Some(value)).or_else(|| Some(value.to_owned()))); Ok(CreditDecision { required: true, diff --git a/gateway-rs/src/policy/evaluator.rs b/gateway-rs/src/policy/evaluator.rs index 1ca4b433..05588016 100644 --- a/gateway-rs/src/policy/evaluator.rs +++ b/gateway-rs/src/policy/evaluator.rs @@ -106,6 +106,18 @@ pub fn evaluate_rest_policy( } else { request.method.as_str() }; + if !documents + .endpoints + .iter() + .any(|endpoint| endpoint_belongs_to_api(endpoint, &api)) + { + return Err(PolicyFailure::new( + PolicyStage::Resolution, + StatusCode::NOT_FOUND, + "GTW002", + "No endpoints found for the requested API", + )); + } if !endpoint_exists(&documents.endpoints, &api, method, &route.endpoint_uri) { return Err(PolicyFailure::new( PolicyStage::Resolution, @@ -226,11 +238,11 @@ pub fn evaluate_rest_policy( } let enforce_admin_sub = std::env::var("ENFORCE_ADMIN_SUBSCRIPTION") - .map(|v| v.eq_ignore_ascii_case("true") || v == "1") + .map(|v| v.eq_ignore_ascii_case("true")) .unwrap_or_else(|_| { api.get("enforce_admin_subscription") .and_then(Value::as_bool) - .unwrap_or(true) + .unwrap_or(false) }); enforce_subscription( @@ -404,14 +416,14 @@ pub async fn evaluate_shared_effects( let now_seconds = request.now_millis / 1000; let bucket = (now_seconds / window) * window; let key = bandwidth_key(username, window, bucket); - let total = storage + let used = storage .current_counter(&key) .await - .map_err(storage_failure)? - .saturating_add(request.content_length); + .map_err(storage_failure)?; + let total = used.saturating_add(request.content_length); decision.bandwidth_key = Some(key); decision.bandwidth_ttl_seconds = Some(window); - if total > limit { + if used >= limit || total > limit { return Err(PolicyFailure::new( PolicyStage::Bandwidth, StatusCode::TOO_MANY_REQUESTS, @@ -503,8 +515,7 @@ fn storage_failure(error: crate::storage::runtime::StorageError) -> PolicyFailur fn endpoint_exists(endpoints: &[Value], api: &Value, method: &str, endpoint_uri: &str) -> bool { endpoints.iter().any(|endpoint| { - let same_api = string_field(endpoint, "api_name") == string_field(api, "api_name") - && string_field(endpoint, "api_version") == string_field(api, "api_version"); + let same_api = endpoint_belongs_to_api(endpoint, api); let same_method = string_field(endpoint, "endpoint_method") .is_some_and(|actual| actual.eq_ignore_ascii_case(method)); let uri = @@ -515,6 +526,19 @@ fn endpoint_exists(endpoints: &[Value], api: &Value, method: &str, endpoint_uri: }) } +fn endpoint_belongs_to_api(endpoint: &Value, api: &Value) -> bool { + match ( + string_field(endpoint, "api_id"), + string_field(api, "api_id"), + ) { + (Some(endpoint_id), Some(api_id)) => endpoint_id == api_id, + _ => { + string_field(endpoint, "api_name") == string_field(api, "api_name") + && string_field(endpoint, "api_version") == string_field(api, "api_version") + } + } +} + fn optional_string_list(value: &Value, field: &str) -> Option> { value.get(field).and_then(Value::as_array).map(|items| { items @@ -526,6 +550,10 @@ fn optional_string_list(value: &Value, field: &str) -> Option> { } pub(crate) fn is_revoked(revocations: &[Value], username: &str, jti: Option<&str>) -> bool { + let now = std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap_or_default() + .as_secs(); revocations .iter() .any(|revocation| match string_field(revocation, "type") { @@ -536,6 +564,10 @@ pub(crate) fn is_revoked(revocations: &[Value], username: &str, jti: Option<&str Some("jti") => { string_field(revocation, "username") == Some(username) && jti.is_some_and(|jti| string_field(revocation, "jti") == Some(jti)) + && revocation + .get("expires_at") + .and_then(Value::as_u64) + .is_some_and(|expires_at| expires_at > now) } _ => false, }) @@ -547,6 +579,29 @@ mod tests { use http::HeaderValue; use serde_json::json; + #[test] + fn expired_or_malformed_jti_revocations_do_not_block_requests() { + let now = std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap() + .as_secs(); + assert!(!is_revoked( + &[json!({"type":"jti", "username":"alice", "jti":"old", "expires_at": now})], + "alice", + Some("old") + )); + assert!(!is_revoked( + &[json!({"type":"jti", "username":"alice", "jti":"missing"})], + "alice", + Some("missing") + )); + assert!(is_revoked( + &[json!({"type":"jti", "username":"alice", "jti":"live", "expires_at": now + 60})], + "alice", + Some("live") + )); + } + #[test] fn mixed_settings_records_cannot_override_api_proxy_policy() { let mut documents = PolicyDocuments { @@ -634,6 +689,39 @@ mod tests { assert_eq!(failure.error_code, "GTW003"); } + #[test] + fn returns_no_endpoints_for_api_without_registered_endpoints() { + let mut documents = PolicyDocuments { + apis: vec![json!({ + "api_id": "api-1", + "api_name": "demo", + "api_version": "v1", + "api_public": true, + })], + ..Default::default() + }; + let request = PolicyRequest { + method: Method::GET, + path: "/api/rest/demo/v1/missing".to_owned(), + headers: HeaderMap::new(), + direct_ip: None, + now_millis: 0, + content_length: 0, + }; + let failure = evaluate_rest_policy( + &mut documents, + &request, + &SharedStorageConfig::default(), + &PolicyRuntime::default(), + ) + .unwrap_err(); + assert_eq!(failure.error_code, "GTW002"); + assert_eq!( + failure.error_message, + "No endpoints found for the requested API" + ); + } + #[test] fn records_client_key_upstream_selection() { let mut headers = HeaderMap::new(); diff --git a/gateway-rs/src/policy/geo.rs b/gateway-rs/src/policy/geo.rs new file mode 100644 index 00000000..e9950f49 --- /dev/null +++ b/gateway-rs/src/policy/geo.rs @@ -0,0 +1,284 @@ +//! Placeholder geographic lookup and country policy from the Python backend. + +use std::{ + collections::{HashMap, HashSet}, + sync::{Arc, Mutex}, + time::{Duration, Instant}, +}; + +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)] +pub struct GeoLocation { + pub ip: String, + pub country_code: Option, + pub country_name: Option, + pub region: Option, + pub city: Option, + pub latitude: Option, + pub longitude: Option, + pub timezone: Option, +} + +#[derive(Clone, Debug)] +struct Expiring { + value: T, + expires_at: Instant, +} + +#[derive(Clone, Debug, Default)] +struct GeoState { + cache: HashMap>, + blocked: HashSet, + allowed: HashSet, + rate_limits: HashMap, + requests: HashMap>, +} + +#[derive(Clone, Debug)] +pub struct GeoLookup { + state: Arc>, + cache_ttl: Duration, +} + +impl Default for GeoLookup { + fn default() -> Self { + Self { + state: Arc::new(Mutex::new(GeoState::default())), + cache_ttl: Duration::from_secs(86_400), + } + } +} + +impl GeoLookup { + pub fn lookup_ip(&self, ip: &str) -> GeoLocation { + let mut state = self.state.lock().expect("geo state mutex poisoned"); + if state + .cache + .get(ip) + .is_some_and(|entry| entry.expires_at <= Instant::now()) + { + state.cache.remove(ip); + } + if let Some(entry) = state.cache.get(ip) { + return entry.value.clone(); + } + let geo = GeoLocation { + ip: ip.to_owned(), + country_code: Some("UNKNOWN".to_owned()), + ..GeoLocation::default() + }; + state.cache.insert( + ip.to_owned(), + Expiring { + value: geo.clone(), + expires_at: Instant::now() + self.cache_ttl, + }, + ); + geo + } + + pub fn cache_geo_data(&self, ip: &str, mut geo: GeoLocation) { + geo.ip = ip.to_owned(); + // Python serializes zero coordinates as an empty string, which reloads + // as None. Preserve that pinned edge case. + if geo.latitude == Some(0.0) { + geo.latitude = None; + } + if geo.longitude == Some(0.0) { + geo.longitude = None; + } + self.state + .lock() + .expect("geo state mutex poisoned") + .cache + .insert( + ip.to_owned(), + Expiring { + value: geo, + expires_at: Instant::now() + self.cache_ttl, + }, + ); + } + + pub fn is_country_blocked(&self, country_code: &str) -> bool { + self.state + .lock() + .expect("geo state mutex poisoned") + .blocked + .contains(country_code) + } + + pub fn is_country_allowed(&self, country_code: &str) -> bool { + let state = self.state.lock().expect("geo state mutex poisoned"); + state.allowed.is_empty() || state.allowed.contains(country_code) + } + + pub fn block_country(&self, country_code: &str) -> bool { + self.state + .lock() + .expect("geo state mutex poisoned") + .blocked + .insert(country_code.to_owned()); + true + } + + pub fn unblock_country(&self, country_code: &str) -> bool { + self.state + .lock() + .expect("geo state mutex poisoned") + .blocked + .remove(country_code); + true + } + + pub fn add_to_allowlist(&self, country_code: &str) -> bool { + self.state + .lock() + .expect("geo state mutex poisoned") + .allowed + .insert(country_code.to_owned()); + true + } + + pub fn remove_from_allowlist(&self, country_code: &str) -> bool { + self.state + .lock() + .expect("geo state mutex poisoned") + .allowed + .remove(country_code); + true + } + + pub fn get_country_rate_limit(&self, country_code: &str) -> Option { + self.state + .lock() + .expect("geo state mutex poisoned") + .rate_limits + .get(country_code) + .copied() + } + + pub fn set_country_rate_limit(&self, country_code: &str, limit: i64) -> bool { + self.state + .lock() + .expect("geo state mutex poisoned") + .rate_limits + .insert(country_code.to_owned(), limit); + true + } + + pub fn check_geographic_access(&self, ip: &str) -> (bool, Option) { + let geo = self.lookup_ip(ip); + let Some(country) = geo + .country_code + .as_deref() + .filter(|country| *country != "UNKNOWN") + else { + return (true, None); + }; + if self.is_country_blocked(country) { + return (false, Some(format!("Country {country} is blocked"))); + } + if !self.is_country_allowed(country) { + return ( + false, + Some(format!("Country {country} is not in allowlist")), + ); + } + (true, None) + } + + pub fn track_country_request(&self, country_code: &str) { + let mut state = self.state.lock().expect("geo state mutex poisoned"); + let now = Instant::now(); + let entry = state + .requests + .entry(country_code.to_owned()) + .or_insert(Expiring { + value: 0, + expires_at: now + Duration::from_secs(86_400), + }); + if entry.expires_at <= now { + entry.value = 0; + } + entry.value = entry.value.saturating_add(1); + entry.expires_at = now + Duration::from_secs(86_400); + } + + pub fn get_geographic_distribution(&self) -> Vec<(String, u64)> { + let now = Instant::now(); + let mut state = self.state.lock().expect("geo state mutex poisoned"); + state.requests.retain(|_, entry| entry.expires_at > now); + let mut values = state + .requests + .iter() + .map(|(country, entry)| (country.clone(), entry.value)) + .collect::>(); + values.sort_by(|left, right| right.1.cmp(&left.1)); + values + } + + pub fn get_blocked_countries(&self) -> HashSet { + self.state + .lock() + .expect("geo state mutex poisoned") + .blocked + .clone() + } + + pub fn get_allowed_countries(&self) -> HashSet { + self.state + .lock() + .expect("geo state mutex poisoned") + .allowed + .clone() + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn unknown_locations_fail_open_like_python() { + let lookup = GeoLookup::default(); + assert_eq!( + lookup.lookup_ip("203.0.113.2").country_code.as_deref(), + Some("UNKNOWN") + ); + assert_eq!(lookup.check_geographic_access("203.0.113.2"), (true, None)); + } + + #[test] + fn country_lists_limits_and_distribution_match_python() { + let lookup = GeoLookup::default(); + lookup.cache_geo_data( + "203.0.113.3", + GeoLocation { + country_code: Some("CA".to_owned()), + ..GeoLocation::default() + }, + ); + lookup.block_country("CA"); + assert_eq!( + lookup.check_geographic_access("203.0.113.3"), + (false, Some("Country CA is blocked".to_owned())) + ); + lookup.unblock_country("CA"); + lookup.add_to_allowlist("US"); + assert_eq!( + lookup.check_geographic_access("203.0.113.3"), + (false, Some("Country CA is not in allowlist".to_owned())) + ); + assert!(lookup.set_country_rate_limit("CA", 25)); + assert_eq!(lookup.get_country_rate_limit("CA"), Some(25)); + lookup.track_country_request("CA"); + lookup.track_country_request("CA"); + lookup.track_country_request("US"); + assert_eq!( + lookup.get_geographic_distribution()[0], + ("CA".to_owned(), 2) + ); + } +} diff --git a/gateway-rs/src/policy/ip.rs b/gateway-rs/src/policy/ip.rs index 37455fad..b7535665 100644 --- a/gateway-rs/src/policy/ip.rs +++ b/gateway-rs/src/policy/ip.rs @@ -133,7 +133,18 @@ pub fn effective_client_ip( } fn is_loopback(ip: IpAddr) -> bool { - ip.is_loopback() + if ip.is_loopback() { + return true; + } + std::env::var("DOORMAN_IN_DOCKER") + .ok() + .is_some_and(|value| { + matches!( + value.trim().to_ascii_lowercase().as_str(), + "1" | "true" | "yes" + ) + }) + && matches!(ip, IpAddr::V4(ip) if ip == Ipv4Addr::new(192, 168, 65, 1) || ip == Ipv4Addr::new(172, 17, 0, 1)) } fn ip_in_list(ip: IpAddr, patterns: &[String]) -> bool { diff --git a/gateway-rs/src/policy/mod.rs b/gateway-rs/src/policy/mod.rs index 3695296d..3dd8a7c7 100644 --- a/gateway-rs/src/policy/mod.rs +++ b/gateway-rs/src/policy/mod.rs @@ -6,11 +6,13 @@ pub mod auth; pub mod bandwidth; pub mod credits; pub mod evaluator; +pub mod geo; pub mod groups; pub mod ip; pub mod quota; pub mod rate_limit; pub mod roles; +pub mod simulator; pub mod subscription; pub mod throttle; pub mod tier; diff --git a/gateway-rs/src/policy/quota.rs b/gateway-rs/src/policy/quota.rs index ed5830df..9e993958 100644 --- a/gateway-rs/src/policy/quota.rs +++ b/gateway-rs/src/policy/quota.rs @@ -16,13 +16,13 @@ pub struct QuotaPolicy { /// Derived usage state used by the quota API and enforcement callers. /// Thresholds deliberately match the Python tracker: warning begins at 80% /// and critical at 95%, including the exhausted boundary. -#[derive(Debug, Clone, Eq, PartialEq, serde::Serialize)] +#[derive(Debug, Clone, PartialEq, serde::Serialize)] pub struct QuotaUsageStatus { pub allowed: bool, pub current_usage: u64, pub limit: u64, pub remaining: u64, - pub percentage_used: u64, + pub percentage_used: f64, pub is_warning: bool, pub is_critical: bool, pub is_exhausted: bool, @@ -31,9 +31,9 @@ pub struct QuotaUsageStatus { pub fn quota_usage_status(current_usage: u64, limit: u64) -> QuotaUsageStatus { let remaining = limit.saturating_sub(current_usage); let percentage_used = if limit == 0 { - 0 + 0.0 } else { - current_usage.saturating_mul(100) / limit + current_usage as f64 / limit as f64 * 100.0 }; let is_exhausted = limit == 0 || current_usage >= limit; QuotaUsageStatus { @@ -42,8 +42,8 @@ pub fn quota_usage_status(current_usage: u64, limit: u64) -> QuotaUsageStatus { limit, remaining, percentage_used, - is_warning: percentage_used >= 80, - is_critical: percentage_used >= 95, + is_warning: percentage_used >= 80.0, + is_critical: percentage_used >= 95.0, is_exhausted, } } @@ -84,11 +84,25 @@ pub fn increment_quota( quota_id: &str, period_seconds: u64, now_seconds: u64, +) -> u64 { + increment_quota_by(counter, user_id, quota_id, 1, period_seconds, now_seconds) +} + +/// Records an arbitrary positive usage amount, matching the Python tracker's +/// `increment_quota(..., amount=...)` contract. +pub fn increment_quota_by( + counter: &WindowCounter, + user_id: &str, + quota_id: &str, + amount: u64, + period_seconds: u64, + now_seconds: u64, ) -> u64 { let period = period_seconds.max(1); let window_index = now_seconds / period; - counter.incr( + counter.incr_by( "a_counter_key(user_id, quota_id, window_index), + amount, period.saturating_mul(2), now_seconds, ) @@ -138,6 +152,9 @@ mod tests { assert!(exhausted.is_exhausted); assert!(!exhausted.allowed); assert_eq!(exhausted.remaining, 0); + + let fractional = quota_usage_status(1, 3); + assert!((fractional.percentage_used - 33.333_333_333_333_33).abs() < f64::EPSILON); } #[test] @@ -146,5 +163,9 @@ mod tests { assert_eq!(increment_quota(&counter, "alice", "requests", 60, 60), 1); assert_eq!(increment_quota(&counter, "alice", "requests", 60, 61), 2); assert_eq!(increment_quota(&counter, "alice", "requests", 60, 120), 1); + assert_eq!( + increment_quota_by(&counter, "alice", "requests", 4, 60, 121), + 5 + ); } } diff --git a/gateway-rs/src/policy/simulator.rs b/gateway-rs/src/policy/simulator.rs new file mode 100644 index 00000000..a6afaf38 --- /dev/null +++ b/gateway-rs/src/policy/simulator.rs @@ -0,0 +1,351 @@ +//! Offline rate-limit simulation, translated from the Python utility. + +use std::{ + collections::{BTreeMap, HashMap}, + time::{SystemTime, UNIX_EPOCH}, +}; + +use serde::Serialize; + +#[derive(Clone, Debug, PartialEq)] +pub struct SimulationRequest { + pub timestamp_seconds: f64, + pub user_id: String, + pub endpoint: String, + pub ip: String, +} + +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct SimulationRule { + pub rule_id: String, + pub rule_type: String, + pub time_window: String, + pub limit: u64, + pub burst_allowance: u64, +} + +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct SimulationResult { + pub total_requests: u64, + pub allowed_requests: u64, + pub blocked_requests: u64, + pub burst_used_count: u64, + pub success_rate: f64, + pub average_remaining: f64, + pub peak_usage: u64, + pub requests_by_second: BTreeMap, +} + +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct SimulationScenario { + pub scenario_name: String, + pub rule: SimulationRule, + pub pattern: String, + pub result: SimulationResult, + pub report: String, +} + +fn now_seconds() -> f64 { + SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap_or_default() + .as_secs_f64() +} + +pub fn window_seconds(window: &str) -> u64 { + match window { + "second" => 1, + "minute" => 60, + "hour" => 3_600, + "day" => 86_400, + "month" => 2_592_000, + _ => 60, + } +} + +pub fn generate_requests( + num_requests: usize, + duration_seconds: f64, + pattern: &str, + start_seconds: f64, +) -> Vec { + if num_requests == 0 { + return Vec::new(); + } + let mut seed = start_seconds.to_bits().wrapping_add(num_requests as u64); + let mut requests = (0..num_requests) + .filter_map(|index| { + let offset = match pattern { + "uniform" => index as f64 * duration_seconds / num_requests as f64, + "burst" => index as f64 * (duration_seconds * 0.1) / num_requests as f64, + "spike" => { + duration_seconds * 0.4 + + index as f64 * (duration_seconds * 0.2) / num_requests as f64 + } + "gradual" => { + let progress = index as f64 / num_requests as f64; + progress * progress * duration_seconds + } + "random" => { + // A local generator keeps this utility dependency-free; Python also + // deliberately leaves random simulations unseeded. + seed = seed.wrapping_mul(6_364_136_223_846_793_005).wrapping_add(1); + seed as f64 / u64::MAX as f64 * duration_seconds + } + _ => return None, + }; + Some(SimulationRequest { + timestamp_seconds: start_seconds + offset, + user_id: "sim_user".to_owned(), + endpoint: "/api/test".to_owned(), + ip: "192.168.1.1".to_owned(), + }) + }) + .collect::>(); + if pattern == "random" { + requests.sort_by(|left, right| left.timestamp_seconds.total_cmp(&right.timestamp_seconds)); + } + requests +} + +pub fn simulate_rule(rule: &SimulationRule, requests: &[SimulationRequest]) -> SimulationResult { + let mut allowed_requests = 0_u64; + let mut blocked_requests = 0_u64; + let mut burst_used_count = 0_u64; + let mut remaining_values = Vec::with_capacity(requests.len()); + let mut requests_by_second = BTreeMap::new(); + + for request in requests { + *requests_by_second + .entry(request.timestamp_seconds as i64) + .or_insert(0) += 1; + } + let window = window_seconds(&rule.time_window) as f64; + for request in requests { + let window_start = request.timestamp_seconds - window; + let current_usage = requests + .iter() + .filter(|candidate| { + candidate.timestamp_seconds >= window_start + && candidate.timestamp_seconds <= request.timestamp_seconds + }) + .count() as u64; + if current_usage <= rule.limit { + allowed_requests += 1; + remaining_values.push(rule.limit - current_usage); + } else if rule.burst_allowance > 0 + && current_usage <= rule.limit.saturating_add(rule.burst_allowance) + { + allowed_requests += 1; + burst_used_count += 1; + remaining_values.push( + rule.limit + .saturating_add(rule.burst_allowance) + .saturating_sub(current_usage), + ); + } else { + blocked_requests += 1; + remaining_values.push(0); + } + } + let total_requests = requests.len() as u64; + let success_rate = if total_requests == 0 { + 0.0 + } else { + allowed_requests as f64 / total_requests as f64 * 100.0 + }; + let average_remaining = if remaining_values.is_empty() { + 0.0 + } else { + remaining_values.iter().sum::() as f64 / remaining_values.len() as f64 + }; + let peak_usage = requests_by_second.values().copied().max().unwrap_or(0); + SimulationResult { + total_requests, + allowed_requests, + blocked_requests, + burst_used_count, + success_rate, + average_remaining, + peak_usage, + requests_by_second, + } +} + +pub fn compare_rules( + rules: &[SimulationRule], + requests: &[SimulationRequest], +) -> HashMap { + rules + .iter() + .map(|rule| (rule.rule_id.clone(), simulate_rule(rule, requests))) + .collect() +} + +pub fn preview_rule_change( + current_rule: &SimulationRule, + new_rule: &SimulationRule, + historical_pattern: &str, + duration_minutes: u64, +) -> HashMap { + let requests = generate_requests( + (current_rule.limit as f64 * 1.5) as usize, + duration_minutes as f64 * 60.0, + historical_pattern, + now_seconds(), + ); + compare_rules(&[current_rule.clone(), new_rule.clone()], &requests) +} + +pub fn test_burst_effectiveness( + base_limit: u64, + burst_allowances: &[u64], + spike_intensity: f64, +) -> BTreeMap { + let requests = generate_requests( + (base_limit as f64 * spike_intensity) as usize, + 60.0, + "spike", + now_seconds(), + ); + burst_allowances + .iter() + .map(|burst| { + let rule = SimulationRule { + rule_id: format!("burst_{burst}"), + rule_type: "per_user".to_owned(), + time_window: "minute".to_owned(), + limit: base_limit, + burst_allowance: *burst, + }; + (*burst, simulate_rule(&rule, &requests)) + }) + .collect() +} + +pub fn generate_report(rule: &SimulationRule, result: &SimulationResult) -> String { + let mut report = format!( + "\nRate Limit Simulation Report\n{line}\n\nRule Configuration:\n Rule ID: {id}\n Type: {kind}\n Time Window: {window}\n Limit: {limit}\n Burst Allowance: {burst}\n\nSimulation Results:\n Total Requests: {total}\n Allowed: {allowed} ({rate:.1}%)\n Blocked: {blocked}\n Burst Used: {burst_used}\n\nPerformance Metrics:\n Success Rate: {rate:.1}%\n Average Remaining: {remaining:.1}\n Peak Usage: {peak} req/sec\n\nRecommendation:\n", + line = "=".repeat(50), + id = rule.rule_id, + kind = rule.rule_type, + window = rule.time_window, + limit = rule.limit, + burst = rule.burst_allowance, + total = result.total_requests, + allowed = result.allowed_requests, + rate = result.success_rate, + blocked = result.blocked_requests, + burst_used = result.burst_used_count, + remaining = result.average_remaining, + peak = result.peak_usage, + ); + if result.success_rate < 90.0 { + report.push_str(" ⚠️ Consider increasing limit or burst allowance\n"); + } else if result.success_rate > 99.0 && result.average_remaining > rule.limit as f64 * 0.5 { + report.push_str(" ℹ️ Limit may be too high, consider reducing\n"); + } else { + report.push_str(" ✅ Rule configuration appears appropriate\n"); + } + if result.burst_used_count > 0 { + let percentage = result.burst_used_count as f64 / result.allowed_requests as f64 * 100.0; + report.push_str(&format!( + " ℹ️ {percentage:.1}% of requests used burst tokens\n" + )); + } + report +} + +pub fn run_scenario( + scenario_name: &str, + rule: &SimulationRule, + pattern: &str, + duration_minutes: u64, +) -> SimulationScenario { + let requests = generate_requests( + rule.limit.saturating_mul(2) as usize, + duration_minutes as f64 * 60.0, + pattern, + now_seconds(), + ); + let result = simulate_rule(rule, &requests); + let report = generate_report(rule, &result); + SimulationScenario { + scenario_name: scenario_name.to_owned(), + rule: rule.clone(), + pattern: pattern.to_owned(), + result, + report, + } +} + +pub fn quick_simulate(limit: u64, time_window: &str, burst: u64, pattern: &str) -> String { + let rule = SimulationRule { + rule_id: "quick_sim".to_owned(), + rule_type: "per_user".to_owned(), + time_window: time_window.to_owned(), + limit, + burst_allowance: burst, + }; + let requests = generate_requests( + limit.saturating_mul(2) as usize, + 60.0, + pattern, + now_seconds(), + ); + generate_report(&rule, &simulate_rule(&rule, &requests)) +} + +#[cfg(test)] +mod tests { + use super::*; + + fn rule(limit: u64, burst: u64) -> SimulationRule { + SimulationRule { + rule_id: "example".to_owned(), + rule_type: "per_user".to_owned(), + time_window: "minute".to_owned(), + limit, + burst_allowance: burst, + } + } + + #[test] + fn generates_python_traffic_patterns() { + let uniform = generate_requests(4, 100.0, "uniform", 1_000.0); + assert_eq!(uniform[3].timestamp_seconds, 1_075.0); + let spike = generate_requests(4, 100.0, "spike", 1_000.0); + assert_eq!(spike[0].timestamp_seconds, 1_040.0); + assert_eq!(spike[3].timestamp_seconds, 1_055.0); + assert!(generate_requests(3, 10.0, "unknown", 0.0).is_empty()); + } + + #[test] + fn simulates_limit_and_burst_like_python() { + let requests = generate_requests(5, 1.0, "burst", 1_000.0); + let result = simulate_rule(&rule(2, 1), &requests); + assert_eq!(result.allowed_requests, 3); + assert_eq!(result.blocked_requests, 2); + assert_eq!(result.burst_used_count, 1); + assert_eq!(result.peak_usage, 5); + assert_eq!(result.success_rate, 60.0); + assert!(generate_report(&rule(2, 1), &result).contains("Consider increasing limit")); + } + + #[test] + fn comparison_and_scenario_helpers_preserve_python_shapes() { + let current = rule(4, 0); + let mut proposed = rule(8, 2); + proposed.rule_id = "proposed".to_owned(); + let comparison = preview_rule_change(¤t, &proposed, "uniform", 1); + assert_eq!(comparison.len(), 2); + assert!(comparison.contains_key("example")); + assert!(comparison.contains_key("proposed")); + let bursts = test_burst_effectiveness(4, &[0, 2], 2.0); + assert_eq!(bursts.len(), 2); + let scenario = run_scenario("load", ¤t, "uniform", 5); + assert_eq!(scenario.scenario_name, "load"); + assert_eq!(scenario.result.total_requests, 8); + assert!(quick_simulate(4, "minute", 0, "uniform").contains("quick_sim")); + } +} diff --git a/gateway-rs/src/policy/subscription.rs b/gateway-rs/src/policy/subscription.rs index 911034ca..4590e132 100644 --- a/gateway-rs/src/policy/subscription.rs +++ b/gateway-rs/src/policy/subscription.rs @@ -55,7 +55,7 @@ mod tests { use serde_json::json; #[test] - fn admin_requires_subscription_by_default() { + fn admin_bypasses_subscription_unless_enforced() { let user = json!({ "username": "admin", "role": "admin" }); assert!(enforce_subscription("demo/v1", &user, &[], &[], true).is_err()); assert!(enforce_subscription("demo/v1", &user, &[], &[], false).is_ok()); diff --git a/gateway-rs/src/routes/platform.rs b/gateway-rs/src/routes/platform.rs index 14e40f09..f9db9571 100644 --- a/gateway-rs/src/routes/platform.rs +++ b/gateway-rs/src/routes/platform.rs @@ -6,7 +6,7 @@ use std::{ io::Read, net::SocketAddr, process::{Command, Stdio}, - sync::{OnceLock, atomic::Ordering}, + sync::OnceLock, time::{SystemTime, UNIX_EPOCH}, }; @@ -18,6 +18,7 @@ use axum::{ use base64::{Engine as _, engine::general_purpose::STANDARD as BASE64_STANDARD}; use http::{HeaderMap, HeaderValue, Method, StatusCode, header}; use jsonwebtoken::{Algorithm, EncodingKey, Header, encode}; +use regex::Regex; use serde::Serialize; use serde_json::{Map, Value, json}; use sha2::{Digest, Sha256}; @@ -31,10 +32,7 @@ static PYTHON_OPENAPI: OnceLock = OnceLock::new(); use crate::{ middleware::{ body_limit::BodyLimits, - chaos::{ - CHAOS_ENABLED, CHAOS_ERROR_BUDGET_BURN, CHAOS_ERROR_STATUS, CHAOS_EVENTS_COUNT, - CHAOS_LATENCY_MS, CHAOS_MONGO_OUTAGE, CHAOS_REDIS_OUTAGE, - }, + chaos::{CHAOS_ERROR_BUDGET_BURN, CHAOS_MONGO_OUTAGE, CHAOS_REDIS_OUTAGE}, response_compat::MessageEnvelope, }, observability::{ @@ -113,26 +111,6 @@ impl Drop for ProtoCompileDirectory { } } -const RBAC_PERMISSIONS: &[&str] = &[ - "manage_users", - "manage_apis", - "manage_endpoints", - "manage_groups", - "manage_roles", - "manage_routings", - "manage_gateway", - "manage_subscriptions", - "manage_credits", - "manage_auth", - "manage_security", - "manage_tiers", - "manage_rate_limits", - "view_analytics", - "view_logs", - "export_logs", - "ui_access", -]; - pub async fn platform_dispatch( State(state): State, OriginalUri(uri): OriginalUri, @@ -196,7 +174,7 @@ pub async fn platform_dispatch( &request_id, ); } - let payload = parsed_payload.unwrap_or(Value::Null); + let mut payload = parsed_payload.unwrap_or(Value::Null); // SubscribeModel requires all three fields. Keep this lightweight // compatibility check at dispatch time until the remaining typed model is // ported, so a missing field reaches FastAPI's global validation envelope @@ -212,6 +190,17 @@ pub async fn platform_dispatch( &request_id, ); } + if method == Method::PUT + && is_update_password_path(path) + && normalize_update_password_model(&mut payload).is_err() + { + return error( + StatusCode::UNPROCESSABLE_ENTITY, + "VAL001", + "Validation Error", + &request_id, + ); + } if path == "/authorization" && method == Method::POST { if let Some(response) = auth_account_rate_limit( @@ -307,6 +296,20 @@ pub async fn platform_dispatch( return response; } } + if tier_route_is_public(path, &method) + && let Some(response) = dispatch_core_entities( + &state, + path, + &method, + payload.clone(), + &query, + "", + &request_id, + ) + .await + { + return response; + } let claims = match authorize(&state, &headers, path, &request_id).await { Ok(claims) => claims, @@ -391,7 +394,7 @@ pub async fn platform_dispatch( &request_id, ) } else { - monitor_metrics(&state, &request_id).await + monitor_metrics(&state, &query, &request_id).await } } (Method::GET, "/monitor/report") => { @@ -407,57 +410,77 @@ pub async fn platform_dispatch( } } (Method::GET, "/analytics/overview") => { - analytics_overview(&state, &username, &query, &request_id).await + if let Some(response) = analytics_query_error(&query, false, &request_id) { + response + } else { + analytics_overview(&state, &username, &query, &request_id).await + } } (Method::GET, "/analytics/timeseries") => { - if !has_permission(&state, &username, "view_analytics").await { + if let Some(response) = analytics_query_error(&query, false, &request_id) { + response + } else if !has_permission(&state, &username, "view_analytics").await { analytics_denied(&request_id) } else { analytics_timeseries(&query, &request_id) } } (Method::GET, "/analytics/top-apis") => { - if !has_permission(&state, &username, "view_analytics").await { + if let Some(response) = analytics_query_error(&query, true, &request_id) { + response + } else if !has_permission(&state, &username, "view_analytics").await { analytics_denied(&request_id) } else { analytics_top("api", &query, &request_id) } } (Method::GET, "/analytics/top-users") => { - if !has_permission(&state, &username, "view_analytics").await { + if let Some(response) = analytics_query_error(&query, true, &request_id) { + response + } else if !has_permission(&state, &username, "view_analytics").await { analytics_denied(&request_id) } else { analytics_top("user", &query, &request_id) } } (Method::GET, "/analytics/top-endpoints") => { - if !has_permission(&state, &username, "view_analytics").await { + if let Some(response) = analytics_query_error(&query, true, &request_id) { + response + } else if !has_permission(&state, &username, "view_analytics").await { analytics_denied(&request_id) } else { analytics_top("endpoint", &query, &request_id) } } (Method::GET, detail) if detail.starts_with("/analytics/api/") => { - analytics_detail( - &state, - &username, - "api", - detail.trim_start_matches("/analytics/api/"), - &query, - &request_id, - ) - .await + if let Some(response) = analytics_query_error(&query, false, &request_id) { + response + } else { + analytics_detail( + &state, + &username, + "api", + detail.trim_start_matches("/analytics/api/"), + &query, + &request_id, + ) + .await + } } (Method::GET, detail) if detail.starts_with("/analytics/user/") => { - analytics_detail( - &state, - &username, - "user", - detail.trim_start_matches("/analytics/user/"), - &query, - &request_id, - ) - .await + if let Some(response) = analytics_query_error(&query, false, &request_id) { + response + } else { + analytics_detail( + &state, + &username, + "user", + detail.trim_start_matches("/analytics/user/"), + &query, + &request_id, + ) + .await + } } (Method::GET, "/security/settings") => { if !has_permission(&state, &username, "manage_security").await { @@ -649,7 +672,11 @@ pub async fn platform_dispatch( "You do not have permission to use tools", &request_id, ) - } else if let Some(backend) = payload.get("backend").and_then(Value::as_str) { + } else { + let (backend, enabled, duration_ms) = match normalize_chaos_toggle(&payload) { + Ok(values) => values, + Err(errors) => return validation_errors(errors, &request_id), + }; let backend = backend.trim().to_ascii_lowercase(); let target = match backend.as_str() { "redis" => &CHAOS_REDIS_OUTAGE, @@ -663,24 +690,11 @@ pub async fn platform_dispatch( ); } }; - let Some(enabled) = payload.get("enabled").and_then(Value::as_bool) else { - return validation_errors( - vec![json!({ - "loc": ["body", "enabled"], - "msg": "field required", - "type": "value_error.missing" - })], - &request_id, - ); - }; - let duration_ms = payload - .get("duration_ms") - .and_then(Value::as_u64) - .unwrap_or(0); if duration_ms > 0 { target.store(true, std::sync::atomic::Ordering::Relaxed); tokio::spawn(async move { - tokio::time::sleep(std::time::Duration::from_millis(duration_ms)).await; + tokio::time::sleep(std::time::Duration::from_millis(duration_ms as u64)) + .await; target.store(false, std::sync::atomic::Ordering::Relaxed); }); } else { @@ -694,32 +708,6 @@ pub async fn platform_dispatch( }), &request_id, ) - } else { - // Retain the additive v2 latency/error injection extension. - let enabled = payload - .get("enabled") - .and_then(Value::as_bool) - .unwrap_or(false); - let latency = payload - .get("latency_ms") - .and_then(Value::as_u64) - .unwrap_or(0); - let error_status = payload - .get("error_status") - .and_then(Value::as_u64) - .unwrap_or(0) as u32; - CHAOS_ENABLED.store(enabled, std::sync::atomic::Ordering::Relaxed); - CHAOS_LATENCY_MS.store(latency, std::sync::atomic::Ordering::Relaxed); - CHAOS_ERROR_STATUS.store(error_status, std::sync::atomic::Ordering::Relaxed); - success( - StatusCode::OK, - json!({ - "enabled": enabled, - "latency_ms": latency, - "error_status": error_status - }), - &request_id, - ) } } (Method::GET, "/tools/chaos/stats") => { @@ -736,11 +724,7 @@ pub async fn platform_dispatch( json!({ "redis_outage": CHAOS_REDIS_OUTAGE.load(std::sync::atomic::Ordering::Relaxed), "mongo_outage": CHAOS_MONGO_OUTAGE.load(std::sync::atomic::Ordering::Relaxed), - "error_budget_burn": CHAOS_ERROR_BUDGET_BURN.load(std::sync::atomic::Ordering::Relaxed), - "enabled": CHAOS_ENABLED.load(std::sync::atomic::Ordering::Relaxed), - "latency_ms": CHAOS_LATENCY_MS.load(std::sync::atomic::Ordering::Relaxed), - "error_status": CHAOS_ERROR_STATUS.load(std::sync::atomic::Ordering::Relaxed), - "events": CHAOS_EVENTS_COUNT.load(std::sync::atomic::Ordering::Relaxed) + "error_budget_burn": CHAOS_ERROR_BUDGET_BURN.load(std::sync::atomic::Ordering::Relaxed) }), &request_id, ) @@ -788,7 +772,16 @@ pub async fn platform_dispatch( if path.starts_with("/subscription") { subscription_routes(&state, path, &method, payload, &username, &request_id).await } else if path.starts_with("/credit") { - credit_routes(&state, path, &method, payload, &username, &request_id).await + credit_routes( + &state, + path, + &method, + payload, + &query, + &username, + &request_id, + ) + .await } else if path.starts_with("/vault") { vault_routes(&state, path, &method, payload, &username, &request_id).await } else if path.starts_with("/quota") { @@ -887,10 +880,11 @@ async fn dispatch_core_entities( let suffix = path.trim_start_matches("/tiers").trim_matches('/'); let basic = suffix.is_empty() || (!suffix.contains('/') - && !matches!( - suffix, - "upgrade" | "downgrade" | "temporary-upgrade" | "compare" | "assignments" - )); + && (method == Method::GET + || !matches!( + suffix, + "upgrade" | "downgrade" | "temporary-upgrade" | "compare" | "assignments" + ))); if basic { return Some( tier_crud_routes(state, path, method, payload, query, username, request_id).await, @@ -945,8 +939,8 @@ async fn dispatch_core_entities( created: "Role created successfully", updated: "Role updated successfully", deleted: "Role deleted successfully", - duplicate_code: "ROL001", - not_found_code: "ROL002", + duplicate_code: "ROLE001", + not_found_code: "ROLE004", }, ), ( @@ -1011,20 +1005,25 @@ async fn dispatch_core_entities( None } +fn tier_route_is_public(path: &str, method: &Method) -> bool { + if !(path == "/tiers" || path == "/tiers/" || path.starts_with("/tiers/")) { + return false; + } + let suffix = path.trim_start_matches("/tiers").trim_matches('/'); + if method == Method::GET + && (suffix.is_empty() || suffix == "statistics/all" || suffix.ends_with("/statistics")) + { + return false; + } + true +} + async fn tier_delete_route( state: &AppState, tier_id: &str, - username: &str, + _username: &str, request_id: &str, ) -> Response { - if !has_permission(state, username, "manage_tiers").await { - return error( - StatusCode::FORBIDDEN, - "TIER001", - "You do not have permission to manage tiers", - request_id, - ); - } let Some(storage) = &state.storage else { return unexpected(request_id); }; @@ -1065,7 +1064,11 @@ async fn tier_crud_routes( username: &str, request_id: &str, ) -> Response { - if !has_permission(state, username, "manage_tiers").await { + let suffix = path.trim_start_matches("/tiers").trim_matches('/'); + if suffix.is_empty() + && method == Method::GET + && !has_permission(state, username, "manage_tiers").await + { return error( StatusCode::FORBIDDEN, "TIER001", @@ -1076,7 +1079,6 @@ async fn tier_crud_routes( let Some(storage) = &state.storage else { return unexpected(request_id); }; - let suffix = path.trim_start_matches("/tiers").trim_matches('/'); if suffix.is_empty() && method == Method::GET { let skip = match tier_pagination(query, "skip", 0, 0, usize::MAX) { Ok(value) => value, @@ -1342,7 +1344,10 @@ async fn tier_management_routes( username: &str, request_id: &str, ) -> Response { - if !has_permission(state, username, "manage_tiers").await { + let suffix = path.trim_start_matches("/tiers/"); + let protected_statistics = + method == Method::GET && (suffix == "statistics/all" || suffix.ends_with("/statistics")); + if protected_statistics && !has_permission(state, username, "manage_tiers").await { return error( StatusCode::FORBIDDEN, "TIER001", @@ -1353,7 +1358,6 @@ async fn tier_management_routes( let Some(storage) = &state.storage else { return unexpected(request_id); }; - let suffix = path.trim_start_matches("/tiers/"); if suffix == "assignments" && method == Method::GET { let items = storage .find_many("user_tier_assignments", &json!({})) @@ -1819,7 +1823,7 @@ async fn tier_management_routes( } Err(_) => return unexpected(request_id), }; - let _ = tier; + let notification_effective_from = effective_from.clone(); return match replace_tier_assignment( storage, user_id, @@ -1834,7 +1838,17 @@ async fn tier_management_routes( ) .await { - Ok(assignment) => success(StatusCode::OK, assignment, request_id), + Ok(assignment) => { + send_tier_notification( + suffix, + user_id, + &tier, + ¬ification_effective_from, + &payload, + ) + .await; + success(StatusCode::OK, assignment, request_id) + } Err(_) => unexpected(request_id), }; } @@ -1846,6 +1860,62 @@ async fn tier_management_routes( ) } +async fn send_tier_notification( + action: &str, + user_id: &str, + tier: &Value, + effective_from: &Value, + payload: &Value, +) { + let display_name = tier + .get("display_name") + .and_then(Value::as_str) + .unwrap_or_default(); + let effective = effective_from.as_str().unwrap_or_default(); + let recipient = format!("{user_id}@example.com"); + let (subject, body) = match action { + "upgrade" => ( + "Tier Upgrade Notification", + format!("You have been upgraded to the {display_name} plan.\nEffective: {effective}"), + ), + "downgrade" => ( + "Tier Downgrade Notification", + format!("You have been downgraded to the {display_name} plan.\nEffective: {effective}"), + ), + "temporary-upgrade" | "trial/start" => { + let days = payload + .get(if action == "temporary-upgrade" { + "duration_days" + } else { + "days" + }) + .and_then(Value::as_i64) + .unwrap_or(if action == "temporary-upgrade" { 0 } else { 14 }); + ( + "Trial Activated", + format!("You have been given a temporary trial of {display_name} for {days} days."), + ) + } + "payment/failure" => ( + "Tier Downgrade Notification", + format!("You have been downgraded to the {display_name} plan.\nEffective: {effective}"), + ), + _ => return, + }; + crate::observability::email::send_email(&recipient, subject, &body, None).await; + if action == "payment/failure" { + crate::observability::email::send_email( + &recipient, + "Payment Failure - Account Downgraded", + &format!( + "We could not process your payment. Your account has been downgraded to {display_name}." + ), + None, + ) + .await; + } +} + async fn tier_action_current_tier_id( storage: &SharedStorage, user_id: &str, @@ -1973,7 +2043,7 @@ async fn rate_limit_management_routes( }; let enabled = rules .iter() - .filter(|rule| rule.get("enabled").and_then(Value::as_bool).unwrap_or(true)) + .filter(|rule| rule.get("enabled").and_then(Value::as_bool) == Some(true)) .count(); let rule_types = [ "per_user", @@ -2061,22 +2131,21 @@ async fn rate_limit_management_routes( .ok() .flatten() else { - return error( - StatusCode::NOT_FOUND, - "RATE404", - "Rule not found", + return http_detail( + StatusCode::BAD_REQUEST, + &format!("Source rule {id} not found"), request_id, ); }; let Some(new_rule_id) = payload .get("new_rule_id") - .and_then(Value::as_str) + .and_then(security_setting_string) .filter(|value| !value.is_empty()) else { - return validation_errors( - vec![ - json!({"loc": ["body", "new_rule_id"], "msg": "field required", "type": "value_error.missing"}), - ], + return rate_rule_validation( + "new_rule_id", + "field required", + "value_error.missing", request_id, ); }; @@ -2129,11 +2198,25 @@ async fn rate_limit_crud_routes( if suffix.is_empty() && method == Method::GET { let skip = match tier_pagination(query, "skip", 0, 0, usize::MAX) { Ok(value) => value, - Err(()) => return tier_pagination_error("skip", request_id), + Err(()) => { + return rate_rule_validation( + "skip", + "value is not valid", + "value_error", + request_id, + ); + } }; let limit = match tier_pagination(query, "limit", 100, 1, 1_000) { Ok(value) => value, - Err(()) => return tier_pagination_error("limit", request_id), + Err(()) => { + return rate_rule_validation( + "limit", + "value is not valid", + "value_error", + request_id, + ); + } }; let rule_type = query.get("rule_type").map(String::as_str); if rule_type.is_some_and(|rule_type| { @@ -2154,9 +2237,20 @@ async fn rate_limit_crud_routes( request_id, ); } - let enabled_only = query - .get("enabled_only") - .is_some_and(|value| value.eq_ignore_ascii_case("true")); + let enabled_only = match query.get("enabled_only") { + Some(value) => match security_setting_bool(&json!(value)) { + Some(value) => value, + None => { + return rate_rule_validation( + "enabled_only", + "value could not be parsed to a boolean", + "type_error.bool", + request_id, + ); + } + }, + None => false, + }; let mut rules = match storage.find_many("rate_limit_rules", &json!({})).await { Ok(rules) => rules, Err(_) => return unexpected(request_id), @@ -2178,6 +2272,14 @@ async fn rate_limit_crud_routes( return success(StatusCode::OK, json!(rules), request_id); } if suffix.is_empty() && method == Method::POST { + if !payload.is_object() { + return rate_rule_validation( + "body", + "value is not a valid dict", + "type_error.dict", + request_id, + ); + } let Some(rule_id) = payload .get("rule_id") .and_then(security_setting_string) @@ -2388,6 +2490,14 @@ async fn rate_limit_crud_routes( }; } if method == Method::PUT { + if !payload.is_object() { + return rate_rule_validation( + "body", + "value is not a valid dict", + "type_error.dict", + request_id, + ); + } let mut updates = Value::Object(Map::new()); if let Some(value) = payload.get("limit").filter(|value| !value.is_null()) { let Some(value) = rate_rule_integer(value).filter(|value| *value > 0) else { @@ -2590,7 +2700,7 @@ async fn entity_routes( } } if method == Method::GET && (suffix.is_empty() || suffix == "all") { - if !has_permission(state, username, spec.permission).await { + if spec.collection != "roles" && !has_permission(state, username, spec.permission).await { return error( StatusCode::FORBIDDEN, spec.permission_code, @@ -2598,21 +2708,77 @@ async fn entity_routes( request_id, ); } - if let Err(message_text) = validate_pagination(query) { - return error(StatusCode::BAD_REQUEST, "PAG001", message_text, request_id); + if spec.collection != "roles" + && let Err(message_text) = validate_pagination(query) + { + return error(StatusCode::BAD_REQUEST, "PAG001", &message_text, request_id); } - let items = match storage.find_many(spec.collection, &json!({})).await { + let mut items = match storage.find_many(spec.collection, &json!({})).await { Ok(items) => items.into_iter().map(strip_internal).collect::>(), Err(_) => return unexpected(request_id), }; - let items = if spec.collection == "roles" && !is_admin_user(state, username).await { - items - .into_iter() - .filter(|role| role.get("role_name").and_then(Value::as_str) != Some("admin")) - .collect() - } else { - items - }; + if spec.collection == "roles" { + items.sort_by_key(|role| { + role.get("role_name") + .and_then(Value::as_str) + .unwrap_or_default() + .to_owned() + }); + let page = query + .get("page") + .and_then(|value| value.parse::().ok()) + .unwrap_or(1); + let page_size = query + .get("page_size") + .and_then(|value| value.parse::().ok()) + .unwrap_or(10); + let maximum = env::var("MAX_PAGE_SIZE") + .ok() + .and_then(|value| value.parse::().ok()) + .filter(|value| *value > 0) + .unwrap_or(200); + if page == 0 || page_size == 0 { + return error( + StatusCode::BAD_REQUEST, + "PAG001", + "Invalid page or page size", + request_id, + ); + } + if page_size > maximum { + return error( + StatusCode::BAD_REQUEST, + "PAG001", + "Page size exceeds maximum limit", + request_id, + ); + } + let total = items.len(); + let start = (page - 1).saturating_mul(page_size); + items = items.into_iter().skip(start).take(page_size).collect(); + if !is_admin_user(state, username).await { + let mut visible = Vec::new(); + for mut role in items { + let role_name = role + .get("role_name") + .and_then(Value::as_str) + .unwrap_or_default(); + if is_admin_role(state, role_name).await { + continue; + } + role.as_object_mut() + .map(|role| role.remove("platform_admin")); + visible.push(role); + } + items = visible; + } + return success( + StatusCode::OK, + json!({"roles": items, "page": page, "page_size": page_size, + "has_next": total > start.saturating_add(page_size), "total": total}), + request_id, + ); + } let payload = match spec.list_key { Some(list_key) => paginate_named(items, query, list_key), None => paginate(items, query), @@ -2628,7 +2794,11 @@ async fn entity_routes( } else { spec.permission_code }, - "Insufficient permissions", + if spec.collection == "roles" { + "You do not have permission to create roles" + } else { + "Insufficient permissions" + }, request_id, ); } @@ -2647,11 +2817,17 @@ async fn entity_routes( request_id, ); }; - if spec.collection == "roles" && key == "admin" && !is_admin_user(state, username).await { + if spec.collection == "roles" + && matches!( + key.trim().to_ascii_lowercase().as_str(), + "admin" | "platform admin" + ) + && !is_admin_user(state, username).await + { return error( StatusCode::FORBIDDEN, - "ROLE009", - "Only an administrator can create the administrator role", + "ROLE013", + "Only admin may create the admin role", request_id, ); } @@ -2664,17 +2840,11 @@ async fn entity_routes( return error( StatusCode::BAD_REQUEST, spec.duplicate_code, - "Resource already exists", - request_id, - ); - } - if spec.collection == "roles" - && !role_permissions_within_actor(state, username, &payload).await - { - return error( - StatusCode::FORBIDDEN, - "ROLE009", - "Roles cannot grant permissions you do not hold", + if spec.collection == "roles" { + "Role already exists" + } else { + "Resource already exists" + }, request_id, ); } @@ -2708,7 +2878,11 @@ async fn entity_routes( Err(duplicate_error) if duplicate_error.is_duplicate_key() => error( StatusCode::BAD_REQUEST, spec.duplicate_code, - "Resource already exists", + if spec.collection == "roles" { + "Role already exists" + } else { + "Resource already exists" + }, request_id, ), Err(_) => unexpected(request_id), @@ -2725,7 +2899,7 @@ async fn entity_routes( } let filter = json!({spec.key: key}); if method == Method::GET { - if !has_permission(state, username, spec.permission).await { + if spec.collection != "roles" && !has_permission(state, username, spec.permission).await { return error( StatusCode::FORBIDDEN, if spec.collection == "routings" { @@ -2737,20 +2911,32 @@ async fn entity_routes( request_id, ); } - if spec.collection == "roles" && key == "admin" && !is_admin_user(state, username).await { - return error( + if spec.collection == "roles" + && is_admin_role(state, key).await + && !is_admin_user(state, username).await + { + return json_response( StatusCode::NOT_FOUND, - spec.not_found_code, - "Resource not found", + json!({"error_message": "Role not found"}), request_id, ); } return match storage.find_one(spec.collection, &filter).await { - Ok(Some(item)) => success(StatusCode::OK, strip_internal(item), request_id), + Ok(Some(mut item)) => { + if spec.collection == "roles" && !is_admin_user(state, username).await { + item.as_object_mut() + .map(|role| role.remove("platform_admin")); + } + success(StatusCode::OK, strip_internal(item), request_id) + } Ok(None) => error( StatusCode::NOT_FOUND, spec.not_found_code, - "Resource not found", + if spec.collection == "roles" { + "Role does not exist" + } else { + "Resource not found" + }, request_id, ), Err(_) => unexpected(request_id), @@ -2765,44 +2951,55 @@ async fn entity_routes( } else { "RTG011" } + } else if spec.collection == "roles" { + if method == Method::PUT { + "ROLE010" + } else { + "ROLE011" + } } else { "AUTH006" }, - "Insufficient permissions", + if spec.collection == "roles" { + if method == Method::PUT { + "You do not have permission to update roles" + } else { + "You do not have permission to delete roles" + } + } else { + "Insufficient permissions" + }, request_id, ); } if spec.collection == "roles" { - let existing = match storage.find_one(spec.collection, &filter).await { - Ok(Some(role)) => role, + match storage.find_one(spec.collection, &filter).await { + Ok(Some(_)) => {} Ok(None) => { return error( - StatusCode::NOT_FOUND, + StatusCode::BAD_REQUEST, spec.not_found_code, - "Resource not found", + "Role does not exist", request_id, ); } Err(_) => return unexpected(request_id), - }; - let actor_is_admin = is_admin_user(state, username).await; - let bootstrap_admin_restores_manage_users = key == "admin" - && actor_is_admin - && payload.as_object().is_some_and(|updates| { - updates.len() == 1 - && updates.get("manage_users").and_then(Value::as_bool) == Some(true) - }); - let actor_can_modify = actor_is_admin - || bootstrap_admin_restores_manage_users - || (role_permissions_within_actor(state, username, &existing).await - && role_permissions_within_actor(state, username, &payload).await); - if (key == "admin" && !actor_is_admin) || !actor_can_modify { + } + if is_admin_role(state, key).await && !is_admin_user(state, username).await { return error( StatusCode::FORBIDDEN, - "ROLE009", - "Roles cannot grant or modify permissions you do not hold", - request_id, - ); + if method == Method::PUT { + "ROLE014" + } else { + "ROLE016" + }, + if method == Method::PUT { + "Only admin may modify the admin role" + } else { + "Only admin may delete the admin role" + }, + request_id, + ); } } if method == Method::PUT { @@ -2849,8 +3046,16 @@ async fn entity_routes( { return error( StatusCode::BAD_REQUEST, - "VAL001", - "Resource identifier cannot be updated", + if spec.collection == "roles" { + "ROLE005" + } else { + "VAL001" + }, + if spec.collection == "roles" { + "Role name cannot be changed" + } else { + "Resource identifier cannot be updated" + }, request_id, ); } @@ -2878,40 +3083,24 @@ async fn entity_routes( } } Ok(None) => error( - StatusCode::NOT_FOUND, + if spec.collection == "roles" { + StatusCode::BAD_REQUEST + } else { + StatusCode::NOT_FOUND + }, spec.not_found_code, - "Resource not found", + if spec.collection == "roles" { + "Role does not exist" + } else { + "Resource not found" + }, request_id, ), Err(_) => unexpected(request_id), }; } if method == Method::DELETE { - if spec.collection == "roles" { - let existing = match storage.find_one(spec.collection, &filter).await { - Ok(Some(role)) => role, - Ok(None) => { - return error( - StatusCode::NOT_FOUND, - spec.not_found_code, - "Resource not found", - request_id, - ); - } - Err(_) => return unexpected(request_id), - }; - if !role_permissions_within_actor(state, username, &existing).await { - return error( - StatusCode::FORBIDDEN, - "ROLE009", - "Roles cannot be deleted when they include permissions you do not hold", - request_id, - ); - } - } - if (spec.collection == "roles" || spec.collection == "groups") - && (key == "admin" || key == "ALL") - { + if spec.collection == "groups" && key == "ALL" { return error( StatusCode::BAD_REQUEST, "AUTH900", @@ -2930,9 +3119,17 @@ async fn entity_routes( message(StatusCode::OK, spec.deleted, request_id) } Ok(false) => error( - StatusCode::NOT_FOUND, + if spec.collection == "roles" { + StatusCode::BAD_REQUEST + } else { + StatusCode::NOT_FOUND + }, spec.not_found_code, - "Resource not found", + if spec.collection == "roles" { + "Role does not exist" + } else { + "Resource not found" + }, request_id, ), Err(_) => unexpected(request_id), @@ -2977,16 +3174,8 @@ async fn api_routes( }; let suffix = path.strip_prefix("/api").unwrap_or("").trim_matches('/'); if method == Method::GET && (suffix.is_empty() || suffix == "all") { - if !has_permission(state, username, "manage_apis").await { - return error( - StatusCode::FORBIDDEN, - "API008", - "You do not have permission to view APIs", - request_id, - ); - } if let Err(message_text) = validate_pagination(query) { - return error(StatusCode::BAD_REQUEST, "PAG001", message_text, request_id); + return error(StatusCode::BAD_REQUEST, "PAG001", &message_text, request_id); } return match storage.find_many("apis", &json!({})).await { Ok(items) => success( @@ -3099,18 +3288,10 @@ async fn api_routes( } let filter = json!({"api_name": parts[0], "api_version": parts[1]}); if method == Method::GET { - if !has_permission(state, username, "manage_apis").await { - return error( - StatusCode::FORBIDDEN, - "API008", - "You do not have permission to view APIs", - request_id, - ); - } return match storage.find_one("apis", &filter).await { Ok(Some(api)) => success(StatusCode::OK, strip_internal(api), request_id), Ok(None) => error( - StatusCode::NOT_FOUND, + StatusCode::BAD_REQUEST, "API003", "API does not exist for the requested name and version", request_id, @@ -3118,15 +3299,15 @@ async fn api_routes( Err(_) => unexpected(request_id), }; } - if !has_permission(state, username, "manage_apis").await { - return error( - StatusCode::FORBIDDEN, - "API008", - "You do not have permission to update APIs", - request_id, - ); - } if method == Method::PUT { + if !has_permission(state, username, "manage_apis").await { + return error( + StatusCode::FORBIDDEN, + "API008", + "You do not have permission to update APIs", + request_id, + ); + } payload = match normalize_update_api(&payload) { Ok(payload) => payload, Err(errors) => return validation_errors(errors, request_id), @@ -3267,16 +3448,8 @@ async fn user_routes( .unwrap_or("") .trim_matches('/'); if method == Method::GET && (suffix.is_empty() || suffix == "all") { - if !has_permission(state, active_user, "manage_users").await { - return error( - StatusCode::FORBIDDEN, - "USR008", - "Unable to retrieve users", - request_id, - ); - } if let Err(message_text) = validate_pagination(query) { - return error(StatusCode::BAD_REQUEST, "PAG001", message_text, request_id); + return error(StatusCode::BAD_REQUEST, "PAG001", &message_text, request_id); } return match storage.find_many("users", &json!({})).await { Ok(items) => { @@ -3315,7 +3488,7 @@ async fn user_routes( return error( StatusCode::FORBIDDEN, "USR006", - "You do not have permission to create users", + "Can only update your own information", request_id, ); } @@ -3333,15 +3506,19 @@ async fn user_routes( if method == Method::GET { return user_by(state, "username", target, active_user, request_id).await; } - if active_user != target && !has_permission(state, active_user, "manage_users").await { - return error( - StatusCode::FORBIDDEN, - "USR008", - "Unable to update user", - request_id, - ); - } if method == Method::PUT { + if active_user != target && !has_permission(state, active_user, "manage_users").await { + return error( + StatusCode::FORBIDDEN, + "USR006", + if suffix.ends_with("/update-password") { + "Can only update your own password" + } else { + "Can only update your own information" + }, + request_id, + ); + } if !suffix.ends_with("/update-password") && normalize_update_user_model(&mut payload).is_err() { @@ -3356,7 +3533,7 @@ async fn user_routes( return error( StatusCode::FORBIDDEN, "USR022", - "Super admin password cannot be changed via the API", + "Super admin password cannot be changed via UI", request_id, ); } @@ -3399,8 +3576,8 @@ async fn user_routes( { return error( StatusCode::FORBIDDEN, - "USR008", - "Only an administrator can modify an administrator account", + "USR012", + "Only admin may modify admin users", request_id, ); } @@ -3423,7 +3600,7 @@ async fn user_routes( return error( StatusCode::FORBIDDEN, "USR013", - "Only an administrator can assign the administrator role", + "Only admin may change admin role assignments", request_id, ); } @@ -3489,15 +3666,7 @@ async fn user_routes( target, "success", ); - message( - StatusCode::OK, - if password_update { - "Password updated successfully" - } else { - "User updated successfully" - }, - request_id, - ) + message(StatusCode::OK, "User updated successfully", request_id) } Ok(None) => error( StatusCode::NOT_FOUND, @@ -3509,6 +3678,22 @@ async fn user_routes( }; } if method == Method::DELETE { + if target == "admin" { + return error( + StatusCode::FORBIDDEN, + "USR021", + "Super admin user cannot be deleted", + request_id, + ); + } + if active_user != target && !has_permission(state, active_user, "manage_users").await { + return error( + StatusCode::FORBIDDEN, + "USR007", + "Can only delete your own account", + request_id, + ); + } let existing = match storage .find_one("users", &json!({"username": target})) .await @@ -3529,16 +3714,8 @@ async fn user_routes( { return error( StatusCode::FORBIDDEN, - "USR008", - "Only an administrator can delete an administrator account", - request_id, - ); - } - if target == "admin" { - return error( - StatusCode::FORBIDDEN, - "USR021", - "Super admin user cannot be deleted", + "USR014", + "Only admin may delete admin users", request_id, ); } @@ -3653,6 +3830,30 @@ async fn endpoint_routes( .strip_prefix("endpoint/validation/") .or_else(|| suffix.strip_prefix("validation/")); if let Some(endpoint_id) = validation_suffix { + if method == Method::PUT + && normalize_endpoint_validation_model(&mut payload, false).is_err() + { + return error( + StatusCode::UNPROCESSABLE_ENTITY, + "VAL001", + "Validation Error", + request_id, + ); + } + if method != Method::GET && !has_permission(state, username, "manage_endpoints").await { + let (code, text) = if method == Method::PUT { + ( + "END014", + "You do not have permission to update endpoint validations", + ) + } else { + ( + "END015", + "You do not have permission to delete endpoint validations", + ) + }; + return error(StatusCode::FORBIDDEN, code, text, request_id); + } let filter = json!({"endpoint_id": endpoint_id}); return document_by_method( state, @@ -3668,11 +3869,19 @@ async fn endpoint_routes( .await; } if (suffix == "endpoint/validation" || suffix == "validation") && method == Method::POST { + if normalize_endpoint_validation_model(&mut payload, true).is_err() { + return error( + StatusCode::UNPROCESSABLE_ENTITY, + "VAL001", + "Validation Error", + request_id, + ); + } if !has_permission(state, username, "manage_endpoints").await { return error( StatusCode::FORBIDDEN, - "END010", - "Insufficient permissions", + "END013", + "You do not have permission to create endpoint validations", request_id, ); } @@ -3820,16 +4029,8 @@ async fn endpoint_routes( } let parts = suffix.split('/').collect::>(); if method == Method::GET && parts.len() == 2 { - if !has_permission(state, username, "manage_endpoints").await { - return error( - StatusCode::FORBIDDEN, - "END010", - "You do not have permission to view endpoints", - request_id, - ); - } if let Err(message_text) = validate_pagination(query) { - return error(StatusCode::BAD_REQUEST, "PAG001", message_text, request_id); + return error(StatusCode::BAD_REQUEST, "PAG001", &message_text, request_id); } return match storage .find_many( @@ -3838,6 +4039,12 @@ async fn endpoint_routes( ) .await { + Ok(items) if items.is_empty() => error( + StatusCode::BAD_REQUEST, + "END005", + "No endpoints found for the requested API name and version", + request_id, + ), Ok(items) => success( StatusCode::OK, paginate(items.into_iter().map(strip_internal).collect(), query), @@ -3858,6 +4065,14 @@ async fn endpoint_routes( let uri = format!("/{}", parts[3..].join("/")); let filter = json!({"endpoint_method": parts[0], "api_name": parts[1], "api_version": parts[2], "endpoint_uri": uri}); if method == Method::PUT { + if !has_permission(state, username, "manage_endpoints").await { + return error( + StatusCode::FORBIDDEN, + "END011", + "You do not have permission to update endpoints", + request_id, + ); + } let existing = match storage.find_one("endpoints", &filter).await { Ok(Some(endpoint)) => endpoint, Ok(None) => { @@ -3963,6 +4178,18 @@ async fn endpoint_routes( Err(_) => unexpected(request_id), }; } + if method == Method::GET { + return match storage.find_one("endpoints", &filter).await { + Ok(Some(endpoint)) => success(StatusCode::OK, strip_internal(endpoint), request_id), + Ok(None) => error( + StatusCode::BAD_REQUEST, + "END004", + "Endpoint does not exist for the requested API name, version and URI", + request_id, + ), + Err(_) => unexpected(request_id), + }; + } return document_by_method( state, "endpoints", @@ -4389,7 +4616,7 @@ fn normalize_role_model(payload: &mut Value, create: bool) -> Result<(), ()> { .get("role_name") .and_then(security_setting_string) .ok_or(())?; - if value.is_empty() || value.len() > 50 { + if value.is_empty() || value.chars().count() > 50 { return Err(()); } object.insert("role_name".to_owned(), json!(value)); @@ -4397,7 +4624,7 @@ fn normalize_role_model(payload: &mut Value, create: bool) -> Result<(), ()> { match object.get("role_description") { Some(value) if !value.is_null() => { let value = security_setting_string(value).ok_or(())?; - if value.len() > 255 || (!create && value.is_empty()) { + if value.chars().count() > 255 || (!create && value.is_empty()) { return Err(()); } object.insert("role_description".to_owned(), json!(value)); @@ -4427,7 +4654,7 @@ fn normalize_group_model(payload: &mut Value, create: bool) -> Result<(), ()> { .get("group_name") .and_then(security_setting_string) .ok_or(())?; - if value.is_empty() || value.len() > 50 { + if value.is_empty() || value.chars().count() > 50 { return Err(()); } object.insert("group_name".to_owned(), json!(value)); @@ -4435,7 +4662,7 @@ fn normalize_group_model(payload: &mut Value, create: bool) -> Result<(), ()> { match object.get("group_description") { Some(value) if !value.is_null() => { let value = security_setting_string(value).ok_or(())?; - if value.len() > 255 || (!create && value.is_empty()) { + if value.chars().count() > 255 || (!create && value.is_empty()) { return Err(()); } object.insert("group_description".to_owned(), json!(value)); @@ -4495,7 +4722,7 @@ fn normalize_routing_model(payload: &mut Value, create: bool) -> Result<(), ()> return Err(()); } let value = security_setting_string(value).ok_or(())?; - if value.is_empty() || value.len() > 50 { + if value.is_empty() || value.chars().count() > 50 { return Err(()); } object.insert(field.to_owned(), json!(value)); @@ -4522,7 +4749,7 @@ fn normalize_routing_model(payload: &mut Value, create: bool) -> Result<(), ()> match object.get("routing_description") { Some(value) if !value.is_null() => { let value = security_setting_string(value).ok_or(())?; - if value.len() > 255 { + if value.chars().count() > 255 { return Err(()); } object.insert("routing_description".to_owned(), json!(value)); @@ -4569,7 +4796,7 @@ fn normalize_endpoint_model(payload: &mut Value, create: bool) -> Result<(), ()> | "endpoint_id" ) && (create || !value.is_null()) }); - for (field, minimum, maximum) in [ + for (field, configured_minimum, configured_maximum) in [ ("api_name", 1, 50), ("api_version", 1, 10), ("endpoint_method", 1, 10), @@ -4579,6 +4806,11 @@ fn normalize_endpoint_model(payload: &mut Value, create: bool) -> Result<(), ()> ("api_id", 1, 255), ("endpoint_id", 1, 255), ] { + let (minimum, maximum) = if create && matches!(field, "api_id" | "endpoint_id") { + (0, usize::MAX) + } else { + (configured_minimum, configured_maximum) + }; if let Some(value) = object.get(field) { if value.is_null() { if create && matches!(field, "client_uri" | "api_id" | "endpoint_id") { @@ -4587,7 +4819,8 @@ fn normalize_endpoint_model(payload: &mut Value, create: bool) -> Result<(), ()> return Err(()); } let value = security_setting_string(value).ok_or(())?; - if value.len() < minimum || value.len() > maximum { + let length = value.chars().count(); + if length < minimum || length > maximum { return Err(()); } object.insert(field.to_owned(), json!(value)); @@ -4614,6 +4847,118 @@ fn normalize_endpoint_model(payload: &mut Value, create: bool) -> Result<(), ()> Ok(()) } +fn normalize_endpoint_validation_model(payload: &mut Value, create: bool) -> Result<(), ()> { + let object = payload.as_object_mut().ok_or(())?; + object.retain(|field, _| { + matches!( + field.as_str(), + "endpoint_id" | "validation_enabled" | "validation_schema" + ) && (create || field != "endpoint_id") + }); + if create { + let endpoint_id = object + .get("endpoint_id") + .and_then(security_setting_string) + .ok_or(())?; + object.insert("endpoint_id".to_owned(), json!(endpoint_id)); + } + let enabled = object + .get("validation_enabled") + .and_then(security_setting_bool) + .ok_or(())?; + object.insert("validation_enabled".to_owned(), json!(enabled)); + let schema = object + .get("validation_schema") + .and_then(normalize_validation_schema_model) + .ok_or(())?; + object.insert("validation_schema".to_owned(), schema); + Ok(()) +} + +fn normalize_validation_schema_model(value: &Value) -> Option { + let rules = value.as_object()?.get("validation_schema")?.as_object()?; + let mut normalized = Map::new(); + for (path, rule) in rules { + normalized.insert(path.clone(), normalize_field_validation_model(rule)?); + } + Some(json!({"validation_schema": normalized})) +} + +fn normalize_field_validation_model(value: &Value) -> Option { + let input = value.as_object()?; + let mut output = Map::new(); + output.insert( + "required".to_owned(), + json!(security_setting_bool(input.get("required")?)?), + ); + output.insert( + "type".to_owned(), + json!(security_setting_string(input.get("type")?)?), + ); + for field in ["min", "max"] { + let value = match input.get(field) { + Some(Value::Null) | None => Value::Null, + Some(value) => validation_model_number(value)?, + }; + output.insert(field.to_owned(), value); + } + for field in ["pattern", "format", "custom_validator"] { + let value = match input.get(field) { + Some(Value::Null) | None => Value::Null, + Some(value) => Value::String(security_setting_string(value)?), + }; + output.insert(field.to_owned(), value); + } + let enum_values = match input.get("enum") { + Some(Value::Null) | None => Value::Null, + Some(Value::Array(values)) => Value::Array(values.clone()), + Some(_) => return None, + }; + output.insert("enum".to_owned(), enum_values); + let nested = match input.get("nested_schema") { + Some(Value::Null) | None => Value::Null, + Some(Value::Object(fields)) => { + let mut normalized = Map::new(); + for (name, rules) in fields { + normalized.insert(name.clone(), normalize_field_validation_model(rules)?); + } + Value::Object(normalized) + } + Some(_) => return None, + }; + output.insert("nested_schema".to_owned(), nested); + let array_items = match input.get("array_items") { + Some(Value::Null) | None => Value::Null, + Some(value) => normalize_field_validation_model(value)?, + }; + output.insert("array_items".to_owned(), array_items); + Some(Value::Object(output)) +} + +fn validation_model_number(value: &Value) -> Option { + match value { + Value::Bool(value) => Some(json!(i64::from(*value))), + Value::Number(value) if value.is_i64() || value.is_u64() => { + Some(Value::Number(value.clone())) + } + Value::Number(value) => value + .as_f64() + .filter(|value| value.is_finite()) + .map(|value| json!(value as i64)), + Value::String(value) => crate::python_scalar::parse_model_integer(value) + .and_then(|value| i64::try_from(value).ok()) + .map(|value| json!(value)) + .or_else(|| { + value + .parse::() + .ok() + .filter(|value| value.is_finite()) + .map(|value| json!(value)) + }), + _ => None, + } +} + fn normalize_subscription_model(payload: &mut Value) -> Result<(), ()> { let object = payload.as_object_mut().ok_or(())?; object.retain(|field, _| matches!(field.as_str(), "username" | "api_name" | "api_version")); @@ -4626,7 +4971,8 @@ fn normalize_subscription_model(payload: &mut Value) -> Result<(), ()> { .get(field) .and_then(security_setting_string) .ok_or(())?; - if value.len() < minimum || value.len() > maximum { + let length = value.chars().count(); + if length < minimum || length > maximum { return Err(()); } object.insert(field.to_owned(), json!(value)); @@ -4652,7 +4998,7 @@ fn normalize_credit_model(payload: &mut Value, create: bool) -> Result<(), ()> { .get(field) .and_then(security_setting_string) .ok_or(())?; - if field == "api_credit_group" && (value.is_empty() || value.len() > 50) { + if field == "api_credit_group" && (value.is_empty() || value.chars().count() > 50) { return Err(()); } object.insert(field.to_owned(), json!(value)); @@ -4667,6 +5013,8 @@ fn normalize_credit_model(payload: &mut Value, create: bool) -> Result<(), ()> { } let value = security_setting_string(value).ok_or(())?; object.insert(field.to_owned(), json!(value)); + } else if create { + object.insert(field.to_owned(), Value::Null); } } let tiers = object @@ -4687,7 +5035,7 @@ fn normalize_credit_model(payload: &mut Value, create: bool) -> Result<(), ()> { .get(field) .and_then(security_setting_string) .ok_or(())?; - if field == "tier_name" && (value.is_empty() || value.len() > 50) { + if field == "tier_name" && (value.is_empty() || value.chars().count() > 50) { return Err(()); } tier.insert(field.to_owned(), json!(value)); @@ -4730,7 +5078,8 @@ fn normalize_user_credit_model(payload: &mut Value) -> Result<(), ()> { .get("username") .and_then(security_setting_string) .ok_or(())?; - if username.len() < 3 || username.len() > 50 { + let username_length = username.chars().count(); + if !(3..=50).contains(&username_length) { return Err(()); } object.insert("username".to_owned(), json!(username)); @@ -4750,7 +5099,7 @@ fn normalize_user_credit_model(payload: &mut Value) -> Result<(), ()> { .get("tier_name") .and_then(security_setting_string) .ok_or(())?; - if tier_name.is_empty() || tier_name.len() > 50 { + if tier_name.is_empty() || tier_name.chars().count() > 50 { return Err(()); } credit.insert("tier_name".to_owned(), json!(tier_name)); @@ -4767,6 +5116,9 @@ fn normalize_user_credit_model(payload: &mut Value) -> Result<(), ()> { let value = security_setting_string(value).ok_or(())?; credit.insert(field.to_owned(), json!(value)); } + if !credit.contains_key(field) { + credit.insert(field.to_owned(), Value::Null); + } } } Ok(()) @@ -4813,14 +5165,15 @@ fn normalize_create_user_model(payload: &mut Value) -> Result<(), ()> { .get(field) .and_then(security_setting_string) .ok_or(())?; - if value.len() < minimum || value.len() > maximum { + let length = value.chars().count(); + if length < minimum || length > maximum { return Err(()); } object.insert(field.to_owned(), json!(value)); } let groups = match object.get("groups") { - None | Some(Value::Null) => json!([]), + None => json!([]), Some(Value::Array(groups)) => Value::Array( groups .iter() @@ -4857,7 +5210,7 @@ fn normalize_create_user_model(payload: &mut Value) -> Result<(), ()> { ] { if let Some(value) = object.get(field).filter(|value| !value.is_null()) { let value = security_setting_string(value).ok_or(())?; - if value.is_empty() || value.len() > maximum { + if value.is_empty() || value.chars().count() > maximum { return Err(()); } object.insert(field.to_owned(), json!(value)); @@ -4866,6 +5219,30 @@ fn normalize_create_user_model(payload: &mut Value) -> Result<(), ()> { if !object.contains_key("bandwidth_limit_window") { object.insert("bandwidth_limit_window".to_owned(), json!("day")); } + for field in [ + "rate_limit_duration", + "rate_limit_duration_type", + "rate_limit_enabled", + "throttle_duration", + "throttle_duration_type", + "throttle_wait_duration", + "throttle_wait_duration_type", + "throttle_queue_limit", + "throttle_enabled", + "custom_attributes", + "bandwidth_limit_bytes", + "bandwidth_limit_enabled", + ] { + if !object.contains_key(field) { + object.insert(field.to_owned(), Value::Null); + } + } + if !object.contains_key("active") { + object.insert("active".to_owned(), json!(true)); + } + if !object.contains_key("ui_access") { + object.insert("ui_access".to_owned(), json!(false)); + } for field in [ "rate_limit_enabled", "throttle_enabled", @@ -4933,7 +5310,8 @@ fn normalize_update_user_model(payload: &mut Value) -> Result<(), ()> { ] { if let Some(value) = object.get(field) { let value = security_setting_string(value).ok_or(())?; - if value.len() < minimum || value.len() > maximum { + let length = value.chars().count(); + if length < minimum || length > maximum { return Err(()); } object.insert(field.to_owned(), json!(value)); @@ -4983,7 +5361,7 @@ fn normalize_update_user_model(payload: &mut Value) -> Result<(), ()> { ] { if let Some(value) = object.get(field) { let value = security_setting_string(value).ok_or(())?; - if value.is_empty() || value.len() > maximum { + if value.is_empty() || value.chars().count() > maximum { return Err(()); } object.insert(field.to_owned(), json!(value)); @@ -5015,6 +5393,23 @@ fn normalize_update_user_model(payload: &mut Value) -> Result<(), ()> { Ok(()) } +/// FastAPI validates UpdatePasswordModel before authentication and route +/// permissions. Pydantic v1 coerces JSON scalars to strings, ignores unknown +/// fields, and measures string bounds in Unicode characters. +fn normalize_update_password_model(payload: &mut Value) -> Result<(), ()> { + let object = payload.as_object_mut().ok_or(())?; + let password = object + .get("new_password") + .and_then(security_setting_string) + .ok_or(())?; + if !(6..=36).contains(&password.chars().count()) { + return Err(()); + } + object.clear(); + object.insert("new_password".to_owned(), json!(password)); + Ok(()) +} + async fn user_by( state: &AppState, field: &str, @@ -5189,7 +5584,11 @@ async fn authorization_routes( } } audit::management_mutation(username, "authorization.invalidate", username, "success"); - let mut response = message(StatusCode::OK, "Token invalidated successfully", request_id); + let mut response = message( + StatusCode::OK, + "Your token has been invalidated", + request_id, + ); response.headers_mut().append( header::SET_COOKIE, HeaderValue::from_static("access_token_cookie=; Path=/; Max-Age=0; HttpOnly"), @@ -5200,37 +5599,31 @@ async fn authorization_routes( .trim_start_matches("/authorization/admin/") .split('/') .collect::>(); - if parts.len() == 2 && has_permission(state, username, "manage_auth").await { + let admin_action = parts.len() == 2 + && matches!( + (parts[0], &method), + ("status", &Method::GET) + | ("disable", &Method::POST) + | ("enable", &Method::POST) + | ("revoke", &Method::POST) + | ("unrevoke", &Method::POST) + ); + if admin_action { + if !has_permission(state, username, "manage_auth").await { + return error( + StatusCode::FORBIDDEN, + "AUTH900", + "You do not have permission to manage auth", + request_id, + ); + } let target = parts[1]; - if matches!( - parts[0], - "status" | "disable" | "enable" | "revoke" | "unrevoke" - ) { - let Some(storage) = &state.storage else { - return unexpected(request_id); - }; - let Some(target_user) = storage - .find_one("users", &json!({"username": target})) - .await - .ok() - .flatten() - else { - return error( - StatusCode::NOT_FOUND, - "USR002", - "User not found", - request_id, - ); - }; - let target_is_admin = target_user.get("role").and_then(Value::as_str) == Some("admin"); - if target_is_admin && !is_admin_user(state, username).await { - return error( - StatusCode::FORBIDDEN, - "AUTH006", - "Only an administrator can manage an administrator account", - request_id, - ); - } + if is_admin_user(state, target).await && !is_admin_user(state, username).await { + return json_response( + StatusCode::NOT_FOUND, + json!({"error_message": "User not found"}), + request_id, + ); } if parts[0] == "status" { let Some(storage) = &state.storage else { @@ -5242,12 +5635,7 @@ async fn authorization_routes( .ok() .flatten() else { - return error( - StatusCode::NOT_FOUND, - "USR002", - "User not found", - request_id, - ); + return unexpected(request_id); }; let revoked = storage .find_one( @@ -5260,50 +5648,60 @@ async fn authorization_routes( .is_some(); return success( StatusCode::OK, - json!({"username": target, "active": user.get("active").and_then(Value::as_bool).unwrap_or(true), "revoked": revoked}), + json!({"active": user.get("active").and_then(Value::as_bool).unwrap_or(false), "revoked": revoked}), request_id, ); } if parts[0] == "disable" || parts[0] == "enable" { let active = parts[0] == "enable"; if let Some(storage) = &state.storage { - return match storage + let update = storage .update_one( "users", &json!({"username": target}), &json!({"active": active}), ) - .await - { - Ok(Some(_)) => { - audit::management_mutation( - username, - if active { - "authorization.enable" - } else { - "authorization.disable" - }, - target, - "success", - ); - message( - StatusCode::OK, - if active { - "User enabled successfully" - } else { - "User disabled successfully" - }, - request_id, + .await; + if update.is_err() { + return unexpected(request_id); + } + if !active { + let _ = storage + .delete_one( + "revocations", + &json!({"type": "revoke_all", "username": target}), + ) + .await; + if let Err(error_value) = storage + .insert_one( + "revocations", + json!({"type": "revoke_all", "username": target, "revoke_all": true, "revoked_at": unix_seconds()}), ) + .await + && !error_value.is_duplicate_key() + { + return unexpected(request_id); } - Ok(None) => error( - StatusCode::NOT_FOUND, - "USR002", - "User not found", - request_id, - ), - Err(_) => unexpected(request_id), - }; + } + audit::management_mutation( + username, + if active { + "authorization.enable" + } else { + "authorization.disable" + }, + target, + "success", + ); + return message( + StatusCode::OK, + &if active { + format!("User {target} enabled") + } else { + format!("User {target} disabled and tokens revoked") + }, + request_id, + ); } } if parts[0] == "revoke" || parts[0] == "unrevoke" { @@ -5350,10 +5748,10 @@ async fn authorization_routes( ); return message( StatusCode::OK, - if parts[0] == "revoke" { - "All tokens revoked" + &if parts[0] == "revoke" { + format!("All tokens revoked for {target}") } else { - "Token revocation cleared" + format!("Token revocation cleared for {target}") }, request_id, ); @@ -5541,25 +5939,19 @@ async fn authorize( request_id, )); } - if let Ok(Some(revocation)) = storage + if let Ok(Some(_revocation)) = storage .find_one( "revocations", &json!({"type": "revoke_all", "username": username}), ) .await { - let revoked_at = revocation - .get("revoked_at") - .and_then(Value::as_u64) - .unwrap_or(u64::MAX); - if (claims.iat.unwrap_or(0) as u64) <= revoked_at { - return Err(error( - StatusCode::UNAUTHORIZED, - "AUTH003", - "Token has been revoked", - request_id, - )); - } + return Err(error( + StatusCode::UNAUTHORIZED, + "AUTH003", + "Token has been revoked", + request_id, + )); } if let Some(jti) = claims.jti.as_deref() { let filter = json!({"type": "jti", "username": username, "jti": jti}); @@ -5620,21 +6012,33 @@ async fn is_admin_user(state: &AppState, username: &str) -> bool { let Some(storage) = &state.storage else { return false; }; - matches!( - storage.find_one("users", &json!({"username": username})).await, - Ok(Some(user)) if user.get("role").and_then(Value::as_str) == Some("admin") - ) + let Ok(Some(user)) = storage + .find_one("users", &json!({"username": username})) + .await + else { + return false; + }; + let Some(role_name) = user.get("role").and_then(Value::as_str) else { + return false; + }; + is_admin_role(state, role_name).await } -async fn role_permissions_within_actor(state: &AppState, username: &str, role: &Value) -> bool { - for permission in RBAC_PERMISSIONS { - if role.get(*permission).and_then(Value::as_bool) == Some(true) - && !has_permission(state, username, permission).await - { - return false; - } +async fn is_admin_role(state: &AppState, role_name: &str) -> bool { + if matches!( + role_name.trim().to_ascii_lowercase().as_str(), + "admin" | "platform admin" + ) { + return true; } - true + let Some(storage) = &state.storage else { + return false; + }; + matches!( + storage.find_one("roles", &json!({"role_name": role_name})).await, + Ok(Some(role)) if role.get("platform_admin").and_then(Value::as_bool) == Some(true) + || role.get("role_name").and_then(Value::as_str).is_some_and(|name| matches!(name.trim().to_ascii_lowercase().as_str(), "admin" | "platform admin")) + ) } async fn memory_dump( @@ -5643,6 +6047,10 @@ async fn memory_dump( username: &str, request_id: &str, ) -> Response { + let path = match memory_request_path(&payload) { + Ok(path) => path, + Err(errors) => return validation_errors(errors, request_id), + }; if !has_permission(state, username, "manage_security").await { return error( StatusCode::FORBIDDEN, @@ -5662,8 +6070,7 @@ async fn memory_dump( request_id, ); } - let path = payload.get("path").and_then(Value::as_str); - match crate::storage::snapshot::dump(storage, path).await { + match crate::storage::snapshot::dump(storage, path.as_deref()).await { Ok(path) => { audit::management_mutation(username, "memory.dump", "memory_snapshot", "success"); success( @@ -5700,6 +6107,10 @@ async fn memory_restore( username: &str, request_id: &str, ) -> Response { + let path = match memory_request_path(&payload) { + Ok(path) => path, + Err(errors) => return validation_errors(errors, request_id), + }; if !has_permission(state, username, "manage_security").await { return error( StatusCode::FORBIDDEN, @@ -5719,8 +6130,7 @@ async fn memory_restore( request_id, ); } - let path = payload.get("path").and_then(Value::as_str); - match crate::storage::snapshot::restore(storage, path).await { + match crate::storage::snapshot::restore(storage, path.as_deref()).await { Ok((version, created_at)) => { audit::management_mutation(username, "memory.restore", "memory_snapshot", "success"); success( @@ -5761,6 +6171,29 @@ async fn memory_restore( } } +fn memory_request_path(payload: &Value) -> Result, Vec> { + if payload.is_null() { + return Ok(None); + } + let Some(values) = payload.as_object() else { + return Err(vec![json!({ + "loc": ["body"], + "msg": "value is not a valid dict", + "type": "type_error.dict" + })]); + }; + match values.get("path") { + None | Some(Value::Null) => Ok(None), + Some(value) => security_setting_string(value).map(Some).ok_or_else(|| { + vec![json!({ + "loc": ["body", "path"], + "msg": "str type expected", + "type": "type_error.str" + })] + }), + } +} + async fn readiness(state: &AppState, privileged: bool, request_id: &str) -> Response { let (mongo_ok, redis_ok, memory_only, missing_grpc_descriptors, grpc_descriptor_errors) = if let Some(storage) = &state.storage { @@ -5807,42 +6240,13 @@ async fn readiness(state: &AppState, privileged: bool, request_id: &str) -> Resp vec![json!({"error": "storage is unavailable"})], ) }; - let memory_snapshot_healthy = state - .runtime - .memory_snapshot_healthy - .load(Ordering::Relaxed); - let metrics_persistence_healthy = state - .runtime - .metrics_persistence_healthy - .load(Ordering::Relaxed); - let revocation_purge_healthy = state - .runtime - .revocation_purge_healthy - .load(Ordering::Relaxed); - let activity_log_healthy = state.runtime.activity_log_healthy.load(Ordering::Relaxed); - let security_audit_log_healthy = state - .runtime - .security_audit_log_healthy - .load(Ordering::Relaxed); - let ready = mongo_ok - && redis_ok - && missing_grpc_descriptors == 0 - && memory_snapshot_healthy - && metrics_persistence_healthy - && revocation_purge_healthy - && activity_log_healthy - && security_audit_log_healthy; + let ready = mongo_ok && redis_ok && missing_grpc_descriptors == 0; let status = if ready { "ready" } else { "degraded" }; - let status_code = if ready { - StatusCode::OK - } else { - StatusCode::SERVICE_UNAVAILABLE - }; if !privileged { - return success(status_code, json!({"status": status}), request_id); + return success(StatusCode::OK, json!({"status": status}), request_id); } success( - status_code, + StatusCode::OK, json!({ "status": status, "mongodb": mongo_ok, @@ -5850,12 +6254,7 @@ async fn readiness(state: &AppState, privileged: bool, request_id: &str) -> Resp "mode": if memory_only { "memory" } else { "mongodb" }, "cache_backend": if memory_only { "memory" } else { "redis" }, "missing_grpc_descriptors": missing_grpc_descriptors, - "grpc_descriptor_errors": grpc_descriptor_errors, - "memory_snapshot_healthy": memory_snapshot_healthy, - "metrics_persistence_healthy": metrics_persistence_healthy, - "revocation_purge_healthy": revocation_purge_healthy, - "activity_log_healthy": activity_log_healthy, - "security_audit_log_healthy": security_audit_log_healthy + "grpc_descriptor_errors": grpc_descriptor_errors }), request_id, ) @@ -5975,15 +6374,94 @@ fn format_dashboard_count(value: u64) -> String { formatted } -async fn monitor_metrics(state: &AppState, request_id: &str) -> Response { +async fn monitor_metrics( + state: &AppState, + query: &HashMap, + request_id: &str, +) -> Response { let analytics = global_analytics(); - let series = analytics.get_timeseries(); - let total_requests = series.iter().map(|point| point.requests).sum::(); - let total_errors = series.iter().map(|point| point.errors).sum::(); + let minutes = match query.get("range").map(String::as_str).unwrap_or("24h") { + "1h" => 60, + "7d" => 60 * 24 * 7, + "30d" => 60 * 24 * 30, + _ => 60 * 24, + }; + let points = analytics.get_timeseries(); + let selected = points + .into_iter() + .rev() + .take(minutes) + .collect::>() + .into_iter() + .rev() + .collect::>(); + let group_by_day = query + .get("group") + .is_some_and(|value| value.eq_ignore_ascii_case("day")); + let mut series = if group_by_day { + let mut days = std::collections::BTreeMap::::new(); + for point in &selected { + let day = (point.timestamp / 86_400) * 86_400; + let bucket = days.entry(day).or_insert_with(|| AggregatedPoint { + timestamp: day, + ..AggregatedPoint::default() + }); + let prior = bucket.requests; + bucket.requests = bucket.requests.saturating_add(point.requests); + bucket.errors = bucket.errors.saturating_add(point.errors); + bucket.bytes_in = bucket.bytes_in.saturating_add(point.bytes_in); + bucket.bytes_out = bucket.bytes_out.saturating_add(point.bytes_out); + if bucket.requests > 0 { + bucket.latency_ms = ((bucket.latency_ms * prior as f64) + + (point.latency_ms * point.requests as f64)) + / bucket.requests as f64; + } + } + days.into_values() + .map(|point| { + json!({ + "timestamp": point.timestamp, + "count": point.requests, + "error_count": point.errors, + "avg_ms": point.latency_ms, + "bytes_in": point.bytes_in, + "bytes_out": point.bytes_out, + "error_rate": if point.requests == 0 { 0.0 } else { point.errors as f64 / point.requests as f64 }, + }) + }) + .collect::>() + } else { + selected + .iter() + .map(|point| { + json!({ + "timestamp": point.timestamp, + "count": point.requests, + "test_count": 0, + "error_count": point.errors, + "avg_ms": point.latency_ms, + "p95_ms": 0.0, + "bytes_in": point.bytes_in, + "bytes_out": point.bytes_out, + "error_rate": if point.requests == 0 { 0.0 } else { point.errors as f64 / point.requests as f64 }, + "upstream_timeouts": 0, + "retries": 0, + }) + }) + .collect::>() + }; + if query + .get("sort") + .is_some_and(|value| value.eq_ignore_ascii_case("desc")) + { + series.reverse(); + } + let total_requests = selected.iter().map(|point| point.requests).sum::(); + let total_errors = selected.iter().map(|point| point.errors).sum::(); let average_response_ms = if total_requests == 0 { 0.0 } else { - series + selected .iter() .map(|point| point.latency_ms * point.requests as f64) .sum::() @@ -5995,11 +6473,16 @@ async fn monitor_metrics(state: &AppState, request_id: &str) -> Response { "uptime_seconds": state.runtime.started_at.elapsed().as_secs(), "active_requests": state.runtime.active_requests.load(std::sync::atomic::Ordering::Relaxed), "total_requests": total_requests, + "total_test_requests": 0, "total_errors": total_errors, "avg_response_ms": average_response_ms, "status_counts": analytics.get_status_distribution(), "series": series, "top_apis": analytics.get_top_apis(10), + "top_users": analytics.get_top_users(10), + "unique_users": analytics.user_count(), + "total_upstream_timeouts": 0, + "total_retries": 0, "total_bytes_in": state.runtime.total_bytes_in.load(std::sync::atomic::Ordering::Relaxed), "total_bytes_out": state.runtime.total_bytes_out.load(std::sync::atomic::Ordering::Relaxed) }), @@ -6104,6 +6587,65 @@ fn csv_cell(value: &str) -> String { value.to_owned() } } +fn analytics_query_error( + query: &HashMap, + has_limit: bool, + request_id: &str, +) -> Option { + for field in ["start_ts", "end_ts"] { + if query + .get(field) + .is_some_and(|value| value.parse::().is_err()) + { + return Some(validation_errors( + vec![json!({ + "loc": ["query", field], + "msg": "value is not a valid integer", + "type": "type_error.integer" + })], + request_id, + )); + } + } + if !has_limit { + return None; + } + let raw = query.get("limit")?; + let Ok(limit) = raw.parse::() else { + return Some(validation_errors( + vec![json!({ + "loc": ["query", "limit"], + "msg": "value is not a valid integer", + "type": "type_error.integer" + })], + request_id, + )); + }; + if limit < 1 { + return Some(validation_errors( + vec![json!({ + "loc": ["query", "limit"], + "msg": "ensure this value is greater than or equal to 1", + "type": "value_error.number.not_ge", + "ctx": {"limit_value": 1} + })], + request_id, + )); + } + if limit > 100 { + return Some(validation_errors( + vec![json!({ + "loc": ["query", "limit"], + "msg": "ensure this value is less than or equal to 100", + "type": "value_error.number.not_le", + "ctx": {"limit_value": 100} + })], + request_id, + )); + } + None +} + fn analytics_denied(request_id: &str) -> Response { error( StatusCode::FORBIDDEN, @@ -6113,17 +6655,23 @@ fn analytics_denied(request_id: &str) -> Response { ) } -fn analytics_time_range(query: &HashMap) -> (u64, u64) { +fn analytics_time_range(query: &HashMap) -> (i64, i64) { if let (Some(start), Some(end)) = ( - query.get("start_ts").and_then(|value| value.parse().ok()), - query.get("end_ts").and_then(|value| value.parse().ok()), + query + .get("start_ts") + .and_then(|value| value.parse().ok()) + .filter(|value| *value != 0), + query + .get("end_ts") + .and_then(|value| value.parse().ok()) + .filter(|value| *value != 0), ) { return (start, end); } let end = SystemTime::now() .duration_since(UNIX_EPOCH) .unwrap_or_default() - .as_secs(); + .as_secs() as i64; let duration = match query.get("range").map(String::as_str).unwrap_or("24h") { "1h" => 3_600, "7d" => 604_800, @@ -6243,7 +6791,8 @@ fn analytics_series_point(point: &AggregatedPoint, metric_type: Option<&str>) -> fn analytics_timeseries(query: &HashMap, request_id: &str) -> Response { let (start_ts, end_ts) = analytics_time_range(query); - let points = global_analytics().get_timeseries_range(start_ts, end_ts); + let points = + global_analytics().get_timeseries_range(start_ts.max(0) as u64, end_ts.max(0) as u64); let metric_type = query.get("metric_type").map(String::as_str); let series = points .iter() @@ -6328,7 +6877,7 @@ async fn analytics_overview( } let (start_ts, end_ts) = analytics_time_range(query); let analytics = global_analytics(); - let points = analytics.get_timeseries_range(start_ts, end_ts); + let points = analytics.get_timeseries_range(start_ts.max(0) as u64, end_ts.max(0) as u64); let total_requests = points.iter().map(|point| point.requests).sum::(); let total_errors = points.iter().map(|point| point.errors).sum::(); let total_ms = points @@ -6706,13 +7255,13 @@ async fn config_export( query: &HashMap, request_id: &str, ) -> Response { - let permission = match only { - None => "manage_gateway", - Some("apis") => "manage_apis", - Some("endpoints") => "manage_endpoints", - Some("roles") => "manage_roles", - Some("groups") => "manage_groups", - Some("routings") => "manage_routings", + let (permission, permission_code) = match only { + None => ("manage_gateway", "CFG001"), + Some("apis") => ("manage_apis", "CFG002"), + Some("endpoints") => ("manage_endpoints", "CFG007"), + Some("roles") => ("manage_roles", "CFG003"), + Some("groups") => ("manage_groups", "CFG004"), + Some("routings") => ("manage_routings", "CFG005"), Some(_) => { return error( StatusCode::NOT_FOUND, @@ -6725,7 +7274,7 @@ async fn config_export( if !has_permission(state, username, permission).await { return error( StatusCode::FORBIDDEN, - "CFG001", + permission_code, "Insufficient permissions", request_id, ); @@ -6734,11 +7283,9 @@ async fn config_export( return unexpected(request_id); }; if let Some("apis") = only { - if let Some(api_name) = query.get("api_name") { - let api_version = query - .get("api_version") - .cloned() - .unwrap_or_else(|| "v1".to_owned()); + if let (Some(api_name), Some(api_version)) = + (query.get("api_name"), query.get("api_version")) + { let filter = json!({"api_name": api_name, "api_version": api_version}); let api = match storage.find_one("apis", &filter).await { Ok(Some(api)) => api, @@ -6766,33 +7313,64 @@ async fn config_export( } } if let Some(collection) = only { - let identifying_filter = match collection { - "roles" => query - .get("role_name") - .map(|value| json!({"role_name": value})), - "groups" => query - .get("group_name") - .map(|value| json!({"group_name": value})), - "routings" => query - .get("client_key") - .map(|value| json!({"client_key": value})), + let named_export = match collection { + "roles" => query.get("role_name").map(|value| { + ( + json!({"role_name": value}), + "role", + "CFG405", + "Role not found", + ) + }), + "groups" => query.get("group_name").map(|value| { + ( + json!({"group_name": value}), + "group", + "CFG406", + "Group not found", + ) + }), + "routings" => query.get("client_key").map(|value| { + ( + json!({"client_key": value}), + "routing", + "CFG407", + "Routing not found", + ) + }), _ => None, }; - if let Some(filter) = identifying_filter { - match storage.find_one(collection, &filter).await { - Ok(Some(_)) => {} - Ok(None) => { - return error( - StatusCode::NOT_FOUND, - "CFG404", - "Configuration item not found", + if let Some((filter, response_key, missing_code, missing_text)) = named_export { + return match storage.find_one(collection, &filter).await { + Ok(Some(value)) => { + audit::config_export(username, only); + success( + StatusCode::OK, + json!({response_key: strip_internal(value)}), request_id, - ); + ) } - Err(_) => return unexpected(request_id), - } + Ok(None) => error( + StatusCode::NOT_FOUND, + missing_code, + missing_text, + request_id, + ), + Err(_) => unexpected(request_id), + }; } - let values = match storage.find_many(collection, &json!({})).await { + let filter = if collection == "endpoints" { + let mut filter = Map::new(); + for key in ["api_name", "api_version"] { + if let Some(value) = query.get(key) { + filter.insert(key.to_owned(), json!(value)); + } + } + Value::Object(filter) + } else { + json!({}) + }; + let values = match storage.find_many(collection, &filter).await { Ok(values) => values.into_iter().map(strip_internal).collect::>(), Err(_) => return unexpected(request_id), }; @@ -6820,7 +7398,7 @@ async fn config_import( if !has_permission(state, username, "manage_gateway").await { return error( StatusCode::FORBIDDEN, - "CFG001", + "CFG006", "Insufficient permissions", request_id, ); @@ -6853,10 +7431,9 @@ async fn config_rollback( request_id: &str, ) -> Response { if !has_permission(state, username, "manage_gateway").await { - return error( - StatusCode::FORBIDDEN, - "CFG006", - "Insufficient permissions", + return http_detail( + StatusCode::INTERNAL_SERVER_ERROR, + "Rollback failed", request_id, ); } @@ -6891,9 +7468,9 @@ async fn config_rollback( .cmp(&right.get("created_at").and_then(Value::as_str)) }) else { return error( - StatusCode::BAD_REQUEST, - "CFG007", - "No configuration snapshot available", + StatusCode::NOT_FOUND, + "CFG404", + "No snapshot found", request_id, ); }; @@ -6936,7 +7513,7 @@ async fn config_rollback( ); success( StatusCode::OK, - json!({"message": format!("Configuration rolled back to {}", restored_to.as_str().unwrap_or("latest")), "restored_to": restored_to, "snapshot_id": snapshot_id}), + json!({"message": format!("Configuration rolled back to {}", restored_to.as_str().unwrap_or("latest"))}), request_id, ) } @@ -7176,14 +7753,12 @@ fn cors_check_config_from(get: impl Fn(&str) -> Option) -> CorsCheckConf if !methods.iter().any(|method| method == "OPTIONS") { methods.push("OPTIONS".to_owned()); } - let raw_headers = { - let value = get("ALLOW_HEADERS") - .filter(|value| !value.trim().is_empty()) - .unwrap_or_else(|| "*".to_owned()); - csv(value) - }; - let used_wildcard_headers = raw_headers.iter().any(|header| header == "*"); - let headers = if used_wildcard_headers { + let raw_headers_value = get("ALLOW_HEADERS") + .filter(|value| !value.trim().is_empty()) + .unwrap_or_else(|| "*".to_owned()); + let used_wildcard_headers = raw_headers_value.split(',').any(|header| header == "*"); + let raw_headers = csv(raw_headers_value); + let headers = if raw_headers.iter().any(|header| header == "*") { ["Accept", "Content-Type", "X-CSRF-Token", "Authorization"] .into_iter() .map(str::to_owned) @@ -7229,6 +7804,10 @@ fn cors_check_config_from(get: impl Fn(&str) -> Option) -> CorsCheckConf } fn cors_check(payload: Value, request_id: &str) -> Response { + let payload = match normalize_cors_check(payload) { + Ok(payload) => payload, + Err(errors) => return validation_errors(errors, request_id), + }; cors_check_with_config( payload, request_id, @@ -7236,6 +7815,121 @@ fn cors_check(payload: Value, request_id: &str) -> Response { ) } +fn normalize_cors_check(payload: Value) -> Result> { + let Value::Object(values) = payload else { + return Err(vec![json!({ + "loc": ["body"], + "msg": "value is not a valid dict", + "type": "type_error.dict" + })]); + }; + let mut errors = Vec::new(); + let mut normalized = Map::new(); + for field in ["origin", "method"] { + match values.get(field) { + None => errors.push(json!({"loc": ["body", field], "msg": "field required", "type": "value_error.missing"})), + Some(Value::Null) => errors.push(json!({"loc": ["body", field], "msg": "none is not an allowed value", "type": "type_error.none.not_allowed"})), + Some(value) => match security_setting_string(value) { + Some(value) => { + normalized.insert(field.to_owned(), json!(value)); + } + None => errors.push(json!({"loc": ["body", field], "msg": "str type expected", "type": "type_error.str"})), + }, + } + } + match values.get("request_headers") { + None | Some(Value::Null) => {} + Some(Value::Array(headers)) => { + let mut parsed = Vec::with_capacity(headers.len()); + for (index, header) in headers.iter().enumerate() { + if header.is_null() { + errors.push(json!({"loc": ["body", "request_headers", index], "msg": "none is not an allowed value", "type": "type_error.none.not_allowed"})); + } else if let Some(header) = security_setting_string(header) { + parsed.push(header); + } else { + errors.push(json!({"loc": ["body", "request_headers", index], "msg": "str type expected", "type": "type_error.str"})); + } + } + normalized.insert("request_headers".to_owned(), json!(parsed)); + } + Some(_) => errors.push(json!({"loc": ["body", "request_headers"], "msg": "value is not a valid list", "type": "type_error.list"})), + } + match values.get("with_credentials") { + None | Some(Value::Null) => {} + Some(value) => match security_setting_bool(value) { + Some(value) => { + normalized.insert("with_credentials".to_owned(), json!(value)); + } + None => errors.push(json!({"loc": ["body", "with_credentials"], "msg": "value could not be parsed to a boolean", "type": "type_error.bool"})), + }, + } + if errors.is_empty() { + Ok(Value::Object(normalized)) + } else { + Err(errors) + } +} + +fn normalize_chaos_toggle(payload: &Value) -> Result<(String, bool, i64), Vec> { + let Some(values) = payload.as_object() else { + return Err(vec![json!({ + "loc": ["body"], + "msg": "value is not a valid dict", + "type": "type_error.dict" + })]); + }; + let mut errors = Vec::new(); + let backend = match values.get("backend") { + None => { + errors.push(json!({"loc": ["body", "backend"], "msg": "field required", "type": "value_error.missing"})); + None + } + Some(Value::Null) => { + errors.push(json!({"loc": ["body", "backend"], "msg": "none is not an allowed value", "type": "type_error.none.not_allowed"})); + None + } + Some(value) => match security_setting_string(value) { + Some(value) => Some(value), + None => { + errors.push(json!({"loc": ["body", "backend"], "msg": "str type expected", "type": "type_error.str"})); + None + } + }, + }; + let enabled = match values.get("enabled") { + None => { + errors.push(json!({"loc": ["body", "enabled"], "msg": "field required", "type": "value_error.missing"})); + None + } + Some(Value::Null) => { + errors.push(json!({"loc": ["body", "enabled"], "msg": "none is not an allowed value", "type": "type_error.none.not_allowed"})); + None + } + Some(value) => match security_setting_bool(value) { + Some(value) => Some(value), + None => { + errors.push(json!({"loc": ["body", "enabled"], "msg": "value could not be parsed to a boolean", "type": "type_error.bool"})); + None + } + }, + }; + let duration_ms = match values.get("duration_ms") { + None | Some(Value::Null) => Some(0), + Some(value) => match rate_rule_integer(value) { + Some(value) => Some(value), + None => { + errors.push(json!({"loc": ["body", "duration_ms"], "msg": "value is not a valid integer", "type": "type_error.integer"})); + None + } + }, + }; + if errors.is_empty() { + Ok((backend.unwrap(), enabled.unwrap(), duration_ms.unwrap())) + } else { + Err(errors) + } +} + fn cors_check_with_config(payload: Value, request_id: &str, config: &CorsCheckConfig) -> Response { let origin = payload .get("origin") @@ -7302,14 +7996,14 @@ fn cors_check_with_config(payload: Value, request_id: &str, config: &CorsCheckCo } let preflight_headers = json!({ - "Access-Control-Allow-Origin": if origin_allowed { &origin } else { "" }, + "Access-Control-Allow-Origin": if origin_allowed { json!(&origin) } else { Value::Null }, "Access-Control-Allow-Methods": config.methods.join(", "), "Access-Control-Allow-Headers": config.headers.join(", "), "Access-Control-Allow-Credentials": if with_credentials && config.credentials { "true" } else { "false" }, "Vary": "Origin", }); let actual_headers = json!({ - "Access-Control-Allow-Origin": if origin_allowed { &origin } else { "" }, + "Access-Control-Allow-Origin": if origin_allowed { json!(&origin) } else { Value::Null }, "Access-Control-Allow-Credentials": if with_credentials && config.credentials { "true" } else { "false" }, "Vary": "Origin", }); @@ -7567,11 +8261,54 @@ fn public_credit_definition(mut value: Value) -> Value { strip_internal(value) } +fn encrypt_credit_definition(value: &mut Value) { + let Some(object) = value.as_object_mut() else { + return; + }; + for field in ["api_key", "api_key_new"] { + let encrypted = object + .get(field) + .and_then(Value::as_str) + .and_then(|value| crate::storage::field_encryption::encrypt_value(Some(value))); + if let Some(encrypted) = encrypted { + object.insert(field.to_owned(), json!(encrypted)); + } + } +} + +fn transform_user_credit_keys(value: &mut Value, encrypt: bool) { + let Some(credits) = value + .get_mut("users_credits") + .and_then(Value::as_object_mut) + else { + return; + }; + for credit in credits.values_mut() { + let Some(credit) = credit.as_object_mut() else { + continue; + }; + let transformed = credit + .get("user_api_key") + .and_then(Value::as_str) + .and_then(|value| { + if encrypt { + crate::storage::field_encryption::encrypt_value(Some(value)) + } else { + crate::storage::field_encryption::decrypt_value(Some(value)) + } + }); + if let Some(transformed) = transformed { + credit.insert("user_api_key".to_owned(), json!(transformed)); + } + } +} + async fn credit_routes( state: &AppState, path: &str, method: &Method, mut payload: Value, + query: &HashMap, username: &str, request_id: &str, ) -> Response { @@ -7603,38 +8340,102 @@ async fn credit_routes( request_id, ); }; - let Some(mut credits) = storage + let existing = storage .find_one("user_credits", &json!({"username": username})) .await .ok() - .flatten() - else { - return error( - StatusCode::NOT_FOUND, - "CRD005", - "Credits not found", - request_id, - ); + .flatten(); + let mut credits = existing + .clone() + .unwrap_or_else(|| json!({"username": username, "users_credits": {}})); + let first = Uuid::new_v4(); + let second = Uuid::new_v4(); + let mut random = [0_u8; 32]; + random[..16].copy_from_slice(first.as_bytes()); + random[16..].copy_from_slice(second.as_bytes()); + let key = base64::engine::general_purpose::URL_SAFE_NO_PAD.encode(random); + let encrypted = crate::storage::field_encryption::encrypt_value(Some(&key)) + .unwrap_or_else(|| key.clone()); + let users_credits = credits + .as_object_mut() + .and_then(|value| value.get_mut("users_credits")) + .and_then(Value::as_object_mut); + let Some(users_credits) = users_credits else { + return unexpected(request_id); }; - let key = Uuid::new_v4().to_string().replace('-', ""); - credits["users_credits"][group]["api_key"] = json!(key); - return match storage - .update_one("user_credits", &json!({"username": username}), &credits) - .await - { - Ok(Some(_)) => success(StatusCode::OK, json!({"api_key": key}), request_id), - _ => unexpected(request_id), + let group_credit = users_credits + .entry(group.to_owned()) + .or_insert_with(|| json!({})); + if !group_credit.is_object() { + *group_credit = json!({ + "available_credits": 0, + "tier_name": "default" + }); + } + group_credit["user_api_key"] = json!(encrypted); + let result = if existing.is_some() { + storage + .update_one("user_credits", &json!({"username": username}), &credits) + .await + .map(|_| ()) + } else { + storage + .insert_one("user_credits", credits) + .await + .map(|_| ()) + }; + return match result { + Ok(()) => success(StatusCode::OK, json!({"api_key": key}), request_id), + Err(_) => unexpected(request_id), }; } - if method == Method::GET && (suffix == "defs" || suffix.is_empty()) { - let values = storage + if method == Method::GET && suffix == "defs" { + if !has_permission(state, username, "manage_credits").await { + return error( + StatusCode::FORBIDDEN, + "CRD002", + "Unable to retrieve credits", + request_id, + ); + } + let mut values = storage .find_many("credit_defs", &json!({})) .await .unwrap_or_default() .into_iter() .map(public_credit_definition) .collect::>(); - return success(StatusCode::OK, json!(values), request_id); + values.sort_by(|left, right| { + left.get("api_credit_group") + .and_then(Value::as_str) + .cmp(&right.get("api_credit_group").and_then(Value::as_str)) + }); + if let Err(message_text) = validate_pagination(query) { + return error(StatusCode::BAD_REQUEST, "PAG001", &message_text, request_id); + } + let page = query + .get("page") + .and_then(|value| value.parse::().ok()) + .unwrap_or(1); + let page_size = query + .get("page_size") + .and_then(|value| value.parse::().ok()) + .unwrap_or(50); + let total = values.len(); + let start = (page - 1).saturating_mul(page_size); + let has_next = start.saturating_add(page_size) < total; + values = values.into_iter().skip(start).take(page_size).collect(); + return success( + StatusCode::OK, + json!({ + "items": values, + "page": page, + "page_size": page_size, + "has_next": has_next, + "total": total + }), + request_id, + ); } if method == Method::GET && suffix == "all" { if !has_permission(state, username, "manage_credits").await { @@ -7645,14 +8446,70 @@ async fn credit_routes( request_id, ); } - let values = storage + if let Err(message_text) = validate_pagination(query) { + return error(StatusCode::BAD_REQUEST, "PAG001", &message_text, request_id); + } + let page = query + .get("page") + .and_then(|value| value.parse::().ok()) + .unwrap_or(1); + let page_size = query + .get("page_size") + .and_then(|value| value.parse::().ok()) + .unwrap_or(10); + let search = query + .get("search") + .map(|value| value.trim().to_ascii_lowercase()) + .unwrap_or_default(); + let mut values = storage .find_many("user_credits", &json!({})) .await .unwrap_or_default() .into_iter() - .map(strip_internal) + .filter(|value| { + search.is_empty() + || value + .get("username") + .and_then(Value::as_str) + .is_some_and(|value| value.to_ascii_lowercase().contains(&search)) + || value + .get("users_credits") + .and_then(Value::as_object) + .is_some_and(|credits| { + credits + .keys() + .any(|group| group.to_ascii_lowercase().contains(&search)) + }) + }) + .map(|mut value| { + transform_user_credit_keys(&mut value, false); + strip_internal(value) + }) + .collect::>(); + values.sort_by(|left, right| { + left.get("username") + .and_then(Value::as_str) + .cmp(&right.get("username").and_then(Value::as_str)) + }); + let total = values.len(); + let start = (page - 1).saturating_mul(page_size); + let has_next = start.saturating_add(page_size) < total; + let values = values + .into_iter() + .skip(start) + .take(page_size) .collect::>(); - return success(StatusCode::OK, json!(values), request_id); + return success( + StatusCode::OK, + json!({ + "user_credits": values, + "page": page, + "page_size": page_size, + "has_next": has_next, + "total": total + }), + request_id, + ); } if method == Method::POST && suffix.is_empty() { if !has_permission(state, username, "manage_credits").await { @@ -7684,6 +8541,7 @@ async fn credit_routes( request_id, ); } + encrypt_credit_definition(&mut payload); return match storage.insert_one("credit_defs", payload).await { Ok(_) => message( StatusCode::CREATED, @@ -7696,13 +8554,21 @@ async fn credit_routes( if let Some(group) = suffix.strip_prefix("defs/") { let filter = json!({"api_credit_group": group}); if method == Method::GET { + if !has_permission(state, username, "manage_credits").await { + return error( + StatusCode::FORBIDDEN, + "CRD002", + "Unable to retrieve credits", + request_id, + ); + } return match storage.find_one("credit_defs", &filter).await { Ok(Some(value)) => { success(StatusCode::OK, public_credit_definition(value), request_id) } _ => error( StatusCode::NOT_FOUND, - "CRD002", + "CRD021", "Credit definition not found", request_id, ), @@ -7747,6 +8613,7 @@ async fn credit_routes( } Err(_) => return unexpected(request_id), } + encrypt_credit_definition(&mut payload); return match storage.update_one("credit_defs", &filter, &payload).await { Ok(Some(_)) => message( StatusCode::OK, @@ -7784,8 +8651,21 @@ async fn credit_routes( request_id, ); } + if payload + .get("username") + .and_then(Value::as_str) + .is_some_and(|body_username| body_username != suffix) + { + return error( + StatusCode::BAD_REQUEST, + "CRD014", + "Username in body does not match path", + request_id, + ); + } let mut value = payload; value["username"] = json!(suffix); + transform_user_credit_keys(&mut value, true); let existing = storage .find_one("user_credits", &json!({"username": suffix})) .await @@ -7817,11 +8697,14 @@ async fn credit_routes( .find_one("user_credits", &json!({"username": suffix})) .await { - Ok(Some(value)) => success(StatusCode::OK, strip_internal(value), request_id), + Ok(Some(mut value)) => { + transform_user_credit_keys(&mut value, false); + success(StatusCode::OK, strip_internal(value), request_id) + } _ => error( StatusCode::NOT_FOUND, - "CRD005", - "Credits not found", + "CRD017", + "User credits not found", request_id, ), }; @@ -8233,9 +9116,8 @@ async fn quota_routes( "daily_requests" => "daily_request_quota", "monthly_bandwidth" => "monthly_bandwidth_quota", _ => { - return error( + return http_detail( StatusCode::BAD_REQUEST, - "QUOTA001", &format!("Invalid quota type: {quota_type}"), request_id, ); @@ -8293,6 +9175,8 @@ async fn quota_tier_and_limits( .unwrap_or(false) }) }; + // The pinned TierService applies assignment overrides before checking the + // assignment's effective dates, even when get_user_tier falls back. let limits = assignment .as_ref() .and_then(|assignment| assignment.get("override_limits")) @@ -8478,7 +9362,7 @@ async fn api_discovery_routes( return error( StatusCode::FORBIDDEN, "AUTHZ001", - "Insufficient permissions", + "Not authorized", request_id, ); } @@ -8494,6 +9378,12 @@ async fn api_discovery_routes( } return error(StatusCode::NOT_FOUND, "API001", "API not found", request_id); }; + if kind == "openapi" { + return openapi_discovery_route( + state, storage, &api, &filter, parts, action, method, username, request_id, + ) + .await; + } if kind == "grpc" && action == "services" && method == Method::GET { use base64::Engine as _; let Some(raw) = api.get("api_grpc_descriptor_set").and_then(Value::as_str) else { @@ -8921,6 +9811,232 @@ async fn api_discovery_routes( ) } +async fn fetch_openapi_spec(state: &AppState, api: &Value, path: &str) -> Option { + let servers = api.get("api_servers").and_then(Value::as_array)?; + for server in servers.iter().filter_map(Value::as_str) { + let Ok(target) = discovery_target(server, path) else { + continue; + }; + let Ok(response) = state.proxy_client.get(target).send().await else { + continue; + }; + if response.status() != StatusCode::OK { + continue; + } + if let Ok(spec) = response.json::().await { + return Some(spec); + } + } + None +} + +fn python_truthy_json(value: &Value) -> bool { + match value { + Value::Null => false, + Value::Bool(value) => *value, + Value::Number(value) => value.as_f64().is_some_and(|value| value != 0.0), + Value::String(value) => !value.is_empty(), + Value::Array(value) => !value.is_empty(), + Value::Object(value) => !value.is_empty(), + } +} + +#[allow(clippy::too_many_arguments)] +async fn openapi_discovery_route( + state: &AppState, + storage: &SharedStorage, + api: &Value, + filter: &Value, + parts: &[&str], + action: &str, + method: &Method, + username: &str, + request_id: &str, +) -> Response { + let cached = api + .get("api_openapi_spec") + .filter(|value| python_truthy_json(value)); + if method == Method::GET && action.is_empty() { + if let Some(spec) = cached { + return success(StatusCode::OK, spec.clone(), request_id); + } + let Some(path) = api.get("api_openapi_url").and_then(Value::as_str) else { + return error( + StatusCode::NOT_FOUND, + "OPENAPI001", + "No OpenAPI URL configured for this API", + request_id, + ); + }; + if api + .get("api_servers") + .and_then(Value::as_array) + .is_none_or(Vec::is_empty) + { + return error( + StatusCode::NOT_FOUND, + "OPENAPI002", + "No upstream servers configured", + request_id, + ); + } + let Some(spec) = fetch_openapi_spec(state, api, path).await else { + return error( + StatusCode::BAD_GATEWAY, + "OPENAPI003", + "Failed to fetch OpenAPI spec from upstream", + request_id, + ); + }; + let _ = storage + .update_one("apis", filter, &json!({"api_openapi_spec": spec.clone()})) + .await; + return success(StatusCode::OK, spec, request_id); + } + if method == Method::POST && action == "refresh" { + let Some(path) = api.get("api_openapi_url").and_then(Value::as_str) else { + return error( + StatusCode::NOT_FOUND, + "OPENAPI001", + "No OpenAPI URL configured", + request_id, + ); + }; + if api + .get("api_servers") + .and_then(Value::as_array) + .is_none_or(Vec::is_empty) + { + return error( + StatusCode::NOT_FOUND, + "OPENAPI002", + "No upstream servers configured", + request_id, + ); + } + let Some(spec) = fetch_openapi_spec(state, api, path).await else { + return error( + StatusCode::BAD_GATEWAY, + "OPENAPI003", + "Failed to fetch OpenAPI spec", + request_id, + ); + }; + let _ = storage + .update_one("apis", filter, &json!({"api_openapi_spec": spec.clone()})) + .await; + return success( + StatusCode::OK, + json!({ + "message": "OpenAPI spec refreshed successfully", + "endpoints_found": spec.get("paths").and_then(Value::as_object).map_or(0, Map::len), + }), + request_id, + ); + } + if method == Method::POST && action == "import" { + if !has_permission(state, username, "manage_endpoints").await { + return error( + StatusCode::FORBIDDEN, + "AUTHZ001", + "Not authorized", + request_id, + ); + } + let spec = if let Some(spec) = cached.cloned() { + Some(spec) + } else if let Some(path) = api.get("api_openapi_url").and_then(Value::as_str) { + let fetched = fetch_openapi_spec(state, api, path).await; + if let Some(spec) = &fetched { + let _ = storage + .update_one("apis", filter, &json!({"api_openapi_spec": spec.clone()})) + .await; + } + fetched + } else { + None + }; + let Some(spec) = spec else { + return error( + StatusCode::NOT_FOUND, + "OPENAPI003", + "No OpenAPI spec available", + request_id, + ); + }; + let candidates = crate::routes::discovery::openapi_endpoints(&spec); + let endpoints_found = candidates.len(); + let api_id = api.get("api_id").cloned().unwrap_or(Value::Null); + let existing = storage + .find_many("endpoints", &json!({"api_id": api_id.clone()})) + .await + .unwrap_or_default(); + let mut imported = 0_u64; + let mut skipped = 0_u64; + for candidate in candidates { + let uri = candidate + .get("endpoint_uri") + .and_then(Value::as_str) + .unwrap_or(""); + let method = candidate + .get("endpoint_method") + .and_then(Value::as_str) + .unwrap_or(""); + let composite = format!("{method}/{}", uri.trim_start_matches('/')); + let duplicate = existing.iter().any(|endpoint| { + let existing_method = endpoint + .get("endpoint_method") + .and_then(Value::as_str) + .unwrap_or(""); + let existing_uri = endpoint + .get("endpoint_uri") + .and_then(Value::as_str) + .unwrap_or(""); + format!("{existing_method}/{}", existing_uri.trim_start_matches('/')) == composite + }); + if duplicate { + skipped += 1; + continue; + } + let description = candidate + .get("endpoint_description") + .and_then(Value::as_str) + .unwrap_or("") + .chars() + .take(127) + .collect::(); + let endpoint = json!({ + "api_id": api_id, + "api_name": parts[0], + "api_version": parts[1], + "endpoint_id": Uuid::new_v4().to_string(), + "endpoint_uri": uri, + "endpoint_method": method, + "endpoint_description": description, + }); + if storage.insert_one("endpoints", endpoint).await.is_ok() { + imported += 1; + } + } + return success( + StatusCode::OK, + json!({ + "message": "OpenAPI import completed", + "endpoints_found": endpoints_found, + "endpoints_imported": imported, + "endpoints_skipped": skipped, + }), + request_id, + ); + } + error( + StatusCode::NOT_FOUND, + "GTW003", + "Platform route does not exist", + request_id, + ) +} + fn graphql_schema_response(schema: Value, cached: bool, request_id: &str) -> Response { let query = schema .get("queryType") @@ -9052,12 +10168,14 @@ async fn proto_routes( request_id: &str, ) -> Response { if !has_permission(state, username, "manage_apis").await { - return error( - StatusCode::FORBIDDEN, - "API008", - "You do not have permission to manage proto files", - request_id, - ); + let (code, message_text) = if method == Method::PUT { + ("API008", "You do not have permission to update proto files") + } else if method == Method::DELETE { + ("API008", "You do not have permission to delete proto files") + } else { + ("AUTH001", "User does not have permission to manage APIs") + }; + return error(StatusCode::FORBIDDEN, code, message_text, request_id); } let Some(storage) = &state.storage else { return unexpected(request_id); @@ -9096,17 +10214,35 @@ async fn proto_routes( .ok() .flatten()); let Some(proto_record) = proto_record else { - return error(StatusCode::NOT_FOUND, "API003", "API not found", request_id); + return error( + StatusCode::NOT_FOUND, + "API002", + &format!("Proto file not found for API {}/{}", parts[0], parts[1]), + request_id, + ); }; return match proto_record .get("api_grpc_proto_source") .and_then(Value::as_str) { - Some(source) => success(StatusCode::OK, json!({"content": source}), request_id), + Some(source) if !source.is_empty() => success( + StatusCode::OK, + json!({ + "message": "Proto file retrieved successfully", + "content": source + }), + request_id, + ), None => error( StatusCode::NOT_FOUND, - "API003", - "Proto file not found", + "API002", + &format!("Proto file not found for API {}/{}", parts[0], parts[1]), + request_id, + ), + Some(_) => error( + StatusCode::NOT_FOUND, + "API002", + &format!("Proto file not found for API {}/{}", parts[0], parts[1]), request_id, ), }; @@ -9118,9 +10254,9 @@ async fn proto_routes( "apis", &filter, &json!({ - "api_grpc_proto_source": "", - "api_grpc_descriptor_set": "", - "api_grpc_descriptor_sha256": "" + "api_grpc_proto_source": null, + "api_grpc_descriptor_set": null, + "api_grpc_descriptor_sha256": null }), ) .await, @@ -9130,33 +10266,25 @@ async fn proto_routes( .delete_one("grpc_proto_uploads", &filter) .await .unwrap_or(false); - return if cleared_api || cleared_pending { - message( - StatusCode::OK, - "Proto file deleted successfully", - request_id, - ) - } else { - error( - StatusCode::NOT_FOUND, - "API003", - "Proto file not found", - request_id, - ) - }; + let _ = (cleared_api, cleared_pending); + return message( + StatusCode::OK, + "Proto file and generated files deleted successfully", + request_id, + ); } if method == Method::POST || method == Method::PUT { - let max_size = env::var("MAX_PROTO_SIZE_BYTES") + let max_size = env::var(crate::constants::Defaults::MAX_MULTIPART_SIZE_BYTES_ENV) .ok() .and_then(|value| value.parse::().ok()) - .unwrap_or(1024 * 1024); + .unwrap_or(crate::constants::Defaults::MAX_MULTIPART_SIZE_BYTES_DEFAULT); let source = match extract_proto_source(headers, body) { Ok(source) if source.len() <= max_size => source, Ok(_) => { return error( StatusCode::PAYLOAD_TOO_LARGE, - "GTW013", - "File too large", + crate::constants::ErrorCodes::REQUEST_TOO_LARGE, + crate::constants::Messages::FILE_TOO_LARGE, request_id, ); } @@ -9209,7 +10337,11 @@ async fn proto_routes( return match result { Ok(Some(_)) => message( StatusCode::OK, - "Proto file uploaded and gRPC code generated successfully", + if method == Method::PUT { + "Proto file updated successfully" + } else { + "Proto file uploaded and gRPC code generated successfully" + }, request_id, ), Ok(None) => { @@ -9243,7 +10375,11 @@ async fn proto_routes( if saved { message( StatusCode::OK, - "Proto file uploaded and gRPC code generated successfully", + if method == Method::PUT { + "Proto file updated successfully" + } else { + "Proto file uploaded and gRPC code generated successfully" + }, request_id, ) } else { @@ -9293,12 +10429,9 @@ fn extract_proto_source(headers: &HeaderMap, body: &[u8]) -> Result Result bool { - filename.ends_with(".proto") - && !filename.is_empty() - && filename.len() <= 255 - && !filename.contains("..") - && !filename.starts_with(['/', '\\']) - && filename.as_bytes().get(1).is_none_or(|byte| *byte != b':') - && filename.chars().all(|character| { - character.is_ascii_alphanumeric() || matches!(character, '_' | '-' | '.') - }) -} - fn extract_proto_package(source: &str) -> Option { for line in source.lines() { let trimmed = line.trim(); @@ -9567,25 +10688,25 @@ fn read_log_records( ) -> Result, LogExportError> { let mut paths = Vec::new(); let entries = match fs::read_dir(directory) { - Ok(entries) => entries, - Err(error_value) if error_value.kind() == std::io::ErrorKind::NotFound => { - return Ok(Vec::new()); - } + Ok(entries) => Some(entries), + Err(error_value) if error_value.kind() == std::io::ErrorKind::NotFound => None, Err(_) => return Err(LogExportError::Read), }; - for entry in entries { - let entry = entry.map_err(|_| LogExportError::Read)?; - let file_type = entry.file_type().map_err(|_| LogExportError::Read)?; - if !file_type.is_file() { - continue; + if let Some(entries) = entries { + for entry in entries { + let entry = entry.map_err(|_| LogExportError::Read)?; + let file_type = entry.file_type().map_err(|_| LogExportError::Read)?; + if !file_type.is_file() { + continue; + } + let metadata = entry.metadata().map_err(|_| LogExportError::Read)?; + paths.push(( + metadata.modified().unwrap_or(UNIX_EPOCH), + metadata.len(), + entry.path(), + )); } - let metadata = entry.metadata().map_err(|_| LogExportError::Read)?; - paths.push(( - metadata.modified().unwrap_or(UNIX_EPOCH), - metadata.len(), - entry.path(), - )); - } + }; paths.sort_by(|left, right| right.0.cmp(&left.0)); let mut read_bytes = 0_u64; @@ -9612,12 +10733,26 @@ fn read_log_records( break; } } + for line in crate::observability::logging::memory_log_snapshot() + .into_iter() + .rev() + .take(max_entries) + { + let Some(mut record) = parse_log_record(&line) else { + continue; + }; + if log_record_matches(&record, query) { + audit::redact_record(&mut record); + logs.push(record); + } + } logs.sort_by(|left, right| { right .get("timestamp") .and_then(Value::as_str) .cmp(&left.get("timestamp").and_then(Value::as_str)) }); + logs.truncate(max_entries); Ok(logs) } @@ -9709,17 +10844,128 @@ fn valid_log_date(value: &str) -> bool { } fn parse_log_record(line: &str) -> Option { - let mut record = serde_json::from_str::(line).ok()?; - let values = record.as_object_mut()?; - let timestamp = values - .remove("time") - .or_else(|| values.get("timestamp").cloned())?; - let source = values - .remove("name") - .unwrap_or(Value::String(String::new())); - values.insert("timestamp".to_owned(), timestamp); - values.insert("source".to_owned(), source); - Some(record) + let line = line.trim(); + if let Ok(mut record) = serde_json::from_str::(line) { + let values = record.as_object_mut()?; + let timestamp = values + .remove("time") + .or_else(|| values.get("timestamp").cloned()) + .unwrap_or_else(|| Value::String(time::OffsetDateTime::now_utc().to_string())); + let source = values + .remove("name") + .unwrap_or(Value::String(String::new())); + let message = values + .get("message") + .and_then(Value::as_str) + .unwrap_or_default(); + let structured = extract_log_fields(message); + for (key, value) in structured { + values.entry(key).or_insert(value); + } + values.insert("timestamp".to_owned(), timestamp); + values.insert("source".to_owned(), source); + return Some(record); + } + + let mut parts = line.splitn(4, " - "); + let timestamp = parts.next()?; + let source = parts.next()?; + let level = parts.next()?; + let full_message = parts.next()?; + let (request_id, message) = full_message + .split_once(" | ") + .map_or((None, full_message), |(request_id, message)| { + (Some(request_id), message) + }); + let mut values = extract_log_fields(message); + if let Some(request_id) = request_id { + values.insert("request_id".to_owned(), json!(request_id)); + } + values.insert( + "timestamp".to_owned(), + json!(timestamp.replace(' ', "T").replace(',', ".")), + ); + values.insert( + "level".to_owned(), + json!(if request_id.is_some() { level } else { "DEBUG" }), + ); + values.insert("message".to_owned(), json!(message)); + values.insert("source".to_owned(), json!(source)); + Some(Value::Object(values)) +} + +fn extract_log_fields(message: &str) -> Map { + let mut values = Map::new(); + let capture = |pattern: &str, group: usize| { + Regex::new(pattern) + .ok()? + .captures(message)? + .get(group) + .map(|value| value.as_str().to_owned()) + }; + if let Some(value) = capture(r"(\w{8}-\w{4}-\w{4}-\w{4}-\w{12})", 1) { + values.insert("request_id".to_owned(), json!(value)); + } + if let Some(value) = capture(r"Username: (\w+)", 1) { + values.insert("user".to_owned(), json!(value)); + } + if let Some(value) = capture(r"(?:effective_ip|client_ip)=([A-Fa-f0-9:.]+)", 1) { + values.insert("ip_address".to_owned(), json!(value)); + } else if let Some(mut value) = capture(r"From:\s+(.+?)$", 1) { + if value.matches(':').count() > 1 { + if let Some((host, _)) = value.rsplit_once(':') { + value = host.to_owned(); + } + } else if let Some((host, _)) = value.split_once(':') { + value = host.to_owned(); + } + values.insert("ip_address".to_owned(), json!(value)); + } + if let Ok(pattern) = Regex::new(r"Endpoint: (\w+) (.+)") + && let Some(captures) = pattern.captures(message) + { + values.insert("method".to_owned(), json!(&captures[1])); + values.insert("endpoint".to_owned(), json!(&captures[2])); + } + if let Some(value) = capture(r"Total time: ([\d.]+)ms", 1) { + values.insert("response_time".to_owned(), json!(value)); + } + if (message.contains("Status check failed") + || message.to_ascii_lowercase().contains("status_code")) + && let Some(value) = capture(r"(?i)status_code[:\s]+(\d+)", 1) + { + values.insert("status_code".to_owned(), json!(value)); + } + let endpoint = values + .get("endpoint") + .and_then(Value::as_str) + .unwrap_or_default() + .to_ascii_lowercase(); + let lower = message.to_ascii_lowercase(); + let request_type = if ["/rest", "/soap", "/graphql"] + .iter() + .any(|part| endpoint.contains(part)) + || [ + "rest gateway", + "soap gateway", + "graphql gateway", + "upstream", + ] + .iter() + .any(|part| lower.contains(part)) + { + "gateway" + } else if endpoint.contains("/authorization") + || ["login", "register", "token", "permission"] + .iter() + .any(|part| lower.contains(part)) + { + "auth" + } else { + "platform" + }; + values.insert("type".to_owned(), json!(request_type)); + values } fn log_record_matches(record: &Value, query: &HashMap) -> bool { @@ -9734,6 +10980,24 @@ fn log_record_matches(record: &Value, query: &HashMap) -> bool { { return false; } + let timestamp = value("timestamp"); + let timestamp_time = timestamp + .get(11..16) + .filter(|value| value.as_bytes().get(2) == Some(&b':')); + if let Some(start_time) = query + .get("start_time") + .filter(|value| !value.trim().is_empty()) + && timestamp_time.is_none_or(|value| value < start_time.as_str()) + { + return false; + } + if let Some(end_time) = query + .get("end_time") + .filter(|value| !value.trim().is_empty()) + && timestamp_time.is_none_or(|value| value > end_time.as_str()) + { + return false; + } for key in [ "user", "api", @@ -9744,17 +11008,23 @@ fn log_record_matches(record: &Value, query: &HashMap) -> bool { "level", "type", ] { - let Some(expected) = query.get(key) else { + let Some(expected) = query.get(key).filter(|value| !value.trim().is_empty()) else { continue; }; - if key == "level" { - if !value(key).eq_ignore_ascii_case(expected) { - return false; - } - } else if value(key) != expected { + if !value(key) + .to_ascii_lowercase() + .contains(&expected.trim().to_ascii_lowercase()) + { return false; } } + if let Some(expected) = query + .get("status_code") + .filter(|value| !value.trim().is_empty()) + && value("status_code") != expected.trim() + { + return false; + } let response_time = record.get("response_time").and_then(log_number); if let Some(minimum) = query .get("min_response_time") @@ -9772,6 +11042,20 @@ fn log_record_matches(record: &Value, query: &HashMap) -> bool { { return false; } + if let Some(excluded) = query + .get("exclude_type") + .filter(|value| !value.trim().is_empty()) + { + let excluded = excluded.trim().to_ascii_lowercase(); + if value("type").eq_ignore_ascii_case(&excluded) + || (excluded == "platform" + && value("endpoint") + .to_ascii_lowercase() + .contains("/platform/")) + { + return false; + } + } true } @@ -9958,7 +11242,17 @@ fn sign_token( }); header.kid = kid; if algorithm.eq_ignore_ascii_case("RS256") { - if let Some(key) = entry.get("private_key").and_then(Value::as_str) { + let key = entry + .get("private_key_path") + .and_then(Value::as_str) + .and_then(|path| fs::read_to_string(path).ok()) + .or_else(|| { + entry + .get("private_key") + .and_then(Value::as_str) + .map(str::to_owned) + }); + if let Some(key) = key { return encode( &header, claims, @@ -10051,10 +11345,10 @@ fn bootstrap_admin_update_fields_are_safe(payload: &Value) -> bool { } fn secure_password(password: &str) -> bool { - password.len() >= 16 - && password.chars().any(|c| c.is_ascii_uppercase()) - && password.chars().any(|c| c.is_ascii_lowercase()) - && password.chars().any(|c| c.is_ascii_digit()) + password.chars().count() >= 16 + && password.chars().any(char::is_uppercase) + && password.chars().any(char::is_lowercase) + && password.chars().any(char::is_numeric) && password .chars() .any(|c| "!@#$%^&*()-_=+[]{};:,.<>?/".contains(c)) @@ -10386,6 +11680,13 @@ fn is_subscription_mutation(path: &str, method: &Method) -> bool { ) } +fn is_update_password_path(path: &str) -> bool { + ["/user/", "/users/"].iter().any(|prefix| { + path.strip_prefix(prefix) + .is_some_and(|suffix| !suffix.is_empty() && suffix.ends_with("/update-password")) + }) +} + fn subscription_payload_has_required_fields(payload: &Value) -> bool { ["username", "api_name", "api_version"] .iter() @@ -10422,30 +11723,37 @@ fn paginate(items: Vec, query: &HashMap) -> Value { /// Validate client pagination before applying the page window. This prevents /// invalid values from being silently normalized and honors the configured /// maximum on each request. -fn validate_pagination(query: &HashMap) -> Result<(), &'static str> { +fn validate_pagination(query: &HashMap) -> Result<(), String> { if query .get("page") .is_some_and(|value| value.parse::().ok().is_none_or(|number| number == 0)) { - return Err("page must be a positive integer"); + return Err("page must be >= 1".to_owned()); } let Some(page_size) = query.get("page_size") else { return Ok(()); }; let Some(page_size) = page_size.parse::().ok().filter(|number| *number > 0) else { - return Err("page_size must be a positive integer"); + return Err("page_size must be >= 1".to_owned()); }; - if let Some(maximum) = env::var("MAX_PAGE_SIZE") - .ok() - .and_then(|value| value.parse::().ok()) - .filter(|number| *number > 0) - && page_size > maximum - { - return Err("page_size exceeds the configured maximum"); + if page_size > configured_max_page_size() { + return Err(format!( + "page_size must be <= {}", + configured_max_page_size() + )); } Ok(()) } +fn configured_max_page_size() -> usize { + env::var("MAX_PAGE_SIZE") + .ok() + .filter(|value| !value.trim().is_empty()) + .and_then(|value| value.parse::().ok()) + .map(|value| value.max(1) as usize) + .unwrap_or(200) +} + fn paginate_named(items: Vec, query: &HashMap, name: &str) -> Value { let page = query .get("page") @@ -10502,6 +11810,9 @@ fn public_user(mut value: Value) -> Value { fn schedule_restart() -> Result<(), (&'static str, &'static str)> { let mut candidates = Vec::new(); + if let Some(path) = env::var_os("PID_FILE") { + candidates.push(std::path::PathBuf::from(path)); + } if let Some(path) = env::var_os("DOORMAN_PID_FILE") { candidates.push(std::path::PathBuf::from(path)); } @@ -10687,6 +11998,37 @@ fn unix_seconds() -> u64 { mod tests { use super::*; + #[test] + fn log_parsing_and_filters_match_python_service() { + let record = parse_log_record( + "2026-09-26 10:11:12,345 - doorman.gateway - INFO - 12345678-1234-1234-1234-123456789012 | Username: Alice Endpoint: GET /rest/pets Total time: 12.5ms status_code: 200 From: 127.0.0.1:1234", + ) + .unwrap(); + assert_eq!(record["timestamp"], "2026-09-26T10:11:12.345"); + assert_eq!(record["user"], "Alice"); + assert_eq!(record["method"], "GET"); + assert_eq!(record["type"], "gateway"); + assert_eq!(record["ip_address"], "127.0.0.1"); + + let filters = HashMap::from([ + ("user".to_owned(), "ali".to_owned()), + ("endpoint".to_owned(), "/REST".to_owned()), + ("start_time".to_owned(), "10:00".to_owned()), + ("end_time".to_owned(), "11:00".to_owned()), + ("status_code".to_owned(), "200".to_owned()), + ]); + assert!(log_record_matches(&record, &filters)); + assert!(!log_record_matches( + &record, + &HashMap::from([("exclude_type".to_owned(), "gateway".to_owned())]) + )); + + let debug = + parse_log_record("2026-09-26 10:11:12 - doorman.gateway - ERROR - startup complete") + .unwrap(); + assert_eq!(debug["level"], "DEBUG"); + } + // Oracle: pinned models/security_settings_model.py, Pydantic 1.10.26. #[test] fn security_settings_scalar_coercion_matches_python_model() { @@ -10991,6 +12333,9 @@ mod tests { Uuid::new_v4().simple().to_string().to_uppercase() ); assert!(!secure_password(&without_special)); + + assert!(secure_password("Ää1!xxxxxxxxxxxx")); + assert!(!secure_password("Ää1!xxxxxxxxxx")); } fn test_password() -> String { @@ -11115,7 +12460,7 @@ mod tests { assert_eq!(wildcard_blocked["actual"]["allowed"], false); assert_eq!( wildcard_blocked["preflight"]["response_headers"]["Access-Control-Allow-Origin"], - "" + Value::Null ); assert_eq!( wildcard_blocked["preflight"]["response_headers"]["Access-Control-Allow-Credentials"], diff --git a/gateway-rs/src/routes/rest.rs b/gateway-rs/src/routes/rest.rs index d13d39e8..43df768c 100644 --- a/gateway-rs/src/routes/rest.rs +++ b/gateway-rs/src/routes/rest.rs @@ -326,7 +326,7 @@ async fn execute_rest( return Ok(( StatusCode::SERVICE_UNAVAILABLE, Json(PolicyErrorBody { - error_code: "GTW006".to_owned(), + error_code: "GTW999".to_owned(), error_message: "Upstream circuit open".to_owned(), }), ) @@ -533,6 +533,15 @@ async fn execute_rest( retry_backoff(attempt).await; } Ok(response) => break response, + Err(error) if error.is_timeout() && attempt < attempts => { + record_failure(&state.runtime.circuits, &circuit_key); + state.runtime.retries_total.fetch_add(1, Ordering::Relaxed); + state + .runtime + .upstream_timeouts_total + .fetch_add(1, Ordering::Relaxed); + retry_backoff(attempt).await; + } Err(_) if attempt < attempts => { record_failure(&state.runtime.circuits, &circuit_key); state.runtime.retries_total.fetch_add(1, Ordering::Relaxed); @@ -633,7 +642,7 @@ async fn execute_rest( return Ok(policy_error_response( StatusCode::INTERNAL_SERVER_ERROR, "GTW006", - "Invalid JSON response from upstream", + "Malformed JSON from upstream", )); } let upstream_content_type = upstream_headers @@ -814,11 +823,15 @@ async fn execute_crud( Ok(response) => Ok(response), Err(crate::storage::runtime::StorageError::InvalidDocument(error)) => { tracing::debug!(error = %error, "CRUD validation failed"); - Ok(policy_error_response( + Ok(( StatusCode::BAD_REQUEST, - "CRUD400", - "Validation failed", - )) + Json(serde_json::json!({ + "error_code": "CRUD400", + "error_message": "Validation failed", + "response": {"errors": error.split("; ").collect::>()} + })), + ) + .into_response()) } Err(error) => { tracing::error!(error = %error, "CRUD storage operation failed"); @@ -851,7 +864,8 @@ fn crud_resource_id(path: &str) -> Option<&str> { } fn parse_crud_body(body: &[u8]) -> Result { - let value: Value = serde_json::from_slice(body)?; + // Python treats request.json() failures as an empty object for CRUD REST. + let value: Value = serde_json::from_slice(body).unwrap_or_else(|_| serde_json::json!({})); if !value.is_object() { return Err(crate::storage::runtime::StorageError::InvalidDocument( "CRUD request body must be a JSON object".to_owned(), @@ -911,8 +925,12 @@ fn validate_crud_fields( let expected = rules.get("type").and_then(Value::as_str); let valid_type = match expected { Some("string") => field_value.is_string(), - Some("number") => field_value.is_number(), - Some("integer") => field_value.as_i64().is_some() || field_value.as_u64().is_some(), + Some("number") => field_value.is_number() || field_value.is_boolean(), + Some("integer") => { + field_value.as_i64().is_some() + || field_value.as_u64().is_some() + || field_value.is_boolean() + } Some("boolean") => field_value.is_boolean(), Some("array") => field_value.is_array(), Some("object") => field_value.is_object(), @@ -931,19 +949,60 @@ fn validate_crud_fields( .and_then(Value::as_u64) .is_some_and(|min| text.chars().count() < min as usize) { - errors.push(format!("Field '{path}' is shorter than min_length")); + errors.push(format!( + "Field '{path}' must be at least {} characters", + rules["min_length"] + )); } if rules .get("max_length") .and_then(Value::as_u64) .is_some_and(|max| text.chars().count() > max as usize) { - errors.push(format!("Field '{path}' is longer than max_length")); + errors.push(format!( + "Field '{path}' must be at most {} characters", + rules["max_length"] + )); + } + if let Some(pattern) = rules.get("pattern").and_then(Value::as_str) + && let Ok(pattern) = regex::Regex::new(&format!("^(?:{pattern})")) + && !pattern.is_match(text) + { + errors.push(format!( + "Field '{path}' does not match pattern {}", + rules["pattern"].as_str().unwrap_or_default() + )); + } + if let Some(allowed) = rules.get("enum").and_then(Value::as_array) + && !allowed.contains(field_value) + { + errors.push(format!( + "Field '{path}' must be one of: {}", + allowed + .iter() + .map(|value| value + .as_str() + .map_or_else(|| value.to_string(), str::to_owned)) + .collect::>() + .join(", ") + )); } } - if let Some(allowed) = rules.get("enum").and_then(Value::as_array) { - if !allowed.contains(field_value) { - errors.push(format!("Field '{path}' is not an allowed value")); + let numeric_value = field_value.as_f64().or_else(|| { + field_value + .as_bool() + .map(|value| if value { 1.0 } else { 0.0 }) + }); + if let Some(numeric_value) = numeric_value { + if let Some(minimum) = rules.get("min_value").and_then(Value::as_f64) + && numeric_value < minimum + { + errors.push(format!("Field '{path}' must be >= {}", rules["min_value"])); + } + if let Some(maximum) = rules.get("max_value").and_then(Value::as_f64) + && numeric_value > maximum + { + errors.push(format!("Field '{path}' must be <= {}", rules["max_value"])); } } if let (Some(properties), Some(object)) = ( @@ -1181,9 +1240,18 @@ async fn retry_backoff(attempt: u32) { .map(|seconds| (seconds * 1000.0) as u64) .unwrap_or(2_000); let delay_ms = base_ms - .saturating_mul(1_u64 << attempt.saturating_sub(1).min(20)) + .saturating_mul(1_u64 << attempt.min(20)) .min(maximum_ms); - tokio::time::sleep(std::time::Duration::from_millis(delay_ms)).await; + let jitter_ms = if delay_ms == 0 { + 0 + } else { + std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap_or_default() + .subsec_nanos() as u64 + % (delay_ms + 1) + }; + tokio::time::sleep(std::time::Duration::from_millis(jitter_ms)).await; } fn is_hop_by_hop(name: &HeaderName) -> bool { @@ -1445,7 +1513,7 @@ mod tests { let body: Value = serde_json::from_slice(&to_bytes(response.into_body(), 4096).await.unwrap()).unwrap(); assert_eq!(body["error_code"], "GTW006"); - assert_eq!(body["error_message"], "Invalid JSON response from upstream"); + assert_eq!(body["error_message"], "Malformed JSON from upstream"); server.abort(); } @@ -1892,6 +1960,30 @@ mod tests { let wrong_type = json!({ "name": "Ada", "count": "two" }); assert!(validate_crud_schema(Some(&schema), &wrong_type, false).is_err()); + + let constraints = json!({ + "code": {"type": "string", "pattern": "[A-Z]{2}", "enum": ["AB", "CD"]}, + "score": {"type": "number", "min_value": 1, "max_value": 5}, + "integer": {"type": "integer"} + }); + assert!( + validate_crud_schema( + Some(&constraints), + &json!({"code": "AB", "score": 3, "integer": true}), + false + ) + .is_ok() + ); + let error = validate_crud_schema( + Some(&constraints), + &json!({"code": "zz", "score": 8, "integer": false}), + false, + ) + .unwrap_err() + .to_string(); + assert!(error.contains("does not match pattern")); + assert!(error.contains("must be one of: AB, CD")); + assert!(error.contains("must be <= 5")); assert_eq!( crud_resource_id("/api/rest/demo/v1/items/resource-1"), Some("resource-1") diff --git a/gateway-rs/src/storage/cache.rs b/gateway-rs/src/storage/cache.rs index 6b5f8238..5f993bc5 100644 --- a/gateway-rs/src/storage/cache.rs +++ b/gateway-rs/src/storage/cache.rs @@ -113,6 +113,10 @@ struct CounterEntry { impl WindowCounter { pub fn incr(&self, key: &str, ttl_seconds: u64, now_seconds: u64) -> u64 { + self.incr_by(key, 1, ttl_seconds, now_seconds) + } + + pub fn incr_by(&self, key: &str, amount: u64, ttl_seconds: u64, now_seconds: u64) -> u64 { let mut inner = self.inner.lock().expect("counter mutex poisoned"); let entry = inner.entry(key.to_owned()).or_insert(CounterEntry { count: 0, @@ -122,7 +126,7 @@ impl WindowCounter { entry.count = 0; entry.expires_at = now_seconds + ttl_seconds; } - entry.count += 1; + entry.count = entry.count.saturating_add(amount); entry.count } diff --git a/gateway-rs/src/storage/field_encryption.rs b/gateway-rs/src/storage/field_encryption.rs new file mode 100644 index 00000000..72f5370e --- /dev/null +++ b/gateway-rs/src/storage/field_encryption.rs @@ -0,0 +1,48 @@ +use std::env; + +use base64::{Engine as _, engine::general_purpose::URL_SAFE}; +use fernet::Fernet; +use sha2::{Digest, Sha256}; + +fn cipher() -> Option { + let key = env::var("TOKEN_ENCRYPTION_KEY") + .ok() + .filter(|value| !value.is_empty()) + .or_else(|| { + env::var("MEM_ENCRYPTION_KEY") + .ok() + .filter(|value| !value.is_empty()) + })?; + Fernet::new(&key).or_else(|| { + let encoded = URL_SAFE.encode(Sha256::digest(key.as_bytes())); + Fernet::new(&encoded) + }) +} + +pub fn encrypt_value(value: Option<&str>) -> Option { + let value = value?; + Some(match cipher() { + Some(cipher) => format!("enc:{}", cipher.encrypt(value.as_bytes())), + None => value.to_owned(), + }) +} + +pub fn decrypt_value(value: Option<&str>) -> Option { + let value = value?; + let Some(token) = value.strip_prefix("enc:") else { + return Some(value.to_owned()); + }; + let cipher = cipher()?; + String::from_utf8(cipher.decrypt(token).ok()?).ok() +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn plaintext_values_pass_through_without_an_encryption_marker() { + assert_eq!(decrypt_value(Some("plain")), Some("plain".to_owned())); + assert_eq!(decrypt_value(None), None); + } +} diff --git a/gateway-rs/src/storage/mod.rs b/gateway-rs/src/storage/mod.rs index edf71786..5bb19df2 100644 --- a/gateway-rs/src/storage/mod.rs +++ b/gateway-rs/src/storage/mod.rs @@ -1,5 +1,6 @@ pub mod cache; pub mod configuration; +pub mod field_encryption; pub mod memory; pub mod models; pub mod mongo; diff --git a/gateway-rs/src/storage/runtime.rs b/gateway-rs/src/storage/runtime.rs index 65a01bf4..5b1cf26d 100644 --- a/gateway-rs/src/storage/runtime.rs +++ b/gateway-rs/src/storage/runtime.rs @@ -103,11 +103,12 @@ impl SharedStorage { async fn ensure_indexes(database: &Database) -> Result<(), StorageError> { let indexes = [ - ("users", doc! {"username": 1}), - ("users", doc! {"email": 1}), - ("roles", doc! {"role_name": 1}), - ("groups", doc! {"group_name": 1}), - ("apis", doc! {"api_name": 1, "api_version": 1}), + ("users", doc! {"username": 1}, true), + ("users", doc! {"email": 1}, true), + ("roles", doc! {"role_name": 1}, true), + ("groups", doc! {"group_name": 1}, true), + ("apis", doc! {"api_id": 1}, true), + ("apis", doc! {"api_name": 1, "api_version": 1}, false), ( "endpoints", doc! { @@ -116,24 +117,33 @@ impl SharedStorage { "endpoint_method": 1, "endpoint_uri": 1 }, + true, + ), + ("subscriptions", doc! {"username": 1}, true), + ("routings", doc! {"client_key": 1}, true), + ("credit_defs", doc! {"api_credit_group": 1}, true), + ("user_credits", doc! {"username": 1}, true), + ("endpoint_validations", doc! {"endpoint_id": 1}, true), + ("tiers", doc! {"tier_id": 1}, true), + ("tiers", doc! {"name": 1}, false), + ("user_tier_assignments", doc! {"user_id": 1}, true), + ("user_tier_assignments", doc! {"tier_id": 1}, false), + ("vault_entries", doc! {"username": 1, "key_name": 1}, true), + ("vault_entries", doc! {"username": 1}, false), + ("config_snapshots", doc! {"snapshot_id": 1}, true), + ( + "revocations", + doc! {"type": 1, "username": 1, "jti": 1}, + true, ), - ("subscriptions", doc! {"username": 1}), - ("routings", doc! {"client_key": 1}), - ("credit_defs", doc! {"api_credit_group": 1}), - ("user_credits", doc! {"username": 1}), - ("tiers", doc! {"tier_name": 1}), - ("user_tier_assignments", doc! {"user_id": 1}), - ("vault_entries", doc! {"username": 1, "key_name": 1}), - ("config_snapshots", doc! {"snapshot_id": 1}), - ("revocations", doc! {"type": 1, "username": 1, "jti": 1}), ]; - for (collection, keys) in indexes { + for (collection, keys, unique) in indexes { database .collection::(collection) .create_index( IndexModel::builder() .keys(keys) - .options(IndexOptions::builder().unique(true).build()) + .options(IndexOptions::builder().unique(unique).build()) .build(), ) .await?; @@ -1313,17 +1323,75 @@ fn value_matches(item: &Value, filter: &Value) -> bool { let Some(filter) = filter.as_object() else { return true; }; - filter - .iter() - .all(|(key, expected)| item.get(key) == Some(expected)) + filter.iter().all(|(key, expected)| { + if key == "$or" { + return expected.as_array().is_none_or(|alternatives| { + alternatives + .iter() + .any(|alternative| value_matches(item, alternative)) + }); + } + if let Some(candidates) = expected.get("$in").and_then(Value::as_array) { + return item + .get(key) + .is_some_and(|actual| candidates.contains(actual)); + } + item.get(key) == Some(expected) + }) } fn merge_object(target: &mut Value, updates: &Value) { if let (Some(target), Some(updates)) = (target.as_object_mut(), updates.as_object()) { for (key, value) in updates { - if key != "_id" && !value.is_null() { - target.insert(key.clone(), value.clone()); + if key == "_id" { + continue; + } + let parts = key.split('.').collect::>(); + let mut current = &mut *target; + for part in &parts[..parts.len().saturating_sub(1)] { + let entry = current + .entry((*part).to_owned()) + .or_insert_with(|| Value::Object(serde_json::Map::new())); + if !entry.is_object() { + *entry = Value::Object(serde_json::Map::new()); + } + current = entry.as_object_mut().expect("object inserted above"); } + let leaf = parts.last().copied().unwrap_or(key.as_str()); + current.insert(leaf.to_owned(), value.clone()); } } } + +#[cfg(test)] +mod parity_tests { + use super::*; + use serde_json::json; + + #[test] + fn memory_filters_match_python_or_and_in_contracts() { + let item = json!({"name": "alice", "role": "admin"}); + assert!(value_matches( + &item, + &json!({"$or": [{"name": "missing"}, {"role": "admin"}]}) + )); + assert!(value_matches( + &item, + &json!({"name": {"$in": ["alice", "bob"]}}) + )); + assert!(!value_matches(&item, &json!({"name": {"$in": ["bob"]}}))); + } + + #[test] + fn memory_updates_set_null_and_dotted_fields_like_python() { + let mut item = json!({"profile": "old", "keep": true}); + merge_object( + &mut item, + &json!({"profile.email": "a@example.com", "keep": null}), + ); + assert_eq!( + item, + json!({"profile": {"email": "a@example.com"}, "keep": null}) + ); + } +} diff --git a/gateway-rs/src/storage/snapshot.rs b/gateway-rs/src/storage/snapshot.rs index 36849400..fc6b21e8 100644 --- a/gateway-rs/src/storage/snapshot.rs +++ b/gateway-rs/src/storage/snapshot.rs @@ -8,6 +8,7 @@ use aes_gcm::{ Aes256Gcm, Nonce, aead::{Aead, Generate, KeyInit}, }; +use base64::Engine as _; use hkdf::Hkdf; use serde::{Deserialize, Serialize}; use serde_json::Value; @@ -172,13 +173,82 @@ async fn restore_file_with_key( ) -> Result<(u8, String), SnapshotError> { validate_key(key_material)?; let blob = fs::read(path)?; - let payload = decrypt_blob(&blob, key_material)?; + let mut payload = decrypt_blob(&blob, key_material)?; let version = payload.version; let created_at = payload.created_at.clone(); + for records in payload.data.values_mut() { + for record in records { + restore_python_json_values(record); + } + } storage.restore_memory_data(payload.data).await?; + reconcile_bootstrap_admin(storage).await; Ok((version, created_at)) } +fn restore_python_json_values(value: &mut Value) { + match value { + Value::Object(object) + if object.get("__type__").and_then(Value::as_str) == Some("bytes") => + { + let decoded = object + .get("data") + .and_then(Value::as_str) + .and_then(|encoded| { + base64::engine::general_purpose::STANDARD + .decode(encoded) + .ok() + }) + .and_then(|bytes| String::from_utf8(bytes).ok()) + .unwrap_or_default(); + *value = Value::String(decoded); + } + Value::Object(object) => { + for value in object.values_mut() { + restore_python_json_values(value); + } + } + Value::Array(values) => { + for value in values { + restore_python_json_values(value); + } + } + _ => {} + } +} + +async fn reconcile_bootstrap_admin(storage: &SharedStorage) { + let Ok(Some(admin)) = storage + .find_one("users", &serde_json::json!({"username": "admin"})) + .await + else { + return; + }; + let mut updates = serde_json::Map::new(); + if let Ok(email) = env::var("DOORMAN_ADMIN_EMAIL") + && admin.get("email").and_then(Value::as_str) != Some(email.as_str()) + { + updates.insert("email".to_owned(), Value::String(email)); + } + if admin.get("ui_access").and_then(Value::as_bool) != Some(true) { + updates.insert("ui_access".to_owned(), Value::Bool(true)); + } + if let Ok(password) = env::var("DOORMAN_ADMIN_PASSWORD") + && let Ok(password) = bcrypt::hash(password, bcrypt::DEFAULT_COST) + { + updates.insert("password".to_owned(), Value::String(password)); + } + if !updates.is_empty() { + let _ = storage + .update_one( + "users", + &serde_json::json!({"username": "admin"}), + &Value::Object(updates), + ) + .await; + } +} + fn decrypt_blob(blob: &[u8], key_material: &str) -> Result { let plaintext = decrypt_plaintext(blob, key_material)?; let snapshot: Snapshot = serde_json::from_slice(&plaintext)?; @@ -630,6 +700,17 @@ mod tests { assert_eq!(snapshot.data["users"][0]["password"], "hash"); } + #[test] + fn restores_python_byte_wrappers_for_password_hashes() { + let mut value = serde_json::json!({ + "password": {"__type__": "bytes", "data": "JDJiJDEyJGhhc2g="}, + "nested": [{"value": {"__type__": "bytes", "data": "dGV4dA=="}}] + }); + restore_python_json_values(&mut value); + assert_eq!(value["password"], "$2b$12$hash"); + assert_eq!(value["nested"][0]["value"], "text"); + } + #[test] fn rejects_unsupported_snapshot_version() { let payload = Snapshot { diff --git a/gateway-rs/src/storage/vault.rs b/gateway-rs/src/storage/vault.rs index 4d31148e..9211bf01 100644 --- a/gateway-rs/src/storage/vault.rs +++ b/gateway-rs/src/storage/vault.rs @@ -12,6 +12,8 @@ pub enum VaultError { MissingKey, #[error("vault encryption failed")] Encryption, + #[error("vault decryption failed")] + Decryption, } pub fn encrypt(value: &str, email: &str, username: &str) -> Result { @@ -28,6 +30,26 @@ pub fn encrypt(value: &str, email: &str, username: &str) -> Result Result { + let vault_key = env::var("VAULT_KEY") + .ok() + .filter(|value| !value.is_empty()) + .ok_or(VaultError::MissingKey)?; + let combined = format!("{email}:{username}:{vault_key}"); + let salt = Sha256::digest(combined.as_bytes()); + let mut derived = [0_u8; 32]; + pbkdf2_hmac::(vault_key.as_bytes(), &salt, 100_000, &mut derived); + let encoded = URL_SAFE.encode(derived); + let cipher = Fernet::new(&encoded).ok_or(VaultError::Decryption)?; + let token = value.strip_prefix("v1:").unwrap_or(value); + let plaintext = cipher.decrypt(token).map_err(|_| VaultError::Decryption)?; + String::from_utf8(plaintext).map_err(|_| VaultError::Decryption) +} + +pub fn is_configured() -> bool { + env::var("VAULT_KEY").is_ok_and(|value| !value.is_empty()) +} + #[cfg(test)] mod tests { use super::*; diff --git a/gateway-rs/src/validation/graphql.rs b/gateway-rs/src/validation/graphql.rs index 346cfb9d..a8319a61 100644 --- a/gateway-rs/src/validation/graphql.rs +++ b/gateway-rs/src/validation/graphql.rs @@ -1,5 +1,15 @@ //! GraphQL validation port: depth, complexity field cost, and introspection control. +use std::sync::LazyLock; + +static DOUBLE_QUOTED: LazyLock = + LazyLock::new(|| regex::Regex::new(r#""[^"]*""#).expect("string expression is valid")); +static SINGLE_QUOTED: LazyLock = + LazyLock::new(|| regex::Regex::new(r"'[^']*'").expect("string expression is valid")); +static GRAPHQL_WORD: LazyLock = LazyLock::new(|| { + regex::Regex::new(r"\b[a-zA-Z_][a-zA-Z0-9_]*\b").expect("field expression is valid") +}); + #[derive(Debug, Clone)] pub struct GraphqlValidationConfig { pub max_depth: usize, @@ -42,29 +52,16 @@ pub fn validate_graphql_query(query: &str, config: &GraphqlValidationConfig) -> } pub fn calculate_graphql_depth(query: &str) -> usize { + let without_comments = query + .lines() + .map(|line| line.split_once('#').map_or(line, |(prefix, _)| prefix)) + .collect::>() + .join("\n"); + let without_strings = DOUBLE_QUOTED.replace_all(&without_comments, "\"\""); + let without_strings = SINGLE_QUOTED.replace_all(&without_strings, "''"); let mut depth = 0usize; let mut max_depth = 0usize; - let mut in_string = false; - let mut in_comment = false; - - for ch in query.chars() { - if in_comment { - if ch == '\n' { - in_comment = false; - } - continue; - } - if ch == '"' { - in_string = !in_string; - continue; - } - if in_string { - continue; - } - if ch == '#' { - in_comment = true; - continue; - } + for ch in without_strings.chars() { if ch == '{' { depth += 1; if depth > max_depth { @@ -79,21 +76,19 @@ pub fn calculate_graphql_depth(query: &str) -> usize { } pub fn calculate_graphql_cost(query: &str) -> usize { - let mut cost = 0usize; - - for word in query.split_whitespace() { - let clean_word = word - .trim_matches(|c| c == '{' || c == '}' || c == '(' || c == ')' || c == ':' || c == ','); - if clean_word.starts_with('#') { - continue; - } - if !clean_word.is_empty() && !clean_word.starts_with('"') && !is_graphql_keyword(clean_word) - { - cost += 1; - } + if query.is_empty() { + return 0; } - - cost.max(1) + let without_comments = query + .lines() + .map(|line| line.split_once('#').map_or(line, |(prefix, _)| prefix)) + .collect::>() + .join("\n"); + let without_strings = DOUBLE_QUOTED.replace_all(&without_comments, ""); + GRAPHQL_WORD + .find_iter(&without_strings) + .filter(|word| !is_graphql_keyword(&word.as_str().to_ascii_lowercase())) + .count() } fn is_graphql_keyword(word: &str) -> bool { @@ -119,5 +114,9 @@ mod tests { let introspection = "query { __schema { types { name } } }"; assert!(validate_graphql_query(introspection, &config).is_err()); + + assert_eq!(calculate_graphql_depth("{ field(arg: '{') { child } }"), 2); + assert_eq!(calculate_graphql_cost("query { user { id name } }"), 3); + assert_eq!(calculate_graphql_cost(""), 0); } } diff --git a/gateway-rs/src/validation/json.rs b/gateway-rs/src/validation/json.rs index 43c50adc..33a85e20 100644 --- a/gateway-rs/src/validation/json.rs +++ b/gateway-rs/src/validation/json.rs @@ -50,6 +50,7 @@ pub fn validate_json_with_registry( .unwrap_or(schema) .as_object() .ok_or_else(|| "Invalid endpoint validation schema".to_owned())?; + validate_schema_paths(mapping, "")?; for (path, rules) in mapping { let found = nested_value(value, path); validate_value(found, rules, path, registry)?; @@ -69,7 +70,7 @@ fn validate_value( .unwrap_or(false); let Some(value) = value.filter(|value| !value.is_null()) else { return if required { - Err(format!("Required field {path} is missing")) + Err("Field is required".to_owned()) } else { Ok(()) }; @@ -80,34 +81,42 @@ fn validate_value( .unwrap_or_default(); let valid_type = match expected { "string" => value.is_string(), - "number" => value.is_number(), + // bool is a subclass of int in Python, so the pinned number validator + // accepts JSON booleans and applies numeric bounds to 0/1. + "number" => value.is_number() || value.is_boolean(), "boolean" => value.is_boolean(), "array" => value.is_array(), "object" => value.is_object(), _ => true, }; if !valid_type { - return Err(format!("Expected {expected} at {path}")); + return Err(format!( + "Expected {expected}, got {}", + python_type_name(value) + )); } if let Some(text) = value.as_str() { let length = text.chars().count() as f64; - enforce_range(length, rules, path, "String length")?; + enforce_range(length, rules, "String length", "", "")?; if let Some(pattern) = rules.get("pattern").and_then(Value::as_str) { let regex = Regex::new(pattern) .map_err(|_| format!("Invalid validation pattern for {path}"))?; - if !regex.is_match(text) { - return Err(format!("String does not match pattern {pattern} at {path}")); + if regex.find(text).is_none_or(|found| found.start() != 0) { + return Err(format!("String does not match pattern {pattern}")); } } if let Some(format) = rules.get("format").and_then(Value::as_str) { validate_format(text, format, path)?; } } - if let Some(number) = value.as_f64() { - enforce_range(number, rules, path, "Value")?; + if let Some(number) = value + .as_f64() + .or_else(|| value.as_bool().map(|value| if value { 1.0 } else { 0.0 })) + { + enforce_range(number, rules, "Value", "", "")?; } if let Some(items) = value.as_array() { - enforce_range(items.len() as f64, rules, path, "Array length")?; + enforce_range(items.len() as f64, rules, "Array", " items", " items")?; if let Some(item_rules) = rules.get("array_items") { for (index, item) in items.iter().enumerate() { validate_value( @@ -124,6 +133,14 @@ fn validate_value( rules.get("nested_schema").and_then(Value::as_object), ) { for (field, nested_rules) in nested { + if nested_rules + .get("required") + .and_then(Value::as_bool) + .unwrap_or(false) + && object.get(field).is_none_or(Value::is_null) + { + return Err(format!("Required field {field} is missing")); + } validate_value( object.get(field), nested_rules, @@ -134,69 +151,169 @@ fn validate_value( } if let Some(allowed) = rules.get("enum").and_then(Value::as_array) { if !allowed.contains(value) { - return Err(format!("Value at {path} must be one of {allowed:?}")); + return Err(format!( + "Value must be one of {}", + python_list_repr(allowed) + )); } } if let Some(name) = rules.get("custom_validator").and_then(Value::as_str) { registry .validate(name, value, rules) - .map_err(|message| format!("{message} at {path}"))?; + .map_err(|message| message.to_owned())?; } Ok(()) } -fn enforce_range(value: f64, rules: &Value, path: &str, description: &str) -> Result<(), String> { - if rules - .get("min") - .and_then(Value::as_f64) - .is_some_and(|minimum| value < minimum) +fn enforce_range( + value: f64, + rules: &Value, + description: &str, + minimum_suffix: &str, + maximum_suffix: &str, +) -> Result<(), String> { + if let Some(minimum) = rules.get("min").and_then(Value::as_f64) + && value < minimum { - return Err(format!("{description} is below minimum at {path}")); + return Err(format!( + "{description} must be at least {}{minimum_suffix}", + python_number(minimum) + )); } - if rules - .get("max") - .and_then(Value::as_f64) - .is_some_and(|maximum| value > maximum) + if let Some(maximum) = rules.get("max").and_then(Value::as_f64) + && value > maximum { - return Err(format!("{description} exceeds maximum at {path}")); + return Err(format!( + "{description} must be at most {}{maximum_suffix}", + python_number(maximum) + )); } Ok(()) } fn validate_format(value: &str, format: &str, path: &str) -> Result<(), String> { let valid = match format { - "email" => value - .split_once('@') - .is_some_and(|(local, domain)| !local.is_empty() && domain.contains('.')), - "url" => { - (value.starts_with("http://") || value.starts_with("https://")) - && value - .split_once("://") - .is_some_and(|(_, host)| host.contains('.')) - } + "email" => Regex::new(r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$") + .is_ok_and(|regex| regex.is_match(value)), + "url" => Regex::new( + r"^https?://(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b[-a-zA-Z0-9()@:%_+.~#?&/=]*$", + ) + .is_ok_and(|regex| regex.is_match(value)), "date" => valid_date(value), - "datetime" => value.contains('T') && value.len() >= 16, + "datetime" => valid_datetime(value), "uuid" => uuid::Uuid::parse_str(value).is_ok(), _ => true, }; if valid { Ok(()) } else { - Err(format!("Invalid {format} format at {path}")) + let message = match format { + "date" => "Invalid date format (YYYY-MM-DD)", + "datetime" => "Invalid datetime format (ISO 8601)", + "uuid" => "Invalid UUID format", + "email" => "Invalid email format", + "url" => "Invalid URL format", + _ => return Ok(()), + }; + let _ = path; + Err(message.to_owned()) } } fn valid_date(value: &str) -> bool { - let mut parts = value.split('-'); - matches!( - ( - parts.next().and_then(|part| part.parse::().ok()), - parts.next().and_then(|part| part.parse::().ok()), - parts.next().and_then(|part| part.parse::().ok()), - parts.next(), - ), - (Some(year), Some(1..=12), Some(1..=31), None) if year > 0 + time::Date::parse( + value, + &time::format_description::well_known::Iso8601::DEFAULT, ) + .is_ok() +} + +fn valid_datetime(value: &str) -> bool { + valid_date(value) + || time::OffsetDateTime::parse( + value, + &time::format_description::well_known::Iso8601::DEFAULT, + ) + .is_ok() + || time::PrimitiveDateTime::parse( + value, + &time::format_description::well_known::Iso8601::DEFAULT, + ) + .is_ok() + || value.find(' ').is_some_and(|index| { + let mut normalized = value.to_owned(); + normalized.replace_range(index..=index, "T"); + time::PrimitiveDateTime::parse( + &normalized, + &time::format_description::well_known::Iso8601::DEFAULT, + ) + .is_ok() + }) +} + +fn python_type_name(value: &Value) -> &'static str { + match value { + Value::Null => "NoneType", + Value::Bool(_) => "bool", + Value::Number(number) if number.is_i64() || number.is_u64() => "int", + Value::Number(_) => "float", + Value::String(_) => "str", + Value::Array(_) => "list", + Value::Object(_) => "dict", + } +} + +fn python_number(value: f64) -> String { + if value.fract() == 0.0 { + format!("{}", value as i64) + } else { + value.to_string() + } +} + +fn python_list_repr(values: &[Value]) -> String { + let values = values + .iter() + .map(|value| match value { + Value::String(value) => format!("'{value}'"), + Value::Bool(true) => "True".to_owned(), + Value::Bool(false) => "False".to_owned(), + Value::Null => "None".to_owned(), + value => value.to_string(), + }) + .collect::>() + .join(", "); + format!("[{values}]") +} + +fn validate_schema_paths( + schema: &serde_json::Map, + parent: &str, +) -> Result<(), String> { + for (path, rules) in schema { + let full_path = if parent.is_empty() { + path.clone() + } else { + format!("{parent}.{path}") + }; + if full_path.split('.').any(|part| { + part.is_empty() + || part.split_once('[').is_some_and(|(field, index)| { + field.is_empty() + && !index + .strip_suffix(']') + .unwrap_or(index) + .bytes() + .all(|byte| byte.is_ascii_digit()) + }) + }) { + return Err(format!("Invalid field path: {full_path}")); + } + if let Some(nested) = rules.get("nested_schema").and_then(Value::as_object) { + validate_schema_paths(nested, &full_path)?; + } + } + Ok(()) } fn nested_value<'a>(root: &'a Value, path: &str) -> Option<&'a Value> { @@ -267,7 +384,7 @@ mod tests { assert!(validate_json_with_registry(&json!({"code": "ABC"}), &schema, ®istry).is_ok()); assert_eq!( validate_json_with_registry(&json!({"code": "Abc"}), &schema, ®istry).unwrap_err(), - "Not upper at code" + "Not upper" ); let unknown = json!({"code": {"custom_validator": "not_compiled"}}); @@ -362,4 +479,51 @@ mod tests { }}}); assert!(validate_json(&json!({"user": {"name": "ok"}}), &invalid_path).is_err()); } + + #[test] + fn preserves_python_validation_messages_and_coercion_edges() { + assert_eq!( + validate_json( + &json!({}), + &json!({"name": {"required": true, "type": "string"}}) + ) + .unwrap_err(), + "Field is required" + ); + assert_eq!( + validate_json(&json!({"name": 1}), &json!({"name": {"type": "string"}})).unwrap_err(), + "Expected string, got int" + ); + assert!( + validate_json( + &json!({"enabled": true}), + &json!({"enabled": {"type": "number", "min": 1}}) + ) + .is_ok() + ); + assert_eq!( + validate_json( + &json!({"code": "xxABC"}), + &json!({"code": {"type": "string", "pattern": "ABC"}}) + ) + .unwrap_err(), + "String does not match pattern ABC" + ); + assert_eq!( + validate_json( + &json!({"when": "2025-02-30"}), + &json!({"when": {"type": "string", "format": "date"}}) + ) + .unwrap_err(), + "Invalid date format (YYYY-MM-DD)" + ); + assert_eq!( + validate_json( + &json!({"status": "CLOSED"}), + &json!({"status": {"enum": ["NEW", "OPEN"]}}) + ) + .unwrap_err(), + "Value must be one of ['NEW', 'OPEN']" + ); + } } diff --git a/gateway-rs/src/validation/mod.rs b/gateway-rs/src/validation/mod.rs index 1fff0cd6..40b65855 100644 --- a/gateway-rs/src/validation/mod.rs +++ b/gateway-rs/src/validation/mod.rs @@ -1,4 +1,5 @@ pub mod graphql; pub mod json; pub mod protobuf; +pub mod sanitize; pub mod xml; diff --git a/gateway-rs/src/validation/sanitize.rs b/gateway-rs/src/validation/sanitize.rs new file mode 100644 index 00000000..f5373fbd --- /dev/null +++ b/gateway-rs/src/validation/sanitize.rs @@ -0,0 +1,85 @@ +use std::sync::LazyLock; + +static HTML_TAG: LazyLock = + LazyLock::new(|| regex::Regex::new(r"<[^>]+>").expect("HTML tag expression is valid")); +static UNSAFE_USERNAME: LazyLock = LazyLock::new(|| { + regex::Regex::new(r"[^a-zA-Z0-9_\-.@]").expect("username expression is valid") +}); +static UNSAFE_API_NAME: LazyLock = + LazyLock::new(|| regex::Regex::new(r"[^a-zA-Z0-9_-]").expect("API-name expression is valid")); + +fn html_escape(text: &str) -> String { + text.replace('&', "&") + .replace('<', "<") + .replace('>', ">") + .replace('"', """) + .replace('\'', "'") +} + +pub fn sanitize_html(text: &str, allow_tags: bool) -> String { + if allow_tags { + html_escape(text) + } else { + html_escape(&HTML_TAG.replace_all(text, "")) + } +} + +pub fn sanitize_input(text: &str, max_length: Option) -> String { + let sanitized = sanitize_html(text, false).replace('\0', ""); + let normalized = sanitized.split_whitespace().collect::>().join(" "); + match max_length.filter(|maximum| normalized.chars().count() > *maximum) { + Some(maximum) => normalized.chars().take(maximum).collect(), + None => normalized, + } +} + +pub fn sanitize_url(url: &str) -> String { + let url = crate::python_scalar::strip(url); + let lower = url.to_lowercase(); + if ["javascript:", "data:", "vbscript:", "file:", "about:"] + .iter() + .any(|scheme| lower.starts_with(scheme)) + { + String::new() + } else { + url.to_owned() + } +} + +pub fn strip_control_characters(text: &str) -> String { + text.chars() + .filter(|character| *character as u32 >= 32 || matches!(character, '\n' | '\r' | '\t')) + .collect() +} + +pub fn sanitize_username(username: &str) -> String { + let sanitized = sanitize_html(username, false); + UNSAFE_USERNAME.replace_all(&sanitized, "").into_owned() +} + +pub fn sanitize_api_name(name: &str) -> String { + let sanitized = sanitize_html(name, false); + UNSAFE_API_NAME.replace_all(&sanitized, "").into_owned() +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn sanitizers_match_python_examples_and_character_limits() { + assert_eq!(sanitize_html("A&B", false), "A&B"); + assert_eq!( + sanitize_html("A&B", true), + "<b>A&B</b>" + ); + assert_eq!( + sanitize_input(" hello\0 world ", Some(8)), + "hello wo" + ); + assert_eq!(sanitize_url(" JAVASCRIPT:alert(1) "), ""); + assert_eq!(strip_control_characters("a\u{1}b\nc"), "ab\nc"); + assert_eq!(sanitize_username("a!._-@"), "a._-@"); + assert_eq!(sanitize_api_name("api name/v1"), "apinamev1"); + } +} diff --git a/gateway-rs/tests/live_tests_parity.rs b/gateway-rs/tests/live_tests_parity.rs index 68cf43c2..2ad2784d 100644 --- a/gateway-rs/tests/live_tests_parity.rs +++ b/gateway-rs/tests/live_tests_parity.rs @@ -3221,7 +3221,7 @@ async fn live_test_90_security_tools_and_config_export_import_parity() { .header(header::AUTHORIZATION, format!("Bearer {token}")) .header(header::CONTENT_TYPE, "application/json") .body(Body::from( - json!({"origin": "http://localhost:3000"}).to_string(), + json!({"origin": "http://localhost:3000", "method": "GET"}).to_string(), )) .unwrap(), ) diff --git a/gateway-rs/tests/memory_routes_parity.rs b/gateway-rs/tests/memory_routes_parity.rs index a26f49d1..46446645 100644 --- a/gateway-rs/tests/memory_routes_parity.rs +++ b/gateway-rs/tests/memory_routes_parity.rs @@ -170,6 +170,17 @@ async fn python_memory_route_contracts_in_isolated_processes() { } let manager = login(&app, "manager").await; + let (status, body) = request( + &app, + Method::POST, + "/platform/memory/dump", + Some(&manager), + json!({"path": []}), + ) + .await; + assert_eq!(status, StatusCode::UNPROCESSABLE_ENTITY, "{body}"); + assert_eq!(body["detail"][0]["loc"], json!(["body", "path"])); + let (status, body) = request( &app, Method::POST, diff --git a/gateway-rs/tests/platform_native.rs b/gateway-rs/tests/platform_native.rs index 2eafa27a..65a0bab1 100644 --- a/gateway-rs/tests/platform_native.rs +++ b/gateway-rs/tests/platform_native.rs @@ -306,7 +306,11 @@ async fn discovery_document_reads_fetch_once_and_reuse_the_python_cache_contract let calls = openapi_counter.clone(); async move { calls.fetch_add(1, Ordering::SeqCst); - Json(json!({"openapi": "3.0.0", "info": {"title": "Test API", "version": "1.0.0"}})) + Json(json!({ + "openapi": "3.0.0", + "info": {"title": "Test API", "version": "1.0.0"}, + "paths": {"/widgets": {"get": {"summary": "List widgets"}}} + })) } }), ) @@ -380,6 +384,45 @@ async fn discovery_document_reads_fetch_once_and_reuse_the_python_cache_contract } assert_eq!(openapi_calls.load(Ordering::SeqCst), 1); + let refreshed = platform_request( + &app, + Method::POST, + "/platform/api/cached-openapi/v1/openapi/refresh", + Some(&cookie), + None, + None, + ) + .await; + assert_eq!(refreshed.status(), StatusCode::OK); + assert_eq!( + response_json(refreshed).await, + json!({ + "message": "OpenAPI spec refreshed successfully", + "endpoints_found": 1 + }) + ); + assert_eq!(openapi_calls.load(Ordering::SeqCst), 2); + + let imported = platform_request( + &app, + Method::POST, + "/platform/api/cached-openapi/v1/openapi/import", + Some(&cookie), + None, + None, + ) + .await; + assert_eq!(imported.status(), StatusCode::OK); + assert_eq!( + response_json(imported).await, + json!({ + "message": "OpenAPI import completed", + "endpoints_found": 1, + "endpoints_imported": 1, + "endpoints_skipped": 0 + }) + ); + for (expected_cached, _) in [(false, 0), (true, 1)] { let response = platform_request( &app, @@ -1015,6 +1058,45 @@ async fn user_create_requires_python_model_role_before_service_logic() { ); } +#[tokio::test] +async fn update_password_model_validates_before_auth_and_matches_pydantic_bounds() { + let app = build_router(memory_state(false).await); + for body in [ + json!({}), + json!({"new_password": []}), + json!({"new_password": "short"}), + json!({"new_password": "x".repeat(37)}), + ] { + let response = platform_request( + &app, + Method::PUT, + "/platform/user/someone/update-password", + None, + None, + Some(body), + ) + .await; + assert_eq!(response.status(), StatusCode::UNPROCESSABLE_ENTITY); + assert_eq!(response_json(response).await["error_code"], "VAL001"); + } + + for body in [ + json!({"new_password": "é".repeat(36)}), + json!({"new_password": 123456, "unknown": "ignored"}), + ] { + let response = platform_request( + &app, + Method::PUT, + "/platform/user/someone/update-password", + None, + None, + Some(body), + ) + .await; + assert_eq!(response.status(), StatusCode::UNAUTHORIZED); + } +} + #[tokio::test] async fn user_create_matches_pydantic_bounds_and_scalar_coercion() { let app = build_router(memory_state(false).await); @@ -1025,6 +1107,8 @@ async fn user_create_matches_pydantic_bounds_and_scalar_coercion() { json!({"username": "shortpassword", "email": "shortpassword@example.com", "password": "TooShort1!", "role": "user"}), json!({"username": "negative-rate", "email": "negative-rate@example.com", "password": "A_secure_password_123!", "role": "user", "rate_limit_duration": -1}), json!({"username": "scalar-groups", "email": "scalar-groups@example.com", "password": "A_secure_password_123!", "role": "user", "groups": "team"}), + json!({"username": "null-groups", "email": "null-groups@example.com", "password": "A_secure_password_123!", "role": "user", "groups": null}), + json!({"username": "unicode-too-long", "email": "unicode-too-long@example.com", "password": "A_secure_password_123!", "role": "é".repeat(51)}), ] { let response = platform_request( &app, @@ -1070,7 +1154,26 @@ async fn user_create_matches_pydantic_bounds_and_scalar_coercion() { assert_eq!(created["rate_limit_duration"], 7); assert_eq!(created["active"], false); assert_eq!(created["bandwidth_limit_window"], "day"); + assert_eq!(created["ui_access"], false); + assert!(created["throttle_duration"].is_null()); + assert!(created["custom_attributes"].is_null()); assert!(created.get("unexpected").is_none()); + + let unicode = platform_request( + &app, + Method::POST, + "/platform/user", + Some(&cookie), + None, + Some(json!({ + "username": "é".repeat(50), + "email": "unicode@example.com", + "password": "A_secure_password_123!", + "role": "é".repeat(50), + })), + ) + .await; + assert_eq!(unicode.status(), StatusCode::CREATED); } #[tokio::test] @@ -1390,6 +1493,35 @@ async fn role_and_group_models_match_pydantic_defaults_coercion_and_empty_update response_json(empty_group_update).await["error_code"], "GRP006" ); + for (path, field) in [ + ("/platform/role", "role_name"), + ("/platform/group", "group_name"), + ] { + let accepted = platform_request( + &app, + Method::POST, + path, + Some(&cookie), + None, + Some(json!({field: "é".repeat(50)})), + ) + .await; + assert_eq!(accepted.status(), StatusCode::CREATED, "{path}"); + let rejected = platform_request( + &app, + Method::POST, + path, + Some(&cookie), + None, + Some(json!({field: "é".repeat(51)})), + ) + .await; + assert_eq!( + rejected.status(), + StatusCode::UNPROCESSABLE_ENTITY, + "{path}" + ); + } } #[tokio::test] @@ -1497,6 +1629,26 @@ async fn routing_models_match_pydantic_generation_coercion_and_update_exclusion( .await; assert_eq!(missing_update.status(), StatusCode::BAD_REQUEST); assert_eq!(response_json(missing_update).await["error_code"], "RTG004"); + let unicode_boundary = platform_request( + &app, + Method::POST, + "/platform/routing", + Some(&cookie), + None, + Some(json!({"routing_name": "é".repeat(50), "routing_servers": ["http://upstream"]})), + ) + .await; + assert_eq!(unicode_boundary.status(), StatusCode::CREATED); + let unicode_too_long = platform_request( + &app, + Method::POST, + "/platform/routing", + Some(&cookie), + None, + Some(json!({"routing_name": "é".repeat(51), "routing_servers": ["http://upstream"]})), + ) + .await; + assert_eq!(unicode_too_long.status(), StatusCode::UNPROCESSABLE_ENTITY); } #[tokio::test] @@ -1521,7 +1673,7 @@ async fn endpoint_models_match_pydantic_coercion_bounds_and_null_elision() { Some(json!({ "api_name": "endpoint-model", "api_version": "v1", "endpoint_method": "GET", "endpoint_uri": "/items", "endpoint_description": 123, "endpoint_servers": [1, false], - "ignored": "field" + "api_id": "", "endpoint_id": "", "ignored": "field" })), ) .await; @@ -1538,6 +1690,32 @@ async fn endpoint_models_match_pydantic_coercion_bounds_and_null_elision() { assert_eq!(endpoint["client_uri"], Value::Null); assert_eq!(endpoint["api_id"], "source-api-id"); assert!(endpoint.get("ignored").is_none()); + let unicode_boundary = platform_request( + &app, + Method::POST, + "/platform/endpoint", + Some(&cookie), + None, + Some(json!({ + "api_name": "endpoint-model", "api_version": "v1", "endpoint_method": "GET", + "endpoint_uri": "/unicode", "endpoint_description": "é".repeat(255) + })), + ) + .await; + assert_eq!(unicode_boundary.status(), StatusCode::CREATED); + let unicode_too_long = platform_request( + &app, + Method::POST, + "/platform/endpoint", + Some(&cookie), + None, + Some(json!({ + "api_name": "endpoint-model", "api_version": "v1", "endpoint_method": "GET", + "endpoint_uri": "/unicode-too-long", "endpoint_description": "é".repeat(256) + })), + ) + .await; + assert_eq!(unicode_too_long.status(), StatusCode::UNPROCESSABLE_ENTITY); let duplicate = platform_request( &app, Method::POST, @@ -1743,6 +1921,30 @@ async fn subscription_model_coerces_python_scalars_and_ignores_unknown_fields() ) .await; assert_eq!(invalid.status(), StatusCode::UNPROCESSABLE_ENTITY); + let unicode_boundary = platform_request( + &app, + Method::POST, + "/platform/subscription/subscribe", + Some(&cookie), + None, + Some(json!({ + "username": "admin", "api_name": "é".repeat(50), "api_version": "v1" + })), + ) + .await; + assert_eq!(unicode_boundary.status(), StatusCode::NOT_FOUND); + let unicode_too_long = platform_request( + &app, + Method::POST, + "/platform/subscription/subscribe", + Some(&cookie), + None, + Some(json!({ + "username": "admin", "api_name": "é".repeat(51), "api_version": "v1" + })), + ) + .await; + assert_eq!(unicode_too_long.status(), StatusCode::UNPROCESSABLE_ENTITY); } #[tokio::test] @@ -1859,6 +2061,10 @@ async fn authorization_refresh_and_invalidate_match_python() { ) .await; assert_eq!(invalidate.status(), StatusCode::OK); + assert_eq!( + response_json(invalidate).await, + json!({"message": "Your token has been invalidated"}) + ); let rejected = platform_request( &app, @@ -2028,8 +2234,7 @@ async fn authorization_admin_lifecycle_and_revoke_match_python() { .await; assert_eq!(status.status(), StatusCode::OK); let status = response_json(status).await; - assert_eq!(status["active"], true); - assert_eq!(status["revoked"], false); + assert_eq!(status, json!({"active": true, "revoked": false})); let revoke_path = format!("/platform/authorization/admin/revoke/{username}"); let revoke = platform_request( @@ -2042,6 +2247,10 @@ async fn authorization_admin_lifecycle_and_revoke_match_python() { ) .await; assert_eq!(revoke.status(), StatusCode::OK); + assert_eq!( + response_json(revoke).await, + json!({"message": format!("All tokens revoked for {username}")}) + ); let rejected = platform_request( &app, Method::GET, @@ -2064,6 +2273,10 @@ async fn authorization_admin_lifecycle_and_revoke_match_python() { ) .await; assert_eq!(disable.status(), StatusCode::OK); + assert_eq!( + response_json(disable).await, + json!({"message": format!("User {username} disabled and tokens revoked")}) + ); let status = platform_request( &app, Method::GET, @@ -2088,6 +2301,10 @@ async fn authorization_admin_lifecycle_and_revoke_match_python() { ) .await; assert_eq!(enable.status(), StatusCode::OK); + assert_eq!( + response_json(enable).await, + json!({"message": format!("User {username} enabled")}) + ); let unrevoke_path = format!("/platform/authorization/admin/unrevoke/{username}"); let unrevoke = platform_request( &app, @@ -2099,6 +2316,10 @@ async fn authorization_admin_lifecycle_and_revoke_match_python() { ) .await; assert_eq!(unrevoke.status(), StatusCode::OK); + assert_eq!( + response_json(unrevoke).await, + json!({"message": format!("Token revocation cleared for {username}")}) + ); let status = platform_request( &app, Method::GET, @@ -2111,6 +2332,49 @@ async fn authorization_admin_lifecycle_and_revoke_match_python() { let status = response_json(status).await; assert_eq!(status["active"], true); assert_eq!(status["revoked"], false); + + for (method, action, expected) in [ + ( + Method::POST, + "revoke", + "All tokens revoked for missing-user", + ), + ( + Method::POST, + "unrevoke", + "Token revocation cleared for missing-user", + ), + ( + Method::POST, + "disable", + "User missing-user disabled and tokens revoked", + ), + (Method::POST, "enable", "User missing-user enabled"), + ] { + let response = platform_request( + &app, + method, + &format!("/platform/authorization/admin/{action}/missing-user"), + Some(&admin_cookie), + None, + Some(json!({})), + ) + .await; + assert_eq!(response.status(), StatusCode::OK, "{action}"); + assert_eq!(response_json(response).await, json!({"message": expected})); + } + + let missing_status = platform_request( + &app, + Method::GET, + "/platform/authorization/admin/status/missing-user", + Some(&admin_cookie), + None, + None, + ) + .await; + assert_eq!(missing_status.status(), StatusCode::INTERNAL_SERVER_ERROR); + assert_eq!(response_json(missing_status).await["error_code"], "GTW999"); } #[derive(Clone, Default)] @@ -3440,7 +3704,7 @@ async fn strict_wildcard_cors_allows_localhost_like_python() { } #[tokio::test] -async fn proto_upload_rejects_traversal_filename() { +async fn proto_upload_ignores_the_client_filename_like_python() { let app = build_router(memory_state(false).await); let (cookie, _) = login(&app).await; let boundary = "doorman-proto-boundary"; @@ -3462,8 +3726,11 @@ async fn proto_upload_rejects_traversal_filename() { ) .await .unwrap(); - assert_eq!(response.status(), StatusCode::BAD_REQUEST); - assert_eq!(response_json(response).await["error_code"], "REQ002"); + assert_eq!(response.status(), StatusCode::OK); + assert_eq!( + response_json(response).await["message"], + "Proto file uploaded and gRPC code generated successfully" + ); } #[tokio::test] @@ -3549,6 +3816,10 @@ async fn proto_upload_extension_acceptance_matches_python_contract() { .await .unwrap(); assert_eq!(updated.status(), StatusCode::OK); + assert_eq!( + response_json(updated).await, + json!({"message": "Proto file updated successfully"}) + ); let fetched = app .clone() .oneshot( @@ -3561,12 +3832,9 @@ async fn proto_upload_extension_acceptance_matches_python_contract() { .await .unwrap(); assert_eq!(fetched.status(), StatusCode::OK); - assert!( - response_json(fetched).await["content"] - .as_str() - .unwrap() - .contains("Pong") - ); + let fetched = response_json(fetched).await; + assert_eq!(fetched["message"], "Proto file retrieved successfully"); + assert!(fetched["content"].as_str().unwrap().contains("Pong")); let deleted = app .clone() .oneshot( @@ -3580,6 +3848,10 @@ async fn proto_upload_extension_acceptance_matches_python_contract() { .await .unwrap(); assert_eq!(deleted.status(), StatusCode::OK); + assert_eq!( + response_json(deleted).await, + json!({"message": "Proto file and generated files deleted successfully"}) + ); for path in [ "/platform/proto/sample/v1", "/platform/proto/doesnotexist/v9", @@ -3596,6 +3868,11 @@ async fn proto_upload_extension_acceptance_matches_python_contract() { .await .unwrap(); assert_eq!(missing.status(), StatusCode::NOT_FOUND, "{path}"); + assert_eq!( + response_json(missing).await["error_code"], + "API002", + "{path}" + ); } } @@ -3807,7 +4084,11 @@ async fn limited_role_cannot_manage_monitor_credits_caches_or_endpoint_validatio "/platform/endpoint/endpoint/validation", Some(&cookie), None, - Some(json!({"endpoint_id": "missing", "validation_enabled": true})), + Some(json!({ + "endpoint_id": "missing", + "validation_enabled": true, + "validation_schema": {"validation_schema": {}} + })), ) .await; assert_eq!(validation.status(), StatusCode::FORBIDDEN); @@ -3938,10 +4219,10 @@ async fn proto_retrieval_requires_manage_apis_permission() { .unwrap(); assert_eq!(response.status(), StatusCode::FORBIDDEN); let body = response_json(response).await; - assert_eq!(body["error_code"], "API008"); + assert_eq!(body["error_code"], "AUTH001"); assert_eq!( body["error_message"], - "You do not have permission to manage proto files" + "User does not have permission to manage APIs" ); } @@ -3996,6 +4277,30 @@ async fn platform_security_headers_csp_hsts_and_request_ids_match_python() { assert!(secure.headers().contains_key("strict-transport-security")); assert_eq!(secure.headers()["x-request-id"], "python-request-id"); assert_eq!(secure.headers()["request_id"], "python-request-id"); + + let docs_app = build_router(memory_state(false).await); + let (cookie, _) = login(&docs_app).await; + let docs = platform_request( + &docs_app, + Method::GET, + "/platform/docs", + Some(&cookie), + None, + None, + ) + .await; + assert_eq!(docs.status(), StatusCode::OK); + assert!( + !docs.headers().contains_key("x-frame-options"), + "{:?}", + docs.headers() + ); + assert!( + docs.headers()["content-security-policy"] + .to_str() + .unwrap() + .contains("frame-ancestors *") + ); } #[tokio::test] @@ -4407,6 +4712,7 @@ async fn management_permissions_readiness_tools_and_restart_preserve_contract() let admin_readiness: Value = serde_json::from_slice(&to_bytes(admin_readiness.into_body(), 4096).await.unwrap()) .unwrap(); + assert_eq!(admin_readiness.as_object().unwrap().len(), 7); assert!(admin_readiness.get("mongodb").is_some()); assert!(admin_readiness.get("cache_backend").is_some()); @@ -4536,6 +4842,79 @@ async fn management_permissions_readiness_tools_and_restart_preserve_contract() assert_eq!(restart["error_code"], "SEC004"); } +#[tokio::test] +async fn tools_permissions_and_required_models_match_python() { + let (gateway_app, gateway_cookie) = + config_permission_app(Some("manage_gateway"), "tools-gateway").await; + let chaos = platform_request( + &gateway_app, + Method::POST, + "/platform/tools/chaos/toggle", + Some(&gateway_cookie), + None, + Some(json!({"backend": "mongo", "enabled": false})), + ) + .await; + assert_eq!(chaos.status(), StatusCode::OK); + + let cors_denied = platform_request( + &gateway_app, + Method::POST, + "/platform/tools/cors/check", + Some(&gateway_cookie), + None, + Some(json!({"origin": "http://localhost:3000", "method": "GET"})), + ) + .await; + assert_eq!(cors_denied.status(), StatusCode::FORBIDDEN); + + let missing = platform_request( + &gateway_app, + Method::POST, + "/platform/tools/chaos/toggle", + Some(&gateway_cookie), + None, + Some(json!({})), + ) + .await; + assert_eq!(missing.status(), StatusCode::UNPROCESSABLE_ENTITY); + let missing: Value = + serde_json::from_slice(&to_bytes(missing.into_body(), 4096).await.unwrap()).unwrap(); + assert_eq!(missing["detail"].as_array().unwrap().len(), 2); + assert_eq!(missing["detail"][0]["loc"], json!(["body", "backend"])); + assert_eq!(missing["detail"][1]["loc"], json!(["body", "enabled"])); + + let (security_app, security_cookie) = + config_permission_app(Some("manage_security"), "tools-security").await; + let cors = platform_request( + &security_app, + Method::POST, + "/platform/tools/cors/check", + Some(&security_cookie), + None, + Some(json!({"origin": "http://not-allowed.example", "method": "GET"})), + ) + .await; + assert_eq!(cors.status(), StatusCode::OK); + let cors: Value = + serde_json::from_slice(&to_bytes(cors.into_body(), 16 * 1024).await.unwrap()).unwrap(); + assert_eq!( + cors["preflight"]["response_headers"]["Access-Control-Allow-Origin"], + Value::Null + ); + + let chaos_denied = platform_request( + &security_app, + Method::POST, + "/platform/tools/chaos/toggle", + Some(&security_cookie), + None, + Some(json!({"backend": "redis", "enabled": true})), + ) + .await; + assert_eq!(chaos_denied.status(), StatusCode::FORBIDDEN); +} + #[tokio::test] async fn readiness_degrades_when_an_active_grpc_api_lacks_a_descriptor() { let state = memory_state(false).await; @@ -4565,7 +4944,7 @@ async fn readiness_degrades_when_an_active_grpc_api_lacks_a_descriptor() { None, ) .await; - assert_eq!(response.status(), StatusCode::SERVICE_UNAVAILABLE); + assert_eq!(response.status(), StatusCode::OK); let readiness = response_json(response).await; assert_eq!(readiness["status"], "degraded"); assert_eq!(readiness["missing_grpc_descriptors"], 1); @@ -4576,7 +4955,7 @@ async fn readiness_degrades_when_an_active_grpc_api_lacks_a_descriptor() { } #[tokio::test] -async fn readiness_degrades_when_a_background_persistence_task_is_unhealthy() { +async fn readiness_matches_python_and_ignores_v2_background_task_health() { let state = memory_state(false).await; state .runtime @@ -4594,10 +4973,10 @@ async fn readiness_degrades_when_a_background_persistence_task_is_unhealthy() { None, ) .await; - assert_eq!(response.status(), StatusCode::SERVICE_UNAVAILABLE); + assert_eq!(response.status(), StatusCode::OK); let readiness = response_json(response).await; - assert_eq!(readiness["status"], "degraded"); - assert_eq!(readiness["metrics_persistence_healthy"], false); + assert_eq!(readiness["status"], "ready"); + assert!(readiness.get("metrics_persistence_healthy").is_none()); } #[tokio::test] @@ -4708,6 +5087,37 @@ async fn analytics_routes_preserve_python_v2_response_contracts() { assert!(top["top_apis"][0]["api"].is_string()); assert!(top["total_apis"].is_number()); + for (path, field, kind) in [ + ( + "/platform/analytics/top-users?limit=0", + "limit", + "value_error.number.not_ge", + ), + ( + "/platform/analytics/overview?start_ts=not-an-int", + "start_ts", + "type_error.integer", + ), + ] { + let invalid = app + .clone() + .oneshot( + Request::builder() + .uri(path) + .header(header::COOKIE, &cookie) + .body(Body::empty()) + .unwrap(), + ) + .await + .unwrap(); + assert_eq!(invalid.status(), StatusCode::UNPROCESSABLE_ENTITY); + let invalid: Value = + serde_json::from_slice(&to_bytes(invalid.into_body(), 16 * 1024).await.unwrap()) + .unwrap(); + assert_eq!(invalid["detail"][0]["loc"], json!(["query", field])); + assert_eq!(invalid["detail"][0]["type"], kind); + } + let detail = app .oneshot( Request::builder() @@ -5503,10 +5913,24 @@ async fn python_endpoint_failure_and_validation_crud_contracts() { None, ) .await; - assert!(matches!( - missing.status(), - StatusCode::BAD_REQUEST | StatusCode::NOT_FOUND - )); + assert_eq!(missing.status(), StatusCode::BAD_REQUEST); + let missing = response_json(missing).await; + assert_eq!(missing["error_code"], "END004"); + assert_eq!( + missing["error_message"], + "Endpoint does not exist for the requested API name, version and URI" + ); + let empty = platform_request( + &app, + Method::GET, + "/platform/endpoint/na/v1", + Some(&cookie), + None, + None, + ) + .await; + assert_eq!(empty.status(), StatusCode::BAD_REQUEST); + assert_eq!(response_json(empty).await["error_code"], "END005"); let api = platform_request(&app, Method::POST, "/platform/api", Some(&cookie), None, Some(json!({"api_name": "valapi", "api_version": "v1", "api_description": "validation api", "api_allowed_roles": ["admin"], "api_allowed_groups": ["ALL"], "api_servers": ["http://127.0.0.1:9"], "api_type": "REST", "active": true}))).await; assert!(api.status().is_success()); let endpoint = platform_request(&app, Method::POST, "/platform/endpoint", Some(&cookie), None, Some(json!({"api_name": "valapi", "api_version": "v1", "endpoint_method": "POST", "endpoint_uri": "/payload", "endpoint_description": "payload"}))).await; @@ -5525,8 +5949,19 @@ async fn python_endpoint_failure_and_validation_crud_contracts() { .as_str() .unwrap() .to_owned(); - let schema = json!({"validation_schema": {"id": {"required": true, "type": "string"}}}); - let validation = json!({"endpoint_id": endpoint_id.clone(), "validation_enabled": true, "validation_schema": schema}); + let schema = json!({"validation_schema": {"id": { + "required": 1, + "type": "string", + "min": "2", + "nested_schema": null, + "ignored": "field" + }}}); + let validation = json!({ + "endpoint_id": endpoint_id.clone(), + "validation_enabled": "yes", + "validation_schema": schema, + "ignored": "field" + }); let created = platform_request( &app, Method::POST, @@ -5547,6 +5982,15 @@ async fn python_endpoint_failure_and_validation_crud_contracts() { ) .await; assert_eq!(fetched.status(), StatusCode::OK); + let fetched = response_json(fetched).await; + assert_eq!(fetched["validation_enabled"], true); + let id_rules = &fetched["validation_schema"]["validation_schema"]["id"]; + assert_eq!(id_rules["required"], true); + assert_eq!(id_rules["min"], 2); + assert_eq!(id_rules["max"], Value::Null); + assert_eq!(id_rules["pattern"], Value::Null); + assert!(id_rules.get("ignored").is_none()); + assert!(fetched.get("ignored").is_none()); let updated = platform_request( &app, Method::PUT, @@ -5557,6 +6001,16 @@ async fn python_endpoint_failure_and_validation_crud_contracts() { ) .await; assert_eq!(updated.status(), StatusCode::OK); + let invalid = platform_request( + &app, + Method::PUT, + &format!("/platform/endpoint/endpoint/validation/{endpoint_id}"), + Some(&cookie), + None, + Some(json!({"validation_enabled": true})), + ) + .await; + assert_eq!(invalid.status(), StatusCode::UNPROCESSABLE_ENTITY); let deleted = platform_request( &app, Method::DELETE, @@ -5620,6 +6074,13 @@ async fn python_config_export_sections_and_import_variants() { .iter() .any(|endpoint| endpoint["endpoint_uri"] == "/x") ); + assert!( + endpoints["endpoints"] + .as_array() + .unwrap() + .iter() + .all(|endpoint| endpoint["api_name"] == "filterapi" && endpoint["api_version"] == "v1") + ); for section in [ json!({"apis": []}), json!({"roles": []}), @@ -5711,13 +6172,14 @@ async fn python_config_permissions_granular_export_and_gateway_import_contracts( .await; assert_eq!(import.status(), StatusCode::OK); let (limited_app, limited_cookie) = config_permission_app(None, "config-limited").await; - for (method, path, payload) in [ - (Method::GET, "/platform/config/export/apis", None), - (Method::GET, "/platform/config/export/all", None), + for (method, path, payload, code) in [ + (Method::GET, "/platform/config/export/apis", None, "CFG002"), + (Method::GET, "/platform/config/export/all", None, "CFG001"), ( Method::POST, "/platform/config/import", Some(json!({"apis": []})), + "CFG006", ), ] { let response = platform_request( @@ -5730,6 +6192,7 @@ async fn python_config_permissions_granular_export_and_gateway_import_contracts( ) .await; assert_eq!(response.status(), StatusCode::FORBIDDEN, "{path}"); + assert_eq!(response_json(response).await["error_code"], code, "{path}"); } } @@ -5737,17 +6200,85 @@ async fn python_config_permissions_granular_export_and_gateway_import_contracts( async fn config_export_missing_named_resources_return_python_404() { let app = build_router(memory_state(false).await); let (cookie, _) = login(&app).await; - for path in [ - "/platform/config/export/apis?api_name=nope&api_version=v9", - "/platform/config/export/roles?role_name=nope-role", - "/platform/config/export/groups?group_name=nope-group", - "/platform/config/export/routings?client_key=nope-key", + let role = platform_request( + &app, + Method::GET, + "/platform/config/export/roles?role_name=admin", + Some(&cookie), + None, + None, + ) + .await; + assert_eq!(role.status(), StatusCode::OK); + let role = response_json(role).await; + assert_eq!(role["role"]["role_name"], "admin"); + assert!(role.get("roles").is_none()); + for (path, code, message) in [ + ( + "/platform/config/export/apis?api_name=nope&api_version=v9", + "CFG404", + "API not found", + ), + ( + "/platform/config/export/roles?role_name=nope-role", + "CFG405", + "Role not found", + ), + ( + "/platform/config/export/groups?group_name=nope-group", + "CFG406", + "Group not found", + ), + ( + "/platform/config/export/routings?client_key=nope-key", + "CFG407", + "Routing not found", + ), ] { let response = platform_request(&app, Method::GET, path, Some(&cookie), None, None).await; assert_eq!(response.status(), StatusCode::NOT_FOUND, "{path}"); + let response = response_json(response).await; + assert_eq!(response["error_code"], code, "{path}"); + assert_eq!(response["error_message"], message, "{path}"); } } +#[tokio::test] +async fn config_rollback_preserves_python_permission_and_missing_snapshot_quirks() { + let (limited_app, limited_cookie) = config_permission_app(None, "rollback-limited").await; + let denied = platform_request( + &limited_app, + Method::POST, + "/platform/config/rollback", + Some(&limited_cookie), + None, + Some(json!({})), + ) + .await; + assert_eq!(denied.status(), StatusCode::INTERNAL_SERVER_ERROR); + assert_eq!( + response_json(denied).await, + json!({"detail": "Rollback failed"}) + ); + + let app = build_router(memory_state(false).await); + let (cookie, _) = login(&app).await; + let missing = platform_request( + &app, + Method::POST, + "/platform/config/rollback", + Some(&cookie), + None, + Some(json!({})), + ) + .await; + assert_eq!(missing.status(), StatusCode::NOT_FOUND); + assert_eq!( + response_json(missing).await, + json!({"error_code": "CFG404", "error_message": "No snapshot found"}) + ); +} + #[tokio::test] async fn python_config_import_ignores_malformed_entries() { let state = memory_state(false).await; @@ -5934,6 +6465,32 @@ async fn python_credit_definition_masks_secret_key_material() { assert_eq!(body["api_key_header"], "x-api-key"); assert_eq!(body["api_key_present"], true); assert!(body.get("api_key").is_none()); + let list = platform_request( + &app, + Method::GET, + "/platform/credit/defs", + Some(&cookie), + None, + None, + ) + .await; + assert_eq!(list.status(), StatusCode::OK); + let list = response_json(list).await; + assert_eq!(list["page"], 1); + assert_eq!(list["page_size"], 50); + assert_eq!(list["total"], 1); + assert_eq!(list["items"][0]["api_credit_group"], "maskgroup"); + let missing = platform_request( + &app, + Method::GET, + "/platform/credit/defs/missing", + Some(&cookie), + None, + None, + ) + .await; + assert_eq!(missing.status(), StatusCode::NOT_FOUND); + assert_eq!(response_json(missing).await["error_code"], "CRD021"); } #[tokio::test] @@ -5951,10 +6508,16 @@ async fn credit_models_match_pydantic_required_fields_coercion_and_unknown_elisi Some(json!({ "api_credit_group": true, "api_key": false, "api_key_header": 7, "api_key_new": 9, - "credit_tiers": [{ - "tier_name": 1, "credits": "8", "input_limit": true, "output_limit": 3.9, - "reset_frequency": false, "ignored": "field" - }], "ignored": "field" + "credit_tiers": [ + { + "tier_name": 1, "credits": "8", "input_limit": true, "output_limit": 3.9, + "reset_frequency": false, "ignored": "field" + }, + { + "tier_name": "é".repeat(50), "credits": 1, "input_limit": 2, + "output_limit": 3, "reset_frequency": "monthly" + } + ], "ignored": "field" })), ) .await; @@ -5967,12 +6530,20 @@ async fn credit_models_match_pydantic_required_fields_coercion_and_unknown_elisi assert_eq!(credit["api_key"], "False"); assert_eq!(credit["api_key_header"], "7"); assert_eq!(credit["api_key_new"], "9"); + assert!(credit["api_key_rotation_expires"].is_null()); assert_eq!( - credit["credit_tiers"], - json!([{ + credit["credit_tiers"][0], + json!({ "tier_name": "1", "credits": 8, "input_limit": 1, "output_limit": 3, "reset_frequency": "False" - }]) + }) + ); + assert_eq!( + credit["credit_tiers"][1], + json!({ + "tier_name": "é".repeat(50), "credits": 1, "input_limit": 2, "output_limit": 3, + "reset_frequency": "monthly" + }) ); assert!(credit.get("ignored").is_none()); let duplicate = platform_request( @@ -6037,8 +6608,11 @@ async fn credit_models_match_pydantic_required_fields_coercion_and_unknown_elisi Some(&cookie), None, Some(json!({ - "username": true, - "users_credits": {"True": {"tier_name": 2, "available_credits": "4", "user_api_key": false, "ignored": "field"}}, + "username": "admin", + "users_credits": { + "True": {"tier_name": 2, "available_credits": "4", "user_api_key": false, "ignored": "field"}, + "unicode": {"tier_name": "é".repeat(50), "available_credits": 1} + }, "ignored": "field" })), ) @@ -6051,7 +6625,28 @@ async fn credit_models_match_pydantic_required_fields_coercion_and_unknown_elisi .unwrap(); assert_eq!( user_credits["users_credits"]["True"], - json!({"tier_name": "2", "available_credits": 4, "user_api_key": "False"}) + json!({"tier_name": "2", "available_credits": 4, "reset_date": null, "user_api_key": "False"}) + ); + assert_eq!( + user_credits["users_credits"]["unicode"], + json!({"tier_name": "é".repeat(50), "available_credits": 1, "reset_date": null, "user_api_key": null}) + ); + let mismatched_username = platform_request( + &app, + Method::POST, + "/platform/credit/admin", + Some(&cookie), + None, + Some(json!({ + "username": true, + "users_credits": {"group": {"tier_name": "tier", "available_credits": 1}} + })), + ) + .await; + assert_eq!(mismatched_username.status(), StatusCode::BAD_REQUEST); + assert_eq!( + response_json(mismatched_username).await["error_code"], + "CRD014" ); let invalid_user_credits = platform_request( &app, @@ -6215,6 +6810,21 @@ async fn quota_status_uses_nested_effective_limits_and_tracker_usage() { assert_eq!(specific.status(), StatusCode::OK); assert_eq!(response_json(specific).await["current_usage"], 8); + let invalid = platform_request( + &app, + Method::GET, + "/platform/quota/status/not-a-quota", + Some(&cookie), + None, + None, + ) + .await; + assert_eq!(invalid.status(), StatusCode::BAD_REQUEST); + assert_eq!( + response_json(invalid).await, + json!({"detail": "Invalid quota type: not-a-quota"}) + ); + let export = platform_request( &app, Method::POST, @@ -6279,7 +6889,10 @@ async fn quota_status_uses_nested_effective_limits_and_tracker_usage() { .update_one( "user_tier_assignments", &json!({"user_id": "admin"}), - &json!({"effective_until": 0}), + &json!({ + "effective_until": 0, + "override_limits": {"monthly_request_quota": 99} + }), ) .await .unwrap(); @@ -6297,6 +6910,22 @@ async fn quota_status_uses_nested_effective_limits_and_tracker_usage() { response_json(expired_assignment).await["current_tier"]["tier_id"], "quota-free" ); + let expired_status = platform_request( + &app, + Method::GET, + "/platform/quota/status", + Some(&cookie), + None, + None, + ) + .await; + assert_eq!(expired_status.status(), StatusCode::OK); + let expired_status = response_json(expired_status).await; + assert_eq!(expired_status["tier_info"]["tier_id"], "quota-free"); + assert_eq!( + expired_status["tier_info"]["limits"]["monthly_request_quota"], + 99 + ); } #[tokio::test] @@ -6866,6 +7495,72 @@ async fn tier_crud_returns_normalized_python_tier_contracts() { ); } +#[tokio::test] +async fn tier_public_and_protected_route_boundaries_match_python() { + let app = build_router(memory_state(false).await); + let created = platform_request( + &app, + Method::POST, + "/platform/tiers/", + None, + None, + Some(json!({ + "tier_id": "public-tier", "name": "custom", "display_name": "Public Tier", + "limits": {"requests_per_minute": 12} + })), + ) + .await; + assert_eq!(created.status(), StatusCode::CREATED); + + let fetched = platform_request( + &app, + Method::GET, + "/platform/tiers/public-tier", + None, + None, + None, + ) + .await; + assert_eq!(fetched.status(), StatusCode::OK); + + let updated = platform_request( + &app, + Method::PUT, + "/platform/tiers/public-tier", + None, + None, + Some(json!({"display_name": "Public Tier Updated"})), + ) + .await; + assert_eq!(updated.status(), StatusCode::OK); + + let assigned = platform_request( + &app, + Method::POST, + "/platform/tiers/assignments", + None, + None, + Some(json!({"user_id": "public-user", "tier_id": "public-tier"})), + ) + .await; + assert_eq!(assigned.status(), StatusCode::CREATED); + let assignment = platform_request( + &app, + Method::GET, + "/platform/tiers/assignments/public-user", + None, + None, + None, + ) + .await; + assert_eq!(assignment.status(), StatusCode::OK); + + for path in ["/platform/tiers/", "/platform/tiers/statistics/all"] { + let protected = platform_request(&app, Method::GET, path, None, None, None).await; + assert_eq!(protected.status(), StatusCode::UNAUTHORIZED, "{path}"); + } +} + #[tokio::test] async fn rate_limit_statistics_and_shadowed_status_match_python_contracts() { let state = memory_state(false).await; @@ -6902,6 +7597,9 @@ async fn rate_limit_statistics_and_shadowed_status_match_python_contracts() { "rule_id": "disabled-ip", "rule_type": "per_ip", "time_window": "day", "limit": 1, "enabled": false }), + json!({ + "rule_id": "legacy-no-enabled", "rule_type": "global", "time_window": "day", "limit": 1 + }), ] { storage.insert_one("rate_limit_rules", rule).await.unwrap(); } @@ -6933,10 +7631,10 @@ async fn rate_limit_statistics_and_shadowed_status_match_python_contracts() { .await; assert_eq!(statistics.status(), StatusCode::OK); let statistics = response_json(statistics).await; - assert_eq!(statistics["total_rules"], 4); + assert_eq!(statistics["total_rules"], 5); assert_eq!(statistics["enabled_rules"], 3); - assert_eq!(statistics["disabled_rules"], 1); - assert_eq!(statistics["rules_by_type"]["global"], 1); + assert_eq!(statistics["disabled_rules"], 2); + assert_eq!(statistics["rules_by_type"]["global"], 2); assert_eq!(statistics["rules_by_type"]["per_user"], 2); assert_eq!(statistics["rules_by_type"]["per_ip"], 1); assert_eq!(statistics["rules_by_type"]["per_api"], 0); @@ -7058,6 +7756,18 @@ async fn rate_limit_crud_and_action_envelopes_match_python() { assert!(listed.is_array()); assert_eq!(listed[0]["rule_id"], "crud-rule"); + let invalid_enabled = platform_request( + &app, + Method::GET, + "/platform/rate-limits/?enabled_only=not-a-bool", + None, + None, + None, + ) + .await; + assert_eq!(invalid_enabled.status(), StatusCode::UNPROCESSABLE_ENTITY); + assert_eq!(response_json(invalid_enabled).await["error_code"], "VAL001"); + let updated = platform_request( &app, Method::PUT, @@ -7195,6 +7905,33 @@ async fn rate_limit_crud_and_action_envelopes_match_python() { assert_eq!(copied["description"], "Copy of crud-rule"); assert_eq!(copied["limit"], 20); + let numeric_copy = platform_request( + &app, + Method::POST, + "/platform/rate-limits/crud-rule/duplicate", + None, + None, + Some(json!({"new_rule_id": 456})), + ) + .await; + assert_eq!(numeric_copy.status(), StatusCode::CREATED); + assert_eq!(response_json(numeric_copy).await["rule_id"], "456"); + + let missing_copy = platform_request( + &app, + Method::POST, + "/platform/rate-limits/missing-source/duplicate", + None, + None, + Some(json!({"new_rule_id": "unused"})), + ) + .await; + assert_eq!(missing_copy.status(), StatusCode::BAD_REQUEST); + assert_eq!( + response_json(missing_copy).await["detail"], + "Source rule missing-source not found" + ); + let disabled = platform_request( &app, Method::POST, diff --git a/gateway-rs/tests/python_parity_suite.rs b/gateway-rs/tests/python_parity_suite.rs index 89c03abb..7caebfb5 100644 --- a/gateway-rs/tests/python_parity_suite.rs +++ b/gateway-rs/tests/python_parity_suite.rs @@ -227,9 +227,8 @@ async fn parity_test_developer_tools_chaos_and_simulator() { .header(header::CONTENT_TYPE, "application/json") .body(Body::from( json!({ + "backend": "redis", "enabled": true, - "latency_ms": 10, - "error_status": 503 }) .to_string(), )) @@ -254,7 +253,7 @@ async fn parity_test_developer_tools_chaos_and_simulator() { assert_eq!(response.status(), StatusCode::OK); let bytes = to_bytes(response.into_body(), usize::MAX).await.unwrap(); let body: Value = serde_json::from_slice(&bytes).unwrap(); - assert_eq!(body["enabled"], true); + assert_eq!(body["redis_outage"], true); let response = app .clone() diff --git a/gateway-rs/tests/roles_groups_parity.rs b/gateway-rs/tests/roles_groups_parity.rs index 413400d4..2d2d7321 100644 --- a/gateway-rs/tests/roles_groups_parity.rs +++ b/gateway-rs/tests/roles_groups_parity.rs @@ -209,6 +209,19 @@ async fn live_role_permission_matrix_blocks_then_allows_each_management_operatio ) .await; assert_eq!(api.status(), StatusCode::CREATED); + let endpoint = request( + &app, + Method::POST, + "/platform/endpoint", + Some(&admin), + Some(json!({ + "api_name": "legacy-open-management", "api_version": "v1", + "endpoint_method": "GET", "endpoint_uri": "/visible", + "endpoint_description": "pinned Python authorization boundary" + })), + ) + .await; + assert_eq!(endpoint.status(), StatusCode::CREATED); for (index, (permission, expected_code)) in [ ("manage_apis", "API007"), @@ -311,6 +324,20 @@ async fn least_privilege_role_cannot_create_apis_or_read_logs() { .await; assert_eq!(viewer.status(), StatusCode::CREATED); let viewer = login(&app, "viewer1@example.com", fixture_password()).await; + let api = request( + &app, + Method::POST, + "/platform/api", + Some(&admin), + Some(json!({ + "api_name": "legacy-open-management", "api_version": "v1", + "api_description": "pinned Python authorization boundary", + "api_allowed_roles": ["admin"], "api_allowed_groups": ["ALL"], + "api_servers": ["http://127.0.0.1:9"], "api_type": "REST" + })), + ) + .await; + assert_eq!(api.status(), StatusCode::CREATED); let create_api = request( &app, Method::POST, @@ -329,6 +356,79 @@ async fn least_privilege_role_cannot_create_apis_or_read_logs() { .await; assert_eq!(create_api.status(), StatusCode::FORBIDDEN); assert_eq!(json_body(create_api).await["error_code"], "API007"); + for path in [ + "/platform/api/all?page=1&page_size=100", + "/platform/api/legacy-open-management/v1", + "/platform/endpoint/legacy-open-management/v1?page=1&page_size=100", + ] { + let response = request(&app, Method::GET, path, Some(&viewer), None).await; + let status = response.status(); + let body = json_body(response).await; + assert_eq!(status, StatusCode::OK, "{path}: {body}"); + } + let update_endpoint = request( + &app, + Method::PUT, + "/platform/endpoint/GET/legacy-open-management/v1/visible", + Some(&viewer), + Some(json!({"endpoint_description": "blocked"})), + ) + .await; + assert_eq!(update_endpoint.status(), StatusCode::FORBIDDEN); + assert_eq!(json_body(update_endpoint).await["error_code"], "END011"); + let delete_endpoint = request( + &app, + Method::DELETE, + "/platform/endpoint/GET/legacy-open-management/v1/visible", + Some(&viewer), + None, + ) + .await; + assert_eq!(delete_endpoint.status(), StatusCode::FORBIDDEN); + assert_eq!(json_body(delete_endpoint).await["error_code"], "END012"); + for (method, path, payload, code) in [ + ( + Method::POST, + "/platform/endpoint/endpoint/validation", + Some(json!({ + "endpoint_id": "missing", "validation_enabled": true, + "validation_schema": {"validation_schema": {}} + })), + "END013", + ), + ( + Method::PUT, + "/platform/endpoint/endpoint/validation/missing", + Some(json!({ + "validation_enabled": true, + "validation_schema": {"validation_schema": {}} + })), + "END014", + ), + ( + Method::DELETE, + "/platform/endpoint/endpoint/validation/missing", + None, + "END015", + ), + ] { + let response = request(&app, method, path, Some(&viewer), payload).await; + assert_eq!(response.status(), StatusCode::FORBIDDEN, "{path}"); + assert_eq!(json_body(response).await["error_code"], code, "{path}"); + } + let deleted = request( + &app, + Method::DELETE, + "/platform/api/legacy-open-management/v1", + Some(&viewer), + None, + ) + .await; + assert_eq!(deleted.status(), StatusCode::OK); + assert_eq!( + json_body(deleted).await, + json!({"message": "API deleted successfully"}) + ); for (path, code) in [ ("/platform/logging/logs", "LOG001"), ("/platform/logging/logs/files", "LOG001"), @@ -441,7 +541,7 @@ async fn non_admin_managers_cannot_discover_or_manage_bootstrap_admin() { .await; assert_eq!(roles.status(), StatusCode::OK); assert!( - json_body(roles).await["response"]["roles"] + json_body(roles).await["roles"] .as_array() .unwrap() .iter() @@ -524,14 +624,9 @@ async fn non_admin_managers_cannot_discover_or_manage_bootstrap_admin() { (Method::POST, "/platform/authorization/admin/enable/admin"), ] { let response = request(&app, method, path, Some(&manager), Some(json!({}))).await; - assert!( - matches!( - response.status(), - StatusCode::FORBIDDEN | StatusCode::NOT_FOUND - ), - "{path}: {}", - response.status() - ); + assert_eq!(response.status(), StatusCode::NOT_FOUND, "{path}"); + let body = json_body(response).await; + assert_eq!(body, json!({"error_message": "User not found"}), "{path}"); } } @@ -891,17 +986,22 @@ async fn routing_crud_requires_manage_routings_and_allows_routing_manager() { } #[tokio::test] -async fn missing_group_and_role_reads_and_deletes_return_not_found() { +async fn missing_group_and_role_contracts_match_python_service_codes() { let app = app().await; let admin = login(&app, "admin@doorman.dev", fixture_password()).await; for (method, path, code) in [ (Method::GET, "/platform/group/not-a-group", "GRP002"), - (Method::GET, "/platform/role/not-a-role", "ROL002"), + (Method::GET, "/platform/role/not-a-role", "ROLE004"), (Method::DELETE, "/platform/group/not-a-group", "GRP002"), - (Method::DELETE, "/platform/role/not-a-role", "ROL002"), + (Method::DELETE, "/platform/role/not-a-role", "ROLE004"), ] { + let expected = if method == Method::DELETE && path.contains("/role/") { + StatusCode::BAD_REQUEST + } else { + StatusCode::NOT_FOUND + }; let response = request(&app, method, path, Some(&admin), None).await; - assert_eq!(response.status(), StatusCode::NOT_FOUND, "{path}"); + assert_eq!(response.status(), expected, "{path}"); assert_eq!(json_body(response).await["error_code"], code, "{path}"); } } @@ -933,5 +1033,95 @@ async fn non_admin_role_manager_cannot_create_admin_role() { ) .await; assert_eq!(response.status(), StatusCode::FORBIDDEN); - assert_eq!(json_body(response).await["error_code"], "ROLE009"); + assert_eq!(json_body(response).await["error_code"], "ROLE013"); +} + +#[tokio::test] +async fn role_route_permissions_visibility_and_admin_codes_match_python() { + let app = app().await; + let admin = login(&app, "admin@doorman.dev", fixture_password()).await; + for (name, manage_roles) in [("role-viewer", false), ("role-manager", true)] { + let response = request( + &app, + Method::POST, + "/platform/role", + Some(&admin), + Some(json!({"role_name": name, "manage_roles": manage_roles})), + ) + .await; + assert_eq!(response.status(), StatusCode::CREATED); + } + let viewer = create_user(&app, &admin, "role-viewer-user", "role-viewer").await; + let manager = create_user(&app, &admin, "role-manager-2", "role-manager").await; + + let listed = request( + &app, + Method::GET, + "/platform/role?page=1&page_size=10", + Some(&viewer), + None, + ) + .await; + assert_eq!(listed.status(), StatusCode::OK); + let listed = json_body(listed).await; + assert!(listed["roles"].is_array()); + assert_eq!(listed["page"], 1); + assert_eq!(listed["page_size"], 10); + assert!( + listed["roles"] + .as_array() + .unwrap() + .iter() + .all(|role| role["role_name"] != "admin") + ); + assert_eq!( + request( + &app, + Method::GET, + "/platform/role/role-viewer", + Some(&viewer), + None, + ) + .await + .status(), + StatusCode::OK + ); + + for (method, path, payload, code) in [ + ( + Method::POST, + "/platform/role", + Some(json!({"role_name": "denied-role"})), + "ROLE009", + ), + ( + Method::PUT, + "/platform/role/role-viewer", + Some(json!({"view_logs": true})), + "ROLE010", + ), + ( + Method::DELETE, + "/platform/role/role-viewer", + None, + "ROLE011", + ), + ] { + let response = request(&app, method, path, Some(&viewer), payload).await; + assert_eq!(response.status(), StatusCode::FORBIDDEN); + assert_eq!(json_body(response).await["error_code"], code); + } + + for (method, code) in [(Method::PUT, "ROLE014"), (Method::DELETE, "ROLE016")] { + let response = request( + &app, + method, + "/platform/role/admin", + Some(&manager), + Some(json!({"view_logs": true})), + ) + .await; + assert_eq!(response.status(), StatusCode::FORBIDDEN); + assert_eq!(json_body(response).await["error_code"], code); + } } diff --git a/gateway-rs/tests/user_lifecycle_parity.rs b/gateway-rs/tests/user_lifecycle_parity.rs index 78c465f1..b6c2265f 100644 --- a/gateway-rs/tests/user_lifecycle_parity.rs +++ b/gateway-rs/tests/user_lifecycle_parity.rs @@ -149,6 +149,22 @@ async fn self_service_updates_cannot_escalate_privileges() { .await; assert_eq!(status, StatusCode::CREATED, "{user}"); let limited = login_as(&app, "limited@example.com", password).await; + let (status, users) = json_request( + &app, + Some(&limited), + Method::GET, + "/platform/user/all?page=1&page_size=100", + None, + ) + .await; + assert_eq!(status, StatusCode::OK, "{users}"); + assert!( + users["response"]["users"] + .as_array() + .unwrap() + .iter() + .all(|user| user["role"] != "admin") + ); for payload in [ json!({"role": "admin"}), json!({"groups": ["ALL", "admin"]}), @@ -275,7 +291,7 @@ async fn admin_can_read_list_update_and_delete_administrator_resources() { .await; assert_eq!(status, StatusCode::OK, "{roles}"); assert!( - roles["response"]["roles"] + roles["roles"] .as_array() .unwrap() .iter() diff --git a/parity/README.md b/parity/README.md index d6cfe914..3e4317cb 100644 --- a/parity/README.md +++ b/parity/README.md @@ -48,6 +48,29 @@ make parity-ledger pinned commit. The verification report includes counts by suite/domain and status, allowing incremental migration work to target a concrete gap. +## Python-to-Rust source coverage ledger + +`source_coverage_ledger.json` inventories production Python modules, classes, +fields, functions, and methods from the same pinned reference. It exists because +test disposition alone cannot prove that untested Python behavior was translated. +`source_coverage_overrides.json` records the reviewed Rust symbol and test evidence +for each unit. Large uniform modules may use a file default, with exact symbol +entries taking precedence for partial or obsolete exceptions. + +Unlisted units generate as `unreviewed`. A unit is `translated` only when the +override identifies both its Rust implementation and assertion-level tests. +`partial` and `missing` keep incomplete work visible; approved changes and +obsoletions require explicit rationales. + +```bash +python3 scripts/generate_source_coverage_ledger.py --write +make parity-source-ledger +``` + +The source-unit percentage measures inventory review, not semantic weighting or +release readiness. Complete parity also requires the operation and system evidence +described below. + With the pinned Python server on port 3102 and Rust on port 3101, provide a fresh administrator token for each disposable fixture and run the differential comparison: diff --git a/parity/source_coverage_ledger.json b/parity/source_coverage_ledger.json new file mode 100644 index 00000000..7205f318 --- /dev/null +++ b/parity/source_coverage_ledger.json @@ -0,0 +1,50918 @@ +{ + "entries": [ + { + "decorators": [], + "domain": "application", + "id": "backend-services/doorman.py::module:doorman", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/main.rs", + "gateway-rs/src/app.rs", + "gateway-rs/src/config.rs" + ], + "rust_tests": [ + "gateway-rs/tests/process_lifecycle.rs", + "gateway-rs/tests/platform_native.rs::platform_security_headers_csp_hsts_and_request_ids_match_python" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/doorman.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "application", + "id": "backend-services/doorman.py::function:_migrate_generated_directory", + "notes": "Rust owns the root-level generated/ directory directly and does not use backend-services/generated as its canonical destination.", + "rationale": "Python-only directory-layout migration is obsolete after removal of the Python backend runtime.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "function", + "line": 140, + "path": "backend-services/doorman.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "application", + "id": "backend-services/doorman.py::async_function:validate_database_connections", + "notes": "Rust establishes and validates configured shared storage before binding its listener.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", + "gateway-rs/src/main.rs::main" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart" + ], + "source": { + "kind": "async_function", + "line": 186, + "path": "backend-services/doorman.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "application", + "id": "backend-services/doorman.py::function:validate_token_revocation_config", + "notes": "Rust fails configuration when memory storage is combined with multiple workers and validates JWT storage requirements before startup.", + "rust_symbols": [ + "gateway-rs/src/config.rs::validate_runtime_environment" + ], + "rust_tests": [ + "gateway-rs/src/config.rs::tests::memory_mode_rejects_multiple_workers" + ], + "source": { + "kind": "function", + "line": 242, + "path": "backend-services/doorman.py" + }, + "status": "translated" + }, + { + "decorators": [ + "asynccontextmanager" + ], + "domain": "application", + "id": "backend-services/doorman.py::async_function:app_lifespan", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/main.rs", + "gateway-rs/src/app.rs", + "gateway-rs/src/config.rs" + ], + "rust_tests": [ + "gateway-rs/tests/process_lifecycle.rs", + "gateway-rs/tests/platform_native.rs::platform_security_headers_csp_hsts_and_request_ids_match_python" + ], + "source": { + "kind": "async_function", + "line": 266, + "path": "backend-services/doorman.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "application", + "id": "backend-services/doorman.py::async_function:app_lifespan._metrics_autosave", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/main.rs", + "gateway-rs/src/app.rs", + "gateway-rs/src/config.rs" + ], + "rust_tests": [ + "gateway-rs/tests/process_lifecycle.rs", + "gateway-rs/tests/platform_native.rs::platform_security_headers_csp_hsts_and_request_ids_match_python" + ], + "source": { + "kind": "async_function", + "line": 379, + "path": "backend-services/doorman.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "application", + "id": "backend-services/doorman.py::function:app_lifespan._int_env", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/main.rs", + "gateway-rs/src/app.rs", + "gateway-rs/src/config.rs" + ], + "rust_tests": [ + "gateway-rs/tests/process_lifecycle.rs", + "gateway-rs/tests/platform_native.rs::platform_security_headers_csp_hsts_and_request_ids_match_python" + ], + "source": { + "kind": "function", + "line": 471, + "path": "backend-services/doorman.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "application", + "id": "backend-services/doorman.py::async_function:app_lifespan._perform_dump", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/main.rs", + "gateway-rs/src/app.rs", + "gateway-rs/src/config.rs" + ], + "rust_tests": [ + "gateway-rs/tests/process_lifecycle.rs", + "gateway-rs/tests/platform_native.rs::platform_security_headers_csp_hsts_and_request_ids_match_python" + ], + "source": { + "kind": "async_function", + "line": 505, + "path": "backend-services/doorman.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "application", + "id": "backend-services/doorman.py::function:app_lifespan._register_forwarding_signal", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/main.rs", + "gateway-rs/src/app.rs", + "gateway-rs/src/config.rs" + ], + "rust_tests": [ + "gateway-rs/tests/process_lifecycle.rs", + "gateway-rs/tests/platform_native.rs::platform_security_headers_csp_hsts_and_request_ids_match_python" + ], + "source": { + "kind": "function", + "line": 539, + "path": "backend-services/doorman.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "application", + "id": "backend-services/doorman.py::async_function:app_lifespan._register_forwarding_signal._handler", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/main.rs", + "gateway-rs/src/app.rs", + "gateway-rs/src/config.rs" + ], + "rust_tests": [ + "gateway-rs/tests/process_lifecycle.rs", + "gateway-rs/tests/platform_native.rs::platform_security_headers_csp_hsts_and_request_ids_match_python" + ], + "source": { + "kind": "async_function", + "line": 540, + "path": "backend-services/doorman.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "application", + "id": "backend-services/doorman.py::async_function:app_lifespan._sighup_reload", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/main.rs", + "gateway-rs/src/app.rs", + "gateway-rs/src/config.rs" + ], + "rust_tests": [ + "gateway-rs/tests/process_lifecycle.rs", + "gateway-rs/tests/platform_native.rs::platform_security_headers_csp_hsts_and_request_ids_match_python" + ], + "source": { + "kind": "async_function", + "line": 572, + "path": "backend-services/doorman.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "application", + "id": "backend-services/doorman.py::function:_generate_unique_id", + "notes": "The pinned Python operation IDs are served unchanged from the frozen platform OpenAPI document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::pinned_openapi_operation_ids_are_stable_and_lowercase" + ], + "source": { + "kind": "function", + "line": 704, + "path": "backend-services/doorman.py" + }, + "status": "translated" + }, + { + "decorators": [ + "doorman.middleware('http')" + ], + "domain": "application", + "id": "backend-services/doorman.py::async_function:forwarded_proto_middleware", + "notes": "The Rust router does not issue FastAPI scheme-derived trailing-slash redirects, so mutating the ASGI request scheme has no Rust runtime role.", + "rationale": "Framework-specific redirect workaround made obsolete by Axum routing.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "async_function", + "line": 968, + "path": "backend-services/doorman.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "application", + "id": "backend-services/doorman.py::function:_platform_cors_config", + "notes": "Rust preserves the environment-derived origin, method, header, credential, and strict-mode defaults.", + "rust_symbols": [ + "gateway-rs/src/middleware/platform_cors.rs" + ], + "rust_tests": [ + "gateway-rs/src/middleware/platform_cors.rs::tests::platform_cors_wildcard_origin_with_credentials_non_strict_echoes_origin" + ], + "source": { + "kind": "function", + "line": 1008, + "path": "backend-services/doorman.py" + }, + "status": "translated" + }, + { + "decorators": [ + "doorman.middleware('http')" + ], + "domain": "application", + "id": "backend-services/doorman.py::async_function:platform_cors", + "notes": "Rust preserves platform preflight and actual-response CORS behavior, including strict wildcard handling and Vary replacement.", + "rust_symbols": [ + "gateway-rs/src/middleware/platform_cors.rs::platform_cors" + ], + "rust_tests": [ + "gateway-rs/src/middleware/platform_cors.rs::tests::platform_cors_actual_response_sets_vary_origin", + "gateway-rs/tests/live_tests_parity.rs::live_platform_cors_default_preflight_parity" + ], + "source": { + "kind": "async_function", + "line": 1070, + "path": "backend-services/doorman.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "application", + "id": "backend-services/doorman.py::function:_get_max_body_size", + "notes": "Rust reads the same global and protocol-specific body-limit environment variables with the Python default.", + "rust_symbols": [ + "gateway-rs/src/middleware/body_limit.rs::BodyLimits.from_env" + ], + "rust_tests": [ + "gateway-rs/tests/runtime.rs::protocol_body_limits_match_python" + ], + "source": { + "kind": "function", + "line": 1143, + "path": "backend-services/doorman.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "application", + "id": "backend-services/doorman.py::class:LimitedStreamReader", + "notes": "Axum's bounded body collection enforces the accumulated streaming limit without an ASGI receive wrapper.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_dispatch" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::platform_body_limit_uses_runtime_environment" + ], + "source": { + "kind": "class", + "line": 1153, + "path": "backend-services/doorman.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "application", + "id": "backend-services/doorman.py::method:LimitedStreamReader.__init__", + "notes": "The bound is carried directly into Axum body collection.", + "rust_symbols": [ + "gateway-rs/src/middleware/body_limit.rs::BodyLimits" + ], + "rust_tests": [ + "gateway-rs/tests/runtime.rs::protocol_body_limits_match_python" + ], + "source": { + "kind": "method", + "line": 1161, + "path": "backend-services/doorman.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "application", + "id": "backend-services/doorman.py::async_method:LimitedStreamReader.__call__", + "notes": "Axum's bounded body collector rejects cumulative streamed bytes above the selected limit.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_dispatch" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::platform_body_limit_uses_runtime_environment" + ], + "source": { + "kind": "async_method", + "line": 1167, + "path": "backend-services/doorman.py" + }, + "status": "translated" + }, + { + "decorators": [ + "doorman.middleware('http')" + ], + "domain": "application", + "id": "backend-services/doorman.py::async_function:body_size_limit", + "notes": "Rust preserves global/protocol limits, exclusions, monitor/security bypasses, and 413 behavior for collected request bodies.", + "rust_symbols": [ + "gateway-rs/src/middleware/body_limit.rs::BodyLimits", + "gateway-rs/src/routes/platform.rs::platform_dispatch" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::platform_body_limit_uses_runtime_environment", + "gateway-rs/tests/runtime.rs::protocol_body_limits_match_python" + ], + "source": { + "kind": "async_function", + "line": 1185, + "path": "backend-services/doorman.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "application", + "id": "backend-services/doorman.py::class:PlatformCORSMiddleware", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/main.rs", + "gateway-rs/src/app.rs", + "gateway-rs/src/config.rs" + ], + "rust_tests": [ + "gateway-rs/tests/process_lifecycle.rs", + "gateway-rs/tests/platform_native.rs::platform_security_headers_csp_hsts_and_request_ids_match_python" + ], + "source": { + "kind": "class", + "line": 1420, + "path": "backend-services/doorman.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "application", + "id": "backend-services/doorman.py::method:PlatformCORSMiddleware.__init__", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/main.rs", + "gateway-rs/src/app.rs", + "gateway-rs/src/config.rs" + ], + "rust_tests": [ + "gateway-rs/tests/process_lifecycle.rs", + "gateway-rs/tests/platform_native.rs::platform_security_headers_csp_hsts_and_request_ids_match_python" + ], + "source": { + "kind": "method", + "line": 1428, + "path": "backend-services/doorman.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "application", + "id": "backend-services/doorman.py::async_method:PlatformCORSMiddleware.__call__", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/main.rs", + "gateway-rs/src/app.rs", + "gateway-rs/src/config.rs" + ], + "rust_tests": [ + "gateway-rs/tests/process_lifecycle.rs", + "gateway-rs/tests/platform_native.rs::platform_security_headers_csp_hsts_and_request_ids_match_python" + ], + "source": { + "kind": "async_method", + "line": 1431, + "path": "backend-services/doorman.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "application", + "id": "backend-services/doorman.py::async_function:PlatformCORSMiddleware.__call__.send_wrapper", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/main.rs", + "gateway-rs/src/app.rs", + "gateway-rs/src/config.rs" + ], + "rust_tests": [ + "gateway-rs/tests/process_lifecycle.rs", + "gateway-rs/tests/platform_native.rs::platform_security_headers_csp_hsts_and_request_ids_match_python" + ], + "source": { + "kind": "async_function", + "line": 1504, + "path": "backend-services/doorman.py" + }, + "status": "partial" + }, + { + "decorators": [ + "doorman.middleware('http')" + ], + "domain": "application", + "id": "backend-services/doorman.py::async_function:policy_revision_middleware", + "notes": "Rust bumps shared policy revision atomically in every successful storage mutation rather than in an HTTP after-hook.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.bump_policy_revision" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart" + ], + "source": { + "kind": "async_function", + "line": 1544, + "path": "backend-services/doorman.py" + }, + "status": "translated" + }, + { + "decorators": [ + "doorman.middleware('http')" + ], + "domain": "application", + "id": "backend-services/doorman.py::async_function:request_id_middleware", + "notes": "Rust accepts the same request-id headers, generates UUIDs, propagates x-request-id internally, and emits both response header spellings.", + "rust_symbols": [ + "gateway-rs/src/middleware/request_id.rs::request_id" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::platform_security_headers_csp_hsts_and_request_ids_match_python", + "gateway-rs/tests/live_tests_parity.rs::request_id_is_forwarded_to_authenticated_rest_upstream_and_response" + ], + "source": { + "kind": "async_function", + "line": 1562, + "path": "backend-services/doorman.py" + }, + "status": "translated" + }, + { + "decorators": [ + "doorman.middleware('http')" + ], + "domain": "application", + "id": "backend-services/doorman.py::async_function:security_headers", + "notes": "Rust matches default security headers, docs CSP/frame behavior, custom CSP, and HTTPS-only HSTS.", + "rust_symbols": [ + "gateway-rs/src/middleware/security_headers.rs::security_headers" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::platform_security_headers_csp_hsts_and_request_ids_match_python" + ], + "source": { + "kind": "async_function", + "line": 1610, + "path": "backend-services/doorman.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "application", + "id": "backend-services/doorman.py::class:JSONFormatter", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/main.rs", + "gateway-rs/src/app.rs", + "gateway-rs/src/config.rs" + ], + "rust_tests": [ + "gateway-rs/tests/process_lifecycle.rs", + "gateway-rs/tests/platform_native.rs::platform_security_headers_csp_hsts_and_request_ids_match_python" + ], + "source": { + "kind": "class", + "line": 1681, + "path": "backend-services/doorman.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "application", + "id": "backend-services/doorman.py::method:JSONFormatter.format", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/main.rs", + "gateway-rs/src/app.rs", + "gateway-rs/src/config.rs" + ], + "rust_tests": [ + "gateway-rs/tests/process_lifecycle.rs", + "gateway-rs/tests/platform_native.rs::platform_security_headers_csp_hsts_and_request_ids_match_python" + ], + "source": { + "kind": "method", + "line": 1682, + "path": "backend-services/doorman.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "application", + "id": "backend-services/doorman.py::function:configure_logger", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/main.rs", + "gateway-rs/src/app.rs", + "gateway-rs/src/config.rs" + ], + "rust_tests": [ + "gateway-rs/tests/process_lifecycle.rs", + "gateway-rs/tests/platform_native.rs::platform_security_headers_csp_hsts_and_request_ids_match_python" + ], + "source": { + "kind": "function", + "line": 1739, + "path": "backend-services/doorman.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "application", + "id": "backend-services/doorman.py::class:configure_logger.RedactFilter", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/main.rs", + "gateway-rs/src/app.rs", + "gateway-rs/src/config.rs" + ], + "rust_tests": [ + "gateway-rs/tests/process_lifecycle.rs", + "gateway-rs/tests/platform_native.rs::platform_security_headers_csp_hsts_and_request_ids_match_python" + ], + "source": { + "kind": "class", + "line": 1751, + "path": "backend-services/doorman.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "application", + "id": "backend-services/doorman.py::field:configure_logger.RedactFilter.PATTERNS", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/main.rs", + "gateway-rs/src/app.rs", + "gateway-rs/src/config.rs" + ], + "rust_tests": [ + "gateway-rs/tests/process_lifecycle.rs", + "gateway-rs/tests/platform_native.rs::platform_security_headers_csp_hsts_and_request_ids_match_python" + ], + "source": { + "kind": "field", + "line": 1763, + "path": "backend-services/doorman.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "application", + "id": "backend-services/doorman.py::method:configure_logger.RedactFilter.filter", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/main.rs", + "gateway-rs/src/app.rs", + "gateway-rs/src/config.rs" + ], + "rust_tests": [ + "gateway-rs/tests/process_lifecycle.rs", + "gateway-rs/tests/platform_native.rs::platform_security_headers_csp_hsts_and_request_ids_match_python" + ], + "source": { + "kind": "method", + "line": 1786, + "path": "backend-services/doorman.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "application", + "id": "backend-services/doorman.py::class:_VaryOriginMiddleware", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/main.rs", + "gateway-rs/src/app.rs", + "gateway-rs/src/config.rs" + ], + "rust_tests": [ + "gateway-rs/tests/process_lifecycle.rs", + "gateway-rs/tests/platform_native.rs::platform_security_headers_csp_hsts_and_request_ids_match_python" + ], + "source": { + "kind": "class", + "line": 1915, + "path": "backend-services/doorman.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "application", + "id": "backend-services/doorman.py::async_method:_VaryOriginMiddleware.dispatch", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/main.rs", + "gateway-rs/src/app.rs", + "gateway-rs/src/config.rs" + ], + "rust_tests": [ + "gateway-rs/tests/process_lifecycle.rs", + "gateway-rs/tests/platform_native.rs::platform_security_headers_csp_hsts_and_request_ids_match_python" + ], + "source": { + "kind": "async_method", + "line": 1916, + "path": "backend-services/doorman.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "application", + "id": "backend-services/doorman.py::class:Settings", + "notes": "Rust loads and validates the equivalent storage and JWT settings before startup, with additional v2 production hardening.", + "rust_symbols": [ + "gateway-rs/src/config.rs::Config", + "gateway-rs/src/config.rs::SharedStorageConfig" + ], + "rust_tests": [ + "gateway-rs/src/config.rs::tests::memory_mode_rejects_multiple_workers" + ], + "source": { + "kind": "class", + "line": 1983, + "path": "backend-services/doorman.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "application", + "id": "backend-services/doorman.py::field:Settings.mongo_db_uri", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/main.rs", + "gateway-rs/src/app.rs", + "gateway-rs/src/config.rs" + ], + "rust_tests": [ + "gateway-rs/tests/process_lifecycle.rs", + "gateway-rs/tests/platform_native.rs::platform_security_headers_csp_hsts_and_request_ids_match_python" + ], + "source": { + "kind": "field", + "line": 1984, + "path": "backend-services/doorman.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "application", + "id": "backend-services/doorman.py::field:Settings.jwt_secret_key", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/main.rs", + "gateway-rs/src/app.rs", + "gateway-rs/src/config.rs" + ], + "rust_tests": [ + "gateway-rs/tests/process_lifecycle.rs", + "gateway-rs/tests/platform_native.rs::platform_security_headers_csp_hsts_and_request_ids_match_python" + ], + "source": { + "kind": "field", + "line": 1985, + "path": "backend-services/doorman.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "application", + "id": "backend-services/doorman.py::field:Settings.jwt_algorithm", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/main.rs", + "gateway-rs/src/app.rs", + "gateway-rs/src/config.rs" + ], + "rust_tests": [ + "gateway-rs/tests/process_lifecycle.rs", + "gateway-rs/tests/platform_native.rs::platform_security_headers_csp_hsts_and_request_ids_match_python" + ], + "source": { + "kind": "field", + "line": 1986, + "path": "backend-services/doorman.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "application", + "id": "backend-services/doorman.py::field:Settings.jwt_access_token_expires", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/main.rs", + "gateway-rs/src/app.rs", + "gateway-rs/src/config.rs" + ], + "rust_tests": [ + "gateway-rs/tests/process_lifecycle.rs", + "gateway-rs/tests/platform_native.rs::platform_security_headers_csp_hsts_and_request_ids_match_python" + ], + "source": { + "kind": "field", + "line": 1987, + "path": "backend-services/doorman.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "application", + "id": "backend-services/doorman.py::field:Settings.jwt_refresh_token_expires", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/main.rs", + "gateway-rs/src/app.rs", + "gateway-rs/src/config.rs" + ], + "rust_tests": [ + "gateway-rs/tests/process_lifecycle.rs", + "gateway-rs/tests/platform_native.rs::platform_security_headers_csp_hsts_and_request_ids_match_python" + ], + "source": { + "kind": "field", + "line": 1990, + "path": "backend-services/doorman.py" + }, + "status": "partial" + }, + { + "decorators": [ + "doorman.middleware('http')" + ], + "domain": "application", + "id": "backend-services/doorman.py::async_function:ip_filter_middleware", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/main.rs", + "gateway-rs/src/app.rs", + "gateway-rs/src/config.rs" + ], + "rust_tests": [ + "gateway-rs/tests/process_lifecycle.rs", + "gateway-rs/tests/platform_native.rs::platform_security_headers_csp_hsts_and_request_ids_match_python" + ], + "source": { + "kind": "async_function", + "line": 1996, + "path": "backend-services/doorman.py" + }, + "status": "partial" + }, + { + "decorators": [ + "doorman.middleware('http')" + ], + "domain": "application", + "id": "backend-services/doorman.py::async_function:metrics_middleware", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/main.rs", + "gateway-rs/src/app.rs", + "gateway-rs/src/config.rs" + ], + "rust_tests": [ + "gateway-rs/tests/process_lifecycle.rs", + "gateway-rs/tests/platform_native.rs::platform_security_headers_csp_hsts_and_request_ids_match_python" + ], + "source": { + "kind": "async_function", + "line": 2098, + "path": "backend-services/doorman.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "application", + "id": "backend-services/doorman.py::function:metrics_middleware._parse_len", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/main.rs", + "gateway-rs/src/app.rs", + "gateway-rs/src/config.rs" + ], + "rust_tests": [ + "gateway-rs/tests/process_lifecycle.rs", + "gateway-rs/tests/platform_native.rs::platform_security_headers_csp_hsts_and_request_ids_match_python" + ], + "source": { + "kind": "function", + "line": 2101, + "path": "backend-services/doorman.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "application", + "id": "backend-services/doorman.py::async_function:automatic_purger", + "notes": "Rust runs an interval-based revocation purge after initial restored-state cleanup.", + "rust_symbols": [ + "gateway-rs/src/main.rs::spawn_revocation_purger", + "gateway-rs/src/main.rs::run_revocation_purge" + ], + "rust_tests": [ + "gateway-rs/tests/common/mod.rs::shared_storage_revocation_lifecycle" + ], + "source": { + "kind": "async_function", + "line": 2213, + "path": "backend-services/doorman.py" + }, + "status": "translated" + }, + { + "decorators": [ + "doorman.exception_handler(JWTError)" + ], + "domain": "application", + "id": "backend-services/doorman.py::async_function:jwt_exception_handler", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/main.rs", + "gateway-rs/src/app.rs", + "gateway-rs/src/config.rs" + ], + "rust_tests": [ + "gateway-rs/tests/process_lifecycle.rs", + "gateway-rs/tests/platform_native.rs::platform_security_headers_csp_hsts_and_request_ids_match_python" + ], + "source": { + "kind": "async_function", + "line": 2221, + "path": "backend-services/doorman.py" + }, + "status": "partial" + }, + { + "decorators": [ + "doorman.exception_handler(500)" + ], + "domain": "application", + "id": "backend-services/doorman.py::async_function:internal_server_error_handler", + "notes": "Rust's panic catcher emits the pinned 500 ISE001 JSON envelope for unhandled request panics.", + "rust_symbols": [ + "gateway-rs/src/app.rs::handle_panic" + ], + "rust_tests": [ + "gateway-rs/src/app.rs::tests::panic_handler_matches_python_internal_error_envelope" + ], + "source": { + "kind": "async_function", + "line": 2229, + "path": "backend-services/doorman.py" + }, + "status": "translated" + }, + { + "decorators": [ + "doorman.exception_handler(RequestValidationError)" + ], + "domain": "application", + "id": "backend-services/doorman.py::async_function:validation_exception_handler", + "notes": "Rust typed request boundaries emit the pinned 422 VAL001 envelope before route logic.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::validation_errors" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::malformed_typed_control_plane_json_validates_before_auth" + ], + "source": { + "kind": "async_function", + "line": 2239, + "path": "backend-services/doorman.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "application", + "id": "backend-services/doorman.py::function:start", + "notes": "The Rust start subcommand preserves the pinned detached child launch, null standard streams, process-group ownership on Unix, already-running PID-file check, PID creation, and success logging. PID_FILE is honored in addition to the legacy doorman.pid default.", + "rust_symbols": [ + "gateway-rs/src/main.rs::start_process" + ], + "rust_tests": [ + "gateway-rs/src/main.rs::tests::pid_files_require_a_positive_integer" + ], + "source": { + "kind": "function", + "line": 2299, + "path": "backend-services/doorman.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "application", + "id": "backend-services/doorman.py::function:stop", + "notes": "The Rust stop subcommand preserves the absent-PID no-op, positive PID parsing, Unix process-group SIGTERM with a 15-second wait, Windows taskkill behavior, and PID-file removal.", + "rust_symbols": [ + "gateway-rs/src/main.rs::stop_process", + "gateway-rs/src/main.rs::stop_unix_process_group" + ], + "rust_tests": [ + "gateway-rs/src/main.rs::tests::pid_files_require_a_positive_integer" + ], + "source": { + "kind": "function", + "line": 2322, + "path": "backend-services/doorman.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "application", + "id": "backend-services/doorman.py::function:restart", + "notes": "The Rust restart subcommand performs the pinned stop, one-second delay, and detached start sequence. The management restart helper now recognizes the same PID_FILE override as the CLI.", + "rust_symbols": [ + "gateway-rs/src/main.rs::main", + "gateway-rs/src/routes/platform.rs::schedule_restart" + ], + "rust_tests": [ + "gateway-rs/src/main.rs::tests::pid_files_require_a_positive_integer" + ], + "source": { + "kind": "function", + "line": 2349, + "path": "backend-services/doorman.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "application", + "id": "backend-services/doorman.py::function:run", + "notes": "The Rust executable validates configuration, binds HOST/PORT, serves the full router, and drains on shutdown signals.", + "rust_symbols": [ + "gateway-rs/src/main.rs::main" + ], + "rust_tests": [ + "gateway-rs/tests/process_lifecycle.rs::sigterm_drains_active_request_before_final_snapshot_and_restart" + ], + "source": { + "kind": "function", + "line": 2365, + "path": "backend-services/doorman.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "application", + "id": "backend-services/doorman.py::function:main", + "notes": "The Rust executable is the direct foreground server entrypoint.", + "rust_symbols": [ + "gateway-rs/src/main.rs::main" + ], + "rust_tests": [ + "gateway-rs/tests/live_tcp_port_3001.rs::rust_binary_serves_live_tcp_port" + ], + "source": { + "kind": "function", + "line": 2395, + "path": "backend-services/doorman.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "application", + "id": "backend-services/doorman.py::function:seed_command", + "notes": "The Rust seed subcommand preserves all seven pinned CLI options and defaults, help, configuration/storage initialization, progress summary, failure exit, success message, and count result while delegating fixture generation to the native demo_seed module.", + "rust_symbols": [ + "gateway-rs/src/main.rs::seed_command", + "gateway-rs/src/main.rs::parse_seed_options", + "gateway-rs/src/demo_seed.rs::run_seed" + ], + "rust_tests": [ + "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults", + "gateway-rs/src/demo_seed.rs::tests::defaults_match_the_python_seed_command" + ], + "source": { + "kind": "function", + "line": 2410, + "path": "backend-services/doorman.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "middleware", + "id": "backend-services/middleware/analytics_middleware.py::module:analytics_middleware", + "notes": "Rust records gateway timing, status, byte counts, API/user/endpoint identity, persistence buckets, and aggregate counters. Some Python-only percentile/sample details remain covered by the partial analytics model mapping.", + "rust_symbols": [ + "gateway-rs/src/middleware/activity.rs::track_active_requests", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/middleware/analytics_middleware.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "middleware", + "id": "backend-services/middleware/analytics_middleware.py::class:AnalyticsMiddleware", + "notes": "Rust records gateway timing, status, byte counts, API/user/endpoint identity, persistence buckets, and aggregate counters. Some Python-only percentile/sample details remain covered by the partial analytics model mapping.", + "rust_symbols": [ + "gateway-rs/src/middleware/activity.rs::track_active_requests", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts" + ], + "source": { + "kind": "class", + "line": 24, + "path": "backend-services/middleware/analytics_middleware.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "middleware", + "id": "backend-services/middleware/analytics_middleware.py::method:AnalyticsMiddleware.__init__", + "notes": "Rust records gateway timing, status, byte counts, API/user/endpoint identity, persistence buckets, and aggregate counters. Some Python-only percentile/sample details remain covered by the partial analytics model mapping.", + "rust_symbols": [ + "gateway-rs/src/middleware/activity.rs::track_active_requests", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts" + ], + "source": { + "kind": "method", + "line": 37, + "path": "backend-services/middleware/analytics_middleware.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "middleware", + "id": "backend-services/middleware/analytics_middleware.py::async_method:AnalyticsMiddleware.dispatch", + "notes": "Rust records gateway timing, status, byte counts, API/user/endpoint identity, persistence buckets, and aggregate counters. Some Python-only percentile/sample details remain covered by the partial analytics model mapping.", + "rust_symbols": [ + "gateway-rs/src/middleware/activity.rs::track_active_requests", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts" + ], + "source": { + "kind": "async_method", + "line": 40, + "path": "backend-services/middleware/analytics_middleware.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "middleware", + "id": "backend-services/middleware/analytics_middleware.py::method:AnalyticsMiddleware._parse_api_endpoint", + "notes": "Rust records gateway timing, status, byte counts, API/user/endpoint identity, persistence buckets, and aggregate counters. Some Python-only percentile/sample details remain covered by the partial analytics model mapping.", + "rust_symbols": [ + "gateway-rs/src/middleware/activity.rs::track_active_requests", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts" + ], + "source": { + "kind": "method", + "line": 183, + "path": "backend-services/middleware/analytics_middleware.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "middleware", + "id": "backend-services/middleware/analytics_middleware.py::function:setup_analytics_middleware", + "notes": "Rust records gateway timing, status, byte counts, API/user/endpoint identity, persistence buckets, and aggregate counters. Some Python-only percentile/sample details remain covered by the partial analytics model mapping.", + "rust_symbols": [ + "gateway-rs/src/middleware/activity.rs::track_active_requests", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts" + ], + "source": { + "kind": "function", + "line": 230, + "path": "backend-services/middleware/analytics_middleware.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "middleware", + "id": "backend-services/middleware/latency_injection_middleware.py::module:latency_injection_middleware", + "notes": "Rust now honors ENABLE_LATENCY_INJECTION and X-Doorman-Latency globally with trimming, invalid-value elision, nonnegative clamping, and the 5000ms cap; Python's arbitrary-size and Unicode integer spellings remain an extreme parsing edge.", + "rust_symbols": [ + "gateway-rs/src/middleware/chaos.rs::latency_injection" + ], + "rust_tests": [ + "gateway-rs/src/middleware/chaos.rs::tests::legacy_header_latency_matches_python_bounds_and_parsing" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/middleware/latency_injection_middleware.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "middleware", + "id": "backend-services/middleware/latency_injection_middleware.py::class:LatencyInjectionMiddleware", + "notes": "Rust now honors ENABLE_LATENCY_INJECTION and X-Doorman-Latency globally with trimming, invalid-value elision, nonnegative clamping, and the 5000ms cap; Python's arbitrary-size and Unicode integer spellings remain an extreme parsing edge.", + "rust_symbols": [ + "gateway-rs/src/middleware/chaos.rs::latency_injection" + ], + "rust_tests": [ + "gateway-rs/src/middleware/chaos.rs::tests::legacy_header_latency_matches_python_bounds_and_parsing" + ], + "source": { + "kind": "class", + "line": 18, + "path": "backend-services/middleware/latency_injection_middleware.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "middleware", + "id": "backend-services/middleware/latency_injection_middleware.py::method:LatencyInjectionMiddleware.__init__", + "notes": "Rust now honors ENABLE_LATENCY_INJECTION and X-Doorman-Latency globally with trimming, invalid-value elision, nonnegative clamping, and the 5000ms cap; Python's arbitrary-size and Unicode integer spellings remain an extreme parsing edge.", + "rust_symbols": [ + "gateway-rs/src/middleware/chaos.rs::latency_injection" + ], + "rust_tests": [ + "gateway-rs/src/middleware/chaos.rs::tests::legacy_header_latency_matches_python_bounds_and_parsing" + ], + "source": { + "kind": "method", + "line": 19, + "path": "backend-services/middleware/latency_injection_middleware.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "middleware", + "id": "backend-services/middleware/latency_injection_middleware.py::async_method:LatencyInjectionMiddleware.dispatch", + "notes": "Rust now honors ENABLE_LATENCY_INJECTION and X-Doorman-Latency globally with trimming, invalid-value elision, nonnegative clamping, and the 5000ms cap; Python's arbitrary-size and Unicode integer spellings remain an extreme parsing edge.", + "rust_symbols": [ + "gateway-rs/src/middleware/chaos.rs::latency_injection" + ], + "rust_tests": [ + "gateway-rs/src/middleware/chaos.rs::tests::legacy_header_latency_matches_python_bounds_and_parsing" + ], + "source": { + "kind": "async_method", + "line": 23, + "path": "backend-services/middleware/latency_injection_middleware.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "middleware", + "id": "backend-services/middleware/logging_middleware.py::module:logging_middleware", + "notes": "Rust records request IDs, method/path, status, duration, byte counts, and structured activity records after every request.", + "rust_symbols": [ + "gateway-rs/src/middleware/activity.rs::track_active_requests", + "gateway-rs/src/middleware/request_id.rs::request_id" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rust_gateway_activity_json_has_queryable_python_log_fields", + "gateway-rs/tests/security_settings_parity.rs::unknown_path_404_is_written_to_the_gateway_activity_log" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/middleware/logging_middleware.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "middleware", + "id": "backend-services/middleware/logging_middleware.py::class:GlobalLoggingMiddleware", + "notes": "Rust records request IDs, method/path, status, duration, byte counts, and structured activity records after every request.", + "rust_symbols": [ + "gateway-rs/src/middleware/activity.rs::track_active_requests", + "gateway-rs/src/middleware/request_id.rs::request_id" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rust_gateway_activity_json_has_queryable_python_log_fields", + "gateway-rs/tests/security_settings_parity.rs::unknown_path_404_is_written_to_the_gateway_activity_log" + ], + "source": { + "kind": "class", + "line": 9, + "path": "backend-services/middleware/logging_middleware.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "middleware", + "id": "backend-services/middleware/logging_middleware.py::async_method:GlobalLoggingMiddleware.dispatch", + "notes": "Rust records request IDs, method/path, status, duration, byte counts, and structured activity records after every request.", + "rust_symbols": [ + "gateway-rs/src/middleware/activity.rs::track_active_requests", + "gateway-rs/src/middleware/request_id.rs::request_id" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rust_gateway_activity_json_has_queryable_python_log_fields", + "gateway-rs/tests/security_settings_parity.rs::unknown_path_404_is_written_to_the_gateway_activity_log" + ], + "source": { + "kind": "async_method", + "line": 10, + "path": "backend-services/middleware/logging_middleware.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "middleware", + "id": "backend-services/middleware/rate_limit_middleware.py::module:rate_limit_middleware", + "notes": "Rust implements user/API/endpoint policy selection, fixed/sliding/token/hybrid counters, quotas, response failures, and headers, but the Python middleware's helper surface has not yet been mapped method-by-method.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs", + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/middleware/rate_limit_middleware.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "middleware", + "id": "backend-services/middleware/rate_limit_middleware.py::class:RateLimitMiddleware", + "notes": "Rust implements user/API/endpoint policy selection, fixed/sliding/token/hybrid counters, quotas, response failures, and headers, but the Python middleware's helper surface has not yet been mapped method-by-method.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs", + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker" + ], + "source": { + "kind": "class", + "line": 23, + "path": "backend-services/middleware/rate_limit_middleware.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "middleware", + "id": "backend-services/middleware/rate_limit_middleware.py::method:RateLimitMiddleware.__init__", + "notes": "Rust implements user/API/endpoint policy selection, fixed/sliding/token/hybrid counters, quotas, response failures, and headers, but the Python middleware's helper surface has not yet been mapped method-by-method.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs", + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker" + ], + "source": { + "kind": "method", + "line": 35, + "path": "backend-services/middleware/rate_limit_middleware.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "middleware", + "id": "backend-services/middleware/rate_limit_middleware.py::async_method:RateLimitMiddleware.dispatch", + "notes": "Rust implements user/API/endpoint policy selection, fixed/sliding/token/hybrid counters, quotas, response failures, and headers, but the Python middleware's helper surface has not yet been mapped method-by-method.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs", + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker" + ], + "source": { + "kind": "async_method", + "line": 59, + "path": "backend-services/middleware/rate_limit_middleware.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "middleware", + "id": "backend-services/middleware/rate_limit_middleware.py::method:RateLimitMiddleware._should_skip", + "notes": "Rust implements user/API/endpoint policy selection, fixed/sliding/token/hybrid counters, quotas, response failures, and headers, but the Python middleware's helper surface has not yet been mapped method-by-method.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs", + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker" + ], + "source": { + "kind": "method", + "line": 126, + "path": "backend-services/middleware/rate_limit_middleware.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "middleware", + "id": "backend-services/middleware/rate_limit_middleware.py::method:RateLimitMiddleware._get_user_id", + "notes": "Rust implements user/API/endpoint policy selection, fixed/sliding/token/hybrid counters, quotas, response failures, and headers, but the Python middleware's helper surface has not yet been mapped method-by-method.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs", + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker" + ], + "source": { + "kind": "method", + "line": 141, + "path": "backend-services/middleware/rate_limit_middleware.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "middleware", + "id": "backend-services/middleware/rate_limit_middleware.py::method:RateLimitMiddleware._get_api_name", + "notes": "Rust implements user/API/endpoint policy selection, fixed/sliding/token/hybrid counters, quotas, response failures, and headers, but the Python middleware's helper surface has not yet been mapped method-by-method.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs", + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker" + ], + "source": { + "kind": "method", + "line": 158, + "path": "backend-services/middleware/rate_limit_middleware.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "middleware", + "id": "backend-services/middleware/rate_limit_middleware.py::method:RateLimitMiddleware._get_client_ip", + "notes": "Rust implements user/API/endpoint policy selection, fixed/sliding/token/hybrid counters, quotas, response failures, and headers, but the Python middleware's helper surface has not yet been mapped method-by-method.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs", + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker" + ], + "source": { + "kind": "method", + "line": 179, + "path": "backend-services/middleware/rate_limit_middleware.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "middleware", + "id": "backend-services/middleware/rate_limit_middleware.py::method:RateLimitMiddleware._get_identifier", + "notes": "Rust implements user/API/endpoint policy selection, fixed/sliding/token/hybrid counters, quotas, response failures, and headers, but the Python middleware's helper surface has not yet been mapped method-by-method.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs", + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker" + ], + "source": { + "kind": "method", + "line": 206, + "path": "backend-services/middleware/rate_limit_middleware.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "middleware", + "id": "backend-services/middleware/rate_limit_middleware.py::async_method:RateLimitMiddleware._default_get_rules", + "notes": "Rust implements user/API/endpoint policy selection, fixed/sliding/token/hybrid counters, quotas, response failures, and headers, but the Python middleware's helper surface has not yet been mapped method-by-method.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs", + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker" + ], + "source": { + "kind": "async_method", + "line": 244, + "path": "backend-services/middleware/rate_limit_middleware.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "middleware", + "id": "backend-services/middleware/rate_limit_middleware.py::async_method:RateLimitMiddleware._default_get_user_tier", + "notes": "Rust implements user/API/endpoint policy selection, fixed/sliding/token/hybrid counters, quotas, response failures, and headers, but the Python middleware's helper surface has not yet been mapped method-by-method.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs", + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker" + ], + "source": { + "kind": "async_method", + "line": 320, + "path": "backend-services/middleware/rate_limit_middleware.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "middleware", + "id": "backend-services/middleware/rate_limit_middleware.py::async_method:RateLimitMiddleware._check_quotas", + "notes": "Rust implements user/API/endpoint policy selection, fixed/sliding/token/hybrid counters, quotas, response failures, and headers, but the Python middleware's helper surface has not yet been mapped method-by-method.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs", + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker" + ], + "source": { + "kind": "async_method", + "line": 342, + "path": "backend-services/middleware/rate_limit_middleware.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "middleware", + "id": "backend-services/middleware/rate_limit_middleware.py::method:RateLimitMiddleware._create_rate_limit_response", + "notes": "Rust implements user/API/endpoint policy selection, fixed/sliding/token/hybrid counters, quotas, response failures, and headers, but the Python middleware's helper surface has not yet been mapped method-by-method.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs", + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker" + ], + "source": { + "kind": "method", + "line": 383, + "path": "backend-services/middleware/rate_limit_middleware.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "middleware", + "id": "backend-services/middleware/rate_limit_middleware.py::method:RateLimitMiddleware._create_quota_exceeded_response", + "notes": "Rust implements user/API/endpoint policy selection, fixed/sliding/token/hybrid counters, quotas, response failures, and headers, but the Python middleware's helper surface has not yet been mapped method-by-method.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs", + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker" + ], + "source": { + "kind": "method", + "line": 411, + "path": "backend-services/middleware/rate_limit_middleware.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "middleware", + "id": "backend-services/middleware/rate_limit_middleware.py::method:RateLimitMiddleware._add_rate_limit_headers", + "notes": "Rust implements user/API/endpoint policy selection, fixed/sliding/token/hybrid counters, quotas, response failures, and headers, but the Python middleware's helper surface has not yet been mapped method-by-method.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs", + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker" + ], + "source": { + "kind": "method", + "line": 440, + "path": "backend-services/middleware/rate_limit_middleware.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "middleware", + "id": "backend-services/middleware/security_audit_middleware.py::module:security_audit_middleware", + "notes": "Rust emits payload-free named management audits and security failure activity records, but Python's audit of every platform read has not been reproduced one-for-one.", + "rust_symbols": [ + "gateway-rs/src/middleware/activity.rs::track_active_requests", + "gateway-rs/src/observability/audit.rs", + "gateway-rs/src/routes/platform.rs::audit_management_request" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::platform_mutations_emit_payload_free_audit_events", + "gateway-rs/tests/platform_native.rs::global_ip_denial_emits_the_python_audit_action" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/middleware/security_audit_middleware.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "middleware", + "id": "backend-services/middleware/security_audit_middleware.py::class:SecurityAuditMiddleware", + "notes": "Rust emits payload-free named management audits and security failure activity records, but Python's audit of every platform read has not been reproduced one-for-one.", + "rust_symbols": [ + "gateway-rs/src/middleware/activity.rs::track_active_requests", + "gateway-rs/src/observability/audit.rs", + "gateway-rs/src/routes/platform.rs::audit_management_request" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::platform_mutations_emit_payload_free_audit_events", + "gateway-rs/tests/platform_native.rs::global_ip_denial_emits_the_python_audit_action" + ], + "source": { + "kind": "class", + "line": 20, + "path": "backend-services/middleware/security_audit_middleware.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "middleware", + "id": "backend-services/middleware/security_audit_middleware.py::async_method:SecurityAuditMiddleware.dispatch", + "notes": "Rust emits payload-free named management audits and security failure activity records, but Python's audit of every platform read has not been reproduced one-for-one.", + "rust_symbols": [ + "gateway-rs/src/middleware/activity.rs::track_active_requests", + "gateway-rs/src/observability/audit.rs", + "gateway-rs/src/routes/platform.rs::audit_management_request" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::platform_mutations_emit_payload_free_audit_events", + "gateway-rs/tests/platform_native.rs::global_ip_denial_emits_the_python_audit_action" + ], + "source": { + "kind": "async_method", + "line": 29, + "path": "backend-services/middleware/security_audit_middleware.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "middleware", + "id": "backend-services/middleware/security_audit_middleware.py::method:SecurityAuditMiddleware._should_audit", + "notes": "Rust emits payload-free named management audits and security failure activity records, but Python's audit of every platform read has not been reproduced one-for-one.", + "rust_symbols": [ + "gateway-rs/src/middleware/activity.rs::track_active_requests", + "gateway-rs/src/observability/audit.rs", + "gateway-rs/src/routes/platform.rs::audit_management_request" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::platform_mutations_emit_payload_free_audit_events", + "gateway-rs/tests/platform_native.rs::global_ip_denial_emits_the_python_audit_action" + ], + "source": { + "kind": "method", + "line": 81, + "path": "backend-services/middleware/security_audit_middleware.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "middleware", + "id": "backend-services/middleware/security_audit_middleware.py::method:SecurityAuditMiddleware._get_actor", + "notes": "Rust emits payload-free named management audits and security failure activity records, but Python's audit of every platform read has not been reproduced one-for-one.", + "rust_symbols": [ + "gateway-rs/src/middleware/activity.rs::track_active_requests", + "gateway-rs/src/observability/audit.rs", + "gateway-rs/src/routes/platform.rs::audit_management_request" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::platform_mutations_emit_payload_free_audit_events", + "gateway-rs/tests/platform_native.rs::global_ip_denial_emits_the_python_audit_action" + ], + "source": { + "kind": "method", + "line": 103, + "path": "backend-services/middleware/security_audit_middleware.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "middleware", + "id": "backend-services/middleware/tier_rate_limit_middleware.py::module:tier_rate_limit_middleware", + "notes": "Rust resolves tier assignments and overrides and enforces tier rate/quota limits, but the Python middleware helper surface has not yet been mapped method-by-method.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::live_test_34_tier_rate_limiting_strict_local_parity", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/middleware/tier_rate_limit_middleware.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "middleware", + "id": "backend-services/middleware/tier_rate_limit_middleware.py::class:TierRateLimitMiddleware", + "notes": "Rust resolves tier assignments and overrides and enforces tier rate/quota limits, but the Python middleware helper surface has not yet been mapped method-by-method.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::live_test_34_tier_rate_limiting_strict_local_parity", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "class", + "line": 35, + "path": "backend-services/middleware/tier_rate_limit_middleware.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "middleware", + "id": "backend-services/middleware/tier_rate_limit_middleware.py::method:TierRateLimitMiddleware.__init__", + "notes": "Rust resolves tier assignments and overrides and enforces tier rate/quota limits, but the Python middleware helper surface has not yet been mapped method-by-method.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::live_test_34_tier_rate_limiting_strict_local_parity", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "method", + "line": 49, + "path": "backend-services/middleware/tier_rate_limit_middleware.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "middleware", + "id": "backend-services/middleware/tier_rate_limit_middleware.py::async_method:TierRateLimitMiddleware.dispatch", + "notes": "Rust resolves tier assignments and overrides and enforces tier rate/quota limits, but the Python middleware helper surface has not yet been mapped method-by-method.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::live_test_34_tier_rate_limiting_strict_local_parity", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "async_method", + "line": 54, + "path": "backend-services/middleware/tier_rate_limit_middleware.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "middleware", + "id": "backend-services/middleware/tier_rate_limit_middleware.py::method:TierRateLimitMiddleware._handle_limit_exceeded", + "notes": "Rust resolves tier assignments and overrides and enforces tier rate/quota limits, but the Python middleware helper surface has not yet been mapped method-by-method.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::live_test_34_tier_rate_limiting_strict_local_parity", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "method", + "line": 142, + "path": "backend-services/middleware/tier_rate_limit_middleware.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "middleware", + "id": "backend-services/middleware/tier_rate_limit_middleware.py::method:TierRateLimitMiddleware._create_rate_limit_response", + "notes": "Rust resolves tier assignments and overrides and enforces tier rate/quota limits, but the Python middleware helper surface has not yet been mapped method-by-method.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::live_test_34_tier_rate_limiting_strict_local_parity", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "method", + "line": 149, + "path": "backend-services/middleware/tier_rate_limit_middleware.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "middleware", + "id": "backend-services/middleware/tier_rate_limit_middleware.py::method:TierRateLimitMiddleware._add_rate_limit_headers", + "notes": "Rust resolves tier assignments and overrides and enforces tier rate/quota limits, but the Python middleware helper surface has not yet been mapped method-by-method.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::live_test_34_tier_rate_limiting_strict_local_parity", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "method", + "line": 170, + "path": "backend-services/middleware/tier_rate_limit_middleware.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "middleware", + "id": "backend-services/middleware/tier_rate_limit_middleware.py::method:TierRateLimitMiddleware._should_skip", + "notes": "Rust resolves tier assignments and overrides and enforces tier rate/quota limits, but the Python middleware helper surface has not yet been mapped method-by-method.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::live_test_34_tier_rate_limiting_strict_local_parity", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "method", + "line": 179, + "path": "backend-services/middleware/tier_rate_limit_middleware.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "middleware", + "id": "backend-services/middleware/tier_rate_limit_middleware.py::method:TierRateLimitMiddleware._get_user_id", + "notes": "Rust resolves tier assignments and overrides and enforces tier rate/quota limits, but the Python middleware helper surface has not yet been mapped method-by-method.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::live_test_34_tier_rate_limiting_strict_local_parity", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "method", + "line": 201, + "path": "backend-services/middleware/tier_rate_limit_middleware.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "middleware", + "id": "backend-services/middleware/websocket_reject_middleware.py::module:websocket_reject_middleware", + "notes": "Rust now preserves the default-disabled WebSocket upgrade gate, performs a standards-compliant upgrade before sending the pinned policy-violation close code 1008, and passes requests through unchanged when WEBSOCKETS_ENABLED is truthy. Non-upgrade HTTP requests are never intercepted.", + "rust_symbols": [ + "gateway-rs/src/config.rs::Config.websockets_enabled", + "gateway-rs/src/middleware/websocket_reject.rs::reject_disabled_websockets" + ], + "rust_tests": [ + "gateway-rs/src/middleware/websocket_reject.rs::tests::recognizes_websocket_upgrade_headers_case_insensitively", + "gateway-rs/tests/platform_native.rs::graphql_websocket_upgrade_has_no_route_like_python" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/middleware/websocket_reject_middleware.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "middleware", + "id": "backend-services/middleware/websocket_reject_middleware.py::class:WebSocketRejectMiddleware", + "notes": "Rust now preserves the default-disabled WebSocket upgrade gate, performs a standards-compliant upgrade before sending the pinned policy-violation close code 1008, and passes requests through unchanged when WEBSOCKETS_ENABLED is truthy. Non-upgrade HTTP requests are never intercepted.", + "rust_symbols": [ + "gateway-rs/src/config.rs::Config.websockets_enabled", + "gateway-rs/src/middleware/websocket_reject.rs::reject_disabled_websockets" + ], + "rust_tests": [ + "gateway-rs/src/middleware/websocket_reject.rs::tests::recognizes_websocket_upgrade_headers_case_insensitively", + "gateway-rs/tests/platform_native.rs::graphql_websocket_upgrade_has_no_route_like_python" + ], + "source": { + "kind": "class", + "line": 1, + "path": "backend-services/middleware/websocket_reject_middleware.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "middleware", + "id": "backend-services/middleware/websocket_reject_middleware.py::method:WebSocketRejectMiddleware.__init__", + "notes": "Rust now preserves the default-disabled WebSocket upgrade gate, performs a standards-compliant upgrade before sending the pinned policy-violation close code 1008, and passes requests through unchanged when WEBSOCKETS_ENABLED is truthy. Non-upgrade HTTP requests are never intercepted.", + "rust_symbols": [ + "gateway-rs/src/config.rs::Config.websockets_enabled", + "gateway-rs/src/middleware/websocket_reject.rs::reject_disabled_websockets" + ], + "rust_tests": [ + "gateway-rs/src/middleware/websocket_reject.rs::tests::recognizes_websocket_upgrade_headers_case_insensitively", + "gateway-rs/tests/platform_native.rs::graphql_websocket_upgrade_has_no_route_like_python" + ], + "source": { + "kind": "method", + "line": 4, + "path": "backend-services/middleware/websocket_reject_middleware.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "middleware", + "id": "backend-services/middleware/websocket_reject_middleware.py::async_method:WebSocketRejectMiddleware.__call__", + "notes": "Rust now preserves the default-disabled WebSocket upgrade gate, performs a standards-compliant upgrade before sending the pinned policy-violation close code 1008, and passes requests through unchanged when WEBSOCKETS_ENABLED is truthy. Non-upgrade HTTP requests are never intercepted.", + "rust_symbols": [ + "gateway-rs/src/config.rs::Config.websockets_enabled", + "gateway-rs/src/middleware/websocket_reject.rs::reject_disabled_websockets" + ], + "rust_tests": [ + "gateway-rs/src/middleware/websocket_reject.rs::tests::recognizes_websocket_upgrade_headers_case_insensitively", + "gateway-rs/tests/platform_native.rs::graphql_websocket_upgrade_has_no_route_like_python" + ], + "source": { + "kind": "async_method", + "line": 8, + "path": "backend-services/middleware/websocket_reject_middleware.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::module:analytics_models", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::class:AggregationLevel", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "class", + "line": 15, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:AggregationLevel.MINUTE", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 18, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:AggregationLevel.FIVE_MINUTE", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 19, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:AggregationLevel.HOUR", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 20, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:AggregationLevel.DAY", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 21, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::class:MetricType", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "class", + "line": 24, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:MetricType.REQUEST_COUNT", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 27, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:MetricType.ERROR_RATE", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 28, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:MetricType.RESPONSE_TIME", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 29, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:MetricType.BANDWIDTH", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 30, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:MetricType.STATUS_CODE", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 31, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:MetricType.LATENCY_PERCENTILE", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 32, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [ + "dataclass" + ], + "domain": "models", + "id": "backend-services/models/analytics_models.py::class:PercentileMetrics", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "class", + "line": 36, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:PercentileMetrics.p50", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 44, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:PercentileMetrics.p75", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 45, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:PercentileMetrics.p90", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 46, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:PercentileMetrics.p95", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 47, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:PercentileMetrics.p99", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 48, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:PercentileMetrics.min", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 49, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:PercentileMetrics.max", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 50, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "models", + "id": "backend-services/models/analytics_models.py::method:PercentileMetrics.calculate", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "method", + "line": 53, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::function:PercentileMetrics.calculate.percentile", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "function", + "line": 61, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::method:PercentileMetrics.to_dict", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "method", + "line": 75, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [ + "dataclass" + ], + "domain": "models", + "id": "backend-services/models/analytics_models.py::class:EndpointMetrics", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "class", + "line": 88, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:EndpointMetrics.endpoint_uri", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 96, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:EndpointMetrics.method", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 97, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:EndpointMetrics.count", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 98, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:EndpointMetrics.error_count", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 99, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:EndpointMetrics.total_ms", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 100, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:EndpointMetrics.latencies", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 101, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:EndpointMetrics.status_counts", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 102, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::method:EndpointMetrics.add", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "method", + "line": 104, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::method:EndpointMetrics.get_percentiles", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "method", + "line": 117, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::method:EndpointMetrics.to_dict", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "method", + "line": 121, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "models", + "id": "backend-services/models/analytics_models.py::method:EndpointMetrics.from_dict", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "method", + "line": 135, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [ + "dataclass" + ], + "domain": "models", + "id": "backend-services/models/analytics_models.py::class:EnhancedMinuteBucket", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "class", + "line": 151, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:EnhancedMinuteBucket.start_ts", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 162, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:EnhancedMinuteBucket.count", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 163, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:EnhancedMinuteBucket.error_count", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 164, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:EnhancedMinuteBucket.total_ms", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 165, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:EnhancedMinuteBucket.bytes_in", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 166, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:EnhancedMinuteBucket.bytes_out", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 167, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:EnhancedMinuteBucket.upstream_timeouts", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 168, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:EnhancedMinuteBucket.retries", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 169, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:EnhancedMinuteBucket.status_counts", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 172, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:EnhancedMinuteBucket.api_counts", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 173, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:EnhancedMinuteBucket.api_error_counts", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 174, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:EnhancedMinuteBucket.user_counts", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 175, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:EnhancedMinuteBucket.latencies", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 176, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:EnhancedMinuteBucket.endpoint_metrics", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 179, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:EnhancedMinuteBucket.unique_users", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 180, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:EnhancedMinuteBucket.request_sizes", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 181, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:EnhancedMinuteBucket.response_sizes", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 182, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::method:EnhancedMinuteBucket.add_request", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "method", + "line": 184, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::method:EnhancedMinuteBucket.get_percentiles", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "method", + "line": 244, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::method:EnhancedMinuteBucket.get_unique_user_count", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "method", + "line": 248, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::method:EnhancedMinuteBucket.get_top_endpoints", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "method", + "line": 252, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::method:EnhancedMinuteBucket.to_dict", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "method", + "line": 259, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "models", + "id": "backend-services/models/analytics_models.py::method:EnhancedMinuteBucket.from_dict", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "method", + "line": 289, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [ + "dataclass" + ], + "domain": "models", + "id": "backend-services/models/analytics_models.py::class:AggregatedMetrics", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "class", + "line": 326, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:AggregatedMetrics.start_ts", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 334, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:AggregatedMetrics.end_ts", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 335, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:AggregatedMetrics.level", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 336, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:AggregatedMetrics.count", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 337, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:AggregatedMetrics.error_count", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 338, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:AggregatedMetrics.total_ms", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 339, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:AggregatedMetrics.bytes_in", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 340, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:AggregatedMetrics.bytes_out", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 341, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:AggregatedMetrics.unique_users", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 342, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:AggregatedMetrics.status_counts", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 344, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:AggregatedMetrics.api_counts", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 345, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:AggregatedMetrics.percentiles", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 346, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:AggregatedMetrics.unique_users_set", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 349, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::method:AggregatedMetrics.to_dict", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "method", + "line": 351, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "models", + "id": "backend-services/models/analytics_models.py::method:AggregatedMetrics.from_dict", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "method", + "line": 371, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [ + "dataclass" + ], + "domain": "models", + "id": "backend-services/models/analytics_models.py::class:AnalyticsSnapshot", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "class", + "line": 408, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:AnalyticsSnapshot.start_ts", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 415, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:AnalyticsSnapshot.end_ts", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 416, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:AnalyticsSnapshot.total_requests", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 417, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:AnalyticsSnapshot.total_errors", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 418, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:AnalyticsSnapshot.error_rate", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 419, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:AnalyticsSnapshot.avg_response_ms", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 420, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:AnalyticsSnapshot.percentiles", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 421, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:AnalyticsSnapshot.total_bytes_in", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 422, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:AnalyticsSnapshot.total_bytes_out", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 423, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:AnalyticsSnapshot.unique_users", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 424, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:AnalyticsSnapshot.series", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 427, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:AnalyticsSnapshot.top_apis", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 430, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:AnalyticsSnapshot.top_users", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 431, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:AnalyticsSnapshot.top_endpoints", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 432, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::field:AnalyticsSnapshot.status_distribution", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "field", + "line": 435, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/analytics_models.py::method:AnalyticsSnapshot.to_dict", + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "source": { + "kind": "method", + "line": 437, + "path": "backend-services/models/analytics_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/api_model_response.py::module:api_model_response", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/models/api_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/api_model_response.py::class:ApiModelResponse", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "class", + "line": 10, + "path": "backend-services/models/api_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/api_model_response.py::field:ApiModelResponse.api_name", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 11, + "path": "backend-services/models/api_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/api_model_response.py::field:ApiModelResponse.api_version", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 14, + "path": "backend-services/models/api_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/api_model_response.py::field:ApiModelResponse.api_description", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 17, + "path": "backend-services/models/api_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/api_model_response.py::field:ApiModelResponse.api_allowed_roles", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 23, + "path": "backend-services/models/api_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/api_model_response.py::field:ApiModelResponse.api_allowed_groups", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 26, + "path": "backend-services/models/api_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/api_model_response.py::field:ApiModelResponse.api_servers", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 29, + "path": "backend-services/models/api_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/api_model_response.py::field:ApiModelResponse.api_type", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 34, + "path": "backend-services/models/api_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/api_model_response.py::field:ApiModelResponse.api_authorization_field_swap", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 37, + "path": "backend-services/models/api_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/api_model_response.py::field:ApiModelResponse.api_allowed_headers", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 42, + "path": "backend-services/models/api_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/api_model_response.py::field:ApiModelResponse.api_allowed_retry_count", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 45, + "path": "backend-services/models/api_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/api_model_response.py::field:ApiModelResponse.api_credits_enabled", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 48, + "path": "backend-services/models/api_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/api_model_response.py::field:ApiModelResponse.api_credit_group", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 51, + "path": "backend-services/models/api_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/api_model_response.py::field:ApiModelResponse.api_id", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 54, + "path": "backend-services/models/api_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/api_model_response.py::field:ApiModelResponse.api_path", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 59, + "path": "backend-services/models/api_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/api_model_response.py::class:ApiModelResponse.Config", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "class", + "line": 63, + "path": "backend-services/models/api_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/api_model_response.py::field:ApiModelResponse.Config.arbitrary_types_allowed", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 64, + "path": "backend-services/models/api_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::module:create_api_model", + "notes": "Pinned model fields are implemented; additive v2 fields prevent an exact whole-module claim.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/models/create_api_model.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::class:CreateApiModel", + "notes": "All pinned fields are normalized, but Rust also permits documented v2 extension fields when explicitly supplied.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "class", + "line": 11, + "path": "backend-services/models/create_api_model.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::field:CreateApiModel.api_name", + "notes": "The shared Rust create normalizer contains the pinned field, Pydantic coercion category, defaults, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 12, + "path": "backend-services/models/create_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::field:CreateApiModel.api_version", + "notes": "The shared Rust create normalizer contains the pinned field, Pydantic coercion category, defaults, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 15, + "path": "backend-services/models/create_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::field:CreateApiModel.api_description", + "notes": "The shared Rust create normalizer contains the pinned field, Pydantic coercion category, defaults, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 18, + "path": "backend-services/models/create_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::field:CreateApiModel.api_allowed_roles", + "notes": "The shared Rust create normalizer contains the pinned field, Pydantic coercion category, defaults, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 24, + "path": "backend-services/models/create_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::field:CreateApiModel.api_allowed_groups", + "notes": "The shared Rust create normalizer contains the pinned field, Pydantic coercion category, defaults, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 29, + "path": "backend-services/models/create_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::field:CreateApiModel.api_servers", + "notes": "The shared Rust create normalizer contains the pinned field, Pydantic coercion category, defaults, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 34, + "path": "backend-services/models/create_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::field:CreateApiModel.api_type", + "notes": "The shared Rust create normalizer contains the pinned field, Pydantic coercion category, defaults, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 39, + "path": "backend-services/models/create_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::field:CreateApiModel.api_allowed_retry_count", + "notes": "The shared Rust create normalizer contains the pinned field, Pydantic coercion category, defaults, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 42, + "path": "backend-services/models/create_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::field:CreateApiModel.api_grpc_package", + "notes": "The shared Rust create normalizer contains the pinned field, Pydantic coercion category, defaults, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 45, + "path": "backend-services/models/create_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::field:CreateApiModel.api_grpc_allowed_packages", + "notes": "The shared Rust create normalizer contains the pinned field, Pydantic coercion category, defaults, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 50, + "path": "backend-services/models/create_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::field:CreateApiModel.api_grpc_allowed_services", + "notes": "The shared Rust create normalizer contains the pinned field, Pydantic coercion category, defaults, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 55, + "path": "backend-services/models/create_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::field:CreateApiModel.api_grpc_allowed_methods", + "notes": "The shared Rust create normalizer contains the pinned field, Pydantic coercion category, defaults, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 60, + "path": "backend-services/models/create_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::field:CreateApiModel.api_authorization_field_swap", + "notes": "The shared Rust create normalizer contains the pinned field, Pydantic coercion category, defaults, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 66, + "path": "backend-services/models/create_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::field:CreateApiModel.api_allowed_headers", + "notes": "The shared Rust create normalizer contains the pinned field, Pydantic coercion category, defaults, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 71, + "path": "backend-services/models/create_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::field:CreateApiModel.api_credits_enabled", + "notes": "The shared Rust create normalizer contains the pinned field, Pydantic coercion category, defaults, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 74, + "path": "backend-services/models/create_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::field:CreateApiModel.api_credit_group", + "notes": "The shared Rust create normalizer contains the pinned field, Pydantic coercion category, defaults, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 77, + "path": "backend-services/models/create_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::field:CreateApiModel.active", + "notes": "The shared Rust create normalizer contains the pinned field, Pydantic coercion category, defaults, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 80, + "path": "backend-services/models/create_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::field:CreateApiModel.api_cors_allow_origins", + "notes": "The shared Rust create normalizer contains the pinned field, Pydantic coercion category, defaults, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 84, + "path": "backend-services/models/create_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::field:CreateApiModel.api_cors_allow_methods", + "notes": "The shared Rust create normalizer contains the pinned field, Pydantic coercion category, defaults, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 88, + "path": "backend-services/models/create_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::field:CreateApiModel.api_cors_allow_headers", + "notes": "The shared Rust create normalizer contains the pinned field, Pydantic coercion category, defaults, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 92, + "path": "backend-services/models/create_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::field:CreateApiModel.api_cors_allow_credentials", + "notes": "The shared Rust create normalizer contains the pinned field, Pydantic coercion category, defaults, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 96, + "path": "backend-services/models/create_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::field:CreateApiModel.api_cors_expose_headers", + "notes": "The shared Rust create normalizer contains the pinned field, Pydantic coercion category, defaults, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 99, + "path": "backend-services/models/create_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::field:CreateApiModel.api_public", + "notes": "The shared Rust create normalizer contains the pinned field, Pydantic coercion category, defaults, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 104, + "path": "backend-services/models/create_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::field:CreateApiModel.api_auth_required", + "notes": "The shared Rust create normalizer contains the pinned field, Pydantic coercion category, defaults, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 108, + "path": "backend-services/models/create_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::field:CreateApiModel.api_id", + "notes": "The shared Rust create normalizer contains the pinned field, Pydantic coercion category, defaults, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 113, + "path": "backend-services/models/create_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::field:CreateApiModel.api_path", + "notes": "The shared Rust create normalizer contains the pinned field, Pydantic coercion category, defaults, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 116, + "path": "backend-services/models/create_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::field:CreateApiModel.api_ip_mode", + "notes": "The shared Rust create normalizer contains the pinned field, Pydantic coercion category, defaults, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 120, + "path": "backend-services/models/create_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::field:CreateApiModel.api_ip_whitelist", + "notes": "The shared Rust create normalizer contains the pinned field, Pydantic coercion category, defaults, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 123, + "path": "backend-services/models/create_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::field:CreateApiModel.api_ip_blacklist", + "notes": "The shared Rust create normalizer contains the pinned field, Pydantic coercion category, defaults, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 126, + "path": "backend-services/models/create_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::field:CreateApiModel.api_trust_x_forwarded_for", + "notes": "The shared Rust create normalizer contains the pinned field, Pydantic coercion category, defaults, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 129, + "path": "backend-services/models/create_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::field:CreateApiModel.api_request_transform", + "notes": "The shared Rust create normalizer contains the pinned field, Pydantic coercion category, defaults, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 134, + "path": "backend-services/models/create_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::field:CreateApiModel.api_response_transform", + "notes": "The shared Rust create normalizer contains the pinned field, Pydantic coercion category, defaults, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 144, + "path": "backend-services/models/create_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::field:CreateApiModel.api_openapi_url", + "notes": "The shared Rust create normalizer contains the pinned field, Pydantic coercion category, defaults, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 157, + "path": "backend-services/models/create_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::field:CreateApiModel.api_openapi_auto_discover", + "notes": "The shared Rust create normalizer contains the pinned field, Pydantic coercion category, defaults, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 162, + "path": "backend-services/models/create_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::field:CreateApiModel.api_wsdl_url", + "notes": "The shared Rust create normalizer contains the pinned field, Pydantic coercion category, defaults, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 168, + "path": "backend-services/models/create_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::field:CreateApiModel.api_soap_version", + "notes": "The shared Rust create normalizer contains the pinned field, Pydantic coercion category, defaults, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 173, + "path": "backend-services/models/create_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::field:CreateApiModel.api_ws_security", + "notes": "The shared Rust create normalizer contains the pinned field, Pydantic coercion category, defaults, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 178, + "path": "backend-services/models/create_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::field:CreateApiModel.api_graphql_max_depth", + "notes": "The shared Rust create normalizer contains the pinned field, Pydantic coercion category, defaults, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 190, + "path": "backend-services/models/create_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::field:CreateApiModel.api_graphql_schema_url", + "notes": "The shared Rust create normalizer contains the pinned field, Pydantic coercion category, defaults, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 195, + "path": "backend-services/models/create_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::field:CreateApiModel.api_graphql_subscriptions", + "notes": "The shared Rust create normalizer contains the pinned field, Pydantic coercion category, defaults, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 200, + "path": "backend-services/models/create_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::field:CreateApiModel.api_grpc_web_enabled", + "notes": "The shared Rust create normalizer contains the pinned field, Pydantic coercion category, defaults, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 206, + "path": "backend-services/models/create_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::field:CreateApiModel.api_grpc_reflection_url", + "notes": "The shared Rust create normalizer contains the pinned field, Pydantic coercion category, defaults, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 210, + "path": "backend-services/models/create_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::field:CreateApiModel.api_is_crud", + "notes": "The shared Rust create normalizer contains the pinned field, Pydantic coercion category, defaults, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 215, + "path": "backend-services/models/create_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::field:CreateApiModel.api_crud_collection", + "notes": "The shared Rust create normalizer contains the pinned field, Pydantic coercion category, defaults, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 219, + "path": "backend-services/models/create_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::field:CreateApiModel.api_crud_schema", + "notes": "The shared Rust create normalizer contains the pinned field, Pydantic coercion category, defaults, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 224, + "path": "backend-services/models/create_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::class:CreateApiModel.Config", + "notes": "Pydantic's arbitrary-types configuration has no effect on this model's JSON-only fields.", + "rationale": "Python framework configuration is unnecessary in the typed Rust/serde implementation.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "class", + "line": 233, + "path": "backend-services/models/create_api_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_api_model.py::field:CreateApiModel.Config.arbitrary_types_allowed", + "notes": "Every accepted field is a JSON scalar, list, or object and does not require arbitrary Python types.", + "rationale": "Python framework flag with no observable contract for this model.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 234, + "path": "backend-services/models/create_api_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_endpoint_model.py::module:create_endpoint_model", + "notes": "Rust matches required fields, scalar/list coercion, character-count limits, optional identifier behavior, defaults, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_endpoint_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::endpoint_models_match_pydantic_coercion_bounds_and_null_elision" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/models/create_endpoint_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_endpoint_model.py::class:CreateEndpointModel", + "notes": "Rust matches required fields, scalar/list coercion, character-count limits, optional identifier behavior, defaults, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_endpoint_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::endpoint_models_match_pydantic_coercion_bounds_and_null_elision" + ], + "source": { + "kind": "class", + "line": 10, + "path": "backend-services/models/create_endpoint_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_endpoint_model.py::field:CreateEndpointModel.api_name", + "notes": "Rust matches required fields, scalar/list coercion, character-count limits, optional identifier behavior, defaults, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_endpoint_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::endpoint_models_match_pydantic_coercion_bounds_and_null_elision" + ], + "source": { + "kind": "field", + "line": 11, + "path": "backend-services/models/create_endpoint_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_endpoint_model.py::field:CreateEndpointModel.api_version", + "notes": "Rust matches required fields, scalar/list coercion, character-count limits, optional identifier behavior, defaults, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_endpoint_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::endpoint_models_match_pydantic_coercion_bounds_and_null_elision" + ], + "source": { + "kind": "field", + "line": 14, + "path": "backend-services/models/create_endpoint_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_endpoint_model.py::field:CreateEndpointModel.endpoint_method", + "notes": "Rust matches required fields, scalar/list coercion, character-count limits, optional identifier behavior, defaults, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_endpoint_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::endpoint_models_match_pydantic_coercion_bounds_and_null_elision" + ], + "source": { + "kind": "field", + "line": 17, + "path": "backend-services/models/create_endpoint_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_endpoint_model.py::field:CreateEndpointModel.endpoint_uri", + "notes": "Rust matches required fields, scalar/list coercion, character-count limits, optional identifier behavior, defaults, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_endpoint_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::endpoint_models_match_pydantic_coercion_bounds_and_null_elision" + ], + "source": { + "kind": "field", + "line": 20, + "path": "backend-services/models/create_endpoint_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_endpoint_model.py::field:CreateEndpointModel.endpoint_description", + "notes": "Rust matches required fields, scalar/list coercion, character-count limits, optional identifier behavior, defaults, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_endpoint_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::endpoint_models_match_pydantic_coercion_bounds_and_null_elision" + ], + "source": { + "kind": "field", + "line": 23, + "path": "backend-services/models/create_endpoint_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_endpoint_model.py::field:CreateEndpointModel.endpoint_servers", + "notes": "Rust matches required fields, scalar/list coercion, character-count limits, optional identifier behavior, defaults, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_endpoint_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::endpoint_models_match_pydantic_coercion_bounds_and_null_elision" + ], + "source": { + "kind": "field", + "line": 30, + "path": "backend-services/models/create_endpoint_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_endpoint_model.py::field:CreateEndpointModel.client_uri", + "notes": "Rust matches required fields, scalar/list coercion, character-count limits, optional identifier behavior, defaults, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_endpoint_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::endpoint_models_match_pydantic_coercion_bounds_and_null_elision" + ], + "source": { + "kind": "field", + "line": 35, + "path": "backend-services/models/create_endpoint_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_endpoint_model.py::field:CreateEndpointModel.api_id", + "notes": "Rust matches required fields, scalar/list coercion, character-count limits, optional identifier behavior, defaults, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_endpoint_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::endpoint_models_match_pydantic_coercion_bounds_and_null_elision" + ], + "source": { + "kind": "field", + "line": 43, + "path": "backend-services/models/create_endpoint_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_endpoint_model.py::field:CreateEndpointModel.endpoint_id", + "notes": "Rust matches required fields, scalar/list coercion, character-count limits, optional identifier behavior, defaults, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_endpoint_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::endpoint_models_match_pydantic_coercion_bounds_and_null_elision" + ], + "source": { + "kind": "field", + "line": 46, + "path": "backend-services/models/create_endpoint_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_endpoint_model.py::class:CreateEndpointModel.Config", + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in the Rust implementation.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "class", + "line": 50, + "path": "backend-services/models/create_endpoint_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_endpoint_model.py::field:CreateEndpointModel.Config.arbitrary_types_allowed", + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Python framework flag with no observable contract for this model.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 51, + "path": "backend-services/models/create_endpoint_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_endpoint_validation_model.py::module:create_endpoint_validation_model", + "notes": "Rust now validates and normalizes the required outer fields and recursive schema before authorization; extreme Pydantic numeric-union coercion remains unproven.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_endpoint_validation_model", + "gateway-rs/src/routes/platform.rs::normalize_validation_schema_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/models/create_endpoint_validation_model.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_endpoint_validation_model.py::class:CreateEndpointValidationModel", + "notes": "Rust now validates and normalizes the required outer fields and recursive schema before authorization; extreme Pydantic numeric-union coercion remains unproven.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_endpoint_validation_model", + "gateway-rs/src/routes/platform.rs::normalize_validation_schema_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" + ], + "source": { + "kind": "class", + "line": 12, + "path": "backend-services/models/create_endpoint_validation_model.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_endpoint_validation_model.py::field:CreateEndpointValidationModel.endpoint_id", + "notes": "Rust now validates and normalizes the required outer fields and recursive schema before authorization; extreme Pydantic numeric-union coercion remains unproven.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_endpoint_validation_model", + "gateway-rs/src/routes/platform.rs::normalize_validation_schema_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" + ], + "source": { + "kind": "field", + "line": 13, + "path": "backend-services/models/create_endpoint_validation_model.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_endpoint_validation_model.py::field:CreateEndpointValidationModel.validation_enabled", + "notes": "Rust now validates and normalizes the required outer fields and recursive schema before authorization; extreme Pydantic numeric-union coercion remains unproven.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_endpoint_validation_model", + "gateway-rs/src/routes/platform.rs::normalize_validation_schema_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" + ], + "source": { + "kind": "field", + "line": 18, + "path": "backend-services/models/create_endpoint_validation_model.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_endpoint_validation_model.py::field:CreateEndpointValidationModel.validation_schema", + "notes": "Rust now validates and normalizes the required outer fields and recursive schema before authorization; extreme Pydantic numeric-union coercion remains unproven.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_endpoint_validation_model", + "gateway-rs/src/routes/platform.rs::normalize_validation_schema_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" + ], + "source": { + "kind": "field", + "line": 21, + "path": "backend-services/models/create_endpoint_validation_model.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_endpoint_validation_model.py::class:CreateEndpointValidationModel.Config", + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "class", + "line": 25, + "path": "backend-services/models/create_endpoint_validation_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_endpoint_validation_model.py::field:CreateEndpointValidationModel.Config.arbitrary_types_allowed", + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Python framework flag with no observable contract for this model.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 26, + "path": "backend-services/models/create_endpoint_validation_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_group_model.py::module:create_group_model", + "notes": "Rust matches required/default fields, scalar/list coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_group_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/models/create_group_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_group_model.py::class:CreateGroupModel", + "notes": "Rust matches required/default fields, scalar/list coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_group_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "class", + "line": 10, + "path": "backend-services/models/create_group_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_group_model.py::field:CreateGroupModel.group_name", + "notes": "Rust matches required/default fields, scalar/list coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_group_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "field", + "line": 11, + "path": "backend-services/models/create_group_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_group_model.py::field:CreateGroupModel.group_description", + "notes": "Rust matches required/default fields, scalar/list coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_group_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "field", + "line": 15, + "path": "backend-services/models/create_group_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_group_model.py::field:CreateGroupModel.api_access", + "notes": "Rust matches required/default fields, scalar/list coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_group_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "field", + "line": 18, + "path": "backend-services/models/create_group_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_group_model.py::class:CreateGroupModel.Config", + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "class", + "line": 24, + "path": "backend-services/models/create_group_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_group_model.py::field:CreateGroupModel.Config.arbitrary_types_allowed", + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Python framework flag with no observable contract for this model.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 25, + "path": "backend-services/models/create_group_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_role_model.py::module:create_role_model", + "notes": "Rust matches role defaults, boolean coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_role_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/models/create_role_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_role_model.py::class:CreateRoleModel", + "notes": "Rust matches role defaults, boolean coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_role_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "class", + "line": 10, + "path": "backend-services/models/create_role_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_role_model.py::field:CreateRoleModel.role_name", + "notes": "Rust matches role defaults, boolean coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_role_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "field", + "line": 11, + "path": "backend-services/models/create_role_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_role_model.py::field:CreateRoleModel.role_description", + "notes": "Rust matches role defaults, boolean coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_role_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "field", + "line": 14, + "path": "backend-services/models/create_role_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_role_model.py::field:CreateRoleModel.manage_users", + "notes": "Rust matches role defaults, boolean coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_role_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "field", + "line": 20, + "path": "backend-services/models/create_role_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_role_model.py::field:CreateRoleModel.manage_apis", + "notes": "Rust matches role defaults, boolean coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_role_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "field", + "line": 21, + "path": "backend-services/models/create_role_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_role_model.py::field:CreateRoleModel.manage_endpoints", + "notes": "Rust matches role defaults, boolean coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_role_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "field", + "line": 22, + "path": "backend-services/models/create_role_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_role_model.py::field:CreateRoleModel.manage_groups", + "notes": "Rust matches role defaults, boolean coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_role_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "field", + "line": 25, + "path": "backend-services/models/create_role_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_role_model.py::field:CreateRoleModel.manage_roles", + "notes": "Rust matches role defaults, boolean coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_role_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "field", + "line": 26, + "path": "backend-services/models/create_role_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_role_model.py::field:CreateRoleModel.manage_routings", + "notes": "Rust matches role defaults, boolean coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_role_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "field", + "line": 27, + "path": "backend-services/models/create_role_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_role_model.py::field:CreateRoleModel.manage_gateway", + "notes": "Rust matches role defaults, boolean coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_role_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "field", + "line": 28, + "path": "backend-services/models/create_role_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_role_model.py::field:CreateRoleModel.manage_subscriptions", + "notes": "Rust matches role defaults, boolean coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_role_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "field", + "line": 29, + "path": "backend-services/models/create_role_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_role_model.py::field:CreateRoleModel.manage_security", + "notes": "Rust matches role defaults, boolean coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_role_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "field", + "line": 32, + "path": "backend-services/models/create_role_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_role_model.py::field:CreateRoleModel.manage_tiers", + "notes": "Rust matches role defaults, boolean coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_role_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "field", + "line": 35, + "path": "backend-services/models/create_role_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_role_model.py::field:CreateRoleModel.manage_rate_limits", + "notes": "Rust matches role defaults, boolean coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_role_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "field", + "line": 38, + "path": "backend-services/models/create_role_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_role_model.py::field:CreateRoleModel.manage_credits", + "notes": "Rust matches role defaults, boolean coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_role_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "field", + "line": 41, + "path": "backend-services/models/create_role_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_role_model.py::field:CreateRoleModel.manage_auth", + "notes": "Rust matches role defaults, boolean coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_role_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "field", + "line": 42, + "path": "backend-services/models/create_role_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_role_model.py::field:CreateRoleModel.view_analytics", + "notes": "Rust matches role defaults, boolean coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_role_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "field", + "line": 45, + "path": "backend-services/models/create_role_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_role_model.py::field:CreateRoleModel.view_logs", + "notes": "Rust matches role defaults, boolean coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_role_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "field", + "line": 48, + "path": "backend-services/models/create_role_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_role_model.py::field:CreateRoleModel.export_logs", + "notes": "Rust matches role defaults, boolean coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_role_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "field", + "line": 49, + "path": "backend-services/models/create_role_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_role_model.py::class:CreateRoleModel.Config", + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "class", + "line": 51, + "path": "backend-services/models/create_role_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_role_model.py::field:CreateRoleModel.Config.arbitrary_types_allowed", + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Python framework flag with no observable contract for this model.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 52, + "path": "backend-services/models/create_role_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_routing_model.py::module:create_routing_model", + "notes": "Rust matches required/default fields, list/scalar/integer coercion, character-count bounds, and minimum server count.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_routing_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::routing_models_match_pydantic_generation_coercion_and_update_exclusion" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/models/create_routing_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_routing_model.py::class:CreateRoutingModel", + "notes": "Rust matches required/default fields, list/scalar/integer coercion, character-count bounds, and minimum server count.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_routing_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::routing_models_match_pydantic_generation_coercion_and_update_exclusion" + ], + "source": { + "kind": "class", + "line": 10, + "path": "backend-services/models/create_routing_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_routing_model.py::field:CreateRoutingModel.routing_name", + "notes": "Rust matches required/default fields, list/scalar/integer coercion, character-count bounds, and minimum server count.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_routing_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::routing_models_match_pydantic_generation_coercion_and_update_exclusion" + ], + "source": { + "kind": "field", + "line": 11, + "path": "backend-services/models/create_routing_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_routing_model.py::field:CreateRoutingModel.routing_servers", + "notes": "Rust matches required/default fields, list/scalar/integer coercion, character-count bounds, and minimum server count.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_routing_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::routing_models_match_pydantic_generation_coercion_and_update_exclusion" + ], + "source": { + "kind": "field", + "line": 18, + "path": "backend-services/models/create_routing_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_routing_model.py::field:CreateRoutingModel.routing_description", + "notes": "Rust matches required/default fields, list/scalar/integer coercion, character-count bounds, and minimum server count.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_routing_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::routing_models_match_pydantic_generation_coercion_and_update_exclusion" + ], + "source": { + "kind": "field", + "line": 24, + "path": "backend-services/models/create_routing_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_routing_model.py::field:CreateRoutingModel.client_key", + "notes": "Rust matches required/default fields, list/scalar/integer coercion, character-count bounds, and minimum server count.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_routing_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::routing_models_match_pydantic_generation_coercion_and_update_exclusion" + ], + "source": { + "kind": "field", + "line": 31, + "path": "backend-services/models/create_routing_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_routing_model.py::field:CreateRoutingModel.server_index", + "notes": "Rust matches required/default fields, list/scalar/integer coercion, character-count bounds, and minimum server count.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_routing_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::routing_models_match_pydantic_generation_coercion_and_update_exclusion" + ], + "source": { + "kind": "field", + "line": 38, + "path": "backend-services/models/create_routing_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_routing_model.py::class:CreateRoutingModel.Config", + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "class", + "line": 42, + "path": "backend-services/models/create_routing_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_routing_model.py::field:CreateRoutingModel.Config.arbitrary_types_allowed", + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Python framework flag with no observable contract for this model.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 43, + "path": "backend-services/models/create_routing_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_user_model.py::module:create_user_model", + "notes": "Rust matches required fields, defaults and null materialization, scalar/list coercion, Unicode character bounds, numeric and boolean constraints, dictionary handling, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_create_user_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::user_create_matches_pydantic_bounds_and_scalar_coercion" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/models/create_user_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_user_model.py::class:CreateUserModel", + "notes": "Rust matches required fields, defaults and null materialization, scalar/list coercion, Unicode character bounds, numeric and boolean constraints, dictionary handling, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_create_user_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::user_create_matches_pydantic_bounds_and_scalar_coercion" + ], + "source": { + "kind": "class", + "line": 10, + "path": "backend-services/models/create_user_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_user_model.py::field:CreateUserModel.username", + "notes": "Rust matches required fields, defaults and null materialization, scalar/list coercion, Unicode character bounds, numeric and boolean constraints, dictionary handling, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_create_user_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::user_create_matches_pydantic_bounds_and_scalar_coercion" + ], + "source": { + "kind": "field", + "line": 11, + "path": "backend-services/models/create_user_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_user_model.py::field:CreateUserModel.email", + "notes": "Rust matches required fields, defaults and null materialization, scalar/list coercion, Unicode character bounds, numeric and boolean constraints, dictionary handling, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_create_user_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::user_create_matches_pydantic_bounds_and_scalar_coercion" + ], + "source": { + "kind": "field", + "line": 14, + "path": "backend-services/models/create_user_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_user_model.py::field:CreateUserModel.password", + "notes": "Rust matches required fields, defaults and null materialization, scalar/list coercion, Unicode character bounds, numeric and boolean constraints, dictionary handling, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_create_user_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::user_create_matches_pydantic_bounds_and_scalar_coercion" + ], + "source": { + "kind": "field", + "line": 21, + "path": "backend-services/models/create_user_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_user_model.py::field:CreateUserModel.role", + "notes": "Rust matches required fields, defaults and null materialization, scalar/list coercion, Unicode character bounds, numeric and boolean constraints, dictionary handling, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_create_user_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::user_create_matches_pydantic_bounds_and_scalar_coercion" + ], + "source": { + "kind": "field", + "line": 28, + "path": "backend-services/models/create_user_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_user_model.py::field:CreateUserModel.groups", + "notes": "Rust matches required fields, defaults and null materialization, scalar/list coercion, Unicode character bounds, numeric and boolean constraints, dictionary handling, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_create_user_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::user_create_matches_pydantic_bounds_and_scalar_coercion" + ], + "source": { + "kind": "field", + "line": 31, + "path": "backend-services/models/create_user_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_user_model.py::field:CreateUserModel.rate_limit_duration", + "notes": "Rust matches required fields, defaults and null materialization, scalar/list coercion, Unicode character bounds, numeric and boolean constraints, dictionary handling, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_create_user_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::user_create_matches_pydantic_bounds_and_scalar_coercion" + ], + "source": { + "kind": "field", + "line": 37, + "path": "backend-services/models/create_user_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_user_model.py::field:CreateUserModel.rate_limit_duration_type", + "notes": "Rust matches required fields, defaults and null materialization, scalar/list coercion, Unicode character bounds, numeric and boolean constraints, dictionary handling, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_create_user_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::user_create_matches_pydantic_bounds_and_scalar_coercion" + ], + "source": { + "kind": "field", + "line": 40, + "path": "backend-services/models/create_user_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_user_model.py::field:CreateUserModel.rate_limit_enabled", + "notes": "Rust matches required fields, defaults and null materialization, scalar/list coercion, Unicode character bounds, numeric and boolean constraints, dictionary handling, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_create_user_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::user_create_matches_pydantic_bounds_and_scalar_coercion" + ], + "source": { + "kind": "field", + "line": 43, + "path": "backend-services/models/create_user_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_user_model.py::field:CreateUserModel.throttle_duration", + "notes": "Rust matches required fields, defaults and null materialization, scalar/list coercion, Unicode character bounds, numeric and boolean constraints, dictionary handling, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_create_user_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::user_create_matches_pydantic_bounds_and_scalar_coercion" + ], + "source": { + "kind": "field", + "line": 46, + "path": "backend-services/models/create_user_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_user_model.py::field:CreateUserModel.throttle_duration_type", + "notes": "Rust matches required fields, defaults and null materialization, scalar/list coercion, Unicode character bounds, numeric and boolean constraints, dictionary handling, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_create_user_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::user_create_matches_pydantic_bounds_and_scalar_coercion" + ], + "source": { + "kind": "field", + "line": 49, + "path": "backend-services/models/create_user_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_user_model.py::field:CreateUserModel.throttle_wait_duration", + "notes": "Rust matches required fields, defaults and null materialization, scalar/list coercion, Unicode character bounds, numeric and boolean constraints, dictionary handling, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_create_user_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::user_create_matches_pydantic_bounds_and_scalar_coercion" + ], + "source": { + "kind": "field", + "line": 56, + "path": "backend-services/models/create_user_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_user_model.py::field:CreateUserModel.throttle_wait_duration_type", + "notes": "Rust matches required fields, defaults and null materialization, scalar/list coercion, Unicode character bounds, numeric and boolean constraints, dictionary handling, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_create_user_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::user_create_matches_pydantic_bounds_and_scalar_coercion" + ], + "source": { + "kind": "field", + "line": 59, + "path": "backend-services/models/create_user_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_user_model.py::field:CreateUserModel.throttle_queue_limit", + "notes": "Rust matches required fields, defaults and null materialization, scalar/list coercion, Unicode character bounds, numeric and boolean constraints, dictionary handling, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_create_user_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::user_create_matches_pydantic_bounds_and_scalar_coercion" + ], + "source": { + "kind": "field", + "line": 66, + "path": "backend-services/models/create_user_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_user_model.py::field:CreateUserModel.throttle_enabled", + "notes": "Rust matches required fields, defaults and null materialization, scalar/list coercion, Unicode character bounds, numeric and boolean constraints, dictionary handling, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_create_user_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::user_create_matches_pydantic_bounds_and_scalar_coercion" + ], + "source": { + "kind": "field", + "line": 69, + "path": "backend-services/models/create_user_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_user_model.py::field:CreateUserModel.custom_attributes", + "notes": "Rust matches required fields, defaults and null materialization, scalar/list coercion, Unicode character bounds, numeric and boolean constraints, dictionary handling, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_create_user_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::user_create_matches_pydantic_bounds_and_scalar_coercion" + ], + "source": { + "kind": "field", + "line": 72, + "path": "backend-services/models/create_user_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_user_model.py::field:CreateUserModel.bandwidth_limit_bytes", + "notes": "Rust matches required fields, defaults and null materialization, scalar/list coercion, Unicode character bounds, numeric and boolean constraints, dictionary handling, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_create_user_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::user_create_matches_pydantic_bounds_and_scalar_coercion" + ], + "source": { + "kind": "field", + "line": 75, + "path": "backend-services/models/create_user_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_user_model.py::field:CreateUserModel.bandwidth_limit_window", + "notes": "Rust matches required fields, defaults and null materialization, scalar/list coercion, Unicode character bounds, numeric and boolean constraints, dictionary handling, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_create_user_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::user_create_matches_pydantic_bounds_and_scalar_coercion" + ], + "source": { + "kind": "field", + "line": 81, + "path": "backend-services/models/create_user_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_user_model.py::field:CreateUserModel.bandwidth_limit_enabled", + "notes": "Rust matches required fields, defaults and null materialization, scalar/list coercion, Unicode character bounds, numeric and boolean constraints, dictionary handling, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_create_user_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::user_create_matches_pydantic_bounds_and_scalar_coercion" + ], + "source": { + "kind": "field", + "line": 88, + "path": "backend-services/models/create_user_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_user_model.py::field:CreateUserModel.active", + "notes": "Rust matches required fields, defaults and null materialization, scalar/list coercion, Unicode character bounds, numeric and boolean constraints, dictionary handling, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_create_user_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::user_create_matches_pydantic_bounds_and_scalar_coercion" + ], + "source": { + "kind": "field", + "line": 93, + "path": "backend-services/models/create_user_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_user_model.py::field:CreateUserModel.ui_access", + "notes": "Rust matches required fields, defaults and null materialization, scalar/list coercion, Unicode character bounds, numeric and boolean constraints, dictionary handling, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_create_user_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::user_create_matches_pydantic_bounds_and_scalar_coercion" + ], + "source": { + "kind": "field", + "line": 94, + "path": "backend-services/models/create_user_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_user_model.py::class:CreateUserModel.Config", + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "class", + "line": 96, + "path": "backend-services/models/create_user_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_user_model.py::field:CreateUserModel.Config.arbitrary_types_allowed", + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 97, + "path": "backend-services/models/create_user_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_vault_entry_model.py::module:create_vault_entry_model", + "notes": "Rust matches required and optional fields, scalar-to-string coercion, Unicode character bounds, ignored unknown fields, and secret handling.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::vault_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::vault_lifecycle_encrypts_at_rest_and_never_returns_the_secret" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/models/create_vault_entry_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_vault_entry_model.py::class:CreateVaultEntryModel", + "notes": "Rust matches required and optional fields, scalar-to-string coercion, Unicode character bounds, ignored unknown fields, and secret handling.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::vault_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::vault_lifecycle_encrypts_at_rest_and_never_returns_the_secret" + ], + "source": { + "kind": "class", + "line": 10, + "path": "backend-services/models/create_vault_entry_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_vault_entry_model.py::field:CreateVaultEntryModel.key_name", + "notes": "Rust matches required and optional fields, scalar-to-string coercion, Unicode character bounds, ignored unknown fields, and secret handling.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::vault_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::vault_lifecycle_encrypts_at_rest_and_never_returns_the_secret" + ], + "source": { + "kind": "field", + "line": 13, + "path": "backend-services/models/create_vault_entry_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_vault_entry_model.py::field:CreateVaultEntryModel.value", + "notes": "Rust matches required and optional fields, scalar-to-string coercion, Unicode character bounds, ignored unknown fields, and secret handling.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::vault_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::vault_lifecycle_encrypts_at_rest_and_never_returns_the_secret" + ], + "source": { + "kind": "field", + "line": 21, + "path": "backend-services/models/create_vault_entry_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_vault_entry_model.py::field:CreateVaultEntryModel.description", + "notes": "Rust matches required and optional fields, scalar-to-string coercion, Unicode character bounds, ignored unknown fields, and secret handling.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::vault_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::vault_lifecycle_encrypts_at_rest_and_never_returns_the_secret" + ], + "source": { + "kind": "field", + "line": 28, + "path": "backend-services/models/create_vault_entry_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_vault_entry_model.py::class:CreateVaultEntryModel.Config", + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "class", + "line": 35, + "path": "backend-services/models/create_vault_entry_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/create_vault_entry_model.py::field:CreateVaultEntryModel.Config.arbitrary_types_allowed", + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 36, + "path": "backend-services/models/create_vault_entry_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/credit_model.py::module:credit_model", + "notes": "CreditTierModel and the remaining CreditModel fields are translated; exact Pydantic datetime parsing remains open.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_credit_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/models/credit_model.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/credit_model.py::class:CreditTierModel", + "notes": "Rust matches required nested fields, defaults and null materialization, Pydantic scalar/integer coercion, Unicode character bounds, list minimums, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_credit_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision" + ], + "source": { + "kind": "class", + "line": 12, + "path": "backend-services/models/credit_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/credit_model.py::field:CreditTierModel.tier_name", + "notes": "Rust matches required nested fields, defaults and null materialization, Pydantic scalar/integer coercion, Unicode character bounds, list minimums, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_credit_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision" + ], + "source": { + "kind": "field", + "line": 13, + "path": "backend-services/models/credit_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/credit_model.py::field:CreditTierModel.credits", + "notes": "Rust matches required nested fields, defaults and null materialization, Pydantic scalar/integer coercion, Unicode character bounds, list minimums, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_credit_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision" + ], + "source": { + "kind": "field", + "line": 16, + "path": "backend-services/models/credit_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/credit_model.py::field:CreditTierModel.input_limit", + "notes": "Rust matches required nested fields, defaults and null materialization, Pydantic scalar/integer coercion, Unicode character bounds, list minimums, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_credit_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision" + ], + "source": { + "kind": "field", + "line": 17, + "path": "backend-services/models/credit_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/credit_model.py::field:CreditTierModel.output_limit", + "notes": "Rust matches required nested fields, defaults and null materialization, Pydantic scalar/integer coercion, Unicode character bounds, list minimums, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_credit_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision" + ], + "source": { + "kind": "field", + "line": 20, + "path": "backend-services/models/credit_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/credit_model.py::field:CreditTierModel.reset_frequency", + "notes": "Rust matches required nested fields, defaults and null materialization, Pydantic scalar/integer coercion, Unicode character bounds, list minimums, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_credit_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision" + ], + "source": { + "kind": "field", + "line": 23, + "path": "backend-services/models/credit_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/credit_model.py::class:CreditTierModel.Config", + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "class", + "line": 27, + "path": "backend-services/models/credit_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/credit_model.py::field:CreditTierModel.Config.arbitrary_types_allowed", + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 28, + "path": "backend-services/models/credit_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/credit_model.py::class:CreditModel", + "notes": "All fields except exact api_key_rotation_expires datetime parsing are translated.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_credit_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision" + ], + "source": { + "kind": "class", + "line": 31, + "path": "backend-services/models/credit_model.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/credit_model.py::field:CreditModel.api_credit_group", + "notes": "Rust matches required nested fields, defaults and null materialization, Pydantic scalar/integer coercion, Unicode character bounds, list minimums, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_credit_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision" + ], + "source": { + "kind": "field", + "line": 32, + "path": "backend-services/models/credit_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/credit_model.py::field:CreditModel.api_key", + "notes": "Rust matches required nested fields, defaults and null materialization, Pydantic scalar/integer coercion, Unicode character bounds, list minimums, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_credit_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision" + ], + "source": { + "kind": "field", + "line": 39, + "path": "backend-services/models/credit_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/credit_model.py::field:CreditModel.api_key_header", + "notes": "Rust matches required nested fields, defaults and null materialization, Pydantic scalar/integer coercion, Unicode character bounds, list minimums, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_credit_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision" + ], + "source": { + "kind": "field", + "line": 42, + "path": "backend-services/models/credit_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/credit_model.py::field:CreditModel.credit_tiers", + "notes": "Rust matches required nested fields, defaults and null materialization, Pydantic scalar/integer coercion, Unicode character bounds, list minimums, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_credit_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision" + ], + "source": { + "kind": "field", + "line": 45, + "path": "backend-services/models/credit_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/credit_model.py::field:CreditModel.api_key_new", + "notes": "Rust matches required nested fields, defaults and null materialization, Pydantic scalar/integer coercion, Unicode character bounds, list minimums, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_credit_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision" + ], + "source": { + "kind": "field", + "line": 49, + "path": "backend-services/models/credit_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/credit_model.py::field:CreditModel.api_key_rotation_expires", + "notes": "Rust accepts and persists scalar string representations, but exact Pydantic datetime parsing and normalization is not yet implemented.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_credit_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision" + ], + "source": { + "kind": "field", + "line": 54, + "path": "backend-services/models/credit_model.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/credit_model.py::class:CreditModel.Config", + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "class", + "line": 60, + "path": "backend-services/models/credit_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/credit_model.py::field:CreditModel.Config.arbitrary_types_allowed", + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 61, + "path": "backend-services/models/credit_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/delete_successfully.py::module:delete_successfully", + "notes": "ResponseMessage is never imported or referenced by pinned production code.", + "rationale": "Unused Python response-model wrapper with no runtime behavior to translate.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/models/delete_successfully.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/delete_successfully.py::class:ResponseMessage", + "notes": "ResponseMessage is never imported or referenced by pinned production code.", + "rationale": "Unused Python response-model wrapper with no runtime behavior to translate.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "class", + "line": 10, + "path": "backend-services/models/delete_successfully.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/delete_successfully.py::field:ResponseMessage.message", + "notes": "ResponseMessage is never imported or referenced by pinned production code.", + "rationale": "Unused Python response-model wrapper with no runtime behavior to translate.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 11, + "path": "backend-services/models/delete_successfully.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/delete_successfully.py::class:ResponseMessage.Config", + "notes": "ResponseMessage is never imported or referenced by pinned production code.", + "rationale": "Unused Python response-model wrapper with no runtime behavior to translate.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "class", + "line": 15, + "path": "backend-services/models/delete_successfully.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/delete_successfully.py::field:ResponseMessage.Config.arbitrary_types_allowed", + "notes": "ResponseMessage is never imported or referenced by pinned production code.", + "rationale": "Unused Python response-model wrapper with no runtime behavior to translate.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 16, + "path": "backend-services/models/delete_successfully.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/endpoint_model_response.py::module:endpoint_model_response", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/models/endpoint_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/endpoint_model_response.py::class:EndpointModelResponse", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "class", + "line": 10, + "path": "backend-services/models/endpoint_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/endpoint_model_response.py::field:EndpointModelResponse.api_name", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 11, + "path": "backend-services/models/endpoint_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/endpoint_model_response.py::field:EndpointModelResponse.api_version", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 14, + "path": "backend-services/models/endpoint_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/endpoint_model_response.py::field:EndpointModelResponse.endpoint_method", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 17, + "path": "backend-services/models/endpoint_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/endpoint_model_response.py::field:EndpointModelResponse.endpoint_uri", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 20, + "path": "backend-services/models/endpoint_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/endpoint_model_response.py::field:EndpointModelResponse.endpoint_description", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 23, + "path": "backend-services/models/endpoint_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/endpoint_model_response.py::field:EndpointModelResponse.endpoint_servers", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 30, + "path": "backend-services/models/endpoint_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/endpoint_model_response.py::field:EndpointModelResponse.api_id", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 35, + "path": "backend-services/models/endpoint_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/endpoint_model_response.py::field:EndpointModelResponse.endpoint_id", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 42, + "path": "backend-services/models/endpoint_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/endpoint_model_response.py::class:EndpointModelResponse.Config", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "class", + "line": 50, + "path": "backend-services/models/endpoint_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/endpoint_model_response.py::field:EndpointModelResponse.Config.arbitrary_types_allowed", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 51, + "path": "backend-services/models/endpoint_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/endpoint_validation_model_response.py::module:endpoint_validation_model_response", + "notes": "Rust returns the normalized stored schema fields, but exact response-model validation for extreme numeric values remains unproven.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::endpoint_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/models/endpoint_validation_model_response.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/endpoint_validation_model_response.py::class:EndpointValidationModelResponse", + "notes": "Rust returns the normalized stored schema fields, but exact response-model validation for extreme numeric values remains unproven.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::endpoint_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" + ], + "source": { + "kind": "class", + "line": 12, + "path": "backend-services/models/endpoint_validation_model_response.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/endpoint_validation_model_response.py::field:EndpointValidationModelResponse.endpoint_id", + "notes": "Rust returns the normalized stored schema fields, but exact response-model validation for extreme numeric values remains unproven.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::endpoint_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" + ], + "source": { + "kind": "field", + "line": 13, + "path": "backend-services/models/endpoint_validation_model_response.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/endpoint_validation_model_response.py::field:EndpointValidationModelResponse.validation_enabled", + "notes": "Rust returns the normalized stored schema fields, but exact response-model validation for extreme numeric values remains unproven.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::endpoint_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" + ], + "source": { + "kind": "field", + "line": 18, + "path": "backend-services/models/endpoint_validation_model_response.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/endpoint_validation_model_response.py::field:EndpointValidationModelResponse.validation_schema", + "notes": "Rust returns the normalized stored schema fields, but exact response-model validation for extreme numeric values remains unproven.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::endpoint_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" + ], + "source": { + "kind": "field", + "line": 21, + "path": "backend-services/models/endpoint_validation_model_response.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/endpoint_validation_model_response.py::class:EndpointValidationModelResponse.Config", + "notes": "The model contains only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "class", + "line": 25, + "path": "backend-services/models/endpoint_validation_model_response.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/endpoint_validation_model_response.py::field:EndpointValidationModelResponse.Config.arbitrary_types_allowed", + "notes": "The model contains only JSON-compatible values.", + "rationale": "Python framework flag with no observable contract for this model.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 26, + "path": "backend-services/models/endpoint_validation_model_response.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/field_validation_model.py::module:field_validation_model", + "notes": "Rust implements required/type, min/max, pattern, enum, format, custom-validator, nested-schema, and array-item behavior; extreme Pydantic numeric-union coercion remains unproven.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_field_validation_model", + "gateway-rs/src/validation/json.rs::validate_json_with_registry" + ], + "rust_tests": [ + "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/models/field_validation_model.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/field_validation_model.py::class:FieldValidation", + "notes": "Rust implements required/type, min/max, pattern, enum, format, custom-validator, nested-schema, and array-item behavior; extreme Pydantic numeric-union coercion remains unproven.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_field_validation_model", + "gateway-rs/src/validation/json.rs::validate_json_with_registry" + ], + "rust_tests": [ + "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" + ], + "source": { + "kind": "class", + "line": 12, + "path": "backend-services/models/field_validation_model.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/field_validation_model.py::field:FieldValidation.required", + "notes": "Rust implements required/type, min/max, pattern, enum, format, custom-validator, nested-schema, and array-item behavior; extreme Pydantic numeric-union coercion remains unproven.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_field_validation_model", + "gateway-rs/src/validation/json.rs::validate_json_with_registry" + ], + "rust_tests": [ + "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" + ], + "source": { + "kind": "field", + "line": 13, + "path": "backend-services/models/field_validation_model.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/field_validation_model.py::field:FieldValidation.type", + "notes": "Rust implements required/type, min/max, pattern, enum, format, custom-validator, nested-schema, and array-item behavior; extreme Pydantic numeric-union coercion remains unproven.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_field_validation_model", + "gateway-rs/src/validation/json.rs::validate_json_with_registry" + ], + "rust_tests": [ + "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" + ], + "source": { + "kind": "field", + "line": 14, + "path": "backend-services/models/field_validation_model.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/field_validation_model.py::field:FieldValidation.min", + "notes": "Rust implements required/type, min/max, pattern, enum, format, custom-validator, nested-schema, and array-item behavior; extreme Pydantic numeric-union coercion remains unproven.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_field_validation_model", + "gateway-rs/src/validation/json.rs::validate_json_with_registry" + ], + "rust_tests": [ + "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" + ], + "source": { + "kind": "field", + "line": 17, + "path": "backend-services/models/field_validation_model.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/field_validation_model.py::field:FieldValidation.max", + "notes": "Rust implements required/type, min/max, pattern, enum, format, custom-validator, nested-schema, and array-item behavior; extreme Pydantic numeric-union coercion remains unproven.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_field_validation_model", + "gateway-rs/src/validation/json.rs::validate_json_with_registry" + ], + "rust_tests": [ + "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" + ], + "source": { + "kind": "field", + "line": 20, + "path": "backend-services/models/field_validation_model.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/field_validation_model.py::field:FieldValidation.pattern", + "notes": "Rust implements required/type, min/max, pattern, enum, format, custom-validator, nested-schema, and array-item behavior; extreme Pydantic numeric-union coercion remains unproven.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_field_validation_model", + "gateway-rs/src/validation/json.rs::validate_json_with_registry" + ], + "rust_tests": [ + "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" + ], + "source": { + "kind": "field", + "line": 23, + "path": "backend-services/models/field_validation_model.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/field_validation_model.py::field:FieldValidation.enum", + "notes": "Rust implements required/type, min/max, pattern, enum, format, custom-validator, nested-schema, and array-item behavior; extreme Pydantic numeric-union coercion remains unproven.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_field_validation_model", + "gateway-rs/src/validation/json.rs::validate_json_with_registry" + ], + "rust_tests": [ + "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" + ], + "source": { + "kind": "field", + "line": 24, + "path": "backend-services/models/field_validation_model.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/field_validation_model.py::field:FieldValidation.format", + "notes": "Rust implements required/type, min/max, pattern, enum, format, custom-validator, nested-schema, and array-item behavior; extreme Pydantic numeric-union coercion remains unproven.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_field_validation_model", + "gateway-rs/src/validation/json.rs::validate_json_with_registry" + ], + "rust_tests": [ + "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" + ], + "source": { + "kind": "field", + "line": 25, + "path": "backend-services/models/field_validation_model.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/field_validation_model.py::field:FieldValidation.custom_validator", + "notes": "Rust implements required/type, min/max, pattern, enum, format, custom-validator, nested-schema, and array-item behavior; extreme Pydantic numeric-union coercion remains unproven.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_field_validation_model", + "gateway-rs/src/validation/json.rs::validate_json_with_registry" + ], + "rust_tests": [ + "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" + ], + "source": { + "kind": "field", + "line": 28, + "path": "backend-services/models/field_validation_model.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/field_validation_model.py::field:FieldValidation.nested_schema", + "notes": "Rust implements required/type, min/max, pattern, enum, format, custom-validator, nested-schema, and array-item behavior; extreme Pydantic numeric-union coercion remains unproven.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_field_validation_model", + "gateway-rs/src/validation/json.rs::validate_json_with_registry" + ], + "rust_tests": [ + "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" + ], + "source": { + "kind": "field", + "line": 29, + "path": "backend-services/models/field_validation_model.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/field_validation_model.py::field:FieldValidation.array_items", + "notes": "Rust implements required/type, min/max, pattern, enum, format, custom-validator, nested-schema, and array-item behavior; extreme Pydantic numeric-union coercion remains unproven.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_field_validation_model", + "gateway-rs/src/validation/json.rs::validate_json_with_registry" + ], + "rust_tests": [ + "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" + ], + "source": { + "kind": "field", + "line": 32, + "path": "backend-services/models/field_validation_model.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/group_model_response.py::module:group_model_response", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/models/group_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/group_model_response.py::class:GroupModelResponse", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "class", + "line": 10, + "path": "backend-services/models/group_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/group_model_response.py::field:GroupModelResponse.group_name", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 11, + "path": "backend-services/models/group_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/group_model_response.py::field:GroupModelResponse.group_description", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 14, + "path": "backend-services/models/group_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/group_model_response.py::field:GroupModelResponse.api_access", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 21, + "path": "backend-services/models/group_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/group_model_response.py::class:GroupModelResponse.Config", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "class", + "line": 25, + "path": "backend-services/models/group_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/group_model_response.py::field:GroupModelResponse.Config.arbitrary_types_allowed", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 26, + "path": "backend-services/models/group_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::module:rate_limit_models", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::class:RuleType", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "class", + "line": 21, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:RuleType.PER_USER", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 24, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:RuleType.PER_API", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 25, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:RuleType.PER_ENDPOINT", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 26, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:RuleType.PER_IP", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 27, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:RuleType.PER_USER_API", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 28, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:RuleType.PER_USER_ENDPOINT", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 29, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:RuleType.GLOBAL", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 30, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::class:TimeWindow", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "class", + "line": 33, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:TimeWindow.SECOND", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 36, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:TimeWindow.MINUTE", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 37, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:TimeWindow.HOUR", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 38, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:TimeWindow.DAY", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 39, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:TimeWindow.MONTH", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 40, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::class:TierName", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "class", + "line": 43, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:TierName.FREE", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 46, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:TierName.PRO", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 47, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:TierName.ENTERPRISE", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 48, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:TierName.CUSTOM", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 49, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::class:QuotaType", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "class", + "line": 52, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:QuotaType.REQUESTS", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 55, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:QuotaType.BANDWIDTH", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 56, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:QuotaType.COMPUTE_TIME", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 57, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [ + "dataclass" + ], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::class:RateLimitRule", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "class", + "line": 66, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:RateLimitRule.rule_id", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 90, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:RateLimitRule.rule_type", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 91, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:RateLimitRule.time_window", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 92, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:RateLimitRule.limit", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 93, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:RateLimitRule.target_identifier", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 96, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:RateLimitRule.burst_allowance", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 97, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:RateLimitRule.priority", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 98, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:RateLimitRule.enabled", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 99, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:RateLimitRule.created_at", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 102, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:RateLimitRule.updated_at", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 103, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:RateLimitRule.created_by", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 104, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:RateLimitRule.description", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 105, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::method:RateLimitRule.to_dict", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "method", + "line": 107, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [ + "classmethod" + ], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::method:RateLimitRule.from_dict", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "method", + "line": 125, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [ + "dataclass" + ], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::class:TierLimits", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "class", + "line": 153, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:TierLimits.requests_per_second", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 157, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:TierLimits.requests_per_minute", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 158, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:TierLimits.requests_per_hour", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 159, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:TierLimits.requests_per_day", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 160, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:TierLimits.requests_per_month", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 161, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:TierLimits.burst_per_second", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 164, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:TierLimits.burst_per_minute", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 165, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:TierLimits.burst_per_hour", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 166, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:TierLimits.monthly_request_quota", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 169, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:TierLimits.daily_request_quota", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 170, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:TierLimits.monthly_bandwidth_quota", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 171, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:TierLimits.enable_throttling", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 174, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:TierLimits.max_queue_time_ms", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 175, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::method:TierLimits.to_dict", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "method", + "line": 177, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [ + "classmethod" + ], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::method:TierLimits.from_dict", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "method", + "line": 196, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [ + "dataclass" + ], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::class:Tier", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "class", + "line": 202, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:Tier.tier_id", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 234, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:Tier.name", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 235, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:Tier.display_name", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 236, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:Tier.limits", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 237, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:Tier.description", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 240, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:Tier.price_monthly", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 241, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:Tier.price_yearly", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 242, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:Tier.features", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 243, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:Tier.is_default", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 244, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:Tier.enabled", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 245, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:Tier.created_at", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 248, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:Tier.updated_at", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 249, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::method:Tier.to_dict", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "method", + "line": 251, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [ + "classmethod" + ], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::method:Tier.from_dict", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "method", + "line": 269, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [ + "dataclass" + ], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::class:UserTierAssignment", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "class", + "line": 292, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:UserTierAssignment.user_id", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 295, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:UserTierAssignment.tier_id", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 296, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:UserTierAssignment.override_limits", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 299, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:UserTierAssignment.effective_from", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 302, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:UserTierAssignment.effective_until", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 303, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:UserTierAssignment.assigned_at", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 306, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:UserTierAssignment.assigned_by", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 307, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:UserTierAssignment.notes", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 308, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::method:UserTierAssignment.to_dict", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "method", + "line": 310, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [ + "dataclass" + ], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::class:QuotaUsage", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "class", + "line": 330, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:QuotaUsage.key", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 337, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:QuotaUsage.quota_type", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 338, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:QuotaUsage.current_usage", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 339, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:QuotaUsage.limit", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 340, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:QuotaUsage.reset_at", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 341, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:QuotaUsage.burst_usage", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 344, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:QuotaUsage.burst_limit", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 345, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [ + "property" + ], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::method:QuotaUsage.remaining", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "method", + "line": 348, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [ + "property" + ], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::method:QuotaUsage.percentage_used", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "method", + "line": 353, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [ + "property" + ], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::method:QuotaUsage.is_exhausted", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "method", + "line": 360, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::method:QuotaUsage.to_dict", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "method", + "line": 364, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [ + "dataclass" + ], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::class:RateLimitCounter", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "class", + "line": 381, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:RateLimitCounter.key", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 388, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:RateLimitCounter.window_start", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 389, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:RateLimitCounter.window_size", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 390, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:RateLimitCounter.count", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 391, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:RateLimitCounter.limit", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 392, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:RateLimitCounter.burst_count", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 393, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:RateLimitCounter.burst_limit", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 394, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [ + "property" + ], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::method:RateLimitCounter.remaining", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "method", + "line": 397, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [ + "property" + ], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::method:RateLimitCounter.is_limited", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "method", + "line": 402, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [ + "property" + ], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::method:RateLimitCounter.reset_at", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "method", + "line": 407, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::method:RateLimitCounter.to_dict", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "method", + "line": 411, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [ + "dataclass" + ], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::class:UsageHistoryRecord", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "class", + "line": 433, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:UsageHistoryRecord.timestamp", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 440, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:UsageHistoryRecord.user_id", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 441, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:UsageHistoryRecord.api_name", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 442, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:UsageHistoryRecord.endpoint_uri", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 443, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:UsageHistoryRecord.ip_address", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 444, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:UsageHistoryRecord.request_count", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 447, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:UsageHistoryRecord.blocked_count", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 448, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:UsageHistoryRecord.burst_used", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 449, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:UsageHistoryRecord.period", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 452, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::method:UsageHistoryRecord.to_dict", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "method", + "line": 454, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [ + "dataclass" + ], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::class:RateLimitInfo", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "class", + "line": 475, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:RateLimitInfo.limit", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 482, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:RateLimitInfo.remaining", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 483, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:RateLimitInfo.reset_at", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 484, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:RateLimitInfo.retry_after", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 485, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:RateLimitInfo.burst_limit", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 488, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:RateLimitInfo.burst_remaining", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 489, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::field:RateLimitInfo.tier", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "field", + "line": 490, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::method:RateLimitInfo.to_headers", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "method", + "line": 492, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::method:RateLimitInfo.to_dict", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "method", + "line": 510, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::function:get_time_window_seconds", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "function", + "line": 528, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::function:generate_redis_key", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "function", + "line": 540, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/rate_limit_models.py::function:generate_quota_key", + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "source": { + "kind": "function", + "line": 555, + "path": "backend-services/models/rate_limit_models.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/request_model.py::module:request_model", + "notes": "No pinned production module imports RequestModel.", + "rationale": "Unused Python model module with no runtime contract to preserve.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/models/request_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/request_model.py::class:RequestModel", + "notes": "The class is declared but never imported or instantiated by pinned production code.", + "rationale": "Unused Python request container with no runtime contract to preserve.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "class", + "line": 4, + "path": "backend-services/models/request_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/request_model.py::field:RequestModel.method", + "notes": "The containing RequestModel is unused by pinned production code.", + "rationale": "Field of an unused Python-only request container.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 5, + "path": "backend-services/models/request_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/request_model.py::field:RequestModel.path", + "notes": "The containing RequestModel is unused by pinned production code.", + "rationale": "Field of an unused Python-only request container.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 6, + "path": "backend-services/models/request_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/request_model.py::field:RequestModel.headers", + "notes": "The containing RequestModel is unused by pinned production code.", + "rationale": "Field of an unused Python-only request container.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 7, + "path": "backend-services/models/request_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/request_model.py::field:RequestModel.query_params", + "notes": "The containing RequestModel is unused by pinned production code.", + "rationale": "Field of an unused Python-only request container.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 8, + "path": "backend-services/models/request_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/request_model.py::field:RequestModel.identity", + "notes": "The containing RequestModel is unused by pinned production code.", + "rationale": "Field of an unused Python-only request container.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 9, + "path": "backend-services/models/request_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/request_model.py::field:RequestModel.body", + "notes": "The containing RequestModel is unused by pinned production code.", + "rationale": "Field of an unused Python-only request container.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 10, + "path": "backend-services/models/request_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/response_model.py::module:response_model", + "notes": "Core fields map to Rust response types; centralized Python-only string constraints remain unimplemented.", + "rust_symbols": [ + "gateway-rs/src/middleware/response_compat.rs", + "gateway-rs/src/policy/mod.rs::PolicyErrorBody" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::strict_envelope_preserves_legacy_status_tokens_and_probe_shape" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/models/response_model.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/response_model.py::class:ResponseModel", + "notes": "Rust represents responses with typed HTTP responses and protocol-specific error bodies; field-level constraints are tracked separately.", + "rust_symbols": [ + "gateway-rs/src/middleware/response_compat.rs::response_compat", + "gateway-rs/src/policy/mod.rs::PolicyErrorBody" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::strict_envelope_preserves_legacy_status_tokens_and_probe_shape" + ], + "source": { + "kind": "class", + "line": 4, + "path": "backend-services/models/response_model.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/response_model.py::field:ResponseModel.status_code", + "notes": "Rust HTTP responses and strict envelopes preserve both transport and original status semantics.", + "rust_symbols": [ + "gateway-rs/src/middleware/response_compat.rs::response_compat" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::strict_envelope_preserves_legacy_status_tokens_and_probe_shape" + ], + "source": { + "kind": "field", + "line": 5, + "path": "backend-services/models/response_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/response_model.py::field:ResponseModel.response_headers", + "notes": "Rust response builders and request-ID middleware preserve compatible response headers.", + "rust_symbols": [ + "gateway-rs/src/middleware/request_id.rs::request_id" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::platform_security_headers_csp_hsts_and_request_ids_match_python", + "gateway-rs/tests/live_tests_parity.rs::request_id_is_forwarded_to_authenticated_rest_upstream_and_response" + ], + "source": { + "kind": "field", + "line": 7, + "path": "backend-services/models/response_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/response_model.py::field:ResponseModel.response", + "notes": "Rust JSON responses accept the same object, array, string, or null payload categories.", + "rust_symbols": [ + "gateway-rs/src/middleware/response_compat.rs::response_compat" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rest_strict_response_envelope_wraps_proxy_message_like_python", + "gateway-rs/tests/platform_native.rs::graphql_strict_response_envelope_wraps_proxy_data_like_python" + ], + "source": { + "kind": "field", + "line": 9, + "path": "backend-services/models/response_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/response_model.py::field:ResponseModel.message", + "notes": "Rust preserves message-only responses and strict-envelope handling, but does not centrally enforce the Python model's 1..255 internal string constraint.", + "rust_symbols": [ + "gateway-rs/src/middleware/response_compat.rs::MessageEnvelope" + ], + "rust_tests": [ + "gateway-rs/src/middleware/response_compat.rs::tests::only_plain_message_payloads_use_message_envelope" + ], + "source": { + "kind": "field", + "line": 10, + "path": "backend-services/models/response_model.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/response_model.py::field:ResponseModel.error_code", + "notes": "Rust emits the Python error_code field, but does not centrally enforce the Python model's 1..255 internal string constraint.", + "rust_symbols": [ + "gateway-rs/src/policy/mod.rs::PolicyErrorBody.error_code" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::strict_envelope_preserves_legacy_status_tokens_and_probe_shape" + ], + "source": { + "kind": "field", + "line": 12, + "path": "backend-services/models/response_model.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/response_model.py::field:ResponseModel.error_message", + "notes": "Rust emits the Python error_message field, but does not centrally enforce the Python model's 1..255 internal string constraint.", + "rust_symbols": [ + "gateway-rs/src/policy/mod.rs::PolicyErrorBody.error_message" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::strict_envelope_preserves_legacy_status_tokens_and_probe_shape" + ], + "source": { + "kind": "field", + "line": 13, + "path": "backend-services/models/response_model.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/role_model_response.py::module:role_model_response", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/models/role_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/role_model_response.py::class:RoleModelResponse", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "class", + "line": 10, + "path": "backend-services/models/role_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/role_model_response.py::field:RoleModelResponse.role_name", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 11, + "path": "backend-services/models/role_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/role_model_response.py::field:RoleModelResponse.role_description", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 14, + "path": "backend-services/models/role_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/role_model_response.py::field:RoleModelResponse.manage_users", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 21, + "path": "backend-services/models/role_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/role_model_response.py::field:RoleModelResponse.manage_apis", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 22, + "path": "backend-services/models/role_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/role_model_response.py::field:RoleModelResponse.manage_endpoints", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 23, + "path": "backend-services/models/role_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/role_model_response.py::field:RoleModelResponse.manage_groups", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 26, + "path": "backend-services/models/role_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/role_model_response.py::field:RoleModelResponse.manage_roles", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 29, + "path": "backend-services/models/role_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/role_model_response.py::field:RoleModelResponse.manage_routings", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 30, + "path": "backend-services/models/role_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/role_model_response.py::field:RoleModelResponse.manage_gateway", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 33, + "path": "backend-services/models/role_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/role_model_response.py::field:RoleModelResponse.manage_subscriptions", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 36, + "path": "backend-services/models/role_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/role_model_response.py::field:RoleModelResponse.manage_security", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 39, + "path": "backend-services/models/role_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/role_model_response.py::field:RoleModelResponse.manage_tiers", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 42, + "path": "backend-services/models/role_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/role_model_response.py::field:RoleModelResponse.manage_rate_limits", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 45, + "path": "backend-services/models/role_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/role_model_response.py::field:RoleModelResponse.manage_credits", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 48, + "path": "backend-services/models/role_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/role_model_response.py::field:RoleModelResponse.manage_auth", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 51, + "path": "backend-services/models/role_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/role_model_response.py::field:RoleModelResponse.view_analytics", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 54, + "path": "backend-services/models/role_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/role_model_response.py::field:RoleModelResponse.view_logs", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 57, + "path": "backend-services/models/role_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/role_model_response.py::field:RoleModelResponse.export_logs", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 58, + "path": "backend-services/models/role_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/role_model_response.py::class:RoleModelResponse.Config", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "class", + "line": 60, + "path": "backend-services/models/role_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/role_model_response.py::field:RoleModelResponse.Config.arbitrary_types_allowed", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 61, + "path": "backend-services/models/role_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/routing_model_response.py::module:routing_model_response", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering and server_index exclusion; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/models/routing_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/routing_model_response.py::class:RoutingModelResponse", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering and server_index exclusion; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "class", + "line": 10, + "path": "backend-services/models/routing_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/routing_model_response.py::field:RoutingModelResponse.routing_name", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering and server_index exclusion; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 11, + "path": "backend-services/models/routing_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/routing_model_response.py::field:RoutingModelResponse.routing_servers", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering and server_index exclusion; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 18, + "path": "backend-services/models/routing_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/routing_model_response.py::field:RoutingModelResponse.routing_description", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering and server_index exclusion; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 24, + "path": "backend-services/models/routing_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/routing_model_response.py::field:RoutingModelResponse.client_key", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering and server_index exclusion; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 32, + "path": "backend-services/models/routing_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/routing_model_response.py::field:RoutingModelResponse.server_index", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering and server_index exclusion; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 39, + "path": "backend-services/models/routing_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/routing_model_response.py::class:RoutingModelResponse.Config", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering and server_index exclusion; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "class", + "line": 43, + "path": "backend-services/models/routing_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/routing_model_response.py::field:RoutingModelResponse.Config.arbitrary_types_allowed", + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering and server_index exclusion; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::platform_openapi" + ], + "rust_tests": [ + "gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface" + ], + "source": { + "kind": "field", + "line": 44, + "path": "backend-services/models/routing_model_response.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/security_settings_model.py::module:security_settings_model", + "notes": "Rust matches all optional fields, null elision, Pydantic v1 scalar/list coercion, the 60-second lower bound, ignored unknown fields, and declaration-ordered validation errors.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_security_settings" + ], + "rust_tests": [ + "gateway-rs/src/routes/platform.rs::tests::security_settings_scalar_coercion_matches_python_model", + "gateway-rs/src/routes/platform.rs::tests::security_settings_list_coercion_and_indexed_errors_match_python", + "gateway-rs/src/routes/platform.rs::tests::security_settings_dump_path_coercion_matches_python_model", + "gateway-rs/src/routes/platform.rs::tests::security_settings_scalar_errors_follow_python_declaration_order" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/models/security_settings_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/security_settings_model.py::class:SecuritySettingsModel", + "notes": "Rust matches all optional fields, null elision, Pydantic v1 scalar/list coercion, the 60-second lower bound, ignored unknown fields, and declaration-ordered validation errors.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_security_settings" + ], + "rust_tests": [ + "gateway-rs/src/routes/platform.rs::tests::security_settings_scalar_coercion_matches_python_model", + "gateway-rs/src/routes/platform.rs::tests::security_settings_list_coercion_and_indexed_errors_match_python", + "gateway-rs/src/routes/platform.rs::tests::security_settings_dump_path_coercion_matches_python_model", + "gateway-rs/src/routes/platform.rs::tests::security_settings_scalar_errors_follow_python_declaration_order" + ], + "source": { + "kind": "class", + "line": 4, + "path": "backend-services/models/security_settings_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/security_settings_model.py::field:SecuritySettingsModel.enable_auto_save", + "notes": "Rust matches all optional fields, null elision, Pydantic v1 scalar/list coercion, the 60-second lower bound, ignored unknown fields, and declaration-ordered validation errors.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_security_settings" + ], + "rust_tests": [ + "gateway-rs/src/routes/platform.rs::tests::security_settings_scalar_coercion_matches_python_model", + "gateway-rs/src/routes/platform.rs::tests::security_settings_list_coercion_and_indexed_errors_match_python", + "gateway-rs/src/routes/platform.rs::tests::security_settings_dump_path_coercion_matches_python_model", + "gateway-rs/src/routes/platform.rs::tests::security_settings_scalar_errors_follow_python_declaration_order" + ], + "source": { + "kind": "field", + "line": 5, + "path": "backend-services/models/security_settings_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/security_settings_model.py::field:SecuritySettingsModel.auto_save_frequency_seconds", + "notes": "Rust matches all optional fields, null elision, Pydantic v1 scalar/list coercion, the 60-second lower bound, ignored unknown fields, and declaration-ordered validation errors.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_security_settings" + ], + "rust_tests": [ + "gateway-rs/src/routes/platform.rs::tests::security_settings_scalar_coercion_matches_python_model", + "gateway-rs/src/routes/platform.rs::tests::security_settings_list_coercion_and_indexed_errors_match_python", + "gateway-rs/src/routes/platform.rs::tests::security_settings_dump_path_coercion_matches_python_model", + "gateway-rs/src/routes/platform.rs::tests::security_settings_scalar_errors_follow_python_declaration_order" + ], + "source": { + "kind": "field", + "line": 6, + "path": "backend-services/models/security_settings_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/security_settings_model.py::field:SecuritySettingsModel.dump_path", + "notes": "Rust matches all optional fields, null elision, Pydantic v1 scalar/list coercion, the 60-second lower bound, ignored unknown fields, and declaration-ordered validation errors.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_security_settings" + ], + "rust_tests": [ + "gateway-rs/src/routes/platform.rs::tests::security_settings_scalar_coercion_matches_python_model", + "gateway-rs/src/routes/platform.rs::tests::security_settings_list_coercion_and_indexed_errors_match_python", + "gateway-rs/src/routes/platform.rs::tests::security_settings_dump_path_coercion_matches_python_model", + "gateway-rs/src/routes/platform.rs::tests::security_settings_scalar_errors_follow_python_declaration_order" + ], + "source": { + "kind": "field", + "line": 9, + "path": "backend-services/models/security_settings_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/security_settings_model.py::field:SecuritySettingsModel.ip_whitelist", + "notes": "Rust matches all optional fields, null elision, Pydantic v1 scalar/list coercion, the 60-second lower bound, ignored unknown fields, and declaration-ordered validation errors.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_security_settings" + ], + "rust_tests": [ + "gateway-rs/src/routes/platform.rs::tests::security_settings_scalar_coercion_matches_python_model", + "gateway-rs/src/routes/platform.rs::tests::security_settings_list_coercion_and_indexed_errors_match_python", + "gateway-rs/src/routes/platform.rs::tests::security_settings_dump_path_coercion_matches_python_model", + "gateway-rs/src/routes/platform.rs::tests::security_settings_scalar_errors_follow_python_declaration_order" + ], + "source": { + "kind": "field", + "line": 10, + "path": "backend-services/models/security_settings_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/security_settings_model.py::field:SecuritySettingsModel.ip_blacklist", + "notes": "Rust matches all optional fields, null elision, Pydantic v1 scalar/list coercion, the 60-second lower bound, ignored unknown fields, and declaration-ordered validation errors.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_security_settings" + ], + "rust_tests": [ + "gateway-rs/src/routes/platform.rs::tests::security_settings_scalar_coercion_matches_python_model", + "gateway-rs/src/routes/platform.rs::tests::security_settings_list_coercion_and_indexed_errors_match_python", + "gateway-rs/src/routes/platform.rs::tests::security_settings_dump_path_coercion_matches_python_model", + "gateway-rs/src/routes/platform.rs::tests::security_settings_scalar_errors_follow_python_declaration_order" + ], + "source": { + "kind": "field", + "line": 13, + "path": "backend-services/models/security_settings_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/security_settings_model.py::field:SecuritySettingsModel.trust_x_forwarded_for", + "notes": "Rust matches all optional fields, null elision, Pydantic v1 scalar/list coercion, the 60-second lower bound, ignored unknown fields, and declaration-ordered validation errors.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_security_settings" + ], + "rust_tests": [ + "gateway-rs/src/routes/platform.rs::tests::security_settings_scalar_coercion_matches_python_model", + "gateway-rs/src/routes/platform.rs::tests::security_settings_list_coercion_and_indexed_errors_match_python", + "gateway-rs/src/routes/platform.rs::tests::security_settings_dump_path_coercion_matches_python_model", + "gateway-rs/src/routes/platform.rs::tests::security_settings_scalar_errors_follow_python_declaration_order" + ], + "source": { + "kind": "field", + "line": 14, + "path": "backend-services/models/security_settings_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/security_settings_model.py::field:SecuritySettingsModel.xff_trusted_proxies", + "notes": "Rust matches all optional fields, null elision, Pydantic v1 scalar/list coercion, the 60-second lower bound, ignored unknown fields, and declaration-ordered validation errors.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_security_settings" + ], + "rust_tests": [ + "gateway-rs/src/routes/platform.rs::tests::security_settings_scalar_coercion_matches_python_model", + "gateway-rs/src/routes/platform.rs::tests::security_settings_list_coercion_and_indexed_errors_match_python", + "gateway-rs/src/routes/platform.rs::tests::security_settings_dump_path_coercion_matches_python_model", + "gateway-rs/src/routes/platform.rs::tests::security_settings_scalar_errors_follow_python_declaration_order" + ], + "source": { + "kind": "field", + "line": 17, + "path": "backend-services/models/security_settings_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/security_settings_model.py::field:SecuritySettingsModel.allow_localhost_bypass", + "notes": "Rust matches all optional fields, null elision, Pydantic v1 scalar/list coercion, the 60-second lower bound, ignored unknown fields, and declaration-ordered validation errors.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_security_settings" + ], + "rust_tests": [ + "gateway-rs/src/routes/platform.rs::tests::security_settings_scalar_coercion_matches_python_model", + "gateway-rs/src/routes/platform.rs::tests::security_settings_list_coercion_and_indexed_errors_match_python", + "gateway-rs/src/routes/platform.rs::tests::security_settings_dump_path_coercion_matches_python_model", + "gateway-rs/src/routes/platform.rs::tests::security_settings_scalar_errors_follow_python_declaration_order" + ], + "source": { + "kind": "field", + "line": 21, + "path": "backend-services/models/security_settings_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/subscribe_model.py::module:subscribe_model", + "notes": "Rust matches required fields, Python scalar-to-string coercion, character-count bounds, unknown-field handling, and validation-before-authentication ordering.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_subscription_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::incomplete_subscription_payload_uses_python_validation_envelope_before_auth", + "gateway-rs/tests/platform_native.rs::subscription_model_coerces_python_scalars_and_ignores_unknown_fields" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/models/subscribe_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/subscribe_model.py::class:SubscribeModel", + "notes": "Rust matches required fields, Python scalar-to-string coercion, character-count bounds, unknown-field handling, and validation-before-authentication ordering.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_subscription_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::incomplete_subscription_payload_uses_python_validation_envelope_before_auth", + "gateway-rs/tests/platform_native.rs::subscription_model_coerces_python_scalars_and_ignores_unknown_fields" + ], + "source": { + "kind": "class", + "line": 10, + "path": "backend-services/models/subscribe_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/subscribe_model.py::field:SubscribeModel.username", + "notes": "Rust matches required fields, Python scalar-to-string coercion, character-count bounds, unknown-field handling, and validation-before-authentication ordering.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_subscription_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::incomplete_subscription_payload_uses_python_validation_envelope_before_auth", + "gateway-rs/tests/platform_native.rs::subscription_model_coerces_python_scalars_and_ignores_unknown_fields" + ], + "source": { + "kind": "field", + "line": 11, + "path": "backend-services/models/subscribe_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/subscribe_model.py::field:SubscribeModel.api_name", + "notes": "Rust matches required fields, Python scalar-to-string coercion, character-count bounds, unknown-field handling, and validation-before-authentication ordering.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_subscription_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::incomplete_subscription_payload_uses_python_validation_envelope_before_auth", + "gateway-rs/tests/platform_native.rs::subscription_model_coerces_python_scalars_and_ignores_unknown_fields" + ], + "source": { + "kind": "field", + "line": 18, + "path": "backend-services/models/subscribe_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/subscribe_model.py::field:SubscribeModel.api_version", + "notes": "Rust matches required fields, Python scalar-to-string coercion, character-count bounds, unknown-field handling, and validation-before-authentication ordering.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_subscription_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::incomplete_subscription_payload_uses_python_validation_envelope_before_auth", + "gateway-rs/tests/platform_native.rs::subscription_model_coerces_python_scalars_and_ignores_unknown_fields" + ], + "source": { + "kind": "field", + "line": 25, + "path": "backend-services/models/subscribe_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/subscribe_model.py::class:SubscribeModel.Config", + "notes": "The model accepts only JSON-compatible scalar values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in the Rust implementation.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "class", + "line": 33, + "path": "backend-services/models/subscribe_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/subscribe_model.py::field:SubscribeModel.Config.arbitrary_types_allowed", + "notes": "The model accepts only JSON-compatible scalar values.", + "rationale": "Python framework flag with no observable contract for this model.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 34, + "path": "backend-services/models/subscribe_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::module:update_api_model", + "notes": "Pinned update fields are implemented; additive v2 fields prevent an exact whole-module claim.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/models/update_api_model.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::class:UpdateApiModel", + "notes": "All pinned fields are normalized with update null-elision, but Rust also permits documented v2 extension fields outside this Python model.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "class", + "line": 11, + "path": "backend-services/models/update_api_model.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::field:UpdateApiModel.api_name", + "notes": "The shared Rust update normalizer contains the pinned field, Pydantic coercion category, null-elision, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 12, + "path": "backend-services/models/update_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::field:UpdateApiModel.api_version", + "notes": "The shared Rust update normalizer contains the pinned field, Pydantic coercion category, null-elision, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 15, + "path": "backend-services/models/update_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::field:UpdateApiModel.api_description", + "notes": "The shared Rust update normalizer contains the pinned field, Pydantic coercion category, null-elision, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 18, + "path": "backend-services/models/update_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::field:UpdateApiModel.api_allowed_roles", + "notes": "The shared Rust update normalizer contains the pinned field, Pydantic coercion category, null-elision, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 24, + "path": "backend-services/models/update_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::field:UpdateApiModel.api_allowed_groups", + "notes": "The shared Rust update normalizer contains the pinned field, Pydantic coercion category, null-elision, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 27, + "path": "backend-services/models/update_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::field:UpdateApiModel.api_servers", + "notes": "The shared Rust update normalizer contains the pinned field, Pydantic coercion category, null-elision, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 30, + "path": "backend-services/models/update_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::field:UpdateApiModel.api_type", + "notes": "The shared Rust update normalizer contains the pinned field, Pydantic coercion category, null-elision, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 35, + "path": "backend-services/models/update_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::field:UpdateApiModel.api_authorization_field_swap", + "notes": "The shared Rust update normalizer contains the pinned field, Pydantic coercion category, null-elision, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 38, + "path": "backend-services/models/update_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::field:UpdateApiModel.api_allowed_headers", + "notes": "The shared Rust update normalizer contains the pinned field, Pydantic coercion category, null-elision, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 43, + "path": "backend-services/models/update_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::field:UpdateApiModel.api_allowed_retry_count", + "notes": "The shared Rust update normalizer contains the pinned field, Pydantic coercion category, null-elision, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 46, + "path": "backend-services/models/update_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::field:UpdateApiModel.api_grpc_package", + "notes": "The shared Rust update normalizer contains the pinned field, Pydantic coercion category, null-elision, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 49, + "path": "backend-services/models/update_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::field:UpdateApiModel.api_grpc_allowed_packages", + "notes": "The shared Rust update normalizer contains the pinned field, Pydantic coercion category, null-elision, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 54, + "path": "backend-services/models/update_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::field:UpdateApiModel.api_grpc_allowed_services", + "notes": "The shared Rust update normalizer contains the pinned field, Pydantic coercion category, null-elision, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 59, + "path": "backend-services/models/update_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::field:UpdateApiModel.api_grpc_allowed_methods", + "notes": "The shared Rust update normalizer contains the pinned field, Pydantic coercion category, null-elision, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 64, + "path": "backend-services/models/update_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::field:UpdateApiModel.api_credits_enabled", + "notes": "The shared Rust update normalizer contains the pinned field, Pydantic coercion category, null-elision, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 69, + "path": "backend-services/models/update_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::field:UpdateApiModel.api_credit_group", + "notes": "The shared Rust update normalizer contains the pinned field, Pydantic coercion category, null-elision, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 72, + "path": "backend-services/models/update_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::field:UpdateApiModel.active", + "notes": "The shared Rust update normalizer contains the pinned field, Pydantic coercion category, null-elision, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 75, + "path": "backend-services/models/update_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::field:UpdateApiModel.api_id", + "notes": "The shared Rust update normalizer contains the pinned field, Pydantic coercion category, null-elision, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 76, + "path": "backend-services/models/update_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::field:UpdateApiModel.api_path", + "notes": "The shared Rust update normalizer contains the pinned field, Pydantic coercion category, null-elision, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 79, + "path": "backend-services/models/update_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::field:UpdateApiModel.api_cors_allow_origins", + "notes": "The shared Rust update normalizer contains the pinned field, Pydantic coercion category, null-elision, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 83, + "path": "backend-services/models/update_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::field:UpdateApiModel.api_cors_allow_methods", + "notes": "The shared Rust update normalizer contains the pinned field, Pydantic coercion category, null-elision, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 87, + "path": "backend-services/models/update_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::field:UpdateApiModel.api_cors_allow_headers", + "notes": "The shared Rust update normalizer contains the pinned field, Pydantic coercion category, null-elision, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 91, + "path": "backend-services/models/update_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::field:UpdateApiModel.api_cors_allow_credentials", + "notes": "The shared Rust update normalizer contains the pinned field, Pydantic coercion category, null-elision, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 95, + "path": "backend-services/models/update_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::field:UpdateApiModel.api_cors_expose_headers", + "notes": "The shared Rust update normalizer contains the pinned field, Pydantic coercion category, null-elision, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 98, + "path": "backend-services/models/update_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::field:UpdateApiModel.api_public", + "notes": "The shared Rust update normalizer contains the pinned field, Pydantic coercion category, null-elision, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 103, + "path": "backend-services/models/update_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::field:UpdateApiModel.api_auth_required", + "notes": "The shared Rust update normalizer contains the pinned field, Pydantic coercion category, null-elision, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 107, + "path": "backend-services/models/update_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::field:UpdateApiModel.api_ip_mode", + "notes": "The shared Rust update normalizer contains the pinned field, Pydantic coercion category, null-elision, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 112, + "path": "backend-services/models/update_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::field:UpdateApiModel.api_ip_whitelist", + "notes": "The shared Rust update normalizer contains the pinned field, Pydantic coercion category, null-elision, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 113, + "path": "backend-services/models/update_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::field:UpdateApiModel.api_ip_blacklist", + "notes": "The shared Rust update normalizer contains the pinned field, Pydantic coercion category, null-elision, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 116, + "path": "backend-services/models/update_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::field:UpdateApiModel.api_trust_x_forwarded_for", + "notes": "The shared Rust update normalizer contains the pinned field, Pydantic coercion category, null-elision, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 119, + "path": "backend-services/models/update_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::field:UpdateApiModel.api_request_transform", + "notes": "The shared Rust update normalizer contains the pinned field, Pydantic coercion category, null-elision, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 124, + "path": "backend-services/models/update_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::field:UpdateApiModel.api_response_transform", + "notes": "The shared Rust update normalizer contains the pinned field, Pydantic coercion category, null-elision, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 128, + "path": "backend-services/models/update_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::field:UpdateApiModel.api_openapi_url", + "notes": "The shared Rust update normalizer contains the pinned field, Pydantic coercion category, null-elision, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 134, + "path": "backend-services/models/update_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::field:UpdateApiModel.api_openapi_auto_discover", + "notes": "The shared Rust update normalizer contains the pinned field, Pydantic coercion category, null-elision, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 138, + "path": "backend-services/models/update_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::field:UpdateApiModel.api_wsdl_url", + "notes": "The shared Rust update normalizer contains the pinned field, Pydantic coercion category, null-elision, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 144, + "path": "backend-services/models/update_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::field:UpdateApiModel.api_soap_version", + "notes": "The shared Rust update normalizer contains the pinned field, Pydantic coercion category, null-elision, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 148, + "path": "backend-services/models/update_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::field:UpdateApiModel.api_ws_security", + "notes": "The shared Rust update normalizer contains the pinned field, Pydantic coercion category, null-elision, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 152, + "path": "backend-services/models/update_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::field:UpdateApiModel.api_graphql_max_depth", + "notes": "The shared Rust update normalizer contains the pinned field, Pydantic coercion category, null-elision, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 158, + "path": "backend-services/models/update_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::field:UpdateApiModel.api_graphql_schema_url", + "notes": "The shared Rust update normalizer contains the pinned field, Pydantic coercion category, null-elision, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 162, + "path": "backend-services/models/update_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::field:UpdateApiModel.api_graphql_subscriptions", + "notes": "The shared Rust update normalizer contains the pinned field, Pydantic coercion category, null-elision, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 166, + "path": "backend-services/models/update_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::field:UpdateApiModel.api_grpc_web_enabled", + "notes": "The shared Rust update normalizer contains the pinned field, Pydantic coercion category, null-elision, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 172, + "path": "backend-services/models/update_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::field:UpdateApiModel.api_grpc_reflection_url", + "notes": "The shared Rust update normalizer contains the pinned field, Pydantic coercion category, null-elision, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 176, + "path": "backend-services/models/update_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::field:UpdateApiModel.api_is_crud", + "notes": "The shared Rust update normalizer contains the pinned field, Pydantic coercion category, null-elision, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 181, + "path": "backend-services/models/update_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::field:UpdateApiModel.api_crud_collection", + "notes": "The shared Rust update normalizer contains the pinned field, Pydantic coercion category, null-elision, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 185, + "path": "backend-services/models/update_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::field:UpdateApiModel.api_crud_schema", + "notes": "The shared Rust update normalizer contains the pinned field, Pydantic coercion category, null-elision, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "source": { + "kind": "field", + "line": 190, + "path": "backend-services/models/update_api_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::class:UpdateApiModel.Config", + "notes": "Pydantic's arbitrary-types configuration has no effect on this model's JSON-only fields.", + "rationale": "Python framework configuration is unnecessary in the typed Rust/serde implementation.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "class", + "line": 195, + "path": "backend-services/models/update_api_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_api_model.py::field:UpdateApiModel.Config.arbitrary_types_allowed", + "notes": "Every accepted field is a JSON scalar, list, or object and does not require arbitrary Python types.", + "rationale": "Python framework flag with no observable contract for this model.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 196, + "path": "backend-services/models/update_api_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_endpoint_model.py::module:update_endpoint_model", + "notes": "Rust matches optional fields, scalar/list coercion, character-count limits, update null-elision, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_endpoint_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::endpoint_models_match_pydantic_coercion_bounds_and_null_elision" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/models/update_endpoint_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_endpoint_model.py::class:UpdateEndpointModel", + "notes": "Rust matches optional fields, scalar/list coercion, character-count limits, update null-elision, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_endpoint_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::endpoint_models_match_pydantic_coercion_bounds_and_null_elision" + ], + "source": { + "kind": "class", + "line": 10, + "path": "backend-services/models/update_endpoint_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_endpoint_model.py::field:UpdateEndpointModel.api_name", + "notes": "Rust matches optional fields, scalar/list coercion, character-count limits, update null-elision, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_endpoint_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::endpoint_models_match_pydantic_coercion_bounds_and_null_elision" + ], + "source": { + "kind": "field", + "line": 11, + "path": "backend-services/models/update_endpoint_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_endpoint_model.py::field:UpdateEndpointModel.api_version", + "notes": "Rust matches optional fields, scalar/list coercion, character-count limits, update null-elision, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_endpoint_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::endpoint_models_match_pydantic_coercion_bounds_and_null_elision" + ], + "source": { + "kind": "field", + "line": 14, + "path": "backend-services/models/update_endpoint_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_endpoint_model.py::field:UpdateEndpointModel.endpoint_method", + "notes": "Rust matches optional fields, scalar/list coercion, character-count limits, update null-elision, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_endpoint_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::endpoint_models_match_pydantic_coercion_bounds_and_null_elision" + ], + "source": { + "kind": "field", + "line": 17, + "path": "backend-services/models/update_endpoint_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_endpoint_model.py::field:UpdateEndpointModel.endpoint_uri", + "notes": "Rust matches optional fields, scalar/list coercion, character-count limits, update null-elision, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_endpoint_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::endpoint_models_match_pydantic_coercion_bounds_and_null_elision" + ], + "source": { + "kind": "field", + "line": 20, + "path": "backend-services/models/update_endpoint_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_endpoint_model.py::field:UpdateEndpointModel.endpoint_description", + "notes": "Rust matches optional fields, scalar/list coercion, character-count limits, update null-elision, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_endpoint_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::endpoint_models_match_pydantic_coercion_bounds_and_null_elision" + ], + "source": { + "kind": "field", + "line": 23, + "path": "backend-services/models/update_endpoint_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_endpoint_model.py::field:UpdateEndpointModel.endpoint_servers", + "notes": "Rust matches optional fields, scalar/list coercion, character-count limits, update null-elision, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_endpoint_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::endpoint_models_match_pydantic_coercion_bounds_and_null_elision" + ], + "source": { + "kind": "field", + "line": 30, + "path": "backend-services/models/update_endpoint_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_endpoint_model.py::field:UpdateEndpointModel.client_uri", + "notes": "Rust matches optional fields, scalar/list coercion, character-count limits, update null-elision, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_endpoint_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::endpoint_models_match_pydantic_coercion_bounds_and_null_elision" + ], + "source": { + "kind": "field", + "line": 35, + "path": "backend-services/models/update_endpoint_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_endpoint_model.py::field:UpdateEndpointModel.api_id", + "notes": "Rust matches optional fields, scalar/list coercion, character-count limits, update null-elision, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_endpoint_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::endpoint_models_match_pydantic_coercion_bounds_and_null_elision" + ], + "source": { + "kind": "field", + "line": 42, + "path": "backend-services/models/update_endpoint_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_endpoint_model.py::field:UpdateEndpointModel.endpoint_id", + "notes": "Rust matches optional fields, scalar/list coercion, character-count limits, update null-elision, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_endpoint_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::endpoint_models_match_pydantic_coercion_bounds_and_null_elision" + ], + "source": { + "kind": "field", + "line": 49, + "path": "backend-services/models/update_endpoint_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_endpoint_model.py::class:UpdateEndpointModel.Config", + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in the Rust implementation.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "class", + "line": 57, + "path": "backend-services/models/update_endpoint_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_endpoint_model.py::field:UpdateEndpointModel.Config.arbitrary_types_allowed", + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Python framework flag with no observable contract for this model.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 58, + "path": "backend-services/models/update_endpoint_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_endpoint_validation_model.py::module:update_endpoint_validation_model", + "notes": "Rust validates required update fields and recursively normalizes schemas; extreme Pydantic numeric-union coercion remains unproven.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_endpoint_validation_model", + "gateway-rs/src/routes/platform.rs::normalize_validation_schema_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/models/update_endpoint_validation_model.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_endpoint_validation_model.py::class:UpdateEndpointValidationModel", + "notes": "Rust validates required update fields and recursively normalizes schemas; extreme Pydantic numeric-union coercion remains unproven.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_endpoint_validation_model", + "gateway-rs/src/routes/platform.rs::normalize_validation_schema_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" + ], + "source": { + "kind": "class", + "line": 12, + "path": "backend-services/models/update_endpoint_validation_model.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_endpoint_validation_model.py::field:UpdateEndpointValidationModel.validation_enabled", + "notes": "Rust validates required update fields and recursively normalizes schemas; extreme Pydantic numeric-union coercion remains unproven.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_endpoint_validation_model", + "gateway-rs/src/routes/platform.rs::normalize_validation_schema_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" + ], + "source": { + "kind": "field", + "line": 13, + "path": "backend-services/models/update_endpoint_validation_model.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_endpoint_validation_model.py::field:UpdateEndpointValidationModel.validation_schema", + "notes": "Rust validates required update fields and recursively normalizes schemas; extreme Pydantic numeric-union coercion remains unproven.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_endpoint_validation_model", + "gateway-rs/src/routes/platform.rs::normalize_validation_schema_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" + ], + "source": { + "kind": "field", + "line": 16, + "path": "backend-services/models/update_endpoint_validation_model.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_endpoint_validation_model.py::class:UpdateEndpointValidationModel.Config", + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "class", + "line": 20, + "path": "backend-services/models/update_endpoint_validation_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_endpoint_validation_model.py::field:UpdateEndpointValidationModel.Config.arbitrary_types_allowed", + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Python framework flag with no observable contract for this model.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 21, + "path": "backend-services/models/update_endpoint_validation_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_group_model.py::module:update_group_model", + "notes": "Rust matches optional fields, null-elision, scalar/list coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_group_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/models/update_group_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_group_model.py::class:UpdateGroupModel", + "notes": "Rust matches optional fields, null-elision, scalar/list coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_group_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "class", + "line": 10, + "path": "backend-services/models/update_group_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_group_model.py::field:UpdateGroupModel.group_name", + "notes": "Rust matches optional fields, null-elision, scalar/list coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_group_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "field", + "line": 11, + "path": "backend-services/models/update_group_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_group_model.py::field:UpdateGroupModel.group_description", + "notes": "Rust matches optional fields, null-elision, scalar/list coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_group_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "field", + "line": 14, + "path": "backend-services/models/update_group_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_group_model.py::field:UpdateGroupModel.api_access", + "notes": "Rust matches optional fields, null-elision, scalar/list coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_group_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "field", + "line": 21, + "path": "backend-services/models/update_group_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_group_model.py::class:UpdateGroupModel.Config", + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "class", + "line": 25, + "path": "backend-services/models/update_group_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_group_model.py::field:UpdateGroupModel.Config.arbitrary_types_allowed", + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Python framework flag with no observable contract for this model.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 26, + "path": "backend-services/models/update_group_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_password_model.py::module:update_password_model", + "notes": "Rust matches the required field, Pydantic scalar-to-string coercion, Unicode character bounds, ignored unknown fields, and validation-before-authentication ordering.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_update_password_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::update_password_model_validates_before_auth_and_matches_pydantic_bounds" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/models/update_password_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_password_model.py::class:UpdatePasswordModel", + "notes": "Rust matches the required field, Pydantic scalar-to-string coercion, Unicode character bounds, ignored unknown fields, and validation-before-authentication ordering.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_update_password_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::update_password_model_validates_before_auth_and_matches_pydantic_bounds" + ], + "source": { + "kind": "class", + "line": 10, + "path": "backend-services/models/update_password_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_password_model.py::field:UpdatePasswordModel.new_password", + "notes": "Rust matches the required field, Pydantic scalar-to-string coercion, Unicode character bounds, ignored unknown fields, and validation-before-authentication ordering.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_update_password_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::update_password_model_validates_before_auth_and_matches_pydantic_bounds" + ], + "source": { + "kind": "field", + "line": 11, + "path": "backend-services/models/update_password_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_password_model.py::class:UpdatePasswordModel.Config", + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "class", + "line": 19, + "path": "backend-services/models/update_password_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_password_model.py::field:UpdatePasswordModel.Config.arbitrary_types_allowed", + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 20, + "path": "backend-services/models/update_password_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_role_model.py::module:update_role_model", + "notes": "Rust matches optional fields, null-elision, boolean coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_role_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/models/update_role_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_role_model.py::class:UpdateRoleModel", + "notes": "Rust matches optional fields, null-elision, boolean coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_role_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "class", + "line": 10, + "path": "backend-services/models/update_role_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_role_model.py::field:UpdateRoleModel.role_name", + "notes": "Rust matches optional fields, null-elision, boolean coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_role_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "field", + "line": 11, + "path": "backend-services/models/update_role_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_role_model.py::field:UpdateRoleModel.role_description", + "notes": "Rust matches optional fields, null-elision, boolean coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_role_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "field", + "line": 14, + "path": "backend-services/models/update_role_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_role_model.py::field:UpdateRoleModel.manage_users", + "notes": "Rust matches optional fields, null-elision, boolean coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_role_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "field", + "line": 21, + "path": "backend-services/models/update_role_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_role_model.py::field:UpdateRoleModel.manage_apis", + "notes": "Rust matches optional fields, null-elision, boolean coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_role_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "field", + "line": 22, + "path": "backend-services/models/update_role_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_role_model.py::field:UpdateRoleModel.manage_endpoints", + "notes": "Rust matches optional fields, null-elision, boolean coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_role_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "field", + "line": 23, + "path": "backend-services/models/update_role_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_role_model.py::field:UpdateRoleModel.manage_groups", + "notes": "Rust matches optional fields, null-elision, boolean coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_role_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "field", + "line": 26, + "path": "backend-services/models/update_role_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_role_model.py::field:UpdateRoleModel.manage_roles", + "notes": "Rust matches optional fields, null-elision, boolean coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_role_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "field", + "line": 29, + "path": "backend-services/models/update_role_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_role_model.py::field:UpdateRoleModel.manage_routings", + "notes": "Rust matches optional fields, null-elision, boolean coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_role_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "field", + "line": 30, + "path": "backend-services/models/update_role_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_role_model.py::field:UpdateRoleModel.manage_gateway", + "notes": "Rust matches optional fields, null-elision, boolean coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_role_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "field", + "line": 33, + "path": "backend-services/models/update_role_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_role_model.py::field:UpdateRoleModel.manage_subscriptions", + "notes": "Rust matches optional fields, null-elision, boolean coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_role_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "field", + "line": 36, + "path": "backend-services/models/update_role_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_role_model.py::field:UpdateRoleModel.manage_security", + "notes": "Rust matches optional fields, null-elision, boolean coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_role_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "field", + "line": 39, + "path": "backend-services/models/update_role_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_role_model.py::field:UpdateRoleModel.manage_tiers", + "notes": "Rust matches optional fields, null-elision, boolean coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_role_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "field", + "line": 42, + "path": "backend-services/models/update_role_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_role_model.py::field:UpdateRoleModel.manage_rate_limits", + "notes": "Rust matches optional fields, null-elision, boolean coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_role_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "field", + "line": 45, + "path": "backend-services/models/update_role_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_role_model.py::field:UpdateRoleModel.manage_credits", + "notes": "Rust matches optional fields, null-elision, boolean coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_role_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "field", + "line": 48, + "path": "backend-services/models/update_role_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_role_model.py::field:UpdateRoleModel.manage_auth", + "notes": "Rust matches optional fields, null-elision, boolean coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_role_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "field", + "line": 51, + "path": "backend-services/models/update_role_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_role_model.py::field:UpdateRoleModel.view_analytics", + "notes": "Rust matches optional fields, null-elision, boolean coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_role_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "field", + "line": 54, + "path": "backend-services/models/update_role_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_role_model.py::field:UpdateRoleModel.view_logs", + "notes": "Rust matches optional fields, null-elision, boolean coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_role_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "field", + "line": 57, + "path": "backend-services/models/update_role_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_role_model.py::field:UpdateRoleModel.export_logs", + "notes": "Rust matches optional fields, null-elision, boolean coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_role_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates" + ], + "source": { + "kind": "field", + "line": 58, + "path": "backend-services/models/update_role_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_role_model.py::class:UpdateRoleModel.Config", + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "class", + "line": 60, + "path": "backend-services/models/update_role_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_role_model.py::field:UpdateRoleModel.Config.arbitrary_types_allowed", + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Python framework flag with no observable contract for this model.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 61, + "path": "backend-services/models/update_role_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_routing_model.py::module:update_routing_model", + "notes": "Rust matches optional fields, null-elision, excluded server_index behavior, list/scalar coercion, and character-count bounds.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_routing_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::routing_models_match_pydantic_generation_coercion_and_update_exclusion" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/models/update_routing_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_routing_model.py::class:UpdateRoutingModel", + "notes": "Rust matches optional fields, null-elision, excluded server_index behavior, list/scalar coercion, and character-count bounds.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_routing_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::routing_models_match_pydantic_generation_coercion_and_update_exclusion" + ], + "source": { + "kind": "class", + "line": 10, + "path": "backend-services/models/update_routing_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_routing_model.py::field:UpdateRoutingModel.routing_name", + "notes": "Rust matches optional fields, null-elision, excluded server_index behavior, list/scalar coercion, and character-count bounds.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_routing_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::routing_models_match_pydantic_generation_coercion_and_update_exclusion" + ], + "source": { + "kind": "field", + "line": 11, + "path": "backend-services/models/update_routing_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_routing_model.py::field:UpdateRoutingModel.routing_servers", + "notes": "Rust matches optional fields, null-elision, excluded server_index behavior, list/scalar coercion, and character-count bounds.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_routing_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::routing_models_match_pydantic_generation_coercion_and_update_exclusion" + ], + "source": { + "kind": "field", + "line": 18, + "path": "backend-services/models/update_routing_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_routing_model.py::field:UpdateRoutingModel.routing_description", + "notes": "Rust matches optional fields, null-elision, excluded server_index behavior, list/scalar coercion, and character-count bounds.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_routing_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::routing_models_match_pydantic_generation_coercion_and_update_exclusion" + ], + "source": { + "kind": "field", + "line": 24, + "path": "backend-services/models/update_routing_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_routing_model.py::field:UpdateRoutingModel.client_key", + "notes": "Rust matches optional fields, null-elision, excluded server_index behavior, list/scalar coercion, and character-count bounds.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_routing_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::routing_models_match_pydantic_generation_coercion_and_update_exclusion" + ], + "source": { + "kind": "field", + "line": 31, + "path": "backend-services/models/update_routing_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_routing_model.py::field:UpdateRoutingModel.server_index", + "notes": "Rust matches optional fields, null-elision, excluded server_index behavior, list/scalar coercion, and character-count bounds.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_routing_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::routing_models_match_pydantic_generation_coercion_and_update_exclusion" + ], + "source": { + "kind": "field", + "line": 38, + "path": "backend-services/models/update_routing_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_routing_model.py::class:UpdateRoutingModel.Config", + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "class", + "line": 42, + "path": "backend-services/models/update_routing_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_routing_model.py::field:UpdateRoutingModel.Config.arbitrary_types_allowed", + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Python framework flag with no observable contract for this model.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 43, + "path": "backend-services/models/update_routing_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_user_model.py::module:update_user_model", + "notes": "Rust matches optional fields, null-elision used by the Python service, scalar/list coercion, Unicode character bounds, numeric and boolean constraints, dictionary handling, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_update_user_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::user_update_matches_pydantic_null_coercion_and_unknown_field_rules" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/models/update_user_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_user_model.py::class:UpdateUserModel", + "notes": "Rust matches optional fields, null-elision used by the Python service, scalar/list coercion, Unicode character bounds, numeric and boolean constraints, dictionary handling, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_update_user_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::user_update_matches_pydantic_null_coercion_and_unknown_field_rules" + ], + "source": { + "kind": "class", + "line": 10, + "path": "backend-services/models/update_user_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_user_model.py::field:UpdateUserModel.username", + "notes": "Rust matches optional fields, null-elision used by the Python service, scalar/list coercion, Unicode character bounds, numeric and boolean constraints, dictionary handling, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_update_user_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::user_update_matches_pydantic_null_coercion_and_unknown_field_rules" + ], + "source": { + "kind": "field", + "line": 11, + "path": "backend-services/models/update_user_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_user_model.py::field:UpdateUserModel.email", + "notes": "Rust matches optional fields, null-elision used by the Python service, scalar/list coercion, Unicode character bounds, numeric and boolean constraints, dictionary handling, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_update_user_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::user_update_matches_pydantic_null_coercion_and_unknown_field_rules" + ], + "source": { + "kind": "field", + "line": 14, + "path": "backend-services/models/update_user_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_user_model.py::field:UpdateUserModel.password", + "notes": "Rust matches optional fields, null-elision used by the Python service, scalar/list coercion, Unicode character bounds, numeric and boolean constraints, dictionary handling, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_update_user_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::user_update_matches_pydantic_null_coercion_and_unknown_field_rules" + ], + "source": { + "kind": "field", + "line": 21, + "path": "backend-services/models/update_user_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_user_model.py::field:UpdateUserModel.role", + "notes": "Rust matches optional fields, null-elision used by the Python service, scalar/list coercion, Unicode character bounds, numeric and boolean constraints, dictionary handling, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_update_user_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::user_update_matches_pydantic_null_coercion_and_unknown_field_rules" + ], + "source": { + "kind": "field", + "line": 28, + "path": "backend-services/models/update_user_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_user_model.py::field:UpdateUserModel.groups", + "notes": "Rust matches optional fields, null-elision used by the Python service, scalar/list coercion, Unicode character bounds, numeric and boolean constraints, dictionary handling, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_update_user_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::user_update_matches_pydantic_null_coercion_and_unknown_field_rules" + ], + "source": { + "kind": "field", + "line": 31, + "path": "backend-services/models/update_user_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_user_model.py::field:UpdateUserModel.rate_limit_duration", + "notes": "Rust matches optional fields, null-elision used by the Python service, scalar/list coercion, Unicode character bounds, numeric and boolean constraints, dictionary handling, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_update_user_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::user_update_matches_pydantic_null_coercion_and_unknown_field_rules" + ], + "source": { + "kind": "field", + "line": 34, + "path": "backend-services/models/update_user_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_user_model.py::field:UpdateUserModel.rate_limit_duration_type", + "notes": "Rust matches optional fields, null-elision used by the Python service, scalar/list coercion, Unicode character bounds, numeric and boolean constraints, dictionary handling, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_update_user_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::user_update_matches_pydantic_null_coercion_and_unknown_field_rules" + ], + "source": { + "kind": "field", + "line": 37, + "path": "backend-services/models/update_user_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_user_model.py::field:UpdateUserModel.rate_limit_enabled", + "notes": "Rust matches optional fields, null-elision used by the Python service, scalar/list coercion, Unicode character bounds, numeric and boolean constraints, dictionary handling, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_update_user_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::user_update_matches_pydantic_null_coercion_and_unknown_field_rules" + ], + "source": { + "kind": "field", + "line": 40, + "path": "backend-services/models/update_user_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_user_model.py::field:UpdateUserModel.throttle_duration", + "notes": "Rust matches optional fields, null-elision used by the Python service, scalar/list coercion, Unicode character bounds, numeric and boolean constraints, dictionary handling, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_update_user_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::user_update_matches_pydantic_null_coercion_and_unknown_field_rules" + ], + "source": { + "kind": "field", + "line": 43, + "path": "backend-services/models/update_user_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_user_model.py::field:UpdateUserModel.throttle_duration_type", + "notes": "Rust matches optional fields, null-elision used by the Python service, scalar/list coercion, Unicode character bounds, numeric and boolean constraints, dictionary handling, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_update_user_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::user_update_matches_pydantic_null_coercion_and_unknown_field_rules" + ], + "source": { + "kind": "field", + "line": 46, + "path": "backend-services/models/update_user_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_user_model.py::field:UpdateUserModel.throttle_wait_duration", + "notes": "Rust matches optional fields, null-elision used by the Python service, scalar/list coercion, Unicode character bounds, numeric and boolean constraints, dictionary handling, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_update_user_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::user_update_matches_pydantic_null_coercion_and_unknown_field_rules" + ], + "source": { + "kind": "field", + "line": 53, + "path": "backend-services/models/update_user_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_user_model.py::field:UpdateUserModel.throttle_wait_duration_type", + "notes": "Rust matches optional fields, null-elision used by the Python service, scalar/list coercion, Unicode character bounds, numeric and boolean constraints, dictionary handling, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_update_user_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::user_update_matches_pydantic_null_coercion_and_unknown_field_rules" + ], + "source": { + "kind": "field", + "line": 56, + "path": "backend-services/models/update_user_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_user_model.py::field:UpdateUserModel.throttle_queue_limit", + "notes": "Rust matches optional fields, null-elision used by the Python service, scalar/list coercion, Unicode character bounds, numeric and boolean constraints, dictionary handling, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_update_user_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::user_update_matches_pydantic_null_coercion_and_unknown_field_rules" + ], + "source": { + "kind": "field", + "line": 63, + "path": "backend-services/models/update_user_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_user_model.py::field:UpdateUserModel.throttle_enabled", + "notes": "Rust matches optional fields, null-elision used by the Python service, scalar/list coercion, Unicode character bounds, numeric and boolean constraints, dictionary handling, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_update_user_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::user_update_matches_pydantic_null_coercion_and_unknown_field_rules" + ], + "source": { + "kind": "field", + "line": 66, + "path": "backend-services/models/update_user_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_user_model.py::field:UpdateUserModel.custom_attributes", + "notes": "Rust matches optional fields, null-elision used by the Python service, scalar/list coercion, Unicode character bounds, numeric and boolean constraints, dictionary handling, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_update_user_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::user_update_matches_pydantic_null_coercion_and_unknown_field_rules" + ], + "source": { + "kind": "field", + "line": 69, + "path": "backend-services/models/update_user_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_user_model.py::field:UpdateUserModel.bandwidth_limit_bytes", + "notes": "Rust matches optional fields, null-elision used by the Python service, scalar/list coercion, Unicode character bounds, numeric and boolean constraints, dictionary handling, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_update_user_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::user_update_matches_pydantic_null_coercion_and_unknown_field_rules" + ], + "source": { + "kind": "field", + "line": 72, + "path": "backend-services/models/update_user_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_user_model.py::field:UpdateUserModel.bandwidth_limit_window", + "notes": "Rust matches optional fields, null-elision used by the Python service, scalar/list coercion, Unicode character bounds, numeric and boolean constraints, dictionary handling, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_update_user_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::user_update_matches_pydantic_null_coercion_and_unknown_field_rules" + ], + "source": { + "kind": "field", + "line": 78, + "path": "backend-services/models/update_user_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_user_model.py::field:UpdateUserModel.bandwidth_limit_enabled", + "notes": "Rust matches optional fields, null-elision used by the Python service, scalar/list coercion, Unicode character bounds, numeric and boolean constraints, dictionary handling, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_update_user_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::user_update_matches_pydantic_null_coercion_and_unknown_field_rules" + ], + "source": { + "kind": "field", + "line": 85, + "path": "backend-services/models/update_user_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_user_model.py::field:UpdateUserModel.active", + "notes": "Rust matches optional fields, null-elision used by the Python service, scalar/list coercion, Unicode character bounds, numeric and boolean constraints, dictionary handling, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_update_user_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::user_update_matches_pydantic_null_coercion_and_unknown_field_rules" + ], + "source": { + "kind": "field", + "line": 90, + "path": "backend-services/models/update_user_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_user_model.py::field:UpdateUserModel.ui_access", + "notes": "Rust matches optional fields, null-elision used by the Python service, scalar/list coercion, Unicode character bounds, numeric and boolean constraints, dictionary handling, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_update_user_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::user_update_matches_pydantic_null_coercion_and_unknown_field_rules" + ], + "source": { + "kind": "field", + "line": 91, + "path": "backend-services/models/update_user_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_user_model.py::class:UpdateUserModel.Config", + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "class", + "line": 93, + "path": "backend-services/models/update_user_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_user_model.py::field:UpdateUserModel.Config.arbitrary_types_allowed", + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 94, + "path": "backend-services/models/update_user_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_vault_entry_model.py::module:update_vault_entry_model", + "notes": "Rust matches the optional nullable description, scalar-to-string coercion, Unicode character bound, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::vault_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::vault_lifecycle_encrypts_at_rest_and_never_returns_the_secret" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/models/update_vault_entry_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_vault_entry_model.py::class:UpdateVaultEntryModel", + "notes": "Rust matches the optional nullable description, scalar-to-string coercion, Unicode character bound, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::vault_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::vault_lifecycle_encrypts_at_rest_and_never_returns_the_secret" + ], + "source": { + "kind": "class", + "line": 10, + "path": "backend-services/models/update_vault_entry_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_vault_entry_model.py::field:UpdateVaultEntryModel.description", + "notes": "Rust matches the optional nullable description, scalar-to-string coercion, Unicode character bound, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::vault_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::vault_lifecycle_encrypts_at_rest_and_never_returns_the_secret" + ], + "source": { + "kind": "field", + "line": 13, + "path": "backend-services/models/update_vault_entry_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_vault_entry_model.py::class:UpdateVaultEntryModel.Config", + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "class", + "line": 20, + "path": "backend-services/models/update_vault_entry_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/update_vault_entry_model.py::field:UpdateVaultEntryModel.Config.arbitrary_types_allowed", + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 21, + "path": "backend-services/models/update_vault_entry_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/user_credits_model.py::module:user_credits_model", + "notes": "Rust matches required nested fields, defaults and null materialization, Pydantic scalar coercion, Unicode character bounds, ignored unknown fields, and the service's path/body username mismatch error.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_user_credit_model", + "gateway-rs/src/routes/platform.rs::credit_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/models/user_credits_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/user_credits_model.py::class:UserCreditInformationModel", + "notes": "Rust matches required nested fields, defaults and null materialization, Pydantic scalar coercion, Unicode character bounds, ignored unknown fields, and the service's path/body username mismatch error.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_user_credit_model", + "gateway-rs/src/routes/platform.rs::credit_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision" + ], + "source": { + "kind": "class", + "line": 10, + "path": "backend-services/models/user_credits_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/user_credits_model.py::field:UserCreditInformationModel.tier_name", + "notes": "Rust matches required nested fields, defaults and null materialization, Pydantic scalar coercion, Unicode character bounds, ignored unknown fields, and the service's path/body username mismatch error.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_user_credit_model", + "gateway-rs/src/routes/platform.rs::credit_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision" + ], + "source": { + "kind": "field", + "line": 11, + "path": "backend-services/models/user_credits_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/user_credits_model.py::field:UserCreditInformationModel.available_credits", + "notes": "Rust matches required nested fields, defaults and null materialization, Pydantic scalar coercion, Unicode character bounds, ignored unknown fields, and the service's path/body username mismatch error.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_user_credit_model", + "gateway-rs/src/routes/platform.rs::credit_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision" + ], + "source": { + "kind": "field", + "line": 14, + "path": "backend-services/models/user_credits_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/user_credits_model.py::field:UserCreditInformationModel.reset_date", + "notes": "Rust matches required nested fields, defaults and null materialization, Pydantic scalar coercion, Unicode character bounds, ignored unknown fields, and the service's path/body username mismatch error.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_user_credit_model", + "gateway-rs/src/routes/platform.rs::credit_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision" + ], + "source": { + "kind": "field", + "line": 16, + "path": "backend-services/models/user_credits_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/user_credits_model.py::field:UserCreditInformationModel.user_api_key", + "notes": "Rust matches required nested fields, defaults and null materialization, Pydantic scalar coercion, Unicode character bounds, ignored unknown fields, and the service's path/body username mismatch error.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_user_credit_model", + "gateway-rs/src/routes/platform.rs::credit_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision" + ], + "source": { + "kind": "field", + "line": 19, + "path": "backend-services/models/user_credits_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/user_credits_model.py::class:UserCreditInformationModel.Config", + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "class", + "line": 25, + "path": "backend-services/models/user_credits_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/user_credits_model.py::field:UserCreditInformationModel.Config.arbitrary_types_allowed", + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 26, + "path": "backend-services/models/user_credits_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/user_credits_model.py::class:UserCreditModel", + "notes": "Rust matches required nested fields, defaults and null materialization, Pydantic scalar coercion, Unicode character bounds, ignored unknown fields, and the service's path/body username mismatch error.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_user_credit_model", + "gateway-rs/src/routes/platform.rs::credit_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision" + ], + "source": { + "kind": "class", + "line": 29, + "path": "backend-services/models/user_credits_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/user_credits_model.py::field:UserCreditModel.username", + "notes": "Rust matches required nested fields, defaults and null materialization, Pydantic scalar coercion, Unicode character bounds, ignored unknown fields, and the service's path/body username mismatch error.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_user_credit_model", + "gateway-rs/src/routes/platform.rs::credit_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision" + ], + "source": { + "kind": "field", + "line": 30, + "path": "backend-services/models/user_credits_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/user_credits_model.py::field:UserCreditModel.users_credits", + "notes": "Rust matches required nested fields, defaults and null materialization, Pydantic scalar coercion, Unicode character bounds, ignored unknown fields, and the service's path/body username mismatch error.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_user_credit_model", + "gateway-rs/src/routes/platform.rs::credit_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision" + ], + "source": { + "kind": "field", + "line": 37, + "path": "backend-services/models/user_credits_model.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/user_credits_model.py::class:UserCreditModel.Config", + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "class", + "line": 41, + "path": "backend-services/models/user_credits_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/user_credits_model.py::field:UserCreditModel.Config.arbitrary_types_allowed", + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 42, + "path": "backend-services/models/user_credits_model.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/user_model_response.py::module:user_model_response", + "notes": "The class is imported by user_routes.py but never referenced by a response_model declaration, annotation, constructor, or runtime check.", + "rationale": "Unused Python response schema with no observable runtime contract to preserve.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/models/user_model_response.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/user_model_response.py::class:UserModelResponse", + "notes": "The class is imported by user_routes.py but never referenced by a response_model declaration, annotation, constructor, or runtime check.", + "rationale": "Unused Python response schema with no observable runtime contract to preserve.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "class", + "line": 10, + "path": "backend-services/models/user_model_response.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/user_model_response.py::field:UserModelResponse.username", + "notes": "The class is imported by user_routes.py but never referenced by a response_model declaration, annotation, constructor, or runtime check.", + "rationale": "Unused Python response schema with no observable runtime contract to preserve.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 11, + "path": "backend-services/models/user_model_response.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/user_model_response.py::field:UserModelResponse.email", + "notes": "The class is imported by user_routes.py but never referenced by a response_model declaration, annotation, constructor, or runtime check.", + "rationale": "Unused Python response schema with no observable runtime contract to preserve.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 14, + "path": "backend-services/models/user_model_response.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/user_model_response.py::field:UserModelResponse.password", + "notes": "The class is imported by user_routes.py but never referenced by a response_model declaration, annotation, constructor, or runtime check.", + "rationale": "Unused Python response schema with no observable runtime contract to preserve.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 15, + "path": "backend-services/models/user_model_response.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/user_model_response.py::field:UserModelResponse.role", + "notes": "The class is imported by user_routes.py but never referenced by a response_model declaration, annotation, constructor, or runtime check.", + "rationale": "Unused Python response schema with no observable runtime contract to preserve.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 22, + "path": "backend-services/models/user_model_response.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/user_model_response.py::field:UserModelResponse.groups", + "notes": "The class is imported by user_routes.py but never referenced by a response_model declaration, annotation, constructor, or runtime check.", + "rationale": "Unused Python response schema with no observable runtime contract to preserve.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 25, + "path": "backend-services/models/user_model_response.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/user_model_response.py::field:UserModelResponse.rate_limit_duration", + "notes": "The class is imported by user_routes.py but never referenced by a response_model declaration, annotation, constructor, or runtime check.", + "rationale": "Unused Python response schema with no observable runtime contract to preserve.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 28, + "path": "backend-services/models/user_model_response.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/user_model_response.py::field:UserModelResponse.rate_limit_duration_type", + "notes": "The class is imported by user_routes.py but never referenced by a response_model declaration, annotation, constructor, or runtime check.", + "rationale": "Unused Python response schema with no observable runtime contract to preserve.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 31, + "path": "backend-services/models/user_model_response.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/user_model_response.py::field:UserModelResponse.rate_limit_enabled", + "notes": "The class is imported by user_routes.py but never referenced by a response_model declaration, annotation, constructor, or runtime check.", + "rationale": "Unused Python response schema with no observable runtime contract to preserve.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 34, + "path": "backend-services/models/user_model_response.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/user_model_response.py::field:UserModelResponse.throttle_duration", + "notes": "The class is imported by user_routes.py but never referenced by a response_model declaration, annotation, constructor, or runtime check.", + "rationale": "Unused Python response schema with no observable runtime contract to preserve.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 37, + "path": "backend-services/models/user_model_response.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/user_model_response.py::field:UserModelResponse.throttle_duration_type", + "notes": "The class is imported by user_routes.py but never referenced by a response_model declaration, annotation, constructor, or runtime check.", + "rationale": "Unused Python response schema with no observable runtime contract to preserve.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 40, + "path": "backend-services/models/user_model_response.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/user_model_response.py::field:UserModelResponse.throttle_wait_duration", + "notes": "The class is imported by user_routes.py but never referenced by a response_model declaration, annotation, constructor, or runtime check.", + "rationale": "Unused Python response schema with no observable runtime contract to preserve.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 47, + "path": "backend-services/models/user_model_response.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/user_model_response.py::field:UserModelResponse.throttle_wait_duration_type", + "notes": "The class is imported by user_routes.py but never referenced by a response_model declaration, annotation, constructor, or runtime check.", + "rationale": "Unused Python response schema with no observable runtime contract to preserve.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 50, + "path": "backend-services/models/user_model_response.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/user_model_response.py::field:UserModelResponse.throttle_queue_limit", + "notes": "The class is imported by user_routes.py but never referenced by a response_model declaration, annotation, constructor, or runtime check.", + "rationale": "Unused Python response schema with no observable runtime contract to preserve.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 57, + "path": "backend-services/models/user_model_response.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/user_model_response.py::field:UserModelResponse.throttle_enabled", + "notes": "The class is imported by user_routes.py but never referenced by a response_model declaration, annotation, constructor, or runtime check.", + "rationale": "Unused Python response schema with no observable runtime contract to preserve.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 60, + "path": "backend-services/models/user_model_response.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/user_model_response.py::field:UserModelResponse.custom_attributes", + "notes": "The class is imported by user_routes.py but never referenced by a response_model declaration, annotation, constructor, or runtime check.", + "rationale": "Unused Python response schema with no observable runtime contract to preserve.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 63, + "path": "backend-services/models/user_model_response.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/user_model_response.py::field:UserModelResponse.bandwidth_limit_bytes", + "notes": "The class is imported by user_routes.py but never referenced by a response_model declaration, annotation, constructor, or runtime check.", + "rationale": "Unused Python response schema with no observable runtime contract to preserve.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 66, + "path": "backend-services/models/user_model_response.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/user_model_response.py::field:UserModelResponse.bandwidth_limit_window", + "notes": "The class is imported by user_routes.py but never referenced by a response_model declaration, annotation, constructor, or runtime check.", + "rationale": "Unused Python response schema with no observable runtime contract to preserve.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 72, + "path": "backend-services/models/user_model_response.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/user_model_response.py::field:UserModelResponse.bandwidth_usage_bytes", + "notes": "The class is imported by user_routes.py but never referenced by a response_model declaration, annotation, constructor, or runtime check.", + "rationale": "Unused Python response schema with no observable runtime contract to preserve.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 79, + "path": "backend-services/models/user_model_response.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/user_model_response.py::field:UserModelResponse.bandwidth_resets_at", + "notes": "The class is imported by user_routes.py but never referenced by a response_model declaration, annotation, constructor, or runtime check.", + "rationale": "Unused Python response schema with no observable runtime contract to preserve.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 85, + "path": "backend-services/models/user_model_response.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/user_model_response.py::field:UserModelResponse.bandwidth_limit_enabled", + "notes": "The class is imported by user_routes.py but never referenced by a response_model declaration, annotation, constructor, or runtime check.", + "rationale": "Unused Python response schema with no observable runtime contract to preserve.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 90, + "path": "backend-services/models/user_model_response.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/user_model_response.py::field:UserModelResponse.active", + "notes": "The class is imported by user_routes.py but never referenced by a response_model declaration, annotation, constructor, or runtime check.", + "rationale": "Unused Python response schema with no observable runtime contract to preserve.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 95, + "path": "backend-services/models/user_model_response.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/user_model_response.py::field:UserModelResponse.ui_access", + "notes": "The class is imported by user_routes.py but never referenced by a response_model declaration, annotation, constructor, or runtime check.", + "rationale": "Unused Python response schema with no observable runtime contract to preserve.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 96, + "path": "backend-services/models/user_model_response.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/user_model_response.py::class:UserModelResponse.Config", + "notes": "The class is imported by user_routes.py but never referenced by a response_model declaration, annotation, constructor, or runtime check.", + "rationale": "Unused Python response schema with no observable runtime contract to preserve.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "class", + "line": 98, + "path": "backend-services/models/user_model_response.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/user_model_response.py::field:UserModelResponse.Config.arbitrary_types_allowed", + "notes": "The class is imported by user_routes.py but never referenced by a response_model declaration, annotation, constructor, or runtime check.", + "rationale": "Unused Python response schema with no observable runtime contract to preserve.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 99, + "path": "backend-services/models/user_model_response.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/validation_schema_model.py::module:validation_schema_model", + "notes": "Rust requires the validation_schema mapping and recursively normalizes its field rules; extreme Pydantic numeric-union coercion remains unproven.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_validation_schema_model", + "gateway-rs/src/validation/json.rs::validate_json_with_registry" + ], + "rust_tests": [ + "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/models/validation_schema_model.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/validation_schema_model.py::class:ValidationSchema", + "notes": "Rust requires the validation_schema mapping and recursively normalizes its field rules; extreme Pydantic numeric-union coercion remains unproven.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_validation_schema_model", + "gateway-rs/src/validation/json.rs::validate_json_with_registry" + ], + "rust_tests": [ + "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" + ], + "source": { + "kind": "class", + "line": 12, + "path": "backend-services/models/validation_schema_model.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/validation_schema_model.py::field:ValidationSchema.validation_schema", + "notes": "Rust requires the validation_schema mapping and recursively normalizes its field rules; extreme Pydantic numeric-union coercion remains unproven.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_validation_schema_model", + "gateway-rs/src/validation/json.rs::validate_json_with_registry" + ], + "rust_tests": [ + "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" + ], + "source": { + "kind": "field", + "line": 61, + "path": "backend-services/models/validation_schema_model.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/vault_entry_model_response.py::module:vault_entry_model_response", + "notes": "The response model is declared but never imported or used by pinned production code; vault routes use ResponseModel instead.", + "rationale": "Unused Python response schema with no runtime contract to preserve.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/models/vault_entry_model_response.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/vault_entry_model_response.py::class:VaultEntryModelResponse", + "notes": "The response model is declared but never imported or used by pinned production code; vault routes use ResponseModel instead.", + "rationale": "Unused Python response schema with no runtime contract to preserve.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "class", + "line": 10, + "path": "backend-services/models/vault_entry_model_response.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/vault_entry_model_response.py::field:VaultEntryModelResponse.key_name", + "notes": "The response model is declared but never imported or used by pinned production code; vault routes use ResponseModel instead.", + "rationale": "Unused Python response schema with no runtime contract to preserve.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 13, + "path": "backend-services/models/vault_entry_model_response.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/vault_entry_model_response.py::field:VaultEntryModelResponse.username", + "notes": "The response model is declared but never imported or used by pinned production code; vault routes use ResponseModel instead.", + "rationale": "Unused Python response schema with no runtime contract to preserve.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 15, + "path": "backend-services/models/vault_entry_model_response.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/vault_entry_model_response.py::field:VaultEntryModelResponse.description", + "notes": "The response model is declared but never imported or used by pinned production code; vault routes use ResponseModel instead.", + "rationale": "Unused Python response schema with no runtime contract to preserve.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 17, + "path": "backend-services/models/vault_entry_model_response.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/vault_entry_model_response.py::field:VaultEntryModelResponse.created_at", + "notes": "The response model is declared but never imported or used by pinned production code; vault routes use ResponseModel instead.", + "rationale": "Unused Python response schema with no runtime contract to preserve.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 23, + "path": "backend-services/models/vault_entry_model_response.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/vault_entry_model_response.py::field:VaultEntryModelResponse.updated_at", + "notes": "The response model is declared but never imported or used by pinned production code; vault routes use ResponseModel instead.", + "rationale": "Unused Python response schema with no runtime contract to preserve.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 27, + "path": "backend-services/models/vault_entry_model_response.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/vault_entry_model_response.py::class:VaultEntryModelResponse.Config", + "notes": "The response model is declared but never imported or used by pinned production code; vault routes use ResponseModel instead.", + "rationale": "Unused Python response schema with no runtime contract to preserve.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "class", + "line": 33, + "path": "backend-services/models/vault_entry_model_response.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "models", + "id": "backend-services/models/vault_entry_model_response.py::field:VaultEntryModelResponse.Config.arbitrary_types_allowed", + "notes": "The response model is declared but never imported or used by pinned production code; vault routes use ResponseModel instead.", + "rationale": "Unused Python response schema with no runtime contract to preserve.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "field", + "line": 34, + "path": "backend-services/models/vault_entry_model_response.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/analytics_routes.py::module:analytics_routes", + "notes": "All seven analytics endpoints and top-pair normalization are implemented natively. Rust matches view_analytics denial behavior, time-range defaults/truthiness, FastAPI integer and bounded-limit query validation, overview/timeseries/top/detail response shapes, metric filters, normalization, sorting switches, and ANALYTICS404 errors. Native aggregate counters are not yet fully time-range scoped, endpoint latency/percentiles are placeholders, and Python's exact granularity rebucketing and snapshot percentile calculations remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::analytics_overview", + "gateway-rs/src/routes/platform.rs::analytics_timeseries", + "gateway-rs/src/routes/platform.rs::analytics_top", + "gateway-rs/src/routes/platform.rs::analytics_detail", + "gateway-rs/src/routes/platform.rs::analytics_query_error" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", + "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/routes/analytics_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/analytics_routes.py::function:_normalize_top_pairs", + "notes": "All seven analytics endpoints and top-pair normalization are implemented natively. Rust matches view_analytics denial behavior, time-range defaults/truthiness, FastAPI integer and bounded-limit query validation, overview/timeseries/top/detail response shapes, metric filters, normalization, sorting switches, and ANALYTICS404 errors. Native aggregate counters are not yet fully time-range scoped, endpoint latency/percentiles are placeholders, and Python's exact granularity rebucketing and snapshot percentile calculations remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::analytics_overview", + "gateway-rs/src/routes/platform.rs::analytics_timeseries", + "gateway-rs/src/routes/platform.rs::analytics_top", + "gateway-rs/src/routes/platform.rs::analytics_detail", + "gateway-rs/src/routes/platform.rs::analytics_query_error" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", + "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract" + ], + "source": { + "kind": "function", + "line": 28, + "path": "backend-services/routes/analytics_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "analytics_router.get('/analytics/overview', description='Get dashboard overview statistics', response_model=ResponseModel, responses={200: {'description': 'Analytics overview', 'content': {'application/json': {'example': {'total_requests': 12345, 'total_errors': 123, 'error_rate': 0.01, 'avg_response_ms': 150.5, 'percentiles': {'p50': 120.0, 'p75': 180.0, 'p90': 250.0, 'p95': 300.0, 'p99': 450.0}, 'unique_users': 150, 'total_bandwidth': 1073741824, 'top_apis': [{'api': 'rest:customer', 'count': 5000}, {'api': 'rest:orders', 'count': 3000}], 'top_users': [{'user': 'john_doe', 'count': 500}, {'user': 'jane_smith', 'count': 300}]}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/analytics_routes.py::async_function:get_analytics_overview", + "notes": "All seven analytics endpoints and top-pair normalization are implemented natively. Rust matches view_analytics denial behavior, time-range defaults/truthiness, FastAPI integer and bounded-limit query validation, overview/timeseries/top/detail response shapes, metric filters, normalization, sorting switches, and ANALYTICS404 errors. Native aggregate counters are not yet fully time-range scoped, endpoint latency/percentiles are placeholders, and Python's exact granularity rebucketing and snapshot percentile calculations remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::analytics_overview", + "gateway-rs/src/routes/platform.rs::analytics_timeseries", + "gateway-rs/src/routes/platform.rs::analytics_top", + "gateway-rs/src/routes/platform.rs::analytics_detail", + "gateway-rs/src/routes/platform.rs::analytics_query_error" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", + "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract" + ], + "source": { + "kind": "async_function", + "line": 84, + "path": "backend-services/routes/analytics_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "analytics_router.get('/analytics/timeseries', description='Get time-series analytics data with filtering', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/analytics_routes.py::async_function:get_analytics_timeseries", + "notes": "All seven analytics endpoints and top-pair normalization are implemented natively. Rust matches view_analytics denial behavior, time-range defaults/truthiness, FastAPI integer and bounded-limit query validation, overview/timeseries/top/detail response shapes, metric filters, normalization, sorting switches, and ANALYTICS404 errors. Native aggregate counters are not yet fully time-range scoped, endpoint latency/percentiles are placeholders, and Python's exact granularity rebucketing and snapshot percentile calculations remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::analytics_overview", + "gateway-rs/src/routes/platform.rs::analytics_timeseries", + "gateway-rs/src/routes/platform.rs::analytics_top", + "gateway-rs/src/routes/platform.rs::analytics_detail", + "gateway-rs/src/routes/platform.rs::analytics_query_error" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", + "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract" + ], + "source": { + "kind": "async_function", + "line": 197, + "path": "backend-services/routes/analytics_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "analytics_router.get('/analytics/top-apis', description='Get most used APIs', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/analytics_routes.py::async_function:get_top_apis", + "notes": "All seven analytics endpoints and top-pair normalization are implemented natively. Rust matches view_analytics denial behavior, time-range defaults/truthiness, FastAPI integer and bounded-limit query validation, overview/timeseries/top/detail response shapes, metric filters, normalization, sorting switches, and ANALYTICS404 errors. Native aggregate counters are not yet fully time-range scoped, endpoint latency/percentiles are placeholders, and Python's exact granularity rebucketing and snapshot percentile calculations remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::analytics_overview", + "gateway-rs/src/routes/platform.rs::analytics_timeseries", + "gateway-rs/src/routes/platform.rs::analytics_top", + "gateway-rs/src/routes/platform.rs::analytics_detail", + "gateway-rs/src/routes/platform.rs::analytics_query_error" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", + "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract" + ], + "source": { + "kind": "async_function", + "line": 311, + "path": "backend-services/routes/analytics_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "analytics_router.get('/analytics/top-users', description='Get highest consuming users', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/analytics_routes.py::async_function:get_top_users", + "notes": "All seven analytics endpoints and top-pair normalization are implemented natively. Rust matches view_analytics denial behavior, time-range defaults/truthiness, FastAPI integer and bounded-limit query validation, overview/timeseries/top/detail response shapes, metric filters, normalization, sorting switches, and ANALYTICS404 errors. Native aggregate counters are not yet fully time-range scoped, endpoint latency/percentiles are placeholders, and Python's exact granularity rebucketing and snapshot percentile calculations remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::analytics_overview", + "gateway-rs/src/routes/platform.rs::analytics_timeseries", + "gateway-rs/src/routes/platform.rs::analytics_top", + "gateway-rs/src/routes/platform.rs::analytics_detail", + "gateway-rs/src/routes/platform.rs::analytics_query_error" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", + "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract" + ], + "source": { + "kind": "async_function", + "line": 398, + "path": "backend-services/routes/analytics_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "analytics_router.get('/analytics/top-endpoints', description='Get slowest/most-used endpoints', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/analytics_routes.py::async_function:get_top_endpoints", + "notes": "All seven analytics endpoints and top-pair normalization are implemented natively. Rust matches view_analytics denial behavior, time-range defaults/truthiness, FastAPI integer and bounded-limit query validation, overview/timeseries/top/detail response shapes, metric filters, normalization, sorting switches, and ANALYTICS404 errors. Native aggregate counters are not yet fully time-range scoped, endpoint latency/percentiles are placeholders, and Python's exact granularity rebucketing and snapshot percentile calculations remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::analytics_overview", + "gateway-rs/src/routes/platform.rs::analytics_timeseries", + "gateway-rs/src/routes/platform.rs::analytics_top", + "gateway-rs/src/routes/platform.rs::analytics_detail", + "gateway-rs/src/routes/platform.rs::analytics_query_error" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", + "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract" + ], + "source": { + "kind": "async_function", + "line": 482, + "path": "backend-services/routes/analytics_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "analytics_router.get('/analytics/api/{api_name}/{version}', description='Get detailed analytics for a specific API', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/analytics_routes.py::async_function:get_api_analytics", + "notes": "All seven analytics endpoints and top-pair normalization are implemented natively. Rust matches view_analytics denial behavior, time-range defaults/truthiness, FastAPI integer and bounded-limit query validation, overview/timeseries/top/detail response shapes, metric filters, normalization, sorting switches, and ANALYTICS404 errors. Native aggregate counters are not yet fully time-range scoped, endpoint latency/percentiles are placeholders, and Python's exact granularity rebucketing and snapshot percentile calculations remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::analytics_overview", + "gateway-rs/src/routes/platform.rs::analytics_timeseries", + "gateway-rs/src/routes/platform.rs::analytics_top", + "gateway-rs/src/routes/platform.rs::analytics_detail", + "gateway-rs/src/routes/platform.rs::analytics_query_error" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", + "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract" + ], + "source": { + "kind": "async_function", + "line": 580, + "path": "backend-services/routes/analytics_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "analytics_router.get('/analytics/user/{username}', description='Get detailed analytics for a specific user', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/analytics_routes.py::async_function:get_user_analytics", + "notes": "All seven analytics endpoints and top-pair normalization are implemented natively. Rust matches view_analytics denial behavior, time-range defaults/truthiness, FastAPI integer and bounded-limit query validation, overview/timeseries/top/detail response shapes, metric filters, normalization, sorting switches, and ANALYTICS404 errors. Native aggregate counters are not yet fully time-range scoped, endpoint latency/percentiles are placeholders, and Python's exact granularity rebucketing and snapshot percentile calculations remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::analytics_overview", + "gateway-rs/src/routes/platform.rs::analytics_timeseries", + "gateway-rs/src/routes/platform.rs::analytics_top", + "gateway-rs/src/routes/platform.rs::analytics_detail", + "gateway-rs/src/routes/platform.rs::analytics_query_error" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", + "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract" + ], + "source": { + "kind": "async_function", + "line": 696, + "path": "backend-services/routes/analytics_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/api_routes.py::module:api_routes", + "notes": "All API CRUD/list routes are implemented natively. Rust matches the pinned create/update-only manage_apis boundary (authenticated reads, listing, and deletion remain available without that permission), model validation, duplicate responses, pagination, immutable identity fields, public-credit exclusion, CRUD bodies, and missing-item status. The proto-upload-before-create path intentionally persists descriptor metadata differently and some auth/storage exceptional envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::api_routes" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::least_privilege_role_cannot_create_apis_or_read_logs", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts", + "gateway-rs/tests/platform_native.rs::python_api_and_endpoint_crud_lookup_and_missing_contracts" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/routes/api_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "api_router.post('', description='Add API', response_model=ResponseModel, responses={200: {'description': 'Successful Response', 'content': {'application/json': {'example': {'message': 'API created successfully'}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/api_routes.py::async_function:create_api", + "notes": "All API CRUD/list routes are implemented natively. Rust matches the pinned create/update-only manage_apis boundary (authenticated reads, listing, and deletion remain available without that permission), model validation, duplicate responses, pagination, immutable identity fields, public-credit exclusion, CRUD bodies, and missing-item status. The proto-upload-before-create path intentionally persists descriptor metadata differently and some auth/storage exceptional envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::api_routes" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::least_privilege_role_cannot_create_apis_or_read_logs", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts", + "gateway-rs/tests/platform_native.rs::python_api_and_endpoint_crud_lookup_and_missing_contracts" + ], + "source": { + "kind": "async_function", + "line": 48, + "path": "backend-services/routes/api_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "api_router.put('/{api_name}/{api_version}', description='Update API', response_model=ResponseModel, responses={200: {'description': 'Successful Response', 'content': {'application/json': {'example': {'message': 'API updated successfully'}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/api_routes.py::async_function:update_api", + "notes": "All API CRUD/list routes are implemented natively. Rust matches the pinned create/update-only manage_apis boundary (authenticated reads, listing, and deletion remain available without that permission), model validation, duplicate responses, pagination, immutable identity fields, public-credit exclusion, CRUD bodies, and missing-item status. The proto-upload-before-create path intentionally persists descriptor metadata differently and some auth/storage exceptional envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::api_routes" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::least_privilege_role_cannot_create_apis_or_read_logs", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts", + "gateway-rs/tests/platform_native.rs::python_api_and_endpoint_crud_lookup_and_missing_contracts" + ], + "source": { + "kind": "async_function", + "line": 116, + "path": "backend-services/routes/api_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "api_router.get('/{api_name}/{api_version}', description='Get API', response_model=ApiModelResponse, responses={200: {'description': 'Successful Response', 'content': {'application/json': {'example': {'message': 'API retrieved successfully'}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/api_routes.py::async_function:get_api_by_name_version", + "notes": "All API CRUD/list routes are implemented natively. Rust matches the pinned create/update-only manage_apis boundary (authenticated reads, listing, and deletion remain available without that permission), model validation, duplicate responses, pagination, immutable identity fields, public-credit exclusion, CRUD bodies, and missing-item status. The proto-upload-before-create path intentionally persists descriptor metadata differently and some auth/storage exceptional envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::api_routes" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::least_privilege_role_cannot_create_apis_or_read_logs", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts", + "gateway-rs/tests/platform_native.rs::python_api_and_endpoint_crud_lookup_and_missing_contracts" + ], + "source": { + "kind": "async_function", + "line": 185, + "path": "backend-services/routes/api_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "api_router.delete('/{api_name}/{api_version}', description='Delete API', response_model=ResponseModel, responses={200: {'description': 'Successful Response', 'content': {'application/json': {'example': {'message': 'API deleted successfully'}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/api_routes.py::async_function:delete_api", + "notes": "All API CRUD/list routes are implemented natively. Rust matches the pinned create/update-only manage_apis boundary (authenticated reads, listing, and deletion remain available without that permission), model validation, duplicate responses, pagination, immutable identity fields, public-credit exclusion, CRUD bodies, and missing-item status. The proto-upload-before-create path intentionally persists descriptor metadata differently and some auth/storage exceptional envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::api_routes" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::least_privilege_role_cannot_create_apis_or_read_logs", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts", + "gateway-rs/tests/platform_native.rs::python_api_and_endpoint_crud_lookup_and_missing_contracts" + ], + "source": { + "kind": "async_function", + "line": 235, + "path": "backend-services/routes/api_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "api_router.get('/all', description='Get all APIs', response_model=list[ApiModelResponse])" + ], + "domain": "routes", + "id": "backend-services/routes/api_routes.py::async_function:get_all_apis", + "notes": "All API CRUD/list routes are implemented natively. Rust matches the pinned create/update-only manage_apis boundary (authenticated reads, listing, and deletion remain available without that permission), model validation, duplicate responses, pagination, immutable identity fields, public-credit exclusion, CRUD bodies, and missing-item status. The proto-upload-before-create path intentionally persists descriptor metadata differently and some auth/storage exceptional envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::api_routes" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::least_privilege_role_cannot_create_apis_or_read_logs", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts", + "gateway-rs/tests/platform_native.rs::python_api_and_endpoint_crud_lookup_and_missing_contracts" + ], + "source": { + "kind": "async_function", + "line": 283, + "path": "backend-services/routes/api_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "api_router.get('', description='Get all APIs (base path)', response_model=list[ApiModelResponse])" + ], + "domain": "routes", + "id": "backend-services/routes/api_routes.py::async_function:get_all_apis_base", + "notes": "All API CRUD/list routes are implemented natively. Rust matches the pinned create/update-only manage_apis boundary (authenticated reads, listing, and deletion remain available without that permission), model validation, duplicate responses, pagination, immutable identity fields, public-credit exclusion, CRUD bodies, and missing-item status. The proto-upload-before-create path intentionally persists descriptor metadata differently and some auth/storage exceptional envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::api_routes" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::least_privilege_role_cannot_create_apis_or_read_logs", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts", + "gateway-rs/tests/platform_native.rs::python_api_and_endpoint_crud_lookup_and_missing_contracts" + ], + "source": { + "kind": "async_function", + "line": 323, + "path": "backend-services/routes/api_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/authorization_routes.py::module:authorization_routes", + "notes": "Every route is mapped to native Rust. Login, registration, refresh-token claims/cookies, authentication-failure envelopes, and cookie deletion still have documented observable differences, so the module is not yet fully translated.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::login", + "gateway-rs/src/routes/platform.rs::register", + "gateway-rs/src/routes/platform.rs::authorization_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python", + "gateway-rs/tests/platform_native.rs::authorization_refresh_and_invalidate_match_python", + "gateway-rs/tests/platform_native.rs::authorization_admin_lifecycle_and_revoke_match_python" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/routes/authorization_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "authorization_router.post('/authorization', description='Create authorization token', response_model=ResponseModel, responses={200: {'description': 'Successful Response', 'content': {'application/json': {'example': {'access_token': '******************'}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/authorization_routes.py::async_function:authorization", + "notes": "Every route is mapped to native Rust. Login, registration, refresh-token claims/cookies, authentication-failure envelopes, and cookie deletion still have documented observable differences, so the module is not yet fully translated.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::login", + "gateway-rs/src/routes/platform.rs::register", + "gateway-rs/src/routes/platform.rs::authorization_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python", + "gateway-rs/tests/platform_native.rs::authorization_refresh_and_invalidate_match_python", + "gateway-rs/tests/platform_native.rs::authorization_admin_lifecycle_and_revoke_match_python" + ], + "source": { + "kind": "async_function", + "line": 57, + "path": "backend-services/routes/authorization_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "authorization_router.post('/authorization/register', description='Register new user', response_model=ResponseModel, responses={200: {'description': 'Successful Response', 'content': {'application/json': {'example': {'message': 'User created successfully'}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/authorization_routes.py::async_function:register", + "notes": "Every route is mapped to native Rust. Login, registration, refresh-token claims/cookies, authentication-failure envelopes, and cookie deletion still have documented observable differences, so the module is not yet fully translated.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::login", + "gateway-rs/src/routes/platform.rs::register", + "gateway-rs/src/routes/platform.rs::authorization_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python", + "gateway-rs/tests/platform_native.rs::authorization_refresh_and_invalidate_match_python", + "gateway-rs/tests/platform_native.rs::authorization_admin_lifecycle_and_revoke_match_python" + ], + "source": { + "kind": "async_function", + "line": 310, + "path": "backend-services/routes/authorization_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "authorization_router.post('/authorization/admin/revoke/{username}', description='Revoke all active tokens for a user (admin)', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/authorization_routes.py::async_function:admin_revoke_user_tokens", + "notes": "Every route is mapped to native Rust. Login, registration, refresh-token claims/cookies, authentication-failure envelopes, and cookie deletion still have documented observable differences, so the module is not yet fully translated.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::login", + "gateway-rs/src/routes/platform.rs::register", + "gateway-rs/src/routes/platform.rs::authorization_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python", + "gateway-rs/tests/platform_native.rs::authorization_refresh_and_invalidate_match_python", + "gateway-rs/tests/platform_native.rs::authorization_admin_lifecycle_and_revoke_match_python" + ], + "source": { + "kind": "async_function", + "line": 394, + "path": "backend-services/routes/authorization_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "authorization_router.post('/authorization/admin/unrevoke/{username}', description='Clear token revocation for a user (admin)', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/authorization_routes.py::async_function:admin_unrevoke_user_tokens", + "notes": "Every route is mapped to native Rust. Login, registration, refresh-token claims/cookies, authentication-failure envelopes, and cookie deletion still have documented observable differences, so the module is not yet fully translated.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::login", + "gateway-rs/src/routes/platform.rs::register", + "gateway-rs/src/routes/platform.rs::authorization_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python", + "gateway-rs/tests/platform_native.rs::authorization_refresh_and_invalidate_match_python", + "gateway-rs/tests/platform_native.rs::authorization_admin_lifecycle_and_revoke_match_python" + ], + "source": { + "kind": "async_function", + "line": 463, + "path": "backend-services/routes/authorization_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "authorization_router.post('/authorization/admin/disable/{username}', description='Disable a user (admin)', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/authorization_routes.py::async_function:admin_disable_user", + "notes": "Every route is mapped to native Rust. Login, registration, refresh-token claims/cookies, authentication-failure envelopes, and cookie deletion still have documented observable differences, so the module is not yet fully translated.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::login", + "gateway-rs/src/routes/platform.rs::register", + "gateway-rs/src/routes/platform.rs::authorization_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python", + "gateway-rs/tests/platform_native.rs::authorization_refresh_and_invalidate_match_python", + "gateway-rs/tests/platform_native.rs::authorization_admin_lifecycle_and_revoke_match_python" + ], + "source": { + "kind": "async_function", + "line": 532, + "path": "backend-services/routes/authorization_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "authorization_router.post('/authorization/admin/enable/{username}', description='Enable a user (admin)', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/authorization_routes.py::async_function:admin_enable_user", + "notes": "Every route is mapped to native Rust. Login, registration, refresh-token claims/cookies, authentication-failure envelopes, and cookie deletion still have documented observable differences, so the module is not yet fully translated.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::login", + "gateway-rs/src/routes/platform.rs::register", + "gateway-rs/src/routes/platform.rs::authorization_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python", + "gateway-rs/tests/platform_native.rs::authorization_refresh_and_invalidate_match_python", + "gateway-rs/tests/platform_native.rs::authorization_admin_lifecycle_and_revoke_match_python" + ], + "source": { + "kind": "async_function", + "line": 604, + "path": "backend-services/routes/authorization_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "authorization_router.get('/authorization/admin/status/{username}', description='Get auth status for a user (admin)', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/authorization_routes.py::async_function:admin_user_status", + "notes": "Every route is mapped to native Rust. Login, registration, refresh-token claims/cookies, authentication-failure envelopes, and cookie deletion still have documented observable differences, so the module is not yet fully translated.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::login", + "gateway-rs/src/routes/platform.rs::register", + "gateway-rs/src/routes/platform.rs::authorization_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python", + "gateway-rs/tests/platform_native.rs::authorization_refresh_and_invalidate_match_python", + "gateway-rs/tests/platform_native.rs::authorization_admin_lifecycle_and_revoke_match_python" + ], + "source": { + "kind": "async_function", + "line": 674, + "path": "backend-services/routes/authorization_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "authorization_router.post('/authorization/refresh', description='Create authorization refresh token', response_model=ResponseModel, responses={200: {'description': 'Successful Response', 'content': {'application/json': {'example': {'refresh_token': '******************'}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/authorization_routes.py::async_function:extended_authorization", + "notes": "Every route is mapped to native Rust. Login, registration, refresh-token claims/cookies, authentication-failure envelopes, and cookie deletion still have documented observable differences, so the module is not yet fully translated.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::login", + "gateway-rs/src/routes/platform.rs::register", + "gateway-rs/src/routes/platform.rs::authorization_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python", + "gateway-rs/tests/platform_native.rs::authorization_refresh_and_invalidate_match_python", + "gateway-rs/tests/platform_native.rs::authorization_admin_lifecycle_and_revoke_match_python" + ], + "source": { + "kind": "async_function", + "line": 748, + "path": "backend-services/routes/authorization_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "authorization_router.get('/authorization/status', description='Get authorization token status', response_model=ResponseModel, responses={200: {'description': 'Successful Response', 'content': {'application/json': {'example': {'status': 'authorized'}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/authorization_routes.py::async_function:authorization_status", + "notes": "Every route is mapped to native Rust. Login, registration, refresh-token claims/cookies, authentication-failure envelopes, and cookie deletion still have documented observable differences, so the module is not yet fully translated.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::login", + "gateway-rs/src/routes/platform.rs::register", + "gateway-rs/src/routes/platform.rs::authorization_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python", + "gateway-rs/tests/platform_native.rs::authorization_refresh_and_invalidate_match_python", + "gateway-rs/tests/platform_native.rs::authorization_admin_lifecycle_and_revoke_match_python" + ], + "source": { + "kind": "async_function", + "line": 911, + "path": "backend-services/routes/authorization_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "authorization_router.post('/authorization/invalidate', description='Invalidate authorization token', response_model=ResponseModel, responses={200: {'description': 'Successful Response', 'content': {'application/json': {'example': {'message': 'Your token has been invalidated'}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/authorization_routes.py::async_function:authorization_invalidate", + "notes": "Every route is mapped to native Rust. Login, registration, refresh-token claims/cookies, authentication-failure envelopes, and cookie deletion still have documented observable differences, so the module is not yet fully translated.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::login", + "gateway-rs/src/routes/platform.rs::register", + "gateway-rs/src/routes/platform.rs::authorization_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python", + "gateway-rs/tests/platform_native.rs::authorization_refresh_and_invalidate_match_python", + "gateway-rs/tests/platform_native.rs::authorization_admin_lifecycle_and_revoke_match_python" + ], + "source": { + "kind": "async_function", + "line": 984, + "path": "backend-services/routes/authorization_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/config_hot_reload_routes.py::module:config_hot_reload_routes", + "notes": "Rust intentionally returns useful current/reload/key data and applies supported gateway settings; Python's ResponseModel silently discarded the undeclared data field and emitted empty success bodies.", + "rationale": "v2 fixes the pinned hot-reload response bug and explicitly distinguishes live-applied keys from restart-required settings.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::config_current", + "gateway-rs/src/hot_reload.rs::HotReloadConfig" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::config_reload_routes_preserve_legacy_values_metadata_and_permissions" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/routes/config_hot_reload_routes.py" + }, + "status": "approved_changed" + }, + { + "decorators": [ + "config_hot_reload_router.get('/current', summary='Get Current Configuration', description='Retrieve current hot-reloadable configuration values', response_model=dict[str, Any])" + ], + "domain": "routes", + "id": "backend-services/routes/config_hot_reload_routes.py::async_function:get_current_config", + "notes": "Rust intentionally returns useful current/reload/key data and applies supported gateway settings; Python's ResponseModel silently discarded the undeclared data field and emitted empty success bodies.", + "rationale": "v2 fixes the pinned hot-reload response bug and explicitly distinguishes live-applied keys from restart-required settings.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::config_current", + "gateway-rs/src/hot_reload.rs::HotReloadConfig" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::config_reload_routes_preserve_legacy_values_metadata_and_permissions" + ], + "source": { + "kind": "async_function", + "line": 27, + "path": "backend-services/routes/config_hot_reload_routes.py" + }, + "status": "approved_changed" + }, + { + "decorators": [ + "config_hot_reload_router.post('/reload', summary='Trigger Configuration Reload', description='Manually trigger configuration reload (same as SIGHUP)', response_model=dict[str, Any])" + ], + "domain": "routes", + "id": "backend-services/routes/config_hot_reload_routes.py::async_function:trigger_config_reload", + "notes": "Rust intentionally returns useful current/reload/key data and applies supported gateway settings; Python's ResponseModel silently discarded the undeclared data field and emitted empty success bodies.", + "rationale": "v2 fixes the pinned hot-reload response bug and explicitly distinguishes live-applied keys from restart-required settings.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::config_current", + "gateway-rs/src/hot_reload.rs::HotReloadConfig" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::config_reload_routes_preserve_legacy_values_metadata_and_permissions" + ], + "source": { + "kind": "async_function", + "line": 62, + "path": "backend-services/routes/config_hot_reload_routes.py" + }, + "status": "approved_changed" + }, + { + "decorators": [ + "config_hot_reload_router.get('/reloadable-keys', summary='List Reloadable Configuration Keys', description='Get list of configuration keys that support hot reload', response_model=dict[str, Any])" + ], + "domain": "routes", + "id": "backend-services/routes/config_hot_reload_routes.py::async_function:get_reloadable_keys", + "notes": "Rust intentionally returns useful current/reload/key data and applies supported gateway settings; Python's ResponseModel silently discarded the undeclared data field and emitted empty success bodies.", + "rationale": "v2 fixes the pinned hot-reload response bug and explicitly distinguishes live-applied keys from restart-required settings.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::config_current", + "gateway-rs/src/hot_reload.rs::HotReloadConfig" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::config_reload_routes_preserve_legacy_values_metadata_and_permissions" + ], + "source": { + "kind": "async_function", + "line": 93, + "path": "backend-services/routes/config_hot_reload_routes.py" + }, + "status": "approved_changed" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/config_routes.py::module:config_routes", + "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are implemented natively. Rust now matches granular export/import permission codes, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, malformed-entry handling, snapshots, and the pinned rollback error/success envelopes. Storage transactions are intentionally stronger than Python's sequential writes, and exact datetime representation plus every partial-write failure mode are not 1:1.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::config_export", + "gateway-rs/src/routes/platform.rs::config_import", + "gateway-rs/src/routes/platform.rs::config_rollback", + "gateway-rs/src/storage/runtime.rs::SharedStorage.import_configuration_atomically" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_config_export_sections_and_import_variants", + "gateway-rs/tests/platform_native.rs::python_config_permissions_granular_export_and_gateway_import_contracts", + "gateway-rs/tests/platform_native.rs::config_export_missing_named_resources_return_python_404", + "gateway-rs/tests/platform_native.rs::config_rollback_preserves_python_permission_and_missing_snapshot_quirks", + "gateway-rs/tests/platform_native.rs::python_config_import_ignores_malformed_entries", + "gateway-rs/tests/platform_native.rs::memory_mode_login_crud_import_and_rollback_are_native" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/routes/config_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/config_routes.py::function:_strip_id", + "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are implemented natively. Rust now matches granular export/import permission codes, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, malformed-entry handling, snapshots, and the pinned rollback error/success envelopes. Storage transactions are intentionally stronger than Python's sequential writes, and exact datetime representation plus every partial-write failure mode are not 1:1.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::config_export", + "gateway-rs/src/routes/platform.rs::config_import", + "gateway-rs/src/routes/platform.rs::config_rollback", + "gateway-rs/src/storage/runtime.rs::SharedStorage.import_configuration_atomically" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_config_export_sections_and_import_variants", + "gateway-rs/tests/platform_native.rs::python_config_permissions_granular_export_and_gateway_import_contracts", + "gateway-rs/tests/platform_native.rs::config_export_missing_named_resources_return_python_404", + "gateway-rs/tests/platform_native.rs::config_rollback_preserves_python_permission_and_missing_snapshot_quirks", + "gateway-rs/tests/platform_native.rs::python_config_import_ignores_malformed_entries", + "gateway-rs/tests/platform_native.rs::memory_mode_login_crud_import_and_rollback_are_native" + ], + "source": { + "kind": "function", + "line": 42, + "path": "backend-services/routes/config_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/config_routes.py::async_function:_export_all", + "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are implemented natively. Rust now matches granular export/import permission codes, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, malformed-entry handling, snapshots, and the pinned rollback error/success envelopes. Storage transactions are intentionally stronger than Python's sequential writes, and exact datetime representation plus every partial-write failure mode are not 1:1.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::config_export", + "gateway-rs/src/routes/platform.rs::config_import", + "gateway-rs/src/routes/platform.rs::config_rollback", + "gateway-rs/src/storage/runtime.rs::SharedStorage.import_configuration_atomically" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_config_export_sections_and_import_variants", + "gateway-rs/tests/platform_native.rs::python_config_permissions_granular_export_and_gateway_import_contracts", + "gateway-rs/tests/platform_native.rs::config_export_missing_named_resources_return_python_404", + "gateway-rs/tests/platform_native.rs::config_rollback_preserves_python_permission_and_missing_snapshot_quirks", + "gateway-rs/tests/platform_native.rs::python_config_import_ignores_malformed_entries", + "gateway-rs/tests/platform_native.rs::memory_mode_login_crud_import_and_rollback_are_native" + ], + "source": { + "kind": "async_function", + "line": 48, + "path": "backend-services/routes/config_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/config_routes.py::async_function:_create_snapshot", + "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are implemented natively. Rust now matches granular export/import permission codes, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, malformed-entry handling, snapshots, and the pinned rollback error/success envelopes. Storage transactions are intentionally stronger than Python's sequential writes, and exact datetime representation plus every partial-write failure mode are not 1:1.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::config_export", + "gateway-rs/src/routes/platform.rs::config_import", + "gateway-rs/src/routes/platform.rs::config_rollback", + "gateway-rs/src/storage/runtime.rs::SharedStorage.import_configuration_atomically" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_config_export_sections_and_import_variants", + "gateway-rs/tests/platform_native.rs::python_config_permissions_granular_export_and_gateway_import_contracts", + "gateway-rs/tests/platform_native.rs::config_export_missing_named_resources_return_python_404", + "gateway-rs/tests/platform_native.rs::config_rollback_preserves_python_permission_and_missing_snapshot_quirks", + "gateway-rs/tests/platform_native.rs::python_config_import_ignores_malformed_entries", + "gateway-rs/tests/platform_native.rs::memory_mode_login_crud_import_and_rollback_are_native" + ], + "source": { + "kind": "async_function", + "line": 64, + "path": "backend-services/routes/config_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/config_routes.py::async_function:_restore_snapshot", + "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are implemented natively. Rust now matches granular export/import permission codes, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, malformed-entry handling, snapshots, and the pinned rollback error/success envelopes. Storage transactions are intentionally stronger than Python's sequential writes, and exact datetime representation plus every partial-write failure mode are not 1:1.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::config_export", + "gateway-rs/src/routes/platform.rs::config_import", + "gateway-rs/src/routes/platform.rs::config_rollback", + "gateway-rs/src/storage/runtime.rs::SharedStorage.import_configuration_atomically" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_config_export_sections_and_import_variants", + "gateway-rs/tests/platform_native.rs::python_config_permissions_granular_export_and_gateway_import_contracts", + "gateway-rs/tests/platform_native.rs::config_export_missing_named_resources_return_python_404", + "gateway-rs/tests/platform_native.rs::config_rollback_preserves_python_permission_and_missing_snapshot_quirks", + "gateway-rs/tests/platform_native.rs::python_config_import_ignores_malformed_entries", + "gateway-rs/tests/platform_native.rs::memory_mode_login_crud_import_and_rollback_are_native" + ], + "source": { + "kind": "async_function", + "line": 85, + "path": "backend-services/routes/config_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "config_router.get('/config/export/all', description='Export all platform configuration (APIs, Endpoints, Roles, Groups, Routings)', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/config_routes.py::async_function:export_all", + "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are implemented natively. Rust now matches granular export/import permission codes, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, malformed-entry handling, snapshots, and the pinned rollback error/success envelopes. Storage transactions are intentionally stronger than Python's sequential writes, and exact datetime representation plus every partial-write failure mode are not 1:1.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::config_export", + "gateway-rs/src/routes/platform.rs::config_import", + "gateway-rs/src/routes/platform.rs::config_rollback", + "gateway-rs/src/storage/runtime.rs::SharedStorage.import_configuration_atomically" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_config_export_sections_and_import_variants", + "gateway-rs/tests/platform_native.rs::python_config_permissions_granular_export_and_gateway_import_contracts", + "gateway-rs/tests/platform_native.rs::config_export_missing_named_resources_return_python_404", + "gateway-rs/tests/platform_native.rs::config_rollback_preserves_python_permission_and_missing_snapshot_quirks", + "gateway-rs/tests/platform_native.rs::python_config_import_ignores_malformed_entries", + "gateway-rs/tests/platform_native.rs::memory_mode_login_crud_import_and_rollback_are_native" + ], + "source": { + "kind": "async_function", + "line": 159, + "path": "backend-services/routes/config_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "config_router.get('/config/export/apis', description='Export APIs (optionally a single API with its endpoints)', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/config_routes.py::async_function:export_apis", + "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are implemented natively. Rust now matches granular export/import permission codes, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, malformed-entry handling, snapshots, and the pinned rollback error/success envelopes. Storage transactions are intentionally stronger than Python's sequential writes, and exact datetime representation plus every partial-write failure mode are not 1:1.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::config_export", + "gateway-rs/src/routes/platform.rs::config_import", + "gateway-rs/src/routes/platform.rs::config_rollback", + "gateway-rs/src/storage/runtime.rs::SharedStorage.import_configuration_atomically" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_config_export_sections_and_import_variants", + "gateway-rs/tests/platform_native.rs::python_config_permissions_granular_export_and_gateway_import_contracts", + "gateway-rs/tests/platform_native.rs::config_export_missing_named_resources_return_python_404", + "gateway-rs/tests/platform_native.rs::config_rollback_preserves_python_permission_and_missing_snapshot_quirks", + "gateway-rs/tests/platform_native.rs::python_config_import_ignores_malformed_entries", + "gateway-rs/tests/platform_native.rs::memory_mode_login_crud_import_and_rollback_are_native" + ], + "source": { + "kind": "async_function", + "line": 217, + "path": "backend-services/routes/config_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "config_router.get('/config/export/roles', description='Export Roles', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/config_routes.py::async_function:export_roles", + "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are implemented natively. Rust now matches granular export/import permission codes, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, malformed-entry handling, snapshots, and the pinned rollback error/success envelopes. Storage transactions are intentionally stronger than Python's sequential writes, and exact datetime representation plus every partial-write failure mode are not 1:1.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::config_export", + "gateway-rs/src/routes/platform.rs::config_import", + "gateway-rs/src/routes/platform.rs::config_rollback", + "gateway-rs/src/storage/runtime.rs::SharedStorage.import_configuration_atomically" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_config_export_sections_and_import_variants", + "gateway-rs/tests/platform_native.rs::python_config_permissions_granular_export_and_gateway_import_contracts", + "gateway-rs/tests/platform_native.rs::config_export_missing_named_resources_return_python_404", + "gateway-rs/tests/platform_native.rs::config_rollback_preserves_python_permission_and_missing_snapshot_quirks", + "gateway-rs/tests/platform_native.rs::python_config_import_ignores_malformed_entries", + "gateway-rs/tests/platform_native.rs::memory_mode_login_crud_import_and_rollback_are_native" + ], + "source": { + "kind": "async_function", + "line": 299, + "path": "backend-services/routes/config_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "config_router.get('/config/export/groups', description='Export Groups', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/config_routes.py::async_function:export_groups", + "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are implemented natively. Rust now matches granular export/import permission codes, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, malformed-entry handling, snapshots, and the pinned rollback error/success envelopes. Storage transactions are intentionally stronger than Python's sequential writes, and exact datetime representation plus every partial-write failure mode are not 1:1.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::config_export", + "gateway-rs/src/routes/platform.rs::config_import", + "gateway-rs/src/routes/platform.rs::config_rollback", + "gateway-rs/src/storage/runtime.rs::SharedStorage.import_configuration_atomically" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_config_export_sections_and_import_variants", + "gateway-rs/tests/platform_native.rs::python_config_permissions_granular_export_and_gateway_import_contracts", + "gateway-rs/tests/platform_native.rs::config_export_missing_named_resources_return_python_404", + "gateway-rs/tests/platform_native.rs::config_rollback_preserves_python_permission_and_missing_snapshot_quirks", + "gateway-rs/tests/platform_native.rs::python_config_import_ignores_malformed_entries", + "gateway-rs/tests/platform_native.rs::memory_mode_login_crud_import_and_rollback_are_native" + ], + "source": { + "kind": "async_function", + "line": 370, + "path": "backend-services/routes/config_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "config_router.get('/config/export/routings', description='Export Routings', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/config_routes.py::async_function:export_routings", + "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are implemented natively. Rust now matches granular export/import permission codes, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, malformed-entry handling, snapshots, and the pinned rollback error/success envelopes. Storage transactions are intentionally stronger than Python's sequential writes, and exact datetime representation plus every partial-write failure mode are not 1:1.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::config_export", + "gateway-rs/src/routes/platform.rs::config_import", + "gateway-rs/src/routes/platform.rs::config_rollback", + "gateway-rs/src/storage/runtime.rs::SharedStorage.import_configuration_atomically" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_config_export_sections_and_import_variants", + "gateway-rs/tests/platform_native.rs::python_config_permissions_granular_export_and_gateway_import_contracts", + "gateway-rs/tests/platform_native.rs::config_export_missing_named_resources_return_python_404", + "gateway-rs/tests/platform_native.rs::config_rollback_preserves_python_permission_and_missing_snapshot_quirks", + "gateway-rs/tests/platform_native.rs::python_config_import_ignores_malformed_entries", + "gateway-rs/tests/platform_native.rs::memory_mode_login_crud_import_and_rollback_are_native" + ], + "source": { + "kind": "async_function", + "line": 441, + "path": "backend-services/routes/config_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "config_router.get('/config/export/endpoints', description='Export endpoints (optionally filter by api_name/api_version)', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/config_routes.py::async_function:export_endpoints", + "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are implemented natively. Rust now matches granular export/import permission codes, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, malformed-entry handling, snapshots, and the pinned rollback error/success envelopes. Storage transactions are intentionally stronger than Python's sequential writes, and exact datetime representation plus every partial-write failure mode are not 1:1.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::config_export", + "gateway-rs/src/routes/platform.rs::config_import", + "gateway-rs/src/routes/platform.rs::config_rollback", + "gateway-rs/src/storage/runtime.rs::SharedStorage.import_configuration_atomically" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_config_export_sections_and_import_variants", + "gateway-rs/tests/platform_native.rs::python_config_permissions_granular_export_and_gateway_import_contracts", + "gateway-rs/tests/platform_native.rs::config_export_missing_named_resources_return_python_404", + "gateway-rs/tests/platform_native.rs::config_rollback_preserves_python_permission_and_missing_snapshot_quirks", + "gateway-rs/tests/platform_native.rs::python_config_import_ignores_malformed_entries", + "gateway-rs/tests/platform_native.rs::memory_mode_login_crud_import_and_rollback_are_native" + ], + "source": { + "kind": "async_function", + "line": 515, + "path": "backend-services/routes/config_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/config_routes.py::async_function:_upsert_api", + "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are implemented natively. Rust now matches granular export/import permission codes, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, malformed-entry handling, snapshots, and the pinned rollback error/success envelopes. Storage transactions are intentionally stronger than Python's sequential writes, and exact datetime representation plus every partial-write failure mode are not 1:1.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::config_export", + "gateway-rs/src/routes/platform.rs::config_import", + "gateway-rs/src/routes/platform.rs::config_rollback", + "gateway-rs/src/storage/runtime.rs::SharedStorage.import_configuration_atomically" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_config_export_sections_and_import_variants", + "gateway-rs/tests/platform_native.rs::python_config_permissions_granular_export_and_gateway_import_contracts", + "gateway-rs/tests/platform_native.rs::config_export_missing_named_resources_return_python_404", + "gateway-rs/tests/platform_native.rs::config_rollback_preserves_python_permission_and_missing_snapshot_quirks", + "gateway-rs/tests/platform_native.rs::python_config_import_ignores_malformed_entries", + "gateway-rs/tests/platform_native.rs::memory_mode_login_crud_import_and_rollback_are_native" + ], + "source": { + "kind": "async_function", + "line": 551, + "path": "backend-services/routes/config_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/config_routes.py::async_function:_upsert_endpoint", + "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are implemented natively. Rust now matches granular export/import permission codes, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, malformed-entry handling, snapshots, and the pinned rollback error/success envelopes. Storage transactions are intentionally stronger than Python's sequential writes, and exact datetime representation plus every partial-write failure mode are not 1:1.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::config_export", + "gateway-rs/src/routes/platform.rs::config_import", + "gateway-rs/src/routes/platform.rs::config_rollback", + "gateway-rs/src/storage/runtime.rs::SharedStorage.import_configuration_atomically" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_config_export_sections_and_import_variants", + "gateway-rs/tests/platform_native.rs::python_config_permissions_granular_export_and_gateway_import_contracts", + "gateway-rs/tests/platform_native.rs::config_export_missing_named_resources_return_python_404", + "gateway-rs/tests/platform_native.rs::config_rollback_preserves_python_permission_and_missing_snapshot_quirks", + "gateway-rs/tests/platform_native.rs::python_config_import_ignores_malformed_entries", + "gateway-rs/tests/platform_native.rs::memory_mode_login_crud_import_and_rollback_are_native" + ], + "source": { + "kind": "async_function", + "line": 573, + "path": "backend-services/routes/config_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/config_routes.py::async_function:_upsert_role", + "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are implemented natively. Rust now matches granular export/import permission codes, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, malformed-entry handling, snapshots, and the pinned rollback error/success envelopes. Storage transactions are intentionally stronger than Python's sequential writes, and exact datetime representation plus every partial-write failure mode are not 1:1.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::config_export", + "gateway-rs/src/routes/platform.rs::config_import", + "gateway-rs/src/routes/platform.rs::config_rollback", + "gateway-rs/src/storage/runtime.rs::SharedStorage.import_configuration_atomically" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_config_export_sections_and_import_variants", + "gateway-rs/tests/platform_native.rs::python_config_permissions_granular_export_and_gateway_import_contracts", + "gateway-rs/tests/platform_native.rs::config_export_missing_named_resources_return_python_404", + "gateway-rs/tests/platform_native.rs::config_rollback_preserves_python_permission_and_missing_snapshot_quirks", + "gateway-rs/tests/platform_native.rs::python_config_import_ignores_malformed_entries", + "gateway-rs/tests/platform_native.rs::memory_mode_login_crud_import_and_rollback_are_native" + ], + "source": { + "kind": "async_function", + "line": 610, + "path": "backend-services/routes/config_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/config_routes.py::async_function:_upsert_group", + "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are implemented natively. Rust now matches granular export/import permission codes, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, malformed-entry handling, snapshots, and the pinned rollback error/success envelopes. Storage transactions are intentionally stronger than Python's sequential writes, and exact datetime representation plus every partial-write failure mode are not 1:1.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::config_export", + "gateway-rs/src/routes/platform.rs::config_import", + "gateway-rs/src/routes/platform.rs::config_rollback", + "gateway-rs/src/storage/runtime.rs::SharedStorage.import_configuration_atomically" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_config_export_sections_and_import_variants", + "gateway-rs/tests/platform_native.rs::python_config_permissions_granular_export_and_gateway_import_contracts", + "gateway-rs/tests/platform_native.rs::config_export_missing_named_resources_return_python_404", + "gateway-rs/tests/platform_native.rs::config_rollback_preserves_python_permission_and_missing_snapshot_quirks", + "gateway-rs/tests/platform_native.rs::python_config_import_ignores_malformed_entries", + "gateway-rs/tests/platform_native.rs::memory_mode_login_crud_import_and_rollback_are_native" + ], + "source": { + "kind": "async_function", + "line": 622, + "path": "backend-services/routes/config_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/config_routes.py::async_function:_upsert_routing", + "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are implemented natively. Rust now matches granular export/import permission codes, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, malformed-entry handling, snapshots, and the pinned rollback error/success envelopes. Storage transactions are intentionally stronger than Python's sequential writes, and exact datetime representation plus every partial-write failure mode are not 1:1.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::config_export", + "gateway-rs/src/routes/platform.rs::config_import", + "gateway-rs/src/routes/platform.rs::config_rollback", + "gateway-rs/src/storage/runtime.rs::SharedStorage.import_configuration_atomically" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_config_export_sections_and_import_variants", + "gateway-rs/tests/platform_native.rs::python_config_permissions_granular_export_and_gateway_import_contracts", + "gateway-rs/tests/platform_native.rs::config_export_missing_named_resources_return_python_404", + "gateway-rs/tests/platform_native.rs::config_rollback_preserves_python_permission_and_missing_snapshot_quirks", + "gateway-rs/tests/platform_native.rs::python_config_import_ignores_malformed_entries", + "gateway-rs/tests/platform_native.rs::memory_mode_login_crud_import_and_rollback_are_native" + ], + "source": { + "kind": "async_function", + "line": 634, + "path": "backend-services/routes/config_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "config_router.post('/config/import', description='Import platform configuration (any subset of apis, endpoints, roles, groups, routings)', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/config_routes.py::async_function:import_all", + "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are implemented natively. Rust now matches granular export/import permission codes, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, malformed-entry handling, snapshots, and the pinned rollback error/success envelopes. Storage transactions are intentionally stronger than Python's sequential writes, and exact datetime representation plus every partial-write failure mode are not 1:1.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::config_export", + "gateway-rs/src/routes/platform.rs::config_import", + "gateway-rs/src/routes/platform.rs::config_rollback", + "gateway-rs/src/storage/runtime.rs::SharedStorage.import_configuration_atomically" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_config_export_sections_and_import_variants", + "gateway-rs/tests/platform_native.rs::python_config_permissions_granular_export_and_gateway_import_contracts", + "gateway-rs/tests/platform_native.rs::config_export_missing_named_resources_return_python_404", + "gateway-rs/tests/platform_native.rs::config_rollback_preserves_python_permission_and_missing_snapshot_quirks", + "gateway-rs/tests/platform_native.rs::python_config_import_ignores_malformed_entries", + "gateway-rs/tests/platform_native.rs::memory_mode_login_crud_import_and_rollback_are_native" + ], + "source": { + "kind": "async_function", + "line": 661, + "path": "backend-services/routes/config_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "config_router.post('/config/rollback', description='Rollback configuration to latest snapshot', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/config_routes.py::async_function:rollback_config", + "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are implemented natively. Rust now matches granular export/import permission codes, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, malformed-entry handling, snapshots, and the pinned rollback error/success envelopes. Storage transactions are intentionally stronger than Python's sequential writes, and exact datetime representation plus every partial-write failure mode are not 1:1.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::config_export", + "gateway-rs/src/routes/platform.rs::config_import", + "gateway-rs/src/routes/platform.rs::config_rollback", + "gateway-rs/src/storage/runtime.rs::SharedStorage.import_configuration_atomically" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_config_export_sections_and_import_variants", + "gateway-rs/tests/platform_native.rs::python_config_permissions_granular_export_and_gateway_import_contracts", + "gateway-rs/tests/platform_native.rs::config_export_missing_named_resources_return_python_404", + "gateway-rs/tests/platform_native.rs::config_rollback_preserves_python_permission_and_missing_snapshot_quirks", + "gateway-rs/tests/platform_native.rs::python_config_import_ignores_malformed_entries", + "gateway-rs/tests/platform_native.rs::memory_mode_login_crud_import_and_rollback_are_native" + ], + "source": { + "kind": "async_function", + "line": 731, + "path": "backend-services/routes/config_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/credit_routes.py::module:credit_routes", + "notes": "All credit-definition, user-credit, retrieval, and key-rotation routes are mapped to native Rust. Definition management now matches manage_credits gates, masked response fields, default paginated list shape, CRD021 misses, typed models, CRUD errors, and user-credit retrieval permissions. Exact query pagination/search, the Python path-username shadowing bug, encrypted key rotation/creation semantics, and some database-specific error envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::credit_routes", + "gateway-rs/src/routes/platform.rs::normalize_credit_model", + "gateway-rs/src/routes/platform.rs::normalize_user_credit_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_credit_definition_masks_secret_key_material", + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision", + "gateway-rs/tests/platform_native.rs::limited_role_cannot_manage_monitor_credits_caches_or_endpoint_validation" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/routes/credit_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "credit_router.get('/defs', description='List credit definitions', response_model=ResponseModel, responses={200: {'description': 'Successful Response'}})" + ], + "domain": "routes", + "id": "backend-services/routes/credit_routes.py::async_function:list_credit_definitions", + "notes": "All credit-definition, user-credit, retrieval, and key-rotation routes are mapped to native Rust. Definition management now matches manage_credits gates, masked response fields, default paginated list shape, CRD021 misses, typed models, CRUD errors, and user-credit retrieval permissions. Exact query pagination/search, the Python path-username shadowing bug, encrypted key rotation/creation semantics, and some database-specific error envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::credit_routes", + "gateway-rs/src/routes/platform.rs::normalize_credit_model", + "gateway-rs/src/routes/platform.rs::normalize_user_credit_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_credit_definition_masks_secret_key_material", + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision", + "gateway-rs/tests/platform_native.rs::limited_role_cannot_manage_monitor_credits_caches_or_endpoint_validation" + ], + "source": { + "kind": "async_function", + "line": 42, + "path": "backend-services/routes/credit_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "credit_router.get('/defs/{api_credit_group}', description='Get a credit definition', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/credit_routes.py::async_function:get_credit_definition", + "notes": "All credit-definition, user-credit, retrieval, and key-rotation routes are mapped to native Rust. Definition management now matches manage_credits gates, masked response fields, default paginated list shape, CRD021 misses, typed models, CRUD errors, and user-credit retrieval permissions. Exact query pagination/search, the Python path-username shadowing bug, encrypted key rotation/creation semantics, and some database-specific error envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::credit_routes", + "gateway-rs/src/routes/platform.rs::normalize_credit_model", + "gateway-rs/src/routes/platform.rs::normalize_user_credit_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_credit_definition_masks_secret_key_material", + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision", + "gateway-rs/tests/platform_native.rs::limited_role_cannot_manage_monitor_credits_caches_or_endpoint_validation" + ], + "source": { + "kind": "async_function", + "line": 102, + "path": "backend-services/routes/credit_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "credit_router.post('', description='Create a credit definition', response_model=ResponseModel, responses={201: {'description': 'Successful Response', 'content': {'application/json': {'example': {'message': 'Credit definition created successfully'}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/credit_routes.py::async_function:create_credit", + "notes": "All credit-definition, user-credit, retrieval, and key-rotation routes are mapped to native Rust. Definition management now matches manage_credits gates, masked response fields, default paginated list shape, CRD021 misses, typed models, CRUD errors, and user-credit retrieval permissions. Exact query pagination/search, the Python path-username shadowing bug, encrypted key rotation/creation semantics, and some database-specific error envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::credit_routes", + "gateway-rs/src/routes/platform.rs::normalize_credit_model", + "gateway-rs/src/routes/platform.rs::normalize_user_credit_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_credit_definition_masks_secret_key_material", + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision", + "gateway-rs/tests/platform_native.rs::limited_role_cannot_manage_monitor_credits_caches_or_endpoint_validation" + ], + "source": { + "kind": "async_function", + "line": 160, + "path": "backend-services/routes/credit_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "credit_router.put('/{api_credit_group}', description='Update a credit definition', response_model=ResponseModel, responses={200: {'description': 'Successful Response', 'content': {'application/json': {'example': {'message': 'Credit definition updated successfully'}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/credit_routes.py::async_function:update_credit", + "notes": "All credit-definition, user-credit, retrieval, and key-rotation routes are mapped to native Rust. Definition management now matches manage_credits gates, masked response fields, default paginated list shape, CRD021 misses, typed models, CRUD errors, and user-credit retrieval permissions. Exact query pagination/search, the Python path-username shadowing bug, encrypted key rotation/creation semantics, and some database-specific error envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::credit_routes", + "gateway-rs/src/routes/platform.rs::normalize_credit_model", + "gateway-rs/src/routes/platform.rs::normalize_user_credit_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_credit_definition_masks_secret_key_material", + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision", + "gateway-rs/tests/platform_native.rs::limited_role_cannot_manage_monitor_credits_caches_or_endpoint_validation" + ], + "source": { + "kind": "async_function", + "line": 230, + "path": "backend-services/routes/credit_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "credit_router.delete('/{api_credit_group}', description='Delete a credit definition', response_model=ResponseModel, responses={200: {'description': 'Successful Response', 'content': {'application/json': {'example': {'message': 'Credit definition deleted successfully'}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/credit_routes.py::async_function:delete_credit", + "notes": "All credit-definition, user-credit, retrieval, and key-rotation routes are mapped to native Rust. Definition management now matches manage_credits gates, masked response fields, default paginated list shape, CRD021 misses, typed models, CRUD errors, and user-credit retrieval permissions. Exact query pagination/search, the Python path-username shadowing bug, encrypted key rotation/creation semantics, and some database-specific error envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::credit_routes", + "gateway-rs/src/routes/platform.rs::normalize_credit_model", + "gateway-rs/src/routes/platform.rs::normalize_user_credit_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_credit_definition_masks_secret_key_material", + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision", + "gateway-rs/tests/platform_native.rs::limited_role_cannot_manage_monitor_credits_caches_or_endpoint_validation" + ], + "source": { + "kind": "async_function", + "line": 300, + "path": "backend-services/routes/credit_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "credit_router.post('/{username}', description='Add credits for a user', response_model=ResponseModel, responses={200: {'description': 'Successful Response', 'content': {'application/json': {'example': {'message': 'Credits saved successfully'}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/credit_routes.py::async_function:add_user_credits", + "notes": "All credit-definition, user-credit, retrieval, and key-rotation routes are mapped to native Rust. Definition management now matches manage_credits gates, masked response fields, default paginated list shape, CRD021 misses, typed models, CRUD errors, and user-credit retrieval permissions. Exact query pagination/search, the Python path-username shadowing bug, encrypted key rotation/creation semantics, and some database-specific error envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::credit_routes", + "gateway-rs/src/routes/platform.rs::normalize_credit_model", + "gateway-rs/src/routes/platform.rs::normalize_user_credit_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_credit_definition_masks_secret_key_material", + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision", + "gateway-rs/tests/platform_native.rs::limited_role_cannot_manage_monitor_credits_caches_or_endpoint_validation" + ], + "source": { + "kind": "async_function", + "line": 366, + "path": "backend-services/routes/credit_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "credit_router.get('/all', description='Get all user credits', response_model=list[UserCreditModel])" + ], + "domain": "routes", + "id": "backend-services/routes/credit_routes.py::async_function:get_all_users_credits", + "notes": "All credit-definition, user-credit, retrieval, and key-rotation routes are mapped to native Rust. Definition management now matches manage_credits gates, masked response fields, default paginated list shape, CRD021 misses, typed models, CRUD errors, and user-credit retrieval permissions. Exact query pagination/search, the Python path-username shadowing bug, encrypted key rotation/creation semantics, and some database-specific error envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::credit_routes", + "gateway-rs/src/routes/platform.rs::normalize_credit_model", + "gateway-rs/src/routes/platform.rs::normalize_user_credit_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_credit_definition_masks_secret_key_material", + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision", + "gateway-rs/tests/platform_native.rs::limited_role_cannot_manage_monitor_credits_caches_or_endpoint_validation" + ], + "source": { + "kind": "async_function", + "line": 422, + "path": "backend-services/routes/credit_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "credit_router.get('/{username}', description='Get credits for a user', response_model=UserCreditModel)" + ], + "domain": "routes", + "id": "backend-services/routes/credit_routes.py::async_function:get_credits", + "notes": "All credit-definition, user-credit, retrieval, and key-rotation routes are mapped to native Rust. Definition management now matches manage_credits gates, masked response fields, default paginated list shape, CRD021 misses, typed models, CRUD errors, and user-credit retrieval permissions. Exact query pagination/search, the Python path-username shadowing bug, encrypted key rotation/creation semantics, and some database-specific error envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::credit_routes", + "gateway-rs/src/routes/platform.rs::normalize_credit_model", + "gateway-rs/src/routes/platform.rs::normalize_user_credit_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_credit_definition_masks_secret_key_material", + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision", + "gateway-rs/tests/platform_native.rs::limited_role_cannot_manage_monitor_credits_caches_or_endpoint_validation" + ], + "source": { + "kind": "async_function", + "line": 474, + "path": "backend-services/routes/credit_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "credit_router.post('/rotate-key', description='Rotate API key for the authenticated user', response_model=ResponseModel, responses={200: {'description': 'Successful Response', 'content': {'application/json': {'example': {'api_key': '******************'}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/credit_routes.py::async_function:rotate_key", + "notes": "All credit-definition, user-credit, retrieval, and key-rotation routes are mapped to native Rust. Definition management now matches manage_credits gates, masked response fields, default paginated list shape, CRD021 misses, typed models, CRUD errors, and user-credit retrieval permissions. Exact query pagination/search, the Python path-username shadowing bug, encrypted key rotation/creation semantics, and some database-specific error envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::credit_routes", + "gateway-rs/src/routes/platform.rs::normalize_credit_model", + "gateway-rs/src/routes/platform.rs::normalize_user_credit_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_credit_definition_masks_secret_key_material", + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision", + "gateway-rs/tests/platform_native.rs::limited_role_cannot_manage_monitor_credits_caches_or_endpoint_validation" + ], + "source": { + "kind": "async_function", + "line": 528, + "path": "backend-services/routes/credit_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/dashboard_routes.py::module:dashboard_routes", + "notes": "Rust returns the pinned dashboard totals, monthly usage, active users, popular APIs, and response shape from native storage and analytics.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::dashboard" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::monitor_dashboard_liveness_readiness_and_metrics_parity" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/routes/dashboard_routes.py" + }, + "status": "translated" + }, + { + "decorators": [ + "dashboard_router.get('', description='Get dashboard data', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/dashboard_routes.py::async_function:get_dashboard_data", + "notes": "Rust returns the pinned dashboard totals, monthly usage, active users, popular APIs, and response shape from native storage and analytics.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::dashboard" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::monitor_dashboard_liveness_readiness_and_metrics_parity" + ], + "source": { + "kind": "async_function", + "line": 34, + "path": "backend-services/routes/dashboard_routes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/demo_routes.py::module:demo_routes", + "notes": "Rust preserves admin-only demo seeding and error envelopes but currently seeds only three API/endpoint examples; Python supports configurable bulk users, APIs, endpoints, groups, protos, logs, and deterministic seeds.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::demo_seed" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/routes/demo_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "demo_router.post('/seed', description='Seed the running server with demo data', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/demo_routes.py::async_function:demo_seed", + "notes": "Rust preserves admin-only demo seeding and error envelopes but currently seeds only three API/endpoint examples; Python supports configurable bulk users, APIs, endpoints, groups, protos, logs, and deterministic seeds.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::demo_seed" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract" + ], + "source": { + "kind": "async_function", + "line": 34, + "path": "backend-services/routes/demo_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/endpoint_routes.py::module:endpoint_routes", + "notes": "All endpoint CRUD, listing, validation, and validation-alias routes are mapped to native Rust. Core endpoints match typed-model validation, create/update/delete permissions and route-specific denial codes, authenticated reads/listing, missing-item/list errors, immutable identity checks, duplicate/client-URI checks, and CRUD responses. Endpoint-validation service error semantics and a few exceptional storage envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::endpoint_routes", + "gateway-rs/src/routes/platform.rs::document_by_method" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::least_privilege_role_cannot_create_apis_or_read_logs", + "gateway-rs/tests/platform_native.rs::endpoint_models_match_pydantic_coercion_bounds_and_null_elision", + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/routes/endpoint_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "endpoint_router.post('', description='Add endpoint', response_model=ResponseModel, responses={200: {'description': 'Successful Response', 'content': {'application/json': {'example': {'message': 'Endpoint created successfully'}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/endpoint_routes.py::async_function:create_endpoint", + "notes": "All endpoint CRUD, listing, validation, and validation-alias routes are mapped to native Rust. Core endpoints match typed-model validation, create/update/delete permissions and route-specific denial codes, authenticated reads/listing, missing-item/list errors, immutable identity checks, duplicate/client-URI checks, and CRUD responses. Endpoint-validation service error semantics and a few exceptional storage envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::endpoint_routes", + "gateway-rs/src/routes/platform.rs::document_by_method" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::least_privilege_role_cannot_create_apis_or_read_logs", + "gateway-rs/tests/platform_native.rs::endpoint_models_match_pydantic_coercion_bounds_and_null_elision", + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" + ], + "source": { + "kind": "async_function", + "line": 53, + "path": "backend-services/routes/endpoint_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "endpoint_router.put('/{endpoint_method}/{api_name}/{api_version}/{endpoint_uri:path}', description='Update endpoint', response_model=ResponseModel, responses={200: {'description': 'Successful Response', 'content': {'application/json': {'example': {'message': 'Endpoint updated successfully'}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/endpoint_routes.py::async_function:update_endpoint", + "notes": "All endpoint CRUD, listing, validation, and validation-alias routes are mapped to native Rust. Core endpoints match typed-model validation, create/update/delete permissions and route-specific denial codes, authenticated reads/listing, missing-item/list errors, immutable identity checks, duplicate/client-URI checks, and CRUD responses. Endpoint-validation service error semantics and a few exceptional storage envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::endpoint_routes", + "gateway-rs/src/routes/platform.rs::document_by_method" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::least_privilege_role_cannot_create_apis_or_read_logs", + "gateway-rs/tests/platform_native.rs::endpoint_models_match_pydantic_coercion_bounds_and_null_elision", + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" + ], + "source": { + "kind": "async_function", + "line": 114, + "path": "backend-services/routes/endpoint_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "endpoint_router.delete('/{endpoint_method}/{api_name}/{api_version}/{endpoint_uri:path}', description='Delete endpoint', response_model=ResponseModel, responses={200: {'description': 'Successful Response', 'content': {'application/json': {'example': {'message': 'Endpoint deleted successfully'}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/endpoint_routes.py::async_function:delete_endpoint", + "notes": "All endpoint CRUD, listing, validation, and validation-alias routes are mapped to native Rust. Core endpoints match typed-model validation, create/update/delete permissions and route-specific denial codes, authenticated reads/listing, missing-item/list errors, immutable identity checks, duplicate/client-URI checks, and CRUD responses. Endpoint-validation service error semantics and a few exceptional storage envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::endpoint_routes", + "gateway-rs/src/routes/platform.rs::document_by_method" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::least_privilege_role_cannot_create_apis_or_read_logs", + "gateway-rs/tests/platform_native.rs::endpoint_models_match_pydantic_coercion_bounds_and_null_elision", + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" + ], + "source": { + "kind": "async_function", + "line": 191, + "path": "backend-services/routes/endpoint_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "endpoint_router.get('/{endpoint_method}/{api_name}/{api_version}/{endpoint_uri:path}', description='Get endpoint by API name, API version and endpoint uri', response_model=EndpointModelResponse)" + ], + "domain": "routes", + "id": "backend-services/routes/endpoint_routes.py::async_function:get_endpoint", + "notes": "All endpoint CRUD, listing, validation, and validation-alias routes are mapped to native Rust. Core endpoints match typed-model validation, create/update/delete permissions and route-specific denial codes, authenticated reads/listing, missing-item/list errors, immutable identity checks, duplicate/client-URI checks, and CRUD responses. Endpoint-validation service error semantics and a few exceptional storage envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::endpoint_routes", + "gateway-rs/src/routes/platform.rs::document_by_method" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::least_privilege_role_cannot_create_apis_or_read_logs", + "gateway-rs/tests/platform_native.rs::endpoint_models_match_pydantic_coercion_bounds_and_null_elision", + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" + ], + "source": { + "kind": "async_function", + "line": 250, + "path": "backend-services/routes/endpoint_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "endpoint_router.get('/{api_name}/{api_version}', description='Get all endpoints for an API', response_model=list[EndpointModelResponse])" + ], + "domain": "routes", + "id": "backend-services/routes/endpoint_routes.py::async_function:get_endpoints_by_name_version", + "notes": "All endpoint CRUD, listing, validation, and validation-alias routes are mapped to native Rust. Core endpoints match typed-model validation, create/update/delete permissions and route-specific denial codes, authenticated reads/listing, missing-item/list errors, immutable identity checks, duplicate/client-URI checks, and CRUD responses. Endpoint-validation service error semantics and a few exceptional storage envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::endpoint_routes", + "gateway-rs/src/routes/platform.rs::document_by_method" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::least_privilege_role_cannot_create_apis_or_read_logs", + "gateway-rs/tests/platform_native.rs::endpoint_models_match_pydantic_coercion_bounds_and_null_elision", + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" + ], + "source": { + "kind": "async_function", + "line": 300, + "path": "backend-services/routes/endpoint_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "endpoint_router.post('/endpoint/validation', description='Create a new endpoint validation', response_model=ResponseModel, responses={200: {'description': 'Successful Response', 'content': {'application/json': {'example': {'message': 'Endpoint validation created successfully'}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/endpoint_routes.py::async_function:create_endpoint_validation", + "notes": "All endpoint CRUD, listing, validation, and validation-alias routes are mapped to native Rust. Core endpoints match typed-model validation, create/update/delete permissions and route-specific denial codes, authenticated reads/listing, missing-item/list errors, immutable identity checks, duplicate/client-URI checks, and CRUD responses. Endpoint-validation service error semantics and a few exceptional storage envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::endpoint_routes", + "gateway-rs/src/routes/platform.rs::document_by_method" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::least_privilege_role_cannot_create_apis_or_read_logs", + "gateway-rs/tests/platform_native.rs::endpoint_models_match_pydantic_coercion_bounds_and_null_elision", + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" + ], + "source": { + "kind": "async_function", + "line": 356, + "path": "backend-services/routes/endpoint_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "endpoint_router.put('/endpoint/validation/{endpoint_id}', description='Update an endpoint validation by endpoint ID', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/endpoint_routes.py::async_function:update_endpoint_validation", + "notes": "All endpoint CRUD, listing, validation, and validation-alias routes are mapped to native Rust. Core endpoints match typed-model validation, create/update/delete permissions and route-specific denial codes, authenticated reads/listing, missing-item/list errors, immutable identity checks, duplicate/client-URI checks, and CRUD responses. Endpoint-validation service error semantics and a few exceptional storage envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::endpoint_routes", + "gateway-rs/src/routes/platform.rs::document_by_method" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::least_privilege_role_cannot_create_apis_or_read_logs", + "gateway-rs/tests/platform_native.rs::endpoint_models_match_pydantic_coercion_bounds_and_null_elision", + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" + ], + "source": { + "kind": "async_function", + "line": 413, + "path": "backend-services/routes/endpoint_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "endpoint_router.delete('/endpoint/validation/{endpoint_id}', description='Delete an endpoint validation by endpoint ID', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/endpoint_routes.py::async_function:delete_endpoint_validation", + "notes": "All endpoint CRUD, listing, validation, and validation-alias routes are mapped to native Rust. Core endpoints match typed-model validation, create/update/delete permissions and route-specific denial codes, authenticated reads/listing, missing-item/list errors, immutable identity checks, duplicate/client-URI checks, and CRUD responses. Endpoint-validation service error semantics and a few exceptional storage envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::endpoint_routes", + "gateway-rs/src/routes/platform.rs::document_by_method" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::least_privilege_role_cannot_create_apis_or_read_logs", + "gateway-rs/tests/platform_native.rs::endpoint_models_match_pydantic_coercion_bounds_and_null_elision", + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" + ], + "source": { + "kind": "async_function", + "line": 472, + "path": "backend-services/routes/endpoint_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "endpoint_router.get('/endpoint/validation/{endpoint_id}', description='Get an endpoint validation by endpoint ID', response_model=EndpointValidationModelResponse)" + ], + "domain": "routes", + "id": "backend-services/routes/endpoint_routes.py::async_function:get_endpoint_validation", + "notes": "All endpoint CRUD, listing, validation, and validation-alias routes are mapped to native Rust. Core endpoints match typed-model validation, create/update/delete permissions and route-specific denial codes, authenticated reads/listing, missing-item/list errors, immutable identity checks, duplicate/client-URI checks, and CRUD responses. Endpoint-validation service error semantics and a few exceptional storage envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::endpoint_routes", + "gateway-rs/src/routes/platform.rs::document_by_method" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::least_privilege_role_cannot_create_apis_or_read_logs", + "gateway-rs/tests/platform_native.rs::endpoint_models_match_pydantic_coercion_bounds_and_null_elision", + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" + ], + "source": { + "kind": "async_function", + "line": 527, + "path": "backend-services/routes/endpoint_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "endpoint_router.post('/validation', description='Create a new endpoint validation (alias)', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/endpoint_routes.py::async_function:create_endpoint_validation_alias", + "notes": "All endpoint CRUD, listing, validation, and validation-alias routes are mapped to native Rust. Core endpoints match typed-model validation, create/update/delete permissions and route-specific denial codes, authenticated reads/listing, missing-item/list errors, immutable identity checks, duplicate/client-URI checks, and CRUD responses. Endpoint-validation service error semantics and a few exceptional storage envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::endpoint_routes", + "gateway-rs/src/routes/platform.rs::document_by_method" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::least_privilege_role_cannot_create_apis_or_read_logs", + "gateway-rs/tests/platform_native.rs::endpoint_models_match_pydantic_coercion_bounds_and_null_elision", + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" + ], + "source": { + "kind": "async_function", + "line": 571, + "path": "backend-services/routes/endpoint_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "endpoint_router.put('/validation/{endpoint_id}', description='Update endpoint validation by endpoint ID (alias)', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/endpoint_routes.py::async_function:update_endpoint_validation_alias", + "notes": "All endpoint CRUD, listing, validation, and validation-alias routes are mapped to native Rust. Core endpoints match typed-model validation, create/update/delete permissions and route-specific denial codes, authenticated reads/listing, missing-item/list errors, immutable identity checks, duplicate/client-URI checks, and CRUD responses. Endpoint-validation service error semantics and a few exceptional storage envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::endpoint_routes", + "gateway-rs/src/routes/platform.rs::document_by_method" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::least_privilege_role_cannot_create_apis_or_read_logs", + "gateway-rs/tests/platform_native.rs::endpoint_models_match_pydantic_coercion_bounds_and_null_elision", + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" + ], + "source": { + "kind": "async_function", + "line": 592, + "path": "backend-services/routes/endpoint_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "endpoint_router.delete('/validation/{endpoint_id}', description='Delete endpoint validation by endpoint ID (alias)', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/endpoint_routes.py::async_function:delete_endpoint_validation_alias", + "notes": "All endpoint CRUD, listing, validation, and validation-alias routes are mapped to native Rust. Core endpoints match typed-model validation, create/update/delete permissions and route-specific denial codes, authenticated reads/listing, missing-item/list errors, immutable identity checks, duplicate/client-URI checks, and CRUD responses. Endpoint-validation service error semantics and a few exceptional storage envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::endpoint_routes", + "gateway-rs/src/routes/platform.rs::document_by_method" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::least_privilege_role_cannot_create_apis_or_read_logs", + "gateway-rs/tests/platform_native.rs::endpoint_models_match_pydantic_coercion_bounds_and_null_elision", + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" + ], + "source": { + "kind": "async_function", + "line": 613, + "path": "backend-services/routes/endpoint_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "endpoint_router.get('/validation/{endpoint_id}', description='Get endpoint validation by endpoint ID (alias)', response_model=EndpointValidationModelResponse)" + ], + "domain": "routes", + "id": "backend-services/routes/endpoint_routes.py::async_function:get_endpoint_validation_alias", + "notes": "All endpoint CRUD, listing, validation, and validation-alias routes are mapped to native Rust. Core endpoints match typed-model validation, create/update/delete permissions and route-specific denial codes, authenticated reads/listing, missing-item/list errors, immutable identity checks, duplicate/client-URI checks, and CRUD responses. Endpoint-validation service error semantics and a few exceptional storage envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::endpoint_routes", + "gateway-rs/src/routes/platform.rs::document_by_method" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::least_privilege_role_cannot_create_apis_or_read_logs", + "gateway-rs/tests/platform_native.rs::endpoint_models_match_pydantic_coercion_bounds_and_null_elision", + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" + ], + "source": { + "kind": "async_function", + "line": 632, + "path": "backend-services/routes/endpoint_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/gateway_routes.py::module:gateway_routes", + "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively. The monolithic Python gateway implementation is distributed across Rust protocol/policy modules, and every exceptional fallback and duplicate legacy gRPC definition has not yet been mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/routes/operations.rs", + "gateway-rs/src/routes/rest.rs", + "gateway-rs/src/routes/soap.rs", + "gateway-rs/src/routes/graphql.rs", + "gateway-rs/src/routes/grpc.rs" + ], + "rust_tests": [ + "gateway-rs/tests/runtime.rs::rust_health_matches_public_contract", + "gateway-rs/tests/runtime.rs::rust_serves_status_unauthorized_from_rust", + "gateway-rs/tests/runtime.rs::rust_handles_cache_delete_locally", + "gateway-rs/tests/runtime.rs::rest_head_uses_a_registered_get_endpoint_like_python", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/routes/gateway_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "gateway_router.api_route('/status', methods=['GET'], description='Gateway status (requires manage_gateway)', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/gateway_routes.py::async_function:status", + "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively. The monolithic Python gateway implementation is distributed across Rust protocol/policy modules, and every exceptional fallback and duplicate legacy gRPC definition has not yet been mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/routes/operations.rs", + "gateway-rs/src/routes/rest.rs", + "gateway-rs/src/routes/soap.rs", + "gateway-rs/src/routes/graphql.rs", + "gateway-rs/src/routes/grpc.rs" + ], + "rust_tests": [ + "gateway-rs/tests/runtime.rs::rust_health_matches_public_contract", + "gateway-rs/tests/runtime.rs::rust_serves_status_unauthorized_from_rust", + "gateway-rs/tests/runtime.rs::rust_handles_cache_delete_locally", + "gateway-rs/tests/runtime.rs::rest_head_uses_a_registered_get_endpoint_like_python", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "source": { + "kind": "async_function", + "line": 59, + "path": "backend-services/routes/gateway_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "gateway_router.get('/health', description='Public health probe', include_in_schema=False)" + ], + "domain": "routes", + "id": "backend-services/routes/gateway_routes.py::async_function:health", + "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively. The monolithic Python gateway implementation is distributed across Rust protocol/policy modules, and every exceptional fallback and duplicate legacy gRPC definition has not yet been mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/routes/operations.rs", + "gateway-rs/src/routes/rest.rs", + "gateway-rs/src/routes/soap.rs", + "gateway-rs/src/routes/graphql.rs", + "gateway-rs/src/routes/grpc.rs" + ], + "rust_tests": [ + "gateway-rs/tests/runtime.rs::rust_health_matches_public_contract", + "gateway-rs/tests/runtime.rs::rust_serves_status_unauthorized_from_rust", + "gateway-rs/tests/runtime.rs::rust_handles_cache_delete_locally", + "gateway-rs/tests/runtime.rs::rest_head_uses_a_registered_get_endpoint_like_python", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "source": { + "kind": "async_function", + "line": 127, + "path": "backend-services/routes/gateway_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "gateway_router.api_route('/caches', methods=['DELETE'], description='Clear all caches', response_model=ResponseModel, dependencies=[Depends(auth_required)], responses={200: {'description': 'Successful Response', 'content': {'application/json': {'example': {'message': 'All caches cleared'}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/gateway_routes.py::async_function:clear_all_caches", + "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively. The monolithic Python gateway implementation is distributed across Rust protocol/policy modules, and every exceptional fallback and duplicate legacy gRPC definition has not yet been mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/routes/operations.rs", + "gateway-rs/src/routes/rest.rs", + "gateway-rs/src/routes/soap.rs", + "gateway-rs/src/routes/graphql.rs", + "gateway-rs/src/routes/grpc.rs" + ], + "rust_tests": [ + "gateway-rs/tests/runtime.rs::rust_health_matches_public_contract", + "gateway-rs/tests/runtime.rs::rust_serves_status_unauthorized_from_rust", + "gateway-rs/tests/runtime.rs::rust_handles_cache_delete_locally", + "gateway-rs/tests/runtime.rs::rest_head_uses_a_registered_get_endpoint_like_python", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "source": { + "kind": "async_function", + "line": 163, + "path": "backend-services/routes/gateway_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "gateway_router.options('/caches', include_in_schema=False)" + ], + "domain": "routes", + "id": "backend-services/routes/gateway_routes.py::async_function:clear_all_caches_options", + "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively. The monolithic Python gateway implementation is distributed across Rust protocol/policy modules, and every exceptional fallback and duplicate legacy gRPC definition has not yet been mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/routes/operations.rs", + "gateway-rs/src/routes/rest.rs", + "gateway-rs/src/routes/soap.rs", + "gateway-rs/src/routes/graphql.rs", + "gateway-rs/src/routes/grpc.rs" + ], + "rust_tests": [ + "gateway-rs/tests/runtime.rs::rust_health_matches_public_contract", + "gateway-rs/tests/runtime.rs::rust_serves_status_unauthorized_from_rust", + "gateway-rs/tests/runtime.rs::rust_handles_cache_delete_locally", + "gateway-rs/tests/runtime.rs::rest_head_uses_a_registered_get_endpoint_like_python", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "source": { + "kind": "async_function", + "line": 246, + "path": "backend-services/routes/gateway_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "gateway_router.api_route('/rest/{path:path}', methods=['GET', 'POST', 'PUT', 'DELETE', 'PATCH'], description='REST gateway endpoint', response_model=ResponseModel, include_in_schema=False)" + ], + "domain": "routes", + "id": "backend-services/routes/gateway_routes.py::async_function:gateway", + "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively. The monolithic Python gateway implementation is distributed across Rust protocol/policy modules, and every exceptional fallback and duplicate legacy gRPC definition has not yet been mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/routes/operations.rs", + "gateway-rs/src/routes/rest.rs", + "gateway-rs/src/routes/soap.rs", + "gateway-rs/src/routes/graphql.rs", + "gateway-rs/src/routes/grpc.rs" + ], + "rust_tests": [ + "gateway-rs/tests/runtime.rs::rust_health_matches_public_contract", + "gateway-rs/tests/runtime.rs::rust_serves_status_unauthorized_from_rust", + "gateway-rs/tests/runtime.rs::rust_handles_cache_delete_locally", + "gateway-rs/tests/runtime.rs::rest_head_uses_a_registered_get_endpoint_like_python", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "source": { + "kind": "async_function", + "line": 277, + "path": "backend-services/routes/gateway_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/gateway_routes.py::async_function:gateway._resolve_api_by", + "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively. The monolithic Python gateway implementation is distributed across Rust protocol/policy modules, and every exceptional fallback and duplicate legacy gRPC definition has not yet been mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/routes/operations.rs", + "gateway-rs/src/routes/rest.rs", + "gateway-rs/src/routes/soap.rs", + "gateway-rs/src/routes/graphql.rs", + "gateway-rs/src/routes/grpc.rs" + ], + "rust_tests": [ + "gateway-rs/tests/runtime.rs::rust_health_matches_public_contract", + "gateway-rs/tests/runtime.rs::rust_serves_status_unauthorized_from_rust", + "gateway-rs/tests/runtime.rs::rust_handles_cache_delete_locally", + "gateway-rs/tests/runtime.rs::rest_head_uses_a_registered_get_endpoint_like_python", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "source": { + "kind": "async_function", + "line": 291, + "path": "backend-services/routes/gateway_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "gateway_router.get('/rest/{path:path}', description='REST gateway endpoint (GET)', response_model=ResponseModel, operation_id='rest_get')" + ], + "domain": "routes", + "id": "backend-services/routes/gateway_routes.py::async_function:rest_get", + "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively. The monolithic Python gateway implementation is distributed across Rust protocol/policy modules, and every exceptional fallback and duplicate legacy gRPC definition has not yet been mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/routes/operations.rs", + "gateway-rs/src/routes/rest.rs", + "gateway-rs/src/routes/soap.rs", + "gateway-rs/src/routes/graphql.rs", + "gateway-rs/src/routes/grpc.rs" + ], + "rust_tests": [ + "gateway-rs/tests/runtime.rs::rust_health_matches_public_contract", + "gateway-rs/tests/runtime.rs::rust_serves_status_unauthorized_from_rust", + "gateway-rs/tests/runtime.rs::rust_handles_cache_delete_locally", + "gateway-rs/tests/runtime.rs::rest_head_uses_a_registered_get_endpoint_like_python", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "source": { + "kind": "async_function", + "line": 439, + "path": "backend-services/routes/gateway_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "gateway_router.post('/rest/{path:path}', description='REST gateway endpoint (POST)', response_model=ResponseModel, operation_id='rest_post')" + ], + "domain": "routes", + "id": "backend-services/routes/gateway_routes.py::async_function:rest_post", + "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively. The monolithic Python gateway implementation is distributed across Rust protocol/policy modules, and every exceptional fallback and duplicate legacy gRPC definition has not yet been mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/routes/operations.rs", + "gateway-rs/src/routes/rest.rs", + "gateway-rs/src/routes/soap.rs", + "gateway-rs/src/routes/graphql.rs", + "gateway-rs/src/routes/grpc.rs" + ], + "rust_tests": [ + "gateway-rs/tests/runtime.rs::rust_health_matches_public_contract", + "gateway-rs/tests/runtime.rs::rust_serves_status_unauthorized_from_rust", + "gateway-rs/tests/runtime.rs::rust_handles_cache_delete_locally", + "gateway-rs/tests/runtime.rs::rest_head_uses_a_registered_get_endpoint_like_python", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "source": { + "kind": "async_function", + "line": 449, + "path": "backend-services/routes/gateway_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "gateway_router.put('/rest/{path:path}', description='REST gateway endpoint (PUT)', response_model=ResponseModel, operation_id='rest_put')" + ], + "domain": "routes", + "id": "backend-services/routes/gateway_routes.py::async_function:rest_put", + "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively. The monolithic Python gateway implementation is distributed across Rust protocol/policy modules, and every exceptional fallback and duplicate legacy gRPC definition has not yet been mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/routes/operations.rs", + "gateway-rs/src/routes/rest.rs", + "gateway-rs/src/routes/soap.rs", + "gateway-rs/src/routes/graphql.rs", + "gateway-rs/src/routes/grpc.rs" + ], + "rust_tests": [ + "gateway-rs/tests/runtime.rs::rust_health_matches_public_contract", + "gateway-rs/tests/runtime.rs::rust_serves_status_unauthorized_from_rust", + "gateway-rs/tests/runtime.rs::rust_handles_cache_delete_locally", + "gateway-rs/tests/runtime.rs::rest_head_uses_a_registered_get_endpoint_like_python", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "source": { + "kind": "async_function", + "line": 459, + "path": "backend-services/routes/gateway_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "gateway_router.patch('/rest/{path:path}', description='REST gateway endpoint (PATCH)', response_model=ResponseModel, operation_id='rest_patch')" + ], + "domain": "routes", + "id": "backend-services/routes/gateway_routes.py::async_function:rest_patch", + "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively. The monolithic Python gateway implementation is distributed across Rust protocol/policy modules, and every exceptional fallback and duplicate legacy gRPC definition has not yet been mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/routes/operations.rs", + "gateway-rs/src/routes/rest.rs", + "gateway-rs/src/routes/soap.rs", + "gateway-rs/src/routes/graphql.rs", + "gateway-rs/src/routes/grpc.rs" + ], + "rust_tests": [ + "gateway-rs/tests/runtime.rs::rust_health_matches_public_contract", + "gateway-rs/tests/runtime.rs::rust_serves_status_unauthorized_from_rust", + "gateway-rs/tests/runtime.rs::rust_handles_cache_delete_locally", + "gateway-rs/tests/runtime.rs::rest_head_uses_a_registered_get_endpoint_like_python", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "source": { + "kind": "async_function", + "line": 469, + "path": "backend-services/routes/gateway_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "gateway_router.delete('/rest/{path:path}', description='REST gateway endpoint (DELETE)', response_model=ResponseModel, operation_id='rest_delete')" + ], + "domain": "routes", + "id": "backend-services/routes/gateway_routes.py::async_function:rest_delete", + "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively. The monolithic Python gateway implementation is distributed across Rust protocol/policy modules, and every exceptional fallback and duplicate legacy gRPC definition has not yet been mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/routes/operations.rs", + "gateway-rs/src/routes/rest.rs", + "gateway-rs/src/routes/soap.rs", + "gateway-rs/src/routes/graphql.rs", + "gateway-rs/src/routes/grpc.rs" + ], + "rust_tests": [ + "gateway-rs/tests/runtime.rs::rust_health_matches_public_contract", + "gateway-rs/tests/runtime.rs::rust_serves_status_unauthorized_from_rust", + "gateway-rs/tests/runtime.rs::rust_handles_cache_delete_locally", + "gateway-rs/tests/runtime.rs::rest_head_uses_a_registered_get_endpoint_like_python", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "source": { + "kind": "async_function", + "line": 479, + "path": "backend-services/routes/gateway_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "gateway_router.head('/rest/{path:path}', description='REST gateway endpoint (HEAD)', response_model=ResponseModel, operation_id='rest_head')" + ], + "domain": "routes", + "id": "backend-services/routes/gateway_routes.py::async_function:rest_head", + "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively. The monolithic Python gateway implementation is distributed across Rust protocol/policy modules, and every exceptional fallback and duplicate legacy gRPC definition has not yet been mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/routes/operations.rs", + "gateway-rs/src/routes/rest.rs", + "gateway-rs/src/routes/soap.rs", + "gateway-rs/src/routes/graphql.rs", + "gateway-rs/src/routes/grpc.rs" + ], + "rust_tests": [ + "gateway-rs/tests/runtime.rs::rust_health_matches_public_contract", + "gateway-rs/tests/runtime.rs::rust_serves_status_unauthorized_from_rust", + "gateway-rs/tests/runtime.rs::rust_handles_cache_delete_locally", + "gateway-rs/tests/runtime.rs::rest_head_uses_a_registered_get_endpoint_like_python", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "source": { + "kind": "async_function", + "line": 489, + "path": "backend-services/routes/gateway_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "gateway_router.api_route('/rest/{path:path}', methods=['OPTIONS'], description='REST gateway CORS preflight', include_in_schema=False)" + ], + "domain": "routes", + "id": "backend-services/routes/gateway_routes.py::async_function:rest_preflight", + "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively. The monolithic Python gateway implementation is distributed across Rust protocol/policy modules, and every exceptional fallback and duplicate legacy gRPC definition has not yet been mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/routes/operations.rs", + "gateway-rs/src/routes/rest.rs", + "gateway-rs/src/routes/soap.rs", + "gateway-rs/src/routes/graphql.rs", + "gateway-rs/src/routes/grpc.rs" + ], + "rust_tests": [ + "gateway-rs/tests/runtime.rs::rust_health_matches_public_contract", + "gateway-rs/tests/runtime.rs::rust_serves_status_unauthorized_from_rust", + "gateway-rs/tests/runtime.rs::rust_handles_cache_delete_locally", + "gateway-rs/tests/runtime.rs::rest_head_uses_a_registered_get_endpoint_like_python", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "source": { + "kind": "async_function", + "line": 518, + "path": "backend-services/routes/gateway_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "gateway_router.api_route('/soap/{path:path}', methods=['POST', 'GET'], description='SOAP gateway endpoint', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/gateway_routes.py::async_function:soap_gateway", + "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively. The monolithic Python gateway implementation is distributed across Rust protocol/policy modules, and every exceptional fallback and duplicate legacy gRPC definition has not yet been mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/routes/operations.rs", + "gateway-rs/src/routes/rest.rs", + "gateway-rs/src/routes/soap.rs", + "gateway-rs/src/routes/graphql.rs", + "gateway-rs/src/routes/grpc.rs" + ], + "rust_tests": [ + "gateway-rs/tests/runtime.rs::rust_health_matches_public_contract", + "gateway-rs/tests/runtime.rs::rust_serves_status_unauthorized_from_rust", + "gateway-rs/tests/runtime.rs::rust_handles_cache_delete_locally", + "gateway-rs/tests/runtime.rs::rest_head_uses_a_registered_get_endpoint_like_python", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "source": { + "kind": "async_function", + "line": 631, + "path": "backend-services/routes/gateway_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "gateway_router.api_route('/grpc/{path:path}', methods=['POST', 'GET'], description='gRPC gateway endpoint', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/gateway_routes.py::async_function:grpc_gateway", + "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively. The monolithic Python gateway implementation is distributed across Rust protocol/policy modules, and every exceptional fallback and duplicate legacy gRPC definition has not yet been mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/routes/operations.rs", + "gateway-rs/src/routes/rest.rs", + "gateway-rs/src/routes/soap.rs", + "gateway-rs/src/routes/graphql.rs", + "gateway-rs/src/routes/grpc.rs" + ], + "rust_tests": [ + "gateway-rs/tests/runtime.rs::rust_health_matches_public_contract", + "gateway-rs/tests/runtime.rs::rust_serves_status_unauthorized_from_rust", + "gateway-rs/tests/runtime.rs::rust_handles_cache_delete_locally", + "gateway-rs/tests/runtime.rs::rest_head_uses_a_registered_get_endpoint_like_python", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "source": { + "kind": "async_function", + "line": 745, + "path": "backend-services/routes/gateway_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "gateway_router.api_route('/soap/{path:path}', methods=['OPTIONS'], description='SOAP gateway CORS preflight', include_in_schema=False)" + ], + "domain": "routes", + "id": "backend-services/routes/gateway_routes.py::async_function:soap_preflight", + "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively. The monolithic Python gateway implementation is distributed across Rust protocol/policy modules, and every exceptional fallback and duplicate legacy gRPC definition has not yet been mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/routes/operations.rs", + "gateway-rs/src/routes/rest.rs", + "gateway-rs/src/routes/soap.rs", + "gateway-rs/src/routes/graphql.rs", + "gateway-rs/src/routes/grpc.rs" + ], + "rust_tests": [ + "gateway-rs/tests/runtime.rs::rust_health_matches_public_contract", + "gateway-rs/tests/runtime.rs::rust_serves_status_unauthorized_from_rust", + "gateway-rs/tests/runtime.rs::rust_handles_cache_delete_locally", + "gateway-rs/tests/runtime.rs::rest_head_uses_a_registered_get_endpoint_like_python", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "source": { + "kind": "async_function", + "line": 878, + "path": "backend-services/routes/gateway_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "gateway_router.api_route('/graphql/{path:path}', methods=['POST'], description='GraphQL gateway endpoint', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/gateway_routes.py::async_function:graphql_gateway", + "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively. The monolithic Python gateway implementation is distributed across Rust protocol/policy modules, and every exceptional fallback and duplicate legacy gRPC definition has not yet been mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/routes/operations.rs", + "gateway-rs/src/routes/rest.rs", + "gateway-rs/src/routes/soap.rs", + "gateway-rs/src/routes/graphql.rs", + "gateway-rs/src/routes/grpc.rs" + ], + "rust_tests": [ + "gateway-rs/tests/runtime.rs::rust_health_matches_public_contract", + "gateway-rs/tests/runtime.rs::rust_serves_status_unauthorized_from_rust", + "gateway-rs/tests/runtime.rs::rust_handles_cache_delete_locally", + "gateway-rs/tests/runtime.rs::rest_head_uses_a_registered_get_endpoint_like_python", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "source": { + "kind": "async_function", + "line": 947, + "path": "backend-services/routes/gateway_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "gateway_router.api_route('/graphql/{path:path}', methods=['OPTIONS'], description='GraphQL gateway CORS preflight', include_in_schema=False)" + ], + "domain": "routes", + "id": "backend-services/routes/gateway_routes.py::async_function:graphql_preflight", + "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively. The monolithic Python gateway implementation is distributed across Rust protocol/policy modules, and every exceptional fallback and duplicate legacy gRPC definition has not yet been mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/routes/operations.rs", + "gateway-rs/src/routes/rest.rs", + "gateway-rs/src/routes/soap.rs", + "gateway-rs/src/routes/graphql.rs", + "gateway-rs/src/routes/grpc.rs" + ], + "rust_tests": [ + "gateway-rs/tests/runtime.rs::rust_health_matches_public_contract", + "gateway-rs/tests/runtime.rs::rust_serves_status_unauthorized_from_rust", + "gateway-rs/tests/runtime.rs::rust_handles_cache_delete_locally", + "gateway-rs/tests/runtime.rs::rest_head_uses_a_registered_get_endpoint_like_python", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "source": { + "kind": "async_function", + "line": 1092, + "path": "backend-services/routes/gateway_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "gateway_router.api_route('/grpc/{path:path}', methods=['OPTIONS'], description='gRPC gateway CORS preflight', include_in_schema=False)" + ], + "domain": "routes", + "id": "backend-services/routes/gateway_routes.py::async_function:grpc_preflight", + "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively. The monolithic Python gateway implementation is distributed across Rust protocol/policy modules, and every exceptional fallback and duplicate legacy gRPC definition has not yet been mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/routes/operations.rs", + "gateway-rs/src/routes/rest.rs", + "gateway-rs/src/routes/soap.rs", + "gateway-rs/src/routes/graphql.rs", + "gateway-rs/src/routes/grpc.rs" + ], + "rust_tests": [ + "gateway-rs/tests/runtime.rs::rust_health_matches_public_contract", + "gateway-rs/tests/runtime.rs::rust_serves_status_unauthorized_from_rust", + "gateway-rs/tests/runtime.rs::rust_handles_cache_delete_locally", + "gateway-rs/tests/runtime.rs::rest_head_uses_a_registered_get_endpoint_like_python", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "source": { + "kind": "async_function", + "line": 1145, + "path": "backend-services/routes/gateway_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "gateway_router.api_route('/grpc/{path:path}', methods=['POST', 'GET'], description='gRPC gateway endpoint', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/gateway_routes.py::async_function:grpc_gateway#2", + "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively. The monolithic Python gateway implementation is distributed across Rust protocol/policy modules, and every exceptional fallback and duplicate legacy gRPC definition has not yet been mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/routes/operations.rs", + "gateway-rs/src/routes/rest.rs", + "gateway-rs/src/routes/soap.rs", + "gateway-rs/src/routes/graphql.rs", + "gateway-rs/src/routes/grpc.rs" + ], + "rust_tests": [ + "gateway-rs/tests/runtime.rs::rust_health_matches_public_contract", + "gateway-rs/tests/runtime.rs::rust_serves_status_unauthorized_from_rust", + "gateway-rs/tests/runtime.rs::rust_handles_cache_delete_locally", + "gateway-rs/tests/runtime.rs::rest_head_uses_a_registered_get_endpoint_like_python", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "source": { + "kind": "async_function", + "line": 1237, + "path": "backend-services/routes/gateway_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/graphql_routes.py::module:graphql_routes", + "notes": "Rust preserves authenticated schema fetch/cache/refresh and type listing with pinned permission and error behavior.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::api_discovery_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::discovery_document_reads_fetch_once_and_reuse_the_python_cache_contract" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/routes/graphql_routes.py" + }, + "status": "translated" + }, + { + "decorators": [ + "graphql_routes_router.get('/platform/api/{api_name}/{api_version}/graphql/schema')" + ], + "domain": "routes", + "id": "backend-services/routes/graphql_routes.py::async_function:get_graphql_schema", + "notes": "Rust preserves authenticated schema fetch/cache/refresh and type listing with pinned permission and error behavior.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::api_discovery_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::discovery_document_reads_fetch_once_and_reuse_the_python_cache_contract" + ], + "source": { + "kind": "async_function", + "line": 42, + "path": "backend-services/routes/graphql_routes.py" + }, + "status": "translated" + }, + { + "decorators": [ + "graphql_routes_router.post('/platform/api/{api_name}/{api_version}/graphql/schema/refresh')" + ], + "domain": "routes", + "id": "backend-services/routes/graphql_routes.py::async_function:refresh_graphql_schema", + "notes": "Rust preserves authenticated schema fetch/cache/refresh and type listing with pinned permission and error behavior.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::api_discovery_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::discovery_document_reads_fetch_once_and_reuse_the_python_cache_contract" + ], + "source": { + "kind": "async_function", + "line": 122, + "path": "backend-services/routes/graphql_routes.py" + }, + "status": "translated" + }, + { + "decorators": [ + "graphql_routes_router.get('/platform/api/{api_name}/{api_version}/graphql/types')" + ], + "domain": "routes", + "id": "backend-services/routes/graphql_routes.py::async_function:get_graphql_types", + "notes": "Rust preserves authenticated schema fetch/cache/refresh and type listing with pinned permission and error behavior.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::api_discovery_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::discovery_document_reads_fetch_once_and_reuse_the_python_cache_contract" + ], + "source": { + "kind": "async_function", + "line": 186, + "path": "backend-services/routes/graphql_routes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/group_routes.py::module:group_routes", + "notes": "Rust preserves group CRUD, model validation, permissions, duplicate/not-found behavior, pagination, and response bodies.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::entity_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates", + "gateway-rs/tests/roles_groups_parity.rs" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/routes/group_routes.py" + }, + "status": "translated" + }, + { + "decorators": [ + "group_router.post('', description='Add group', response_model=ResponseModel, responses={200: {'description': 'Successful Response', 'content': {'application/json': {'example': {'message': 'Group created successfully'}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/group_routes.py::async_function:create_group", + "notes": "Rust preserves group CRUD, model validation, permissions, duplicate/not-found behavior, pagination, and response bodies.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::entity_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates", + "gateway-rs/tests/roles_groups_parity.rs" + ], + "source": { + "kind": "async_function", + "line": 48, + "path": "backend-services/routes/group_routes.py" + }, + "status": "translated" + }, + { + "decorators": [ + "group_router.put('/{group_name}', description='Update group', response_model=ResponseModel, responses={200: {'description': 'Successful Response', 'content': {'application/json': {'example': {'message': 'Group updated successfully'}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/group_routes.py::async_function:update_group", + "notes": "Rust preserves group CRUD, model validation, permissions, duplicate/not-found behavior, pagination, and response bodies.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::entity_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates", + "gateway-rs/tests/roles_groups_parity.rs" + ], + "source": { + "kind": "async_function", + "line": 106, + "path": "backend-services/routes/group_routes.py" + }, + "status": "translated" + }, + { + "decorators": [ + "group_router.delete('/{group_name}', description='Delete group', response_model=ResponseModel, responses={200: {'description': 'Successful Response', 'content': {'application/json': {'example': {'message': 'Group deleted successfully'}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/group_routes.py::async_function:delete_group", + "notes": "Rust preserves group CRUD, model validation, permissions, duplicate/not-found behavior, pagination, and response bodies.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::entity_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates", + "gateway-rs/tests/roles_groups_parity.rs" + ], + "source": { + "kind": "async_function", + "line": 164, + "path": "backend-services/routes/group_routes.py" + }, + "status": "translated" + }, + { + "decorators": [ + "group_router.get('/all', description='Get all groups', response_model=list[GroupModelResponse])" + ], + "domain": "routes", + "id": "backend-services/routes/group_routes.py::async_function:get_groups", + "notes": "Rust preserves group CRUD, model validation, permissions, duplicate/not-found behavior, pagination, and response bodies.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::entity_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates", + "gateway-rs/tests/roles_groups_parity.rs" + ], + "source": { + "kind": "async_function", + "line": 212, + "path": "backend-services/routes/group_routes.py" + }, + "status": "translated" + }, + { + "decorators": [ + "group_router.get('/{group_name}', description='Get group', response_model=GroupModelResponse)" + ], + "domain": "routes", + "id": "backend-services/routes/group_routes.py::async_function:get_group", + "notes": "Rust preserves group CRUD, model validation, permissions, duplicate/not-found behavior, pagination, and response bodies.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::entity_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates", + "gateway-rs/tests/roles_groups_parity.rs" + ], + "source": { + "kind": "async_function", + "line": 254, + "path": "backend-services/routes/group_routes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/grpc_routes.py::module:grpc_routes", + "notes": "Rust provides authenticated descriptor-backed service discovery and the native gRPC-Web proxy with policy, CORS, unary, and streaming behavior.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::api_discovery_routes", + "gateway-rs/src/routes/grpc_web.rs::grpc_web_policy_then_execute" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::grpc_web_unary_cors_and_streaming_policy_parity", + "gateway-rs/tests/live_tests_parity.rs::live_test_60_grpc_gateway_basic_flow_parity" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/routes/grpc_routes.py" + }, + "status": "translated" + }, + { + "decorators": [ + "grpc_router.get('/platform/api/{api_name}/{api_version}/grpc/services')" + ], + "domain": "routes", + "id": "backend-services/routes/grpc_routes.py::async_function:list_grpc_services", + "notes": "Rust provides authenticated descriptor-backed service discovery and the native gRPC-Web proxy with policy, CORS, unary, and streaming behavior.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::api_discovery_routes", + "gateway-rs/src/routes/grpc_web.rs::grpc_web_policy_then_execute" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::grpc_web_unary_cors_and_streaming_policy_parity", + "gateway-rs/tests/live_tests_parity.rs::live_test_60_grpc_gateway_basic_flow_parity" + ], + "source": { + "kind": "async_function", + "line": 41, + "path": "backend-services/routes/grpc_routes.py" + }, + "status": "translated" + }, + { + "decorators": [ + "grpc_router.post('/grpc-web/{api_name}/{service}/{method}')" + ], + "domain": "routes", + "id": "backend-services/routes/grpc_routes.py::async_function:grpc_web_proxy", + "notes": "Rust provides authenticated descriptor-backed service discovery and the native gRPC-Web proxy with policy, CORS, unary, and streaming behavior.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::api_discovery_routes", + "gateway-rs/src/routes/grpc_web.rs::grpc_web_policy_then_execute" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::grpc_web_unary_cors_and_streaming_policy_parity", + "gateway-rs/tests/live_tests_parity.rs::live_test_60_grpc_gateway_basic_flow_parity" + ], + "source": { + "kind": "async_function", + "line": 99, + "path": "backend-services/routes/grpc_routes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/logging_routes.py::module:logging_routes", + "notes": "Rust preserves authenticated log querying, file listing, statistics, filtered/redacted export, and downloads over native structured log files.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::logging_routes" + ], + "rust_tests": [ + "gateway-rs/tests/security_settings_parity.rs::live_logging_endpoints_match_python", + "gateway-rs/tests/security_settings_parity.rs::log_export_filters_records_and_redacts_nested_credentials" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/routes/logging_routes.py" + }, + "status": "translated" + }, + { + "decorators": [ + "logging_router.get('/logs', description='Get logs with filtering', response_model=ResponseModel, responses={200: {'description': 'Successful Response', 'content': {'application/json': {'example': {'logs': [{'timestamp': '2024-01-01T12:00:00', 'level': 'INFO', 'message': 'Request processed', 'source': 'doorman.gateway', 'user': 'john_doe', 'api': 'customer', 'endpoint': '/api/customer/v1/users', 'method': 'GET', 'status_code': 200, 'response_time': '150.5', 'ip_address': '192.168.1.1', 'protocol': 'HTTP/1.1', 'request_id': '123e4567-e89b-12d3-a456-426614174000'}], 'total': 100, 'has_more': False}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/logging_routes.py::async_function:get_logs", + "notes": "Rust preserves authenticated log querying, file listing, statistics, filtered/redacted export, and downloads over native structured log files.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::logging_routes" + ], + "rust_tests": [ + "gateway-rs/tests/security_settings_parity.rs::live_logging_endpoints_match_python", + "gateway-rs/tests/security_settings_parity.rs::log_export_filters_records_and_redacts_nested_credentials" + ], + "source": { + "kind": "async_function", + "line": 71, + "path": "backend-services/routes/logging_routes.py" + }, + "status": "translated" + }, + { + "decorators": [ + "logging_router.get('/logs/files', description='Get list of available log files', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/logging_routes.py::async_function:get_log_files", + "notes": "Rust preserves authenticated log querying, file listing, statistics, filtered/redacted export, and downloads over native structured log files.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::logging_routes" + ], + "rust_tests": [ + "gateway-rs/tests/security_settings_parity.rs::live_logging_endpoints_match_python", + "gateway-rs/tests/security_settings_parity.rs::log_export_filters_records_and_redacts_nested_credentials" + ], + "source": { + "kind": "async_function", + "line": 169, + "path": "backend-services/routes/logging_routes.py" + }, + "status": "translated" + }, + { + "decorators": [ + "logging_router.get('/logs/statistics', description='Get log statistics for dashboard', response_model=ResponseModel, responses={200: {'description': 'Successful Response', 'content': {'application/json': {'example': {'total_logs': 1000, 'error_count': 50, 'warning_count': 100, 'info_count': 800, 'debug_count': 50, 'avg_response_time': 150.5, 'top_apis': [{'name': 'customer', 'count': 500}, {'name': 'orders', 'count': 300}], 'top_users': [{'name': 'john_doe', 'count': 200}, {'name': 'jane_smith', 'count': 150}], 'top_endpoints': [{'name': '/api/customer/v1/users', 'count': 100}, {'name': '/api/orders/v1/orders', 'count': 80}]}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/logging_routes.py::async_function:get_log_statistics", + "notes": "Rust preserves authenticated log querying, file listing, statistics, filtered/redacted export, and downloads over native structured log files.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::logging_routes" + ], + "rust_tests": [ + "gateway-rs/tests/security_settings_parity.rs::live_logging_endpoints_match_python", + "gateway-rs/tests/security_settings_parity.rs::log_export_filters_records_and_redacts_nested_credentials" + ], + "source": { + "kind": "async_function", + "line": 262, + "path": "backend-services/routes/logging_routes.py" + }, + "status": "translated" + }, + { + "decorators": [ + "logging_router.get('/logs/export', description='Export logs in various formats', response_model=ResponseModel, responses={200: {'description': 'Successful Response', 'content': {'application/json': {'example': {'format': 'json', 'data': '[{\"timestamp\": \"2024-01-01T12:00:00\", \"level\": \"INFO\"}]', 'filename': 'logs_export_20240101_120000.json'}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/logging_routes.py::async_function:export_logs", + "notes": "Rust preserves authenticated log querying, file listing, statistics, filtered/redacted export, and downloads over native structured log files.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::logging_routes" + ], + "rust_tests": [ + "gateway-rs/tests/security_settings_parity.rs::live_logging_endpoints_match_python", + "gateway-rs/tests/security_settings_parity.rs::log_export_filters_records_and_redacts_nested_credentials" + ], + "source": { + "kind": "async_function", + "line": 339, + "path": "backend-services/routes/logging_routes.py" + }, + "status": "translated" + }, + { + "decorators": [ + "logging_router.get('/logs/download', description='Download logs as file', include_in_schema=False, responses={200: {'description': 'File download', 'content': {'application/json': {}, 'text/csv': {}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/logging_routes.py::async_function:download_logs", + "notes": "Rust preserves authenticated log querying, file listing, statistics, filtered/redacted export, and downloads over native structured log files.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::logging_routes" + ], + "rust_tests": [ + "gateway-rs/tests/security_settings_parity.rs::live_logging_endpoints_match_python", + "gateway-rs/tests/security_settings_parity.rs::log_export_filters_records_and_redacts_nested_credentials" + ], + "source": { + "kind": "async_function", + "line": 435, + "path": "backend-services/routes/logging_routes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/memory_routes.py::module:memory_routes", + "notes": "Both encrypted memory dump/restore routes and optional request models are implemented natively. Rust matches manage_security gates and SEC codes, memory-mode and key checks, Pydantic path validation/coercion, encrypted round trips, response nesting, missing-file handling, and generic failure envelopes. Rust deliberately restricts snapshot paths to the configured dump directory rather than accepting arbitrary filesystem paths, so path-policy behavior is not 1:1.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::memory_dump", + "gateway-rs/src/routes/platform.rs::memory_restore", + "gateway-rs/src/routes/platform.rs::memory_request_path", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/tests/memory_routes_parity.rs::python_memory_route_contracts_in_isolated_processes" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/routes/memory_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/memory_routes.py::class:DumpRequest", + "notes": "Both encrypted memory dump/restore routes and optional request models are implemented natively. Rust matches manage_security gates and SEC codes, memory-mode and key checks, Pydantic path validation/coercion, encrypted round trips, response nesting, missing-file handling, and generic failure envelopes. Rust deliberately restricts snapshot paths to the configured dump directory rather than accepting arbitrary filesystem paths, so path-policy behavior is not 1:1.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::memory_dump", + "gateway-rs/src/routes/platform.rs::memory_restore", + "gateway-rs/src/routes/platform.rs::memory_request_path", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/tests/memory_routes_parity.rs::python_memory_route_contracts_in_isolated_processes" + ], + "source": { + "kind": "class", + "line": 24, + "path": "backend-services/routes/memory_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/memory_routes.py::field:DumpRequest.path", + "notes": "Both encrypted memory dump/restore routes and optional request models are implemented natively. Rust matches manage_security gates and SEC codes, memory-mode and key checks, Pydantic path validation/coercion, encrypted round trips, response nesting, missing-file handling, and generic failure envelopes. Rust deliberately restricts snapshot paths to the configured dump directory rather than accepting arbitrary filesystem paths, so path-policy behavior is not 1:1.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::memory_dump", + "gateway-rs/src/routes/platform.rs::memory_restore", + "gateway-rs/src/routes/platform.rs::memory_request_path", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/tests/memory_routes_parity.rs::python_memory_route_contracts_in_isolated_processes" + ], + "source": { + "kind": "field", + "line": 25, + "path": "backend-services/routes/memory_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "memory_router.post('/memory/dump', description='Dump in-memory database to an encrypted file', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/memory_routes.py::async_function:memory_dump", + "notes": "Both encrypted memory dump/restore routes and optional request models are implemented natively. Rust matches manage_security gates and SEC codes, memory-mode and key checks, Pydantic path validation/coercion, encrypted round trips, response nesting, missing-file handling, and generic failure envelopes. Rust deliberately restricts snapshot paths to the configured dump directory rather than accepting arbitrary filesystem paths, so path-policy behavior is not 1:1.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::memory_dump", + "gateway-rs/src/routes/platform.rs::memory_restore", + "gateway-rs/src/routes/platform.rs::memory_request_path", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/tests/memory_routes_parity.rs::python_memory_route_contracts_in_isolated_processes" + ], + "source": { + "kind": "async_function", + "line": 43, + "path": "backend-services/routes/memory_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/memory_routes.py::class:RestoreRequest", + "notes": "Both encrypted memory dump/restore routes and optional request models are implemented natively. Rust matches manage_security gates and SEC codes, memory-mode and key checks, Pydantic path validation/coercion, encrypted round trips, response nesting, missing-file handling, and generic failure envelopes. Rust deliberately restricts snapshot paths to the configured dump directory rather than accepting arbitrary filesystem paths, so path-policy behavior is not 1:1.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::memory_dump", + "gateway-rs/src/routes/platform.rs::memory_restore", + "gateway-rs/src/routes/platform.rs::memory_request_path", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/tests/memory_routes_parity.rs::python_memory_route_contracts_in_isolated_processes" + ], + "source": { + "kind": "class", + "line": 118, + "path": "backend-services/routes/memory_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/memory_routes.py::field:RestoreRequest.path", + "notes": "Both encrypted memory dump/restore routes and optional request models are implemented natively. Rust matches manage_security gates and SEC codes, memory-mode and key checks, Pydantic path validation/coercion, encrypted round trips, response nesting, missing-file handling, and generic failure envelopes. Rust deliberately restricts snapshot paths to the configured dump directory rather than accepting arbitrary filesystem paths, so path-policy behavior is not 1:1.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::memory_dump", + "gateway-rs/src/routes/platform.rs::memory_restore", + "gateway-rs/src/routes/platform.rs::memory_request_path", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/tests/memory_routes_parity.rs::python_memory_route_contracts_in_isolated_processes" + ], + "source": { + "kind": "field", + "line": 119, + "path": "backend-services/routes/memory_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "memory_router.post('/memory/restore', description='Restore in-memory database from an encrypted file', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/memory_routes.py::async_function:memory_restore", + "notes": "Both encrypted memory dump/restore routes and optional request models are implemented natively. Rust matches manage_security gates and SEC codes, memory-mode and key checks, Pydantic path validation/coercion, encrypted round trips, response nesting, missing-file handling, and generic failure envelopes. Rust deliberately restricts snapshot paths to the configured dump directory rather than accepting arbitrary filesystem paths, so path-policy behavior is not 1:1.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::memory_dump", + "gateway-rs/src/routes/platform.rs::memory_restore", + "gateway-rs/src/routes/platform.rs::memory_request_path", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/tests/memory_routes_parity.rs::python_memory_route_contracts_in_isolated_processes" + ], + "source": { + "kind": "async_function", + "line": 137, + "path": "backend-services/routes/memory_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/metrics_routes.py::module:metrics_routes", + "notes": "Rust preserves the Prometheus endpoint, enable flag, IP allowlist, bearer/query token extraction, authorization, and exposition counters.", + "rust_symbols": [ + "gateway-rs/src/routes/metrics.rs::metrics" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::prometheus_metrics_exposition_counters_allowlist_and_token_match_python" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/routes/metrics_routes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/metrics_routes.py::function:_env_flag", + "notes": "Rust preserves the Prometheus endpoint, enable flag, IP allowlist, bearer/query token extraction, authorization, and exposition counters.", + "rust_symbols": [ + "gateway-rs/src/routes/metrics.rs::metrics" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::prometheus_metrics_exposition_counters_allowlist_and_token_match_python" + ], + "source": { + "kind": "function", + "line": 16, + "path": "backend-services/routes/metrics_routes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/metrics_routes.py::function:_parse_allowlist", + "notes": "Rust preserves the Prometheus endpoint, enable flag, IP allowlist, bearer/query token extraction, authorization, and exposition counters.", + "rust_symbols": [ + "gateway-rs/src/routes/metrics.rs::metrics" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::prometheus_metrics_exposition_counters_allowlist_and_token_match_python" + ], + "source": { + "kind": "function", + "line": 23, + "path": "backend-services/routes/metrics_routes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/metrics_routes.py::function:_extract_token", + "notes": "Rust preserves the Prometheus endpoint, enable flag, IP allowlist, bearer/query token extraction, authorization, and exposition counters.", + "rust_symbols": [ + "gateway-rs/src/routes/metrics.rs::metrics" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::prometheus_metrics_exposition_counters_allowlist_and_token_match_python" + ], + "source": { + "kind": "function", + "line": 28, + "path": "backend-services/routes/metrics_routes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/metrics_routes.py::function:_metrics_allowed", + "notes": "Rust preserves the Prometheus endpoint, enable flag, IP allowlist, bearer/query token extraction, authorization, and exposition counters.", + "rust_symbols": [ + "gateway-rs/src/routes/metrics.rs::metrics" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::prometheus_metrics_exposition_counters_allowlist_and_token_match_python" + ], + "source": { + "kind": "function", + "line": 36, + "path": "backend-services/routes/metrics_routes.py" + }, + "status": "translated" + }, + { + "decorators": [ + "metrics_router.get('/metrics', include_in_schema=False)" + ], + "domain": "routes", + "id": "backend-services/routes/metrics_routes.py::async_function:metrics", + "notes": "Rust preserves the Prometheus endpoint, enable flag, IP allowlist, bearer/query token extraction, authorization, and exposition counters.", + "rust_symbols": [ + "gateway-rs/src/routes/metrics.rs::metrics" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::prometheus_metrics_exposition_counters_allowlist_and_token_match_python" + ], + "source": { + "kind": "async_function", + "line": 53, + "path": "backend-services/routes/metrics_routes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/monitor_routes.py::module:monitor_routes", + "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness now matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. Metrics aggregation and report sections are present, but exact range/group/sort aggregation, Python date parsing, log-backed report reconstruction, daily bandwidth rows, and dynamic filenames remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::readiness", + "gateway-rs/src/routes/platform.rs::monitor_metrics", + "gateway-rs/src/routes/platform.rs::monitor_report" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::monitor_dashboard_liveness_readiness_and_metrics_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_report_returns_python_compatible_csv_sections", + "gateway-rs/tests/platform_native.rs::readiness_degrades_when_an_active_grpc_api_lacks_a_descriptor", + "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/routes/monitor_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/monitor_routes.py::class:LivenessResponse", + "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness now matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. Metrics aggregation and report sections are present, but exact range/group/sort aggregation, Python date parsing, log-backed report reconstruction, daily bandwidth rows, and dynamic filenames remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::readiness", + "gateway-rs/src/routes/platform.rs::monitor_metrics", + "gateway-rs/src/routes/platform.rs::monitor_report" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::monitor_dashboard_liveness_readiness_and_metrics_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_report_returns_python_compatible_csv_sections", + "gateway-rs/tests/platform_native.rs::readiness_degrades_when_an_active_grpc_api_lacks_a_descriptor", + "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health" + ], + "source": { + "kind": "class", + "line": 27, + "path": "backend-services/routes/monitor_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/monitor_routes.py::field:LivenessResponse.status", + "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness now matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. Metrics aggregation and report sections are present, but exact range/group/sort aggregation, Python date parsing, log-backed report reconstruction, daily bandwidth rows, and dynamic filenames remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::readiness", + "gateway-rs/src/routes/platform.rs::monitor_metrics", + "gateway-rs/src/routes/platform.rs::monitor_report" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::monitor_dashboard_liveness_readiness_and_metrics_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_report_returns_python_compatible_csv_sections", + "gateway-rs/tests/platform_native.rs::readiness_degrades_when_an_active_grpc_api_lacks_a_descriptor", + "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health" + ], + "source": { + "kind": "field", + "line": 28, + "path": "backend-services/routes/monitor_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/monitor_routes.py::class:ReadinessResponse", + "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness now matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. Metrics aggregation and report sections are present, but exact range/group/sort aggregation, Python date parsing, log-backed report reconstruction, daily bandwidth rows, and dynamic filenames remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::readiness", + "gateway-rs/src/routes/platform.rs::monitor_metrics", + "gateway-rs/src/routes/platform.rs::monitor_report" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::monitor_dashboard_liveness_readiness_and_metrics_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_report_returns_python_compatible_csv_sections", + "gateway-rs/tests/platform_native.rs::readiness_degrades_when_an_active_grpc_api_lacks_a_descriptor", + "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health" + ], + "source": { + "kind": "class", + "line": 31, + "path": "backend-services/routes/monitor_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/monitor_routes.py::field:ReadinessResponse.status", + "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness now matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. Metrics aggregation and report sections are present, but exact range/group/sort aggregation, Python date parsing, log-backed report reconstruction, daily bandwidth rows, and dynamic filenames remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::readiness", + "gateway-rs/src/routes/platform.rs::monitor_metrics", + "gateway-rs/src/routes/platform.rs::monitor_report" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::monitor_dashboard_liveness_readiness_and_metrics_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_report_returns_python_compatible_csv_sections", + "gateway-rs/tests/platform_native.rs::readiness_degrades_when_an_active_grpc_api_lacks_a_descriptor", + "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health" + ], + "source": { + "kind": "field", + "line": 32, + "path": "backend-services/routes/monitor_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/monitor_routes.py::field:ReadinessResponse.mongodb", + "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness now matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. Metrics aggregation and report sections are present, but exact range/group/sort aggregation, Python date parsing, log-backed report reconstruction, daily bandwidth rows, and dynamic filenames remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::readiness", + "gateway-rs/src/routes/platform.rs::monitor_metrics", + "gateway-rs/src/routes/platform.rs::monitor_report" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::monitor_dashboard_liveness_readiness_and_metrics_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_report_returns_python_compatible_csv_sections", + "gateway-rs/tests/platform_native.rs::readiness_degrades_when_an_active_grpc_api_lacks_a_descriptor", + "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health" + ], + "source": { + "kind": "field", + "line": 33, + "path": "backend-services/routes/monitor_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/monitor_routes.py::field:ReadinessResponse.redis", + "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness now matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. Metrics aggregation and report sections are present, but exact range/group/sort aggregation, Python date parsing, log-backed report reconstruction, daily bandwidth rows, and dynamic filenames remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::readiness", + "gateway-rs/src/routes/platform.rs::monitor_metrics", + "gateway-rs/src/routes/platform.rs::monitor_report" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::monitor_dashboard_liveness_readiness_and_metrics_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_report_returns_python_compatible_csv_sections", + "gateway-rs/tests/platform_native.rs::readiness_degrades_when_an_active_grpc_api_lacks_a_descriptor", + "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health" + ], + "source": { + "kind": "field", + "line": 34, + "path": "backend-services/routes/monitor_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/monitor_routes.py::field:ReadinessResponse.mode", + "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness now matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. Metrics aggregation and report sections are present, but exact range/group/sort aggregation, Python date parsing, log-backed report reconstruction, daily bandwidth rows, and dynamic filenames remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::readiness", + "gateway-rs/src/routes/platform.rs::monitor_metrics", + "gateway-rs/src/routes/platform.rs::monitor_report" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::monitor_dashboard_liveness_readiness_and_metrics_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_report_returns_python_compatible_csv_sections", + "gateway-rs/tests/platform_native.rs::readiness_degrades_when_an_active_grpc_api_lacks_a_descriptor", + "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health" + ], + "source": { + "kind": "field", + "line": 35, + "path": "backend-services/routes/monitor_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/monitor_routes.py::field:ReadinessResponse.cache_backend", + "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness now matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. Metrics aggregation and report sections are present, but exact range/group/sort aggregation, Python date parsing, log-backed report reconstruction, daily bandwidth rows, and dynamic filenames remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::readiness", + "gateway-rs/src/routes/platform.rs::monitor_metrics", + "gateway-rs/src/routes/platform.rs::monitor_report" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::monitor_dashboard_liveness_readiness_and_metrics_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_report_returns_python_compatible_csv_sections", + "gateway-rs/tests/platform_native.rs::readiness_degrades_when_an_active_grpc_api_lacks_a_descriptor", + "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health" + ], + "source": { + "kind": "field", + "line": 36, + "path": "backend-services/routes/monitor_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/monitor_routes.py::field:ReadinessResponse.missing_grpc_descriptors", + "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness now matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. Metrics aggregation and report sections are present, but exact range/group/sort aggregation, Python date parsing, log-backed report reconstruction, daily bandwidth rows, and dynamic filenames remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::readiness", + "gateway-rs/src/routes/platform.rs::monitor_metrics", + "gateway-rs/src/routes/platform.rs::monitor_report" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::monitor_dashboard_liveness_readiness_and_metrics_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_report_returns_python_compatible_csv_sections", + "gateway-rs/tests/platform_native.rs::readiness_degrades_when_an_active_grpc_api_lacks_a_descriptor", + "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health" + ], + "source": { + "kind": "field", + "line": 37, + "path": "backend-services/routes/monitor_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/monitor_routes.py::field:ReadinessResponse.grpc_descriptor_errors", + "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness now matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. Metrics aggregation and report sections are present, but exact range/group/sort aggregation, Python date parsing, log-backed report reconstruction, daily bandwidth rows, and dynamic filenames remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::readiness", + "gateway-rs/src/routes/platform.rs::monitor_metrics", + "gateway-rs/src/routes/platform.rs::monitor_report" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::monitor_dashboard_liveness_readiness_and_metrics_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_report_returns_python_compatible_csv_sections", + "gateway-rs/tests/platform_native.rs::readiness_degrades_when_an_active_grpc_api_lacks_a_descriptor", + "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health" + ], + "source": { + "kind": "field", + "line": 38, + "path": "backend-services/routes/monitor_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "monitor_router.get('/monitor/metrics', description='Get aggregated gateway metrics', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/monitor_routes.py::async_function:get_metrics", + "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness now matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. Metrics aggregation and report sections are present, but exact range/group/sort aggregation, Python date parsing, log-backed report reconstruction, daily bandwidth rows, and dynamic filenames remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::readiness", + "gateway-rs/src/routes/platform.rs::monitor_metrics", + "gateway-rs/src/routes/platform.rs::monitor_report" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::monitor_dashboard_liveness_readiness_and_metrics_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_report_returns_python_compatible_csv_sections", + "gateway-rs/tests/platform_native.rs::readiness_degrades_when_an_active_grpc_api_lacks_a_descriptor", + "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health" + ], + "source": { + "kind": "async_function", + "line": 57, + "path": "backend-services/routes/monitor_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/monitor_routes.py::function:get_metrics._name", + "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness now matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. Metrics aggregation and report sections are present, but exact range/group/sort aggregation, Python date parsing, log-backed report reconstruction, daily bandwidth rows, and dynamic filenames remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::readiness", + "gateway-rs/src/routes/platform.rs::monitor_metrics", + "gateway-rs/src/routes/platform.rs::monitor_report" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::monitor_dashboard_liveness_readiness_and_metrics_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_report_returns_python_compatible_csv_sections", + "gateway-rs/tests/platform_native.rs::readiness_degrades_when_an_active_grpc_api_lacks_a_descriptor", + "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health" + ], + "source": { + "kind": "function", + "line": 91, + "path": "backend-services/routes/monitor_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "monitor_router.get('/monitor/liveness', description='Kubernetes liveness probe endpoint (no auth)', response_model=LivenessResponse)" + ], + "domain": "routes", + "id": "backend-services/routes/monitor_routes.py::async_function:liveness", + "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness now matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. Metrics aggregation and report sections are present, but exact range/group/sort aggregation, Python date parsing, log-backed report reconstruction, daily bandwidth rows, and dynamic filenames remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::readiness", + "gateway-rs/src/routes/platform.rs::monitor_metrics", + "gateway-rs/src/routes/platform.rs::monitor_report" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::monitor_dashboard_liveness_readiness_and_metrics_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_report_returns_python_compatible_csv_sections", + "gateway-rs/tests/platform_native.rs::readiness_degrades_when_an_active_grpc_api_lacks_a_descriptor", + "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health" + ], + "source": { + "kind": "async_function", + "line": 158, + "path": "backend-services/routes/monitor_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "monitor_router.get('/monitor/readiness', description='Kubernetes readiness probe endpoint. Detailed status requires manage_gateway permission.', response_model=ReadinessResponse)" + ], + "domain": "routes", + "id": "backend-services/routes/monitor_routes.py::async_function:readiness", + "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness now matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. Metrics aggregation and report sections are present, but exact range/group/sort aggregation, Python date parsing, log-backed report reconstruction, daily bandwidth rows, and dynamic filenames remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::readiness", + "gateway-rs/src/routes/platform.rs::monitor_metrics", + "gateway-rs/src/routes/platform.rs::monitor_report" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::monitor_dashboard_liveness_readiness_and_metrics_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_report_returns_python_compatible_csv_sections", + "gateway-rs/tests/platform_native.rs::readiness_degrades_when_an_active_grpc_api_lacks_a_descriptor", + "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health" + ], + "source": { + "kind": "async_function", + "line": 177, + "path": "backend-services/routes/monitor_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "monitor_router.get('/monitor/report', description='Generate a CSV report for a date range (requires manage_gateway)', include_in_schema=False)" + ], + "domain": "routes", + "id": "backend-services/routes/monitor_routes.py::async_function:generate_report", + "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness now matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. Metrics aggregation and report sections are present, but exact range/group/sort aggregation, Python date parsing, log-backed report reconstruction, daily bandwidth rows, and dynamic filenames remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::readiness", + "gateway-rs/src/routes/platform.rs::monitor_metrics", + "gateway-rs/src/routes/platform.rs::monitor_report" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::monitor_dashboard_liveness_readiness_and_metrics_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_report_returns_python_compatible_csv_sections", + "gateway-rs/tests/platform_native.rs::readiness_degrades_when_an_active_grpc_api_lacks_a_descriptor", + "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health" + ], + "source": { + "kind": "async_function", + "line": 235, + "path": "backend-services/routes/monitor_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/monitor_routes.py::function:generate_report._parse_ts", + "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness now matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. Metrics aggregation and report sections are present, but exact range/group/sort aggregation, Python date parsing, log-backed report reconstruction, daily bandwidth rows, and dynamic filenames remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::readiness", + "gateway-rs/src/routes/platform.rs::monitor_metrics", + "gateway-rs/src/routes/platform.rs::monitor_report" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::monitor_dashboard_liveness_readiness_and_metrics_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_report_returns_python_compatible_csv_sections", + "gateway-rs/tests/platform_native.rs::readiness_degrades_when_an_active_grpc_api_lacks_a_descriptor", + "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health" + ], + "source": { + "kind": "function", + "line": 252, + "path": "backend-services/routes/monitor_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/monitor_routes.py::function:generate_report._to_date_time", + "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness now matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. Metrics aggregation and report sections are present, but exact range/group/sort aggregation, Python date parsing, log-backed report reconstruction, daily bandwidth rows, and dynamic filenames remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::readiness", + "gateway-rs/src/routes/platform.rs::monitor_metrics", + "gateway-rs/src/routes/platform.rs::monitor_report" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::monitor_dashboard_liveness_readiness_and_metrics_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_report_returns_python_compatible_csv_sections", + "gateway-rs/tests/platform_native.rs::readiness_degrades_when_an_active_grpc_api_lacks_a_descriptor", + "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health" + ], + "source": { + "kind": "function", + "line": 276, + "path": "backend-services/routes/monitor_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/monitor_routes.py::function:generate_report._api_from_endpoint", + "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness now matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. Metrics aggregation and report sections are present, but exact range/group/sort aggregation, Python date parsing, log-backed report reconstruction, daily bandwidth rows, and dynamic filenames remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::readiness", + "gateway-rs/src/routes/platform.rs::monitor_metrics", + "gateway-rs/src/routes/platform.rs::monitor_report" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::monitor_dashboard_liveness_readiness_and_metrics_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_report_returns_python_compatible_csv_sections", + "gateway-rs/tests/platform_native.rs::readiness_degrades_when_an_active_grpc_api_lacks_a_descriptor", + "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health" + ], + "source": { + "kind": "function", + "line": 304, + "path": "backend-services/routes/monitor_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/openapi_routes.py::module:openapi_routes", + "notes": "All four OpenAPI discovery routes and both helpers are implemented natively. Rust now matches manage_apis/manage_endpoints boundaries, route-specific errors and messages, ordered multi-server fetching, parsed endpoint shape, cached reads, refresh summary responses, fetch-on-import behavior, duplicate skipping, description truncation, and parse previews. Rust persists fetched specs with the API record instead of using Python's process-local one-hour cache, and exact malformed nested-spec exceptions/storage failure envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::openapi_discovery_route", + "gateway-rs/src/routes/platform.rs::fetch_openapi_spec", + "gateway-rs/src/routes/discovery.rs::parse_openapi", + "gateway-rs/src/routes/discovery.rs::openapi_endpoints" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::discovery_permissions_and_missing_document_contracts_match_python", + "gateway-rs/tests/platform_native.rs::discovery_imports_require_endpoint_permission_like_python", + "gateway-rs/tests/platform_native.rs::discovery_document_reads_fetch_once_and_reuse_the_python_cache_contract" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/routes/openapi_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/openapi_routes.py::async_function:_fetch_upstream_openapi", + "notes": "All four OpenAPI discovery routes and both helpers are implemented natively. Rust now matches manage_apis/manage_endpoints boundaries, route-specific errors and messages, ordered multi-server fetching, parsed endpoint shape, cached reads, refresh summary responses, fetch-on-import behavior, duplicate skipping, description truncation, and parse previews. Rust persists fetched specs with the API record instead of using Python's process-local one-hour cache, and exact malformed nested-spec exceptions/storage failure envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::openapi_discovery_route", + "gateway-rs/src/routes/platform.rs::fetch_openapi_spec", + "gateway-rs/src/routes/discovery.rs::parse_openapi", + "gateway-rs/src/routes/discovery.rs::openapi_endpoints" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::discovery_permissions_and_missing_document_contracts_match_python", + "gateway-rs/tests/platform_native.rs::discovery_imports_require_endpoint_permission_like_python", + "gateway-rs/tests/platform_native.rs::discovery_document_reads_fetch_once_and_reuse_the_python_cache_contract" + ], + "source": { + "kind": "async_function", + "line": 31, + "path": "backend-services/routes/openapi_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/openapi_routes.py::function:_parse_openapi_endpoints", + "notes": "All four OpenAPI discovery routes and both helpers are implemented natively. Rust now matches manage_apis/manage_endpoints boundaries, route-specific errors and messages, ordered multi-server fetching, parsed endpoint shape, cached reads, refresh summary responses, fetch-on-import behavior, duplicate skipping, description truncation, and parse previews. Rust persists fetched specs with the API record instead of using Python's process-local one-hour cache, and exact malformed nested-spec exceptions/storage failure envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::openapi_discovery_route", + "gateway-rs/src/routes/platform.rs::fetch_openapi_spec", + "gateway-rs/src/routes/discovery.rs::parse_openapi", + "gateway-rs/src/routes/discovery.rs::openapi_endpoints" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::discovery_permissions_and_missing_document_contracts_match_python", + "gateway-rs/tests/platform_native.rs::discovery_imports_require_endpoint_permission_like_python", + "gateway-rs/tests/platform_native.rs::discovery_document_reads_fetch_once_and_reuse_the_python_cache_contract" + ], + "source": { + "kind": "function", + "line": 55, + "path": "backend-services/routes/openapi_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "openapi_router.get('/platform/api/{api_name}/{api_version}/openapi')" + ], + "domain": "routes", + "id": "backend-services/routes/openapi_routes.py::async_function:get_openapi_spec", + "notes": "All four OpenAPI discovery routes and both helpers are implemented natively. Rust now matches manage_apis/manage_endpoints boundaries, route-specific errors and messages, ordered multi-server fetching, parsed endpoint shape, cached reads, refresh summary responses, fetch-on-import behavior, duplicate skipping, description truncation, and parse previews. Rust persists fetched specs with the API record instead of using Python's process-local one-hour cache, and exact malformed nested-spec exceptions/storage failure envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::openapi_discovery_route", + "gateway-rs/src/routes/platform.rs::fetch_openapi_spec", + "gateway-rs/src/routes/discovery.rs::parse_openapi", + "gateway-rs/src/routes/discovery.rs::openapi_endpoints" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::discovery_permissions_and_missing_document_contracts_match_python", + "gateway-rs/tests/platform_native.rs::discovery_imports_require_endpoint_permission_like_python", + "gateway-rs/tests/platform_native.rs::discovery_document_reads_fetch_once_and_reuse_the_python_cache_contract" + ], + "source": { + "kind": "async_function", + "line": 128, + "path": "backend-services/routes/openapi_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "openapi_router.post('/platform/api/{api_name}/{api_version}/openapi/refresh')" + ], + "domain": "routes", + "id": "backend-services/routes/openapi_routes.py::async_function:refresh_openapi_spec", + "notes": "All four OpenAPI discovery routes and both helpers are implemented natively. Rust now matches manage_apis/manage_endpoints boundaries, route-specific errors and messages, ordered multi-server fetching, parsed endpoint shape, cached reads, refresh summary responses, fetch-on-import behavior, duplicate skipping, description truncation, and parse previews. Rust persists fetched specs with the API record instead of using Python's process-local one-hour cache, and exact malformed nested-spec exceptions/storage failure envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::openapi_discovery_route", + "gateway-rs/src/routes/platform.rs::fetch_openapi_spec", + "gateway-rs/src/routes/discovery.rs::parse_openapi", + "gateway-rs/src/routes/discovery.rs::openapi_endpoints" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::discovery_permissions_and_missing_document_contracts_match_python", + "gateway-rs/tests/platform_native.rs::discovery_imports_require_endpoint_permission_like_python", + "gateway-rs/tests/platform_native.rs::discovery_document_reads_fetch_once_and_reuse_the_python_cache_contract" + ], + "source": { + "kind": "async_function", + "line": 209, + "path": "backend-services/routes/openapi_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "openapi_router.post('/platform/api/{api_name}/{api_version}/openapi/import')" + ], + "domain": "routes", + "id": "backend-services/routes/openapi_routes.py::async_function:import_openapi_endpoints", + "notes": "All four OpenAPI discovery routes and both helpers are implemented natively. Rust now matches manage_apis/manage_endpoints boundaries, route-specific errors and messages, ordered multi-server fetching, parsed endpoint shape, cached reads, refresh summary responses, fetch-on-import behavior, duplicate skipping, description truncation, and parse previews. Rust persists fetched specs with the API record instead of using Python's process-local one-hour cache, and exact malformed nested-spec exceptions/storage failure envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::openapi_discovery_route", + "gateway-rs/src/routes/platform.rs::fetch_openapi_spec", + "gateway-rs/src/routes/discovery.rs::parse_openapi", + "gateway-rs/src/routes/discovery.rs::openapi_endpoints" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::discovery_permissions_and_missing_document_contracts_match_python", + "gateway-rs/tests/platform_native.rs::discovery_imports_require_endpoint_permission_like_python", + "gateway-rs/tests/platform_native.rs::discovery_document_reads_fetch_once_and_reuse_the_python_cache_contract" + ], + "source": { + "kind": "async_function", + "line": 286, + "path": "backend-services/routes/openapi_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "openapi_router.post('/platform/openapi/parse')" + ], + "domain": "routes", + "id": "backend-services/routes/openapi_routes.py::async_function:parse_openapi_spec", + "notes": "All four OpenAPI discovery routes and both helpers are implemented natively. Rust now matches manage_apis/manage_endpoints boundaries, route-specific errors and messages, ordered multi-server fetching, parsed endpoint shape, cached reads, refresh summary responses, fetch-on-import behavior, duplicate skipping, description truncation, and parse previews. Rust persists fetched specs with the API record instead of using Python's process-local one-hour cache, and exact malformed nested-spec exceptions/storage failure envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::openapi_discovery_route", + "gateway-rs/src/routes/platform.rs::fetch_openapi_spec", + "gateway-rs/src/routes/discovery.rs::parse_openapi", + "gateway-rs/src/routes/discovery.rs::openapi_endpoints" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::discovery_permissions_and_missing_document_contracts_match_python", + "gateway-rs/tests/platform_native.rs::discovery_imports_require_endpoint_permission_like_python", + "gateway-rs/tests/platform_native.rs::discovery_document_reads_fetch_once_and_reuse_the_python_cache_contract" + ], + "source": { + "kind": "async_function", + "line": 390, + "path": "backend-services/routes/openapi_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/proto_routes.py::module:proto_routes", + "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust now matches operation-specific AUTH001/API008 permission errors, case-insensitive filename extension handling, Python's ignored client filename, retrieval message/API002 miss, update message, nullable descriptor deletion, and delete-always-success behavior. Filesystem archive/package-init helpers are obsolete in the native runtime, while exact compiler diagnostics and every validation error string remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::proto_routes", + "gateway-rs/src/routes/platform.rs::compile_proto", + "gateway-rs/src/routes/platform.rs::backfill_grpc_descriptors" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract", + "gateway-rs/tests/platform_native.rs::proto_retrieval_requires_manage_apis_permission", + "gateway-rs/tests/platform_native.rs::descriptor_backfill_compiles_active_grpc_apis_missing_descriptors" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/routes/proto_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/proto_routes.py::function:sanitize_filename", + "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust now matches operation-specific AUTH001/API008 permission errors, case-insensitive filename extension handling, Python's ignored client filename, retrieval message/API002 miss, update message, nullable descriptor deletion, and delete-always-success behavior. Filesystem archive/package-init helpers are obsolete in the native runtime, while exact compiler diagnostics and every validation error string remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::proto_routes", + "gateway-rs/src/routes/platform.rs::compile_proto", + "gateway-rs/src/routes/platform.rs::backfill_grpc_descriptors" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract", + "gateway-rs/tests/platform_native.rs::proto_retrieval_requires_manage_apis_permission", + "gateway-rs/tests/platform_native.rs::descriptor_backfill_compiles_active_grpc_apis_missing_descriptors" + ], + "source": { + "kind": "function", + "line": 36, + "path": "backend-services/routes/proto_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/proto_routes.py::function:validate_path", + "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust now matches operation-specific AUTH001/API008 permission errors, case-insensitive filename extension handling, Python's ignored client filename, retrieval message/API002 miss, update message, nullable descriptor deletion, and delete-always-success behavior. Filesystem archive/package-init helpers are obsolete in the native runtime, while exact compiler diagnostics and every validation error string remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::proto_routes", + "gateway-rs/src/routes/platform.rs::compile_proto", + "gateway-rs/src/routes/platform.rs::backfill_grpc_descriptors" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract", + "gateway-rs/tests/platform_native.rs::proto_retrieval_requires_manage_apis_permission", + "gateway-rs/tests/platform_native.rs::descriptor_backfill_compiles_active_grpc_apis_missing_descriptors" + ], + "source": { + "kind": "function", + "line": 72, + "path": "backend-services/routes/proto_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/proto_routes.py::function:validate_proto_content", + "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust now matches operation-specific AUTH001/API008 permission errors, case-insensitive filename extension handling, Python's ignored client filename, retrieval message/API002 miss, update message, nullable descriptor deletion, and delete-always-success behavior. Filesystem archive/package-init helpers are obsolete in the native runtime, while exact compiler diagnostics and every validation error string remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::proto_routes", + "gateway-rs/src/routes/platform.rs::compile_proto", + "gateway-rs/src/routes/platform.rs::backfill_grpc_descriptors" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract", + "gateway-rs/tests/platform_native.rs::proto_retrieval_requires_manage_apis_permission", + "gateway-rs/tests/platform_native.rs::descriptor_backfill_compiles_active_grpc_apis_missing_descriptors" + ], + "source": { + "kind": "function", + "line": 103, + "path": "backend-services/routes/proto_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/proto_routes.py::function:_extract_package_name", + "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust now matches operation-specific AUTH001/API008 permission errors, case-insensitive filename extension handling, Python's ignored client filename, retrieval message/API002 miss, update message, nullable descriptor deletion, and delete-always-success behavior. Filesystem archive/package-init helpers are obsolete in the native runtime, while exact compiler diagnostics and every validation error string remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::proto_routes", + "gateway-rs/src/routes/platform.rs::compile_proto", + "gateway-rs/src/routes/platform.rs::backfill_grpc_descriptors" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract", + "gateway-rs/tests/platform_native.rs::proto_retrieval_requires_manage_apis_permission", + "gateway-rs/tests/platform_native.rs::descriptor_backfill_compiles_active_grpc_apis_missing_descriptors" + ], + "source": { + "kind": "function", + "line": 131, + "path": "backend-services/routes/proto_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/proto_routes.py::function:_ensure_package_inits", + "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust now matches operation-specific AUTH001/API008 permission errors, case-insensitive filename extension handling, Python's ignored client filename, retrieval message/API002 miss, update message, nullable descriptor deletion, and delete-always-success behavior. Filesystem archive/package-init helpers are obsolete in the native runtime, while exact compiler diagnostics and every validation error string remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::proto_routes", + "gateway-rs/src/routes/platform.rs::compile_proto", + "gateway-rs/src/routes/platform.rs::backfill_grpc_descriptors" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract", + "gateway-rs/tests/platform_native.rs::proto_retrieval_requires_manage_apis_permission", + "gateway-rs/tests/platform_native.rs::descriptor_backfill_compiles_active_grpc_apis_missing_descriptors" + ], + "source": { + "kind": "function", + "line": 144, + "path": "backend-services/routes/proto_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/proto_routes.py::function:get_safe_proto_path", + "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust now matches operation-specific AUTH001/API008 permission errors, case-insensitive filename extension handling, Python's ignored client filename, retrieval message/API002 miss, update message, nullable descriptor deletion, and delete-always-success behavior. Filesystem archive/package-init helpers are obsolete in the native runtime, while exact compiler diagnostics and every validation error string remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::proto_routes", + "gateway-rs/src/routes/platform.rs::compile_proto", + "gateway-rs/src/routes/platform.rs::backfill_grpc_descriptors" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract", + "gateway-rs/tests/platform_native.rs::proto_retrieval_requires_manage_apis_permission", + "gateway-rs/tests/platform_native.rs::descriptor_backfill_compiles_active_grpc_apis_missing_descriptors" + ], + "source": { + "kind": "function", + "line": 162, + "path": "backend-services/routes/proto_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/proto_routes.py::function:compile_descriptor_fields", + "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust now matches operation-specific AUTH001/API008 permission errors, case-insensitive filename extension handling, Python's ignored client filename, retrieval message/API002 miss, update message, nullable descriptor deletion, and delete-always-success behavior. Filesystem archive/package-init helpers are obsolete in the native runtime, while exact compiler diagnostics and every validation error string remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::proto_routes", + "gateway-rs/src/routes/platform.rs::compile_proto", + "gateway-rs/src/routes/platform.rs::backfill_grpc_descriptors" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract", + "gateway-rs/tests/platform_native.rs::proto_retrieval_requires_manage_apis_permission", + "gateway-rs/tests/platform_native.rs::descriptor_backfill_compiles_active_grpc_apis_missing_descriptors" + ], + "source": { + "kind": "function", + "line": 183, + "path": "backend-services/routes/proto_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/proto_routes.py::async_function:persist_descriptor_set", + "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust now matches operation-specific AUTH001/API008 permission errors, case-insensitive filename extension handling, Python's ignored client filename, retrieval message/API002 miss, update message, nullable descriptor deletion, and delete-always-success behavior. Filesystem archive/package-init helpers are obsolete in the native runtime, while exact compiler diagnostics and every validation error string remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::proto_routes", + "gateway-rs/src/routes/platform.rs::compile_proto", + "gateway-rs/src/routes/platform.rs::backfill_grpc_descriptors" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract", + "gateway-rs/tests/platform_native.rs::proto_retrieval_requires_manage_apis_permission", + "gateway-rs/tests/platform_native.rs::descriptor_backfill_compiles_active_grpc_apis_missing_descriptors" + ], + "source": { + "kind": "async_function", + "line": 209, + "path": "backend-services/routes/proto_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/proto_routes.py::function:archive_existing_proto", + "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust now matches operation-specific AUTH001/API008 permission errors, case-insensitive filename extension handling, Python's ignored client filename, retrieval message/API002 miss, update message, nullable descriptor deletion, and delete-always-success behavior. Filesystem archive/package-init helpers are obsolete in the native runtime, while exact compiler diagnostics and every validation error string remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::proto_routes", + "gateway-rs/src/routes/platform.rs::compile_proto", + "gateway-rs/src/routes/platform.rs::backfill_grpc_descriptors" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract", + "gateway-rs/tests/platform_native.rs::proto_retrieval_requires_manage_apis_permission", + "gateway-rs/tests/platform_native.rs::descriptor_backfill_compiles_active_grpc_apis_missing_descriptors" + ], + "source": { + "kind": "function", + "line": 221, + "path": "backend-services/routes/proto_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/proto_routes.py::async_function:backfill_descriptor_sets", + "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust now matches operation-specific AUTH001/API008 permission errors, case-insensitive filename extension handling, Python's ignored client filename, retrieval message/API002 miss, update message, nullable descriptor deletion, and delete-always-success behavior. Filesystem archive/package-init helpers are obsolete in the native runtime, while exact compiler diagnostics and every validation error string remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::proto_routes", + "gateway-rs/src/routes/platform.rs::compile_proto", + "gateway-rs/src/routes/platform.rs::backfill_grpc_descriptors" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract", + "gateway-rs/tests/platform_native.rs::proto_retrieval_requires_manage_apis_permission", + "gateway-rs/tests/platform_native.rs::descriptor_backfill_compiles_active_grpc_apis_missing_descriptors" + ], + "source": { + "kind": "async_function", + "line": 270, + "path": "backend-services/routes/proto_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "proto_router.post('/descriptors/backfill', description='Backfill language-neutral descriptors for existing gRPC APIs', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/proto_routes.py::async_function:backfill_descriptors", + "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust now matches operation-specific AUTH001/API008 permission errors, case-insensitive filename extension handling, Python's ignored client filename, retrieval message/API002 miss, update message, nullable descriptor deletion, and delete-always-success behavior. Filesystem archive/package-init helpers are obsolete in the native runtime, while exact compiler diagnostics and every validation error string remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::proto_routes", + "gateway-rs/src/routes/platform.rs::compile_proto", + "gateway-rs/src/routes/platform.rs::backfill_grpc_descriptors" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract", + "gateway-rs/tests/platform_native.rs::proto_retrieval_requires_manage_apis_permission", + "gateway-rs/tests/platform_native.rs::descriptor_backfill_compiles_active_grpc_apis_missing_descriptors" + ], + "source": { + "kind": "async_function", + "line": 329, + "path": "backend-services/routes/proto_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "proto_router.post('/{api_name}/{api_version}', description='Upload proto file', response_model=ResponseModel, responses={200: {'description': 'Successful Response', 'content': {'application/json': {'example': {'message': 'Proto file uploaded successfully'}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/proto_routes.py::async_function:upload_proto_file", + "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust now matches operation-specific AUTH001/API008 permission errors, case-insensitive filename extension handling, Python's ignored client filename, retrieval message/API002 miss, update message, nullable descriptor deletion, and delete-always-success behavior. Filesystem archive/package-init helpers are obsolete in the native runtime, while exact compiler diagnostics and every validation error string remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::proto_routes", + "gateway-rs/src/routes/platform.rs::compile_proto", + "gateway-rs/src/routes/platform.rs::backfill_grpc_descriptors" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract", + "gateway-rs/tests/platform_native.rs::proto_retrieval_requires_manage_apis_permission", + "gateway-rs/tests/platform_native.rs::descriptor_backfill_compiles_active_grpc_apis_missing_descriptors" + ], + "source": { + "kind": "async_function", + "line": 378, + "path": "backend-services/routes/proto_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "proto_router.get('/{api_name}/{api_version}', description='Get proto file', response_model=ResponseModel, responses={200: {'description': 'Successful Response', 'content': {'application/json': {'example': {'message': 'Proto file retrieved successfully'}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/proto_routes.py::async_function:get_proto_file", + "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust now matches operation-specific AUTH001/API008 permission errors, case-insensitive filename extension handling, Python's ignored client filename, retrieval message/API002 miss, update message, nullable descriptor deletion, and delete-always-success behavior. Filesystem archive/package-init helpers are obsolete in the native runtime, while exact compiler diagnostics and every validation error string remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::proto_routes", + "gateway-rs/src/routes/platform.rs::compile_proto", + "gateway-rs/src/routes/platform.rs::backfill_grpc_descriptors" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract", + "gateway-rs/tests/platform_native.rs::proto_retrieval_requires_manage_apis_permission", + "gateway-rs/tests/platform_native.rs::descriptor_backfill_compiles_active_grpc_apis_missing_descriptors" + ], + "source": { + "kind": "async_function", + "line": 632, + "path": "backend-services/routes/proto_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "proto_router.put('/{api_name}/{api_version}', description='Update proto file', response_model=ResponseModel, responses={200: {'description': 'Successful Response', 'content': {'application/json': {'example': {'message': 'Proto file updated successfully'}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/proto_routes.py::async_function:update_proto_file", + "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust now matches operation-specific AUTH001/API008 permission errors, case-insensitive filename extension handling, Python's ignored client filename, retrieval message/API002 miss, update message, nullable descriptor deletion, and delete-always-success behavior. Filesystem archive/package-init helpers are obsolete in the native runtime, while exact compiler diagnostics and every validation error string remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::proto_routes", + "gateway-rs/src/routes/platform.rs::compile_proto", + "gateway-rs/src/routes/platform.rs::backfill_grpc_descriptors" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract", + "gateway-rs/tests/platform_native.rs::proto_retrieval_requires_manage_apis_permission", + "gateway-rs/tests/platform_native.rs::descriptor_backfill_compiles_active_grpc_apis_missing_descriptors" + ], + "source": { + "kind": "async_function", + "line": 722, + "path": "backend-services/routes/proto_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "proto_router.delete('/{api_name}/{api_version}', description='Delete proto file', response_model=ResponseModel, responses={200: {'description': 'Successful Response', 'content': {'application/json': {'example': {'message': 'Proto file deleted successfully'}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/proto_routes.py::async_function:delete_proto_file", + "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust now matches operation-specific AUTH001/API008 permission errors, case-insensitive filename extension handling, Python's ignored client filename, retrieval message/API002 miss, update message, nullable descriptor deletion, and delete-always-success behavior. Filesystem archive/package-init helpers are obsolete in the native runtime, while exact compiler diagnostics and every validation error string remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::proto_routes", + "gateway-rs/src/routes/platform.rs::compile_proto", + "gateway-rs/src/routes/platform.rs::backfill_grpc_descriptors" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract", + "gateway-rs/tests/platform_native.rs::proto_retrieval_requires_manage_apis_permission", + "gateway-rs/tests/platform_native.rs::descriptor_backfill_compiles_active_grpc_apis_missing_descriptors" + ], + "source": { + "kind": "async_function", + "line": 876, + "path": "backend-services/routes/proto_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/quota_routes.py::module:quota_routes", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::quota_routes", + "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", + "gateway-rs/src/routes/platform.rs::quota_values", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period", + "gateway-rs/src/routes/platform.rs::quota_tier_info" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/routes/quota_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/quota_routes.py::class:QuotaStatusResponse", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::quota_routes", + "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", + "gateway-rs/src/routes/platform.rs::quota_values", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period", + "gateway-rs/src/routes/platform.rs::quota_tier_info" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "class", + "line": 33, + "path": "backend-services/routes/quota_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/quota_routes.py::field:QuotaStatusResponse.quota_type", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::quota_routes", + "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", + "gateway-rs/src/routes/platform.rs::quota_values", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period", + "gateway-rs/src/routes/platform.rs::quota_tier_info" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "field", + "line": 36, + "path": "backend-services/routes/quota_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/quota_routes.py::field:QuotaStatusResponse.current_usage", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::quota_routes", + "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", + "gateway-rs/src/routes/platform.rs::quota_values", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period", + "gateway-rs/src/routes/platform.rs::quota_tier_info" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "field", + "line": 37, + "path": "backend-services/routes/quota_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/quota_routes.py::field:QuotaStatusResponse.limit", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::quota_routes", + "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", + "gateway-rs/src/routes/platform.rs::quota_values", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period", + "gateway-rs/src/routes/platform.rs::quota_tier_info" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "field", + "line": 38, + "path": "backend-services/routes/quota_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/quota_routes.py::field:QuotaStatusResponse.remaining", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::quota_routes", + "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", + "gateway-rs/src/routes/platform.rs::quota_values", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period", + "gateway-rs/src/routes/platform.rs::quota_tier_info" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "field", + "line": 39, + "path": "backend-services/routes/quota_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/quota_routes.py::field:QuotaStatusResponse.percentage_used", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::quota_routes", + "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", + "gateway-rs/src/routes/platform.rs::quota_values", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period", + "gateway-rs/src/routes/platform.rs::quota_tier_info" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "field", + "line": 40, + "path": "backend-services/routes/quota_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/quota_routes.py::field:QuotaStatusResponse.reset_at", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::quota_routes", + "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", + "gateway-rs/src/routes/platform.rs::quota_values", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period", + "gateway-rs/src/routes/platform.rs::quota_tier_info" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "field", + "line": 41, + "path": "backend-services/routes/quota_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/quota_routes.py::field:QuotaStatusResponse.is_warning", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::quota_routes", + "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", + "gateway-rs/src/routes/platform.rs::quota_values", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period", + "gateway-rs/src/routes/platform.rs::quota_tier_info" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "field", + "line": 42, + "path": "backend-services/routes/quota_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/quota_routes.py::field:QuotaStatusResponse.is_critical", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::quota_routes", + "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", + "gateway-rs/src/routes/platform.rs::quota_values", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period", + "gateway-rs/src/routes/platform.rs::quota_tier_info" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "field", + "line": 43, + "path": "backend-services/routes/quota_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/quota_routes.py::field:QuotaStatusResponse.is_exhausted", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::quota_routes", + "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", + "gateway-rs/src/routes/platform.rs::quota_values", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period", + "gateway-rs/src/routes/platform.rs::quota_tier_info" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "field", + "line": 44, + "path": "backend-services/routes/quota_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/quota_routes.py::field:QuotaStatusResponse.burst_used", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::quota_routes", + "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", + "gateway-rs/src/routes/platform.rs::quota_values", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period", + "gateway-rs/src/routes/platform.rs::quota_tier_info" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "field", + "line": 45, + "path": "backend-services/routes/quota_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/quota_routes.py::field:QuotaStatusResponse.burst_limit", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::quota_routes", + "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", + "gateway-rs/src/routes/platform.rs::quota_values", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period", + "gateway-rs/src/routes/platform.rs::quota_tier_info" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "field", + "line": 46, + "path": "backend-services/routes/quota_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/quota_routes.py::field:QuotaStatusResponse.burst_percentage", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::quota_routes", + "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", + "gateway-rs/src/routes/platform.rs::quota_values", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period", + "gateway-rs/src/routes/platform.rs::quota_tier_info" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "field", + "line": 47, + "path": "backend-services/routes/quota_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/quota_routes.py::class:TierInfoResponse", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::quota_routes", + "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", + "gateway-rs/src/routes/platform.rs::quota_values", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period", + "gateway-rs/src/routes/platform.rs::quota_tier_info" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "class", + "line": 50, + "path": "backend-services/routes/quota_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/quota_routes.py::field:TierInfoResponse.tier_id", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::quota_routes", + "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", + "gateway-rs/src/routes/platform.rs::quota_values", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period", + "gateway-rs/src/routes/platform.rs::quota_tier_info" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "field", + "line": 53, + "path": "backend-services/routes/quota_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/quota_routes.py::field:TierInfoResponse.tier_name", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::quota_routes", + "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", + "gateway-rs/src/routes/platform.rs::quota_values", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period", + "gateway-rs/src/routes/platform.rs::quota_tier_info" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "field", + "line": 54, + "path": "backend-services/routes/quota_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/quota_routes.py::field:TierInfoResponse.display_name", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::quota_routes", + "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", + "gateway-rs/src/routes/platform.rs::quota_values", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period", + "gateway-rs/src/routes/platform.rs::quota_tier_info" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "field", + "line": 55, + "path": "backend-services/routes/quota_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/quota_routes.py::field:TierInfoResponse.limits", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::quota_routes", + "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", + "gateway-rs/src/routes/platform.rs::quota_values", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period", + "gateway-rs/src/routes/platform.rs::quota_tier_info" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "field", + "line": 56, + "path": "backend-services/routes/quota_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/quota_routes.py::field:TierInfoResponse.price_monthly", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::quota_routes", + "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", + "gateway-rs/src/routes/platform.rs::quota_values", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period", + "gateway-rs/src/routes/platform.rs::quota_tier_info" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "field", + "line": 57, + "path": "backend-services/routes/quota_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/quota_routes.py::field:TierInfoResponse.features", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::quota_routes", + "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", + "gateway-rs/src/routes/platform.rs::quota_values", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period", + "gateway-rs/src/routes/platform.rs::quota_tier_info" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "field", + "line": 58, + "path": "backend-services/routes/quota_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/quota_routes.py::class:QuotaDashboardResponse", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::quota_routes", + "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", + "gateway-rs/src/routes/platform.rs::quota_values", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period", + "gateway-rs/src/routes/platform.rs::quota_tier_info" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "class", + "line": 61, + "path": "backend-services/routes/quota_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/quota_routes.py::field:QuotaDashboardResponse.user_id", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::quota_routes", + "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", + "gateway-rs/src/routes/platform.rs::quota_values", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period", + "gateway-rs/src/routes/platform.rs::quota_tier_info" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "field", + "line": 64, + "path": "backend-services/routes/quota_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/quota_routes.py::field:QuotaDashboardResponse.tier_info", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::quota_routes", + "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", + "gateway-rs/src/routes/platform.rs::quota_values", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period", + "gateway-rs/src/routes/platform.rs::quota_tier_info" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "field", + "line": 65, + "path": "backend-services/routes/quota_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/quota_routes.py::field:QuotaDashboardResponse.quotas", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::quota_routes", + "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", + "gateway-rs/src/routes/platform.rs::quota_values", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period", + "gateway-rs/src/routes/platform.rs::quota_tier_info" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "field", + "line": 66, + "path": "backend-services/routes/quota_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/quota_routes.py::field:QuotaDashboardResponse.usage_summary", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::quota_routes", + "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", + "gateway-rs/src/routes/platform.rs::quota_values", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period", + "gateway-rs/src/routes/platform.rs::quota_tier_info" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "field", + "line": 67, + "path": "backend-services/routes/quota_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/quota_routes.py::async_function:get_quota_tracker_dep", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::quota_routes", + "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", + "gateway-rs/src/routes/platform.rs::quota_values", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period", + "gateway-rs/src/routes/platform.rs::quota_tier_info" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "async_function", + "line": 75, + "path": "backend-services/routes/quota_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/quota_routes.py::async_function:get_tier_service_dep", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::quota_routes", + "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", + "gateway-rs/src/routes/platform.rs::quota_values", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period", + "gateway-rs/src/routes/platform.rs::quota_tier_info" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "async_function", + "line": 80, + "path": "backend-services/routes/quota_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/quota_routes.py::async_function:get_current_user_id", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::quota_routes", + "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", + "gateway-rs/src/routes/platform.rs::quota_values", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period", + "gateway-rs/src/routes/platform.rs::quota_tier_info" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "async_function", + "line": 86, + "path": "backend-services/routes/quota_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "quota_router.get('/status', response_model=QuotaDashboardResponse)" + ], + "domain": "routes", + "id": "backend-services/routes/quota_routes.py::async_function:get_quota_status", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::quota_routes", + "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", + "gateway-rs/src/routes/platform.rs::quota_values", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period", + "gateway-rs/src/routes/platform.rs::quota_tier_info" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "async_function", + "line": 108, + "path": "backend-services/routes/quota_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "quota_router.get('/status/{quota_type}', response_model=QuotaStatusResponse)" + ], + "domain": "routes", + "id": "backend-services/routes/quota_routes.py::async_function:get_specific_quota_status", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::quota_routes", + "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", + "gateway-rs/src/routes/platform.rs::quota_values", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period", + "gateway-rs/src/routes/platform.rs::quota_tier_info" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "async_function", + "line": 232, + "path": "backend-services/routes/quota_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "quota_router.get('/usage/history', response_model=Dict[str, Any])" + ], + "domain": "routes", + "id": "backend-services/routes/quota_routes.py::async_function:get_usage_history", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::quota_routes", + "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", + "gateway-rs/src/routes/platform.rs::quota_values", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period", + "gateway-rs/src/routes/platform.rs::quota_tier_info" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "async_function", + "line": 298, + "path": "backend-services/routes/quota_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "quota_router.post('/usage/export', response_model=Dict[str, Any])" + ], + "domain": "routes", + "id": "backend-services/routes/quota_routes.py::async_function:export_usage_data", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::quota_routes", + "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", + "gateway-rs/src/routes/platform.rs::quota_values", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period", + "gateway-rs/src/routes/platform.rs::quota_tier_info" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "async_function", + "line": 325, + "path": "backend-services/routes/quota_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "quota_router.get('/tier/info', response_model=Dict[str, Any])" + ], + "domain": "routes", + "id": "backend-services/routes/quota_routes.py::async_function:get_tier_info", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::quota_routes", + "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", + "gateway-rs/src/routes/platform.rs::quota_values", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period", + "gateway-rs/src/routes/platform.rs::quota_tier_info" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "async_function", + "line": 405, + "path": "backend-services/routes/quota_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "quota_router.get('/burst/status', response_model=Dict[str, Any])" + ], + "domain": "routes", + "id": "backend-services/routes/quota_routes.py::async_function:get_burst_status", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::quota_routes", + "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", + "gateway-rs/src/routes/platform.rs::quota_values", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period", + "gateway-rs/src/routes/platform.rs::quota_tier_info" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "async_function", + "line": 460, + "path": "backend-services/routes/quota_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/quota_routes.py::function:get_burst_status._get_burst_usage", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::quota_routes", + "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", + "gateway-rs/src/routes/platform.rs::quota_values", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period", + "gateway-rs/src/routes/platform.rs::quota_tier_info" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "function", + "line": 485, + "path": "backend-services/routes/quota_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::module:rate_limit_rule_routes", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::class:RuleCreateRequest", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "class", + "line": 28, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleCreateRequest.rule_id", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "field", + "line": 31, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleCreateRequest.rule_type", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "field", + "line": 32, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleCreateRequest.time_window", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "field", + "line": 35, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleCreateRequest.limit", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "field", + "line": 36, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleCreateRequest.target_identifier", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "field", + "line": 37, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleCreateRequest.burst_allowance", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "field", + "line": 40, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleCreateRequest.priority", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "field", + "line": 41, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleCreateRequest.enabled", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "field", + "line": 42, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleCreateRequest.description", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "field", + "line": 43, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::class:RuleUpdateRequest", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "class", + "line": 46, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleUpdateRequest.limit", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "field", + "line": 49, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleUpdateRequest.target_identifier", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "field", + "line": 50, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleUpdateRequest.burst_allowance", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "field", + "line": 51, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleUpdateRequest.priority", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "field", + "line": 52, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleUpdateRequest.enabled", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "field", + "line": 53, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleUpdateRequest.description", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "field", + "line": 54, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::class:BulkRuleRequest", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "class", + "line": 57, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::field:BulkRuleRequest.rule_ids", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "field", + "line": 60, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::class:RuleDuplicateRequest", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "class", + "line": 63, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleDuplicateRequest.new_rule_id", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "field", + "line": 66, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::class:RuleResponse", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "class", + "line": 69, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleResponse.rule_id", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "field", + "line": 72, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleResponse.rule_type", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "field", + "line": 73, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleResponse.time_window", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "field", + "line": 74, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleResponse.limit", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "field", + "line": 75, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleResponse.target_identifier", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "field", + "line": 76, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleResponse.burst_allowance", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "field", + "line": 77, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleResponse.priority", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "field", + "line": 78, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleResponse.enabled", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "field", + "line": 79, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleResponse.description", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "field", + "line": 80, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleResponse.created_at", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "field", + "line": 81, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleResponse.updated_at", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "field", + "line": 82, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::async_function:get_rule_service_dep", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "async_function", + "line": 90, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "rate_limit_rule_router.post('/', response_model=RuleResponse, status_code=status.HTTP_201_CREATED)" + ], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::async_function:create_rule", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "async_function", + "line": 101, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "rate_limit_rule_router.get('/', response_model=list[RuleResponse])" + ], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::async_function:list_rules", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "async_function", + "line": 137, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "rate_limit_rule_router.get('/search', response_model=List[RuleResponse])" + ], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::async_function:search_rules", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "async_function", + "line": 161, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "rate_limit_rule_router.get('/{rule_id}', response_model=RuleResponse)" + ], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::async_function:get_rule", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "async_function", + "line": 178, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "rate_limit_rule_router.put('/{rule_id}', response_model=RuleResponse)" + ], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::async_function:update_rule", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "async_function", + "line": 202, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "rate_limit_rule_router.delete('/{rule_id}', status_code=status.HTTP_200_OK, response_model=Dict[str, Any])" + ], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::async_function:delete_rule", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "async_function", + "line": 230, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "rate_limit_rule_router.post('/{rule_id}/enable', response_model=RuleResponse)" + ], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::async_function:enable_rule", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "async_function", + "line": 252, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "rate_limit_rule_router.post('/{rule_id}/disable', response_model=RuleResponse)" + ], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::async_function:disable_rule", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "async_function", + "line": 276, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "rate_limit_rule_router.post('/bulk/delete', response_model=Dict[str, int])" + ], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::async_function:bulk_delete_rules", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "async_function", + "line": 305, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "rate_limit_rule_router.post('/bulk/enable', response_model=Dict[str, int])" + ], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::async_function:bulk_enable_rules", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "async_function", + "line": 321, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "rate_limit_rule_router.post('/bulk/disable', response_model=Dict[str, int])" + ], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::async_function:bulk_disable_rules", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "async_function", + "line": 337, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "rate_limit_rule_router.post('/{rule_id}/duplicate', response_model=RuleResponse, status_code=status.HTTP_201_CREATED)" + ], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::async_function:duplicate_rule", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "async_function", + "line": 360, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "rate_limit_rule_router.get('/statistics/summary', response_model=Dict[str, Any])" + ], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::async_function:get_rule_statistics", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "async_function", + "line": 385, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::async_function:get_current_user_id", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "async_function", + "line": 403, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "rate_limit_rule_router.get('/status', response_model=Dict[str, Any])" + ], + "domain": "routes", + "id": "backend-services/routes/rate_limit_rule_routes.py::async_function:get_rate_limit_status", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "source": { + "kind": "async_function", + "line": 420, + "path": "backend-services/routes/rate_limit_rule_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/role_routes.py::module:role_routes", + "notes": "All role CRUD/list aliases and administrator-visibility checks are implemented natively. Rust now matches authenticated permission-free reads, operation-specific ROLE009/010/011 denials, ROLE013-016 administrator protections, legacy platform_admin detection, service ROLE001/004/005 errors, sorted pagination metadata, non-admin filtering, Pydantic model normalization, and CRUD responses. Exact malformed integer query validation and exceptional cache/database failure envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::entity_routes", + "gateway-rs/src/routes/platform.rs::normalize_role_model", + "gateway-rs/src/routes/platform.rs::is_admin_role", + "gateway-rs/src/routes/platform.rs::is_admin_user" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::role_route_permissions_visibility_and_admin_codes_match_python", + "gateway-rs/tests/roles_groups_parity.rs::non_admin_managers_cannot_discover_or_manage_bootstrap_admin", + "gateway-rs/tests/roles_groups_parity.rs::missing_group_and_role_contracts_match_python_service_codes", + "gateway-rs/tests/roles_groups_parity.rs::python_test_roles_and_groups_crud" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/routes/role_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "role_router.post('', description='Add role', response_model=ResponseModel, responses={200: {'description': 'Successful Response', 'content': {'application/json': {'example': {'message': 'Role created successfully'}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/role_routes.py::async_function:create_role", + "notes": "All role CRUD/list aliases and administrator-visibility checks are implemented natively. Rust now matches authenticated permission-free reads, operation-specific ROLE009/010/011 denials, ROLE013-016 administrator protections, legacy platform_admin detection, service ROLE001/004/005 errors, sorted pagination metadata, non-admin filtering, Pydantic model normalization, and CRUD responses. Exact malformed integer query validation and exceptional cache/database failure envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::entity_routes", + "gateway-rs/src/routes/platform.rs::normalize_role_model", + "gateway-rs/src/routes/platform.rs::is_admin_role", + "gateway-rs/src/routes/platform.rs::is_admin_user" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::role_route_permissions_visibility_and_admin_codes_match_python", + "gateway-rs/tests/roles_groups_parity.rs::non_admin_managers_cannot_discover_or_manage_bootstrap_admin", + "gateway-rs/tests/roles_groups_parity.rs::missing_group_and_role_contracts_match_python_service_codes", + "gateway-rs/tests/roles_groups_parity.rs::python_test_roles_and_groups_crud" + ], + "source": { + "kind": "async_function", + "line": 48, + "path": "backend-services/routes/role_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "role_router.put('/{role_name}', description='Update role', response_model=ResponseModel, responses={200: {'description': 'Successful Response', 'content': {'application/json': {'example': {'message': 'Role updated successfully'}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/role_routes.py::async_function:update_role", + "notes": "All role CRUD/list aliases and administrator-visibility checks are implemented natively. Rust now matches authenticated permission-free reads, operation-specific ROLE009/010/011 denials, ROLE013-016 administrator protections, legacy platform_admin detection, service ROLE001/004/005 errors, sorted pagination metadata, non-admin filtering, Pydantic model normalization, and CRUD responses. Exact malformed integer query validation and exceptional cache/database failure envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::entity_routes", + "gateway-rs/src/routes/platform.rs::normalize_role_model", + "gateway-rs/src/routes/platform.rs::is_admin_role", + "gateway-rs/src/routes/platform.rs::is_admin_user" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::role_route_permissions_visibility_and_admin_codes_match_python", + "gateway-rs/tests/roles_groups_parity.rs::non_admin_managers_cannot_discover_or_manage_bootstrap_admin", + "gateway-rs/tests/roles_groups_parity.rs::missing_group_and_role_contracts_match_python_service_codes", + "gateway-rs/tests/roles_groups_parity.rs::python_test_roles_and_groups_crud" + ], + "source": { + "kind": "async_function", + "line": 123, + "path": "backend-services/routes/role_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "role_router.delete('/{role_name}', description='Delete role', response_model=ResponseModel, responses={200: {'description': 'Successful Response', 'content': {'application/json': {'example': {'message': 'Role deleted successfully'}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/role_routes.py::async_function:delete_role", + "notes": "All role CRUD/list aliases and administrator-visibility checks are implemented natively. Rust now matches authenticated permission-free reads, operation-specific ROLE009/010/011 denials, ROLE013-016 administrator protections, legacy platform_admin detection, service ROLE001/004/005 errors, sorted pagination metadata, non-admin filtering, Pydantic model normalization, and CRUD responses. Exact malformed integer query validation and exceptional cache/database failure envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::entity_routes", + "gateway-rs/src/routes/platform.rs::normalize_role_model", + "gateway-rs/src/routes/platform.rs::is_admin_role", + "gateway-rs/src/routes/platform.rs::is_admin_user" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::role_route_permissions_visibility_and_admin_codes_match_python", + "gateway-rs/tests/roles_groups_parity.rs::non_admin_managers_cannot_discover_or_manage_bootstrap_admin", + "gateway-rs/tests/roles_groups_parity.rs::missing_group_and_role_contracts_match_python_service_codes", + "gateway-rs/tests/roles_groups_parity.rs::python_test_roles_and_groups_crud" + ], + "source": { + "kind": "async_function", + "line": 208, + "path": "backend-services/routes/role_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "role_router.get('/all', description='Get all roles', response_model=list[RoleModelResponse])" + ], + "domain": "routes", + "id": "backend-services/routes/role_routes.py::async_function:get_roles", + "notes": "All role CRUD/list aliases and administrator-visibility checks are implemented natively. Rust now matches authenticated permission-free reads, operation-specific ROLE009/010/011 denials, ROLE013-016 administrator protections, legacy platform_admin detection, service ROLE001/004/005 errors, sorted pagination metadata, non-admin filtering, Pydantic model normalization, and CRUD responses. Exact malformed integer query validation and exceptional cache/database failure envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::entity_routes", + "gateway-rs/src/routes/platform.rs::normalize_role_model", + "gateway-rs/src/routes/platform.rs::is_admin_role", + "gateway-rs/src/routes/platform.rs::is_admin_user" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::role_route_permissions_visibility_and_admin_codes_match_python", + "gateway-rs/tests/roles_groups_parity.rs::non_admin_managers_cannot_discover_or_manage_bootstrap_admin", + "gateway-rs/tests/roles_groups_parity.rs::missing_group_and_role_contracts_match_python_service_codes", + "gateway-rs/tests/roles_groups_parity.rs::python_test_roles_and_groups_crud" + ], + "source": { + "kind": "async_function", + "line": 266, + "path": "backend-services/routes/role_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "role_router.get('/{role_name}', description='Get role', response_model=RoleModelResponse)" + ], + "domain": "routes", + "id": "backend-services/routes/role_routes.py::async_function:get_role", + "notes": "All role CRUD/list aliases and administrator-visibility checks are implemented natively. Rust now matches authenticated permission-free reads, operation-specific ROLE009/010/011 denials, ROLE013-016 administrator protections, legacy platform_admin detection, service ROLE001/004/005 errors, sorted pagination metadata, non-admin filtering, Pydantic model normalization, and CRUD responses. Exact malformed integer query validation and exceptional cache/database failure envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::entity_routes", + "gateway-rs/src/routes/platform.rs::normalize_role_model", + "gateway-rs/src/routes/platform.rs::is_admin_role", + "gateway-rs/src/routes/platform.rs::is_admin_user" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::role_route_permissions_visibility_and_admin_codes_match_python", + "gateway-rs/tests/roles_groups_parity.rs::non_admin_managers_cannot_discover_or_manage_bootstrap_admin", + "gateway-rs/tests/roles_groups_parity.rs::missing_group_and_role_contracts_match_python_service_codes", + "gateway-rs/tests/roles_groups_parity.rs::python_test_roles_and_groups_crud" + ], + "source": { + "kind": "async_function", + "line": 325, + "path": "backend-services/routes/role_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "role_router.get('', description='Get all roles (base path)', response_model=list[RoleModelResponse])" + ], + "domain": "routes", + "id": "backend-services/routes/role_routes.py::async_function:get_roles_base", + "notes": "All role CRUD/list aliases and administrator-visibility checks are implemented natively. Rust now matches authenticated permission-free reads, operation-specific ROLE009/010/011 denials, ROLE013-016 administrator protections, legacy platform_admin detection, service ROLE001/004/005 errors, sorted pagination metadata, non-admin filtering, Pydantic model normalization, and CRUD responses. Exact malformed integer query validation and exceptional cache/database failure envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::entity_routes", + "gateway-rs/src/routes/platform.rs::normalize_role_model", + "gateway-rs/src/routes/platform.rs::is_admin_role", + "gateway-rs/src/routes/platform.rs::is_admin_user" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::role_route_permissions_visibility_and_admin_codes_match_python", + "gateway-rs/tests/roles_groups_parity.rs::non_admin_managers_cannot_discover_or_manage_bootstrap_admin", + "gateway-rs/tests/roles_groups_parity.rs::missing_group_and_role_contracts_match_python_service_codes", + "gateway-rs/tests/roles_groups_parity.rs::python_test_roles_and_groups_crud" + ], + "source": { + "kind": "async_function", + "line": 375, + "path": "backend-services/routes/role_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/routing_routes.py::module:routing_routes", + "notes": "Rust preserves routing CRUD, generated client keys, validation, permission/error behavior, pagination, and server-index update exclusion.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::entity_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::routing_models_match_pydantic_generation_coercion_and_update_exclusion", + "gateway-rs/tests/roles_groups_parity.rs" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/routes/routing_routes.py" + }, + "status": "translated" + }, + { + "decorators": [ + "routing_router.post('', description='Add routing', response_model=ResponseModel, responses={200: {'description': 'Successful Response', 'content': {'application/json': {'example': {'message': 'Routing created successfully'}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/routing_routes.py::async_function:create_routing", + "notes": "Rust preserves routing CRUD, generated client keys, validation, permission/error behavior, pagination, and server-index update exclusion.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::entity_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::routing_models_match_pydantic_generation_coercion_and_update_exclusion", + "gateway-rs/tests/roles_groups_parity.rs" + ], + "source": { + "kind": "async_function", + "line": 49, + "path": "backend-services/routes/routing_routes.py" + }, + "status": "translated" + }, + { + "decorators": [ + "routing_router.put('/{client_key}', description='Update routing', response_model=ResponseModel, responses={200: {'description': 'Successful Response', 'content': {'application/json': {'example': {'message': 'Routing updated successfully'}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/routing_routes.py::async_function:update_routing", + "notes": "Rust preserves routing CRUD, generated client keys, validation, permission/error behavior, pagination, and server-index update exclusion.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::entity_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::routing_models_match_pydantic_generation_coercion_and_update_exclusion", + "gateway-rs/tests/roles_groups_parity.rs" + ], + "source": { + "kind": "async_function", + "line": 110, + "path": "backend-services/routes/routing_routes.py" + }, + "status": "translated" + }, + { + "decorators": [ + "routing_router.delete('/{client_key}', description='Delete routing', response_model=ResponseModel, responses={200: {'description': 'Successful Response', 'content': {'application/json': {'example': {'message': 'Routing deleted successfully'}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/routing_routes.py::async_function:delete_routing", + "notes": "Rust preserves routing CRUD, generated client keys, validation, permission/error behavior, pagination, and server-index update exclusion.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::entity_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::routing_models_match_pydantic_generation_coercion_and_update_exclusion", + "gateway-rs/tests/roles_groups_parity.rs" + ], + "source": { + "kind": "async_function", + "line": 171, + "path": "backend-services/routes/routing_routes.py" + }, + "status": "translated" + }, + { + "decorators": [ + "routing_router.get('/all', description='Get all routings', response_model=list[RoutingModelResponse])" + ], + "domain": "routes", + "id": "backend-services/routes/routing_routes.py::async_function:get_routings", + "notes": "Rust preserves routing CRUD, generated client keys, validation, permission/error behavior, pagination, and server-index update exclusion.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::entity_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::routing_models_match_pydantic_generation_coercion_and_update_exclusion", + "gateway-rs/tests/roles_groups_parity.rs" + ], + "source": { + "kind": "async_function", + "line": 222, + "path": "backend-services/routes/routing_routes.py" + }, + "status": "translated" + }, + { + "decorators": [ + "routing_router.get('/{client_key}', description='Get routing', response_model=RoutingModelResponse)" + ], + "domain": "routes", + "id": "backend-services/routes/routing_routes.py::async_function:get_routing", + "notes": "Rust preserves routing CRUD, generated client keys, validation, permission/error behavior, pagination, and server-index update exclusion.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::entity_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::routing_models_match_pydantic_generation_coercion_and_update_exclusion", + "gateway-rs/tests/roles_groups_parity.rs" + ], + "source": { + "kind": "async_function", + "line": 269, + "path": "backend-services/routes/routing_routes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/security_routes.py::module:security_routes", + "notes": "Rust preserves settings read/update validation, permission checks, persistence/runtime publication, redaction, and controlled restart scheduling.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::get_security_settings", + "gateway-rs/src/routes/platform.rs::upsert_security_settings", + "gateway-rs/src/routes/platform.rs::schedule_restart" + ], + "rust_tests": [ + "gateway-rs/tests/security_settings_parity.rs::live_security_settings_get_put_matches_python", + "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/routes/security_routes.py" + }, + "status": "translated" + }, + { + "decorators": [ + "security_router.get('/security/settings', description='Get security settings', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/security_routes.py::async_function:get_security_settings", + "notes": "Rust preserves settings read/update validation, permission checks, persistence/runtime publication, redaction, and controlled restart scheduling.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::get_security_settings", + "gateway-rs/src/routes/platform.rs::upsert_security_settings", + "gateway-rs/src/routes/platform.rs::schedule_restart" + ], + "rust_tests": [ + "gateway-rs/tests/security_settings_parity.rs::live_security_settings_get_put_matches_python", + "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract" + ], + "source": { + "kind": "async_function", + "line": 38, + "path": "backend-services/routes/security_routes.py" + }, + "status": "translated" + }, + { + "decorators": [ + "security_router.put('/security/settings', description='Update security settings', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/security_routes.py::async_function:update_security_settings", + "notes": "Rust preserves settings read/update validation, permission checks, persistence/runtime publication, redaction, and controlled restart scheduling.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::get_security_settings", + "gateway-rs/src/routes/platform.rs::upsert_security_settings", + "gateway-rs/src/routes/platform.rs::schedule_restart" + ], + "rust_tests": [ + "gateway-rs/tests/security_settings_parity.rs::live_security_settings_get_put_matches_python", + "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract" + ], + "source": { + "kind": "async_function", + "line": 140, + "path": "backend-services/routes/security_routes.py" + }, + "status": "translated" + }, + { + "decorators": [ + "security_router.post('/security/restart', description='Schedule a safe gateway restart (PID-based)', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/security_routes.py::async_function:restart_gateway", + "notes": "Rust preserves settings read/update validation, permission checks, persistence/runtime publication, redaction, and controlled restart scheduling.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::get_security_settings", + "gateway-rs/src/routes/platform.rs::upsert_security_settings", + "gateway-rs/src/routes/platform.rs::schedule_restart" + ], + "rust_tests": [ + "gateway-rs/tests/security_settings_parity.rs::live_security_settings_get_put_matches_python", + "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract" + ], + "source": { + "kind": "async_function", + "line": 232, + "path": "backend-services/routes/security_routes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/subscription_routes.py::module:subscription_routes", + "notes": "Rust preserves subscribe/unsubscribe, current/admin list access, available-API filtering, model coercion, permissions, and pinned errors.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::subscription_routes" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::live_test_21_subscription_list_unsubscribe_parity", + "gateway-rs/tests/platform_native.rs::subscription_model_coerces_python_scalars_and_ignores_unknown_fields" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/routes/subscription_routes.py" + }, + "status": "translated" + }, + { + "decorators": [ + "subscription_router.post('/subscribe', description='Subscribe to API', response_model=ResponseModel, responses={200: {'description': 'Successful Response', 'content': {'application/json': {'example': {'message': 'Subscription created successfully'}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/subscription_routes.py::async_function:subscribe_api", + "notes": "Rust preserves subscribe/unsubscribe, current/admin list access, available-API filtering, model coercion, permissions, and pinned errors.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::subscription_routes" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::live_test_21_subscription_list_unsubscribe_parity", + "gateway-rs/tests/platform_native.rs::subscription_model_coerces_python_scalars_and_ignores_unknown_fields" + ], + "source": { + "kind": "async_function", + "line": 50, + "path": "backend-services/routes/subscription_routes.py" + }, + "status": "translated" + }, + { + "decorators": [ + "subscription_router.post('/unsubscribe', description='Unsubscribe from API', response_model=ResponseModel, responses={200: {'description': 'Successful Response', 'content': {'application/json': {'example': {'message': 'Subscription deleted successfully'}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/subscription_routes.py::async_function:unsubscribe_api", + "notes": "Rust preserves subscribe/unsubscribe, current/admin list access, available-API filtering, model coercion, permissions, and pinned errors.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::subscription_routes" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::live_test_21_subscription_list_unsubscribe_parity", + "gateway-rs/tests/platform_native.rs::subscription_model_coerces_python_scalars_and_ignores_unknown_fields" + ], + "source": { + "kind": "async_function", + "line": 149, + "path": "backend-services/routes/subscription_routes.py" + }, + "status": "translated" + }, + { + "decorators": [ + "subscription_router.get('/subscriptions', description=\"Get current user's subscriptions\", response_model=ResponseModel, responses={200: {'description': 'Successful Response', 'content': {'application/json': {'example': {'apis': ['customer/v1', 'orders/v1']}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/subscription_routes.py::async_function:subscriptions_for_current_user", + "notes": "Rust preserves subscribe/unsubscribe, current/admin list access, available-API filtering, model coercion, permissions, and pinned errors.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::subscription_routes" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::live_test_21_subscription_list_unsubscribe_parity", + "gateway-rs/tests/platform_native.rs::subscription_model_coerces_python_scalars_and_ignores_unknown_fields" + ], + "source": { + "kind": "async_function", + "line": 246, + "path": "backend-services/routes/subscription_routes.py" + }, + "status": "translated" + }, + { + "decorators": [ + "subscription_router.get('/subscriptions/{user_id}', description=\"Get user's subscriptions\", response_model=ResponseModel, responses={200: {'description': 'Successful Response', 'content': {'application/json': {'example': {'apis': ['customer/v1', 'orders/v1']}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/subscription_routes.py::async_function:subscriptions_for_user_by_id", + "notes": "Rust preserves subscribe/unsubscribe, current/admin list access, available-API filtering, model coercion, permissions, and pinned errors.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::subscription_routes" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::live_test_21_subscription_list_unsubscribe_parity", + "gateway-rs/tests/platform_native.rs::subscription_model_coerces_python_scalars_and_ignores_unknown_fields" + ], + "source": { + "kind": "async_function", + "line": 293, + "path": "backend-services/routes/subscription_routes.py" + }, + "status": "translated" + }, + { + "decorators": [ + "subscription_router.get('/available-apis/{username}', description='List available APIs for subscription based on permissions and groups', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/subscription_routes.py::async_function:available_apis", + "notes": "Rust preserves subscribe/unsubscribe, current/admin list access, available-API filtering, model coercion, permissions, and pinned errors.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::subscription_routes" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::live_test_21_subscription_list_unsubscribe_parity", + "gateway-rs/tests/platform_native.rs::subscription_model_coerces_python_scalars_and_ignores_unknown_fields" + ], + "source": { + "kind": "async_function", + "line": 347, + "path": "backend-services/routes/subscription_routes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::module:tier_routes", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::class:TierLimitsRequest", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "class", + "line": 34, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierLimitsRequest.requests_per_second", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 37, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierLimitsRequest.requests_per_minute", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 38, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierLimitsRequest.requests_per_hour", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 39, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierLimitsRequest.requests_per_day", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 40, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierLimitsRequest.requests_per_month", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 41, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierLimitsRequest.burst_per_second", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 42, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierLimitsRequest.burst_per_minute", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 43, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierLimitsRequest.burst_per_hour", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 44, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierLimitsRequest.monthly_request_quota", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 45, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierLimitsRequest.daily_request_quota", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 46, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierLimitsRequest.monthly_bandwidth_quota", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 47, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierLimitsRequest.enable_throttling", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 48, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierLimitsRequest.max_queue_time_ms", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 49, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::class:TierCreateRequest", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "class", + "line": 52, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierCreateRequest.tier_id", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 55, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierCreateRequest.name", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 56, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierCreateRequest.display_name", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 57, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierCreateRequest.description", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 58, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierCreateRequest.limits", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 59, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierCreateRequest.price_monthly", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 60, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierCreateRequest.price_yearly", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 61, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierCreateRequest.features", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 62, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierCreateRequest.is_default", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 63, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierCreateRequest.enabled", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 64, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::class:TierUpdateRequest", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "class", + "line": 67, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierUpdateRequest.display_name", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 70, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierUpdateRequest.description", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 71, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierUpdateRequest.limits", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 72, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierUpdateRequest.price_monthly", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 73, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierUpdateRequest.price_yearly", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 74, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierUpdateRequest.features", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 75, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierUpdateRequest.is_default", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 76, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierUpdateRequest.enabled", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 77, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::class:UserAssignmentRequest", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "class", + "line": 80, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:UserAssignmentRequest.user_id", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 83, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:UserAssignmentRequest.tier_id", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 84, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:UserAssignmentRequest.effective_from", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 85, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:UserAssignmentRequest.effective_until", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 86, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:UserAssignmentRequest.override_limits", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 87, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:UserAssignmentRequest.notes", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 88, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::class:TierUpgradeRequest", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "class", + "line": 91, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierUpgradeRequest.user_id", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 94, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierUpgradeRequest.new_tier_id", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 95, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierUpgradeRequest.immediate", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 96, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierUpgradeRequest.scheduled_date", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 97, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::class:TierDowngradeRequest", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "class", + "line": 100, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierDowngradeRequest.user_id", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 103, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierDowngradeRequest.new_tier_id", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 104, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierDowngradeRequest.grace_period_days", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 105, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::class:TemporaryUpgradeRequest", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "class", + "line": 108, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TemporaryUpgradeRequest.user_id", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 111, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TemporaryUpgradeRequest.temp_tier_id", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 112, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TemporaryUpgradeRequest.duration_days", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 113, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::class:TrialStartRequest", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "class", + "line": 116, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TrialStartRequest.user_id", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 119, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TrialStartRequest.tier_id", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 120, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TrialStartRequest.days", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 121, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::class:PaymentFailureRequest", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "class", + "line": 124, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:PaymentFailureRequest.user_id", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 127, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:PaymentFailureRequest.reason", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 128, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::class:TierResponse", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "class", + "line": 131, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierResponse.tier_id", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 134, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierResponse.name", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 135, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierResponse.display_name", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 136, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierResponse.description", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 137, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierResponse.limits", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 138, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierResponse.price_monthly", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 139, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierResponse.price_yearly", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 140, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierResponse.features", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 141, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierResponse.is_default", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 142, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierResponse.enabled", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 143, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierResponse.created_at", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 144, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::field:TierResponse.updated_at", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "field", + "line": 145, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::async_function:get_tier_service_dep", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "async_function", + "line": 153, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "tier_router.post('/', response_model=TierResponse, status_code=status.HTTP_201_CREATED)" + ], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::async_function:create_tier", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "async_function", + "line": 164, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "tier_router.get('/', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::async_function:list_tiers", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "async_function", + "line": 221, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "tier_router.get('/{tier_id}', response_model=TierResponse)" + ], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::async_function:get_tier", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "async_function", + "line": 305, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "tier_router.put('/{tier_id}', response_model=TierResponse)" + ], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::async_function:update_tier", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "async_function", + "line": 329, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "tier_router.delete('/{tier_id}', status_code=status.HTTP_200_OK, response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::async_function:delete_tier", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "async_function", + "line": 378, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "tier_router.post('/assignments', status_code=status.HTTP_201_CREATED, response_model=Dict[str, Any])" + ], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::async_function:assign_user_to_tier", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "async_function", + "line": 410, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "tier_router.get('/assignments/{user_id}', response_model=Dict[str, Any])" + ], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::async_function:get_user_assignment", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "async_function", + "line": 445, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "tier_router.get('/assignments/{user_id}/tier', response_model=TierResponse)" + ], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::async_function:get_user_tier", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "async_function", + "line": 472, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "tier_router.delete('/assignments/{user_id}', status_code=status.HTTP_200_OK, response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::async_function:remove_user_assignment", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "async_function", + "line": 498, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "tier_router.get('/{tier_id}/users', response_model=List[Dict[str, Any]])" + ], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::async_function:list_users_in_tier", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "async_function", + "line": 525, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "tier_router.post('/upgrade', response_model=Dict[str, Any])" + ], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::async_function:upgrade_user_tier", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "async_function", + "line": 554, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "tier_router.post('/downgrade', response_model=Dict[str, Any])" + ], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::async_function:downgrade_user_tier", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "async_function", + "line": 582, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "tier_router.post('/temporary-upgrade', response_model=Dict[str, Any])" + ], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::async_function:temporary_tier_upgrade", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "async_function", + "line": 609, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "tier_router.post('/trial/start', response_model=Dict[str, Any])" + ], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::async_function:start_trial", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "async_function", + "line": 637, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "tier_router.post('/payment/failure', response_model=Dict[str, Any])" + ], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::async_function:handle_payment_failure", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "async_function", + "line": 660, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "tier_router.post('/compare', response_model=Dict[str, Any])" + ], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::async_function:compare_tiers", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "async_function", + "line": 684, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "tier_router.get('/statistics/all', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::async_function:get_all_tier_statistics", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "async_function", + "line": 702, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "tier_router.get('/{tier_id}/statistics', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/tier_routes.py::async_function:get_tier_statistics", + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "source": { + "kind": "async_function", + "line": 757, + "path": "backend-services/routes/tier_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tools_routes.py::module:tools_routes", + "notes": "The CORS checker, gRPC environment report, and backend chaos controls are implemented natively. Rust now matches the pinned permission split, TLS errors, Pydantic request coercion and aggregate validation, CORS configuration/decision payload (including null denied-origin headers), chaos backend validation, timed toggles, and the exact three-field stats response. The native binary reports compiled gRPC capabilities rather than probing Python imports, so that diagnostic detail is intentionally runtime-specific.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::cors_check_config_from", + "gateway-rs/src/routes/platform.rs::cors_check", + "gateway-rs/src/routes/platform.rs::normalize_cors_check", + "gateway-rs/src/routes/platform.rs::normalize_chaos_toggle" + ], + "rust_tests": [ + "gateway-rs/src/routes/platform.rs::tests::tools_cors_checker_matches_pinned_python_matrix", + "gateway-rs/tests/platform_native.rs::tools_permissions_and_required_models_match_python", + "gateway-rs/tests/python_parity_suite.rs::parity_test_developer_tools_chaos_and_simulator", + "gateway-rs/tests/security_settings_parity.rs::live_tools_cors_check_matches_python" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/routes/tools_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tools_routes.py::class:CorsCheckRequest", + "notes": "The CORS checker, gRPC environment report, and backend chaos controls are implemented natively. Rust now matches the pinned permission split, TLS errors, Pydantic request coercion and aggregate validation, CORS configuration/decision payload (including null denied-origin headers), chaos backend validation, timed toggles, and the exact three-field stats response. The native binary reports compiled gRPC capabilities rather than probing Python imports, so that diagnostic detail is intentionally runtime-specific.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::cors_check_config_from", + "gateway-rs/src/routes/platform.rs::cors_check", + "gateway-rs/src/routes/platform.rs::normalize_cors_check", + "gateway-rs/src/routes/platform.rs::normalize_chaos_toggle" + ], + "rust_tests": [ + "gateway-rs/src/routes/platform.rs::tests::tools_cors_checker_matches_pinned_python_matrix", + "gateway-rs/tests/platform_native.rs::tools_permissions_and_required_models_match_python", + "gateway-rs/tests/python_parity_suite.rs::parity_test_developer_tools_chaos_and_simulator", + "gateway-rs/tests/security_settings_parity.rs::live_tools_cors_check_matches_python" + ], + "source": { + "kind": "class", + "line": 24, + "path": "backend-services/routes/tools_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tools_routes.py::field:CorsCheckRequest.origin", + "notes": "The CORS checker, gRPC environment report, and backend chaos controls are implemented natively. Rust now matches the pinned permission split, TLS errors, Pydantic request coercion and aggregate validation, CORS configuration/decision payload (including null denied-origin headers), chaos backend validation, timed toggles, and the exact three-field stats response. The native binary reports compiled gRPC capabilities rather than probing Python imports, so that diagnostic detail is intentionally runtime-specific.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::cors_check_config_from", + "gateway-rs/src/routes/platform.rs::cors_check", + "gateway-rs/src/routes/platform.rs::normalize_cors_check", + "gateway-rs/src/routes/platform.rs::normalize_chaos_toggle" + ], + "rust_tests": [ + "gateway-rs/src/routes/platform.rs::tests::tools_cors_checker_matches_pinned_python_matrix", + "gateway-rs/tests/platform_native.rs::tools_permissions_and_required_models_match_python", + "gateway-rs/tests/python_parity_suite.rs::parity_test_developer_tools_chaos_and_simulator", + "gateway-rs/tests/security_settings_parity.rs::live_tools_cors_check_matches_python" + ], + "source": { + "kind": "field", + "line": 25, + "path": "backend-services/routes/tools_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tools_routes.py::field:CorsCheckRequest.method", + "notes": "The CORS checker, gRPC environment report, and backend chaos controls are implemented natively. Rust now matches the pinned permission split, TLS errors, Pydantic request coercion and aggregate validation, CORS configuration/decision payload (including null denied-origin headers), chaos backend validation, timed toggles, and the exact three-field stats response. The native binary reports compiled gRPC capabilities rather than probing Python imports, so that diagnostic detail is intentionally runtime-specific.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::cors_check_config_from", + "gateway-rs/src/routes/platform.rs::cors_check", + "gateway-rs/src/routes/platform.rs::normalize_cors_check", + "gateway-rs/src/routes/platform.rs::normalize_chaos_toggle" + ], + "rust_tests": [ + "gateway-rs/src/routes/platform.rs::tests::tools_cors_checker_matches_pinned_python_matrix", + "gateway-rs/tests/platform_native.rs::tools_permissions_and_required_models_match_python", + "gateway-rs/tests/python_parity_suite.rs::parity_test_developer_tools_chaos_and_simulator", + "gateway-rs/tests/security_settings_parity.rs::live_tools_cors_check_matches_python" + ], + "source": { + "kind": "field", + "line": 26, + "path": "backend-services/routes/tools_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tools_routes.py::field:CorsCheckRequest.request_headers", + "notes": "The CORS checker, gRPC environment report, and backend chaos controls are implemented natively. Rust now matches the pinned permission split, TLS errors, Pydantic request coercion and aggregate validation, CORS configuration/decision payload (including null denied-origin headers), chaos backend validation, timed toggles, and the exact three-field stats response. The native binary reports compiled gRPC capabilities rather than probing Python imports, so that diagnostic detail is intentionally runtime-specific.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::cors_check_config_from", + "gateway-rs/src/routes/platform.rs::cors_check", + "gateway-rs/src/routes/platform.rs::normalize_cors_check", + "gateway-rs/src/routes/platform.rs::normalize_chaos_toggle" + ], + "rust_tests": [ + "gateway-rs/src/routes/platform.rs::tests::tools_cors_checker_matches_pinned_python_matrix", + "gateway-rs/tests/platform_native.rs::tools_permissions_and_required_models_match_python", + "gateway-rs/tests/python_parity_suite.rs::parity_test_developer_tools_chaos_and_simulator", + "gateway-rs/tests/security_settings_parity.rs::live_tools_cors_check_matches_python" + ], + "source": { + "kind": "field", + "line": 27, + "path": "backend-services/routes/tools_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tools_routes.py::field:CorsCheckRequest.with_credentials", + "notes": "The CORS checker, gRPC environment report, and backend chaos controls are implemented natively. Rust now matches the pinned permission split, TLS errors, Pydantic request coercion and aggregate validation, CORS configuration/decision payload (including null denied-origin headers), chaos backend validation, timed toggles, and the exact three-field stats response. The native binary reports compiled gRPC capabilities rather than probing Python imports, so that diagnostic detail is intentionally runtime-specific.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::cors_check_config_from", + "gateway-rs/src/routes/platform.rs::cors_check", + "gateway-rs/src/routes/platform.rs::normalize_cors_check", + "gateway-rs/src/routes/platform.rs::normalize_chaos_toggle" + ], + "rust_tests": [ + "gateway-rs/src/routes/platform.rs::tests::tools_cors_checker_matches_pinned_python_matrix", + "gateway-rs/tests/platform_native.rs::tools_permissions_and_required_models_match_python", + "gateway-rs/tests/python_parity_suite.rs::parity_test_developer_tools_chaos_and_simulator", + "gateway-rs/tests/security_settings_parity.rs::live_tools_cors_check_matches_python" + ], + "source": { + "kind": "field", + "line": 30, + "path": "backend-services/routes/tools_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tools_routes.py::function:_compute_cors_config", + "notes": "The CORS checker, gRPC environment report, and backend chaos controls are implemented natively. Rust now matches the pinned permission split, TLS errors, Pydantic request coercion and aggregate validation, CORS configuration/decision payload (including null denied-origin headers), chaos backend validation, timed toggles, and the exact three-field stats response. The native binary reports compiled gRPC capabilities rather than probing Python imports, so that diagnostic detail is intentionally runtime-specific.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::cors_check_config_from", + "gateway-rs/src/routes/platform.rs::cors_check", + "gateway-rs/src/routes/platform.rs::normalize_cors_check", + "gateway-rs/src/routes/platform.rs::normalize_chaos_toggle" + ], + "rust_tests": [ + "gateway-rs/src/routes/platform.rs::tests::tools_cors_checker_matches_pinned_python_matrix", + "gateway-rs/tests/platform_native.rs::tools_permissions_and_required_models_match_python", + "gateway-rs/tests/python_parity_suite.rs::parity_test_developer_tools_chaos_and_simulator", + "gateway-rs/tests/security_settings_parity.rs::live_tools_cors_check_matches_python" + ], + "source": { + "kind": "function", + "line": 36, + "path": "backend-services/routes/tools_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "tools_router.post('/cors/check', description='Simulate CORS preflight/actual decisions against current gateway config', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/tools_routes.py::async_function:cors_check", + "notes": "The CORS checker, gRPC environment report, and backend chaos controls are implemented natively. Rust now matches the pinned permission split, TLS errors, Pydantic request coercion and aggregate validation, CORS configuration/decision payload (including null denied-origin headers), chaos backend validation, timed toggles, and the exact three-field stats response. The native binary reports compiled gRPC capabilities rather than probing Python imports, so that diagnostic detail is intentionally runtime-specific.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::cors_check_config_from", + "gateway-rs/src/routes/platform.rs::cors_check", + "gateway-rs/src/routes/platform.rs::normalize_cors_check", + "gateway-rs/src/routes/platform.rs::normalize_chaos_toggle" + ], + "rust_tests": [ + "gateway-rs/src/routes/platform.rs::tests::tools_cors_checker_matches_pinned_python_matrix", + "gateway-rs/tests/platform_native.rs::tools_permissions_and_required_models_match_python", + "gateway-rs/tests/python_parity_suite.rs::parity_test_developer_tools_chaos_and_simulator", + "gateway-rs/tests/security_settings_parity.rs::live_tools_cors_check_matches_python" + ], + "source": { + "kind": "async_function", + "line": 94, + "path": "backend-services/routes/tools_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "tools_router.get('/grpc/check', description='Report gRPC/grpc-tools availability and reflection flag', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/tools_routes.py::async_function:grpc_env_check", + "notes": "The CORS checker, gRPC environment report, and backend chaos controls are implemented natively. Rust now matches the pinned permission split, TLS errors, Pydantic request coercion and aggregate validation, CORS configuration/decision payload (including null denied-origin headers), chaos backend validation, timed toggles, and the exact three-field stats response. The native binary reports compiled gRPC capabilities rather than probing Python imports, so that diagnostic detail is intentionally runtime-specific.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::cors_check_config_from", + "gateway-rs/src/routes/platform.rs::cors_check", + "gateway-rs/src/routes/platform.rs::normalize_cors_check", + "gateway-rs/src/routes/platform.rs::normalize_chaos_toggle" + ], + "rust_tests": [ + "gateway-rs/src/routes/platform.rs::tests::tools_cors_checker_matches_pinned_python_matrix", + "gateway-rs/tests/platform_native.rs::tools_permissions_and_required_models_match_python", + "gateway-rs/tests/python_parity_suite.rs::parity_test_developer_tools_chaos_and_simulator", + "gateway-rs/tests/security_settings_parity.rs::live_tools_cors_check_matches_python" + ], + "source": { + "kind": "async_function", + "line": 246, + "path": "backend-services/routes/tools_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tools_routes.py::class:ChaosToggleRequest", + "notes": "The CORS checker, gRPC environment report, and backend chaos controls are implemented natively. Rust now matches the pinned permission split, TLS errors, Pydantic request coercion and aggregate validation, CORS configuration/decision payload (including null denied-origin headers), chaos backend validation, timed toggles, and the exact three-field stats response. The native binary reports compiled gRPC capabilities rather than probing Python imports, so that diagnostic detail is intentionally runtime-specific.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::cors_check_config_from", + "gateway-rs/src/routes/platform.rs::cors_check", + "gateway-rs/src/routes/platform.rs::normalize_cors_check", + "gateway-rs/src/routes/platform.rs::normalize_chaos_toggle" + ], + "rust_tests": [ + "gateway-rs/src/routes/platform.rs::tests::tools_cors_checker_matches_pinned_python_matrix", + "gateway-rs/tests/platform_native.rs::tools_permissions_and_required_models_match_python", + "gateway-rs/tests/python_parity_suite.rs::parity_test_developer_tools_chaos_and_simulator", + "gateway-rs/tests/security_settings_parity.rs::live_tools_cors_check_matches_python" + ], + "source": { + "kind": "class", + "line": 324, + "path": "backend-services/routes/tools_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tools_routes.py::field:ChaosToggleRequest.backend", + "notes": "The CORS checker, gRPC environment report, and backend chaos controls are implemented natively. Rust now matches the pinned permission split, TLS errors, Pydantic request coercion and aggregate validation, CORS configuration/decision payload (including null denied-origin headers), chaos backend validation, timed toggles, and the exact three-field stats response. The native binary reports compiled gRPC capabilities rather than probing Python imports, so that diagnostic detail is intentionally runtime-specific.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::cors_check_config_from", + "gateway-rs/src/routes/platform.rs::cors_check", + "gateway-rs/src/routes/platform.rs::normalize_cors_check", + "gateway-rs/src/routes/platform.rs::normalize_chaos_toggle" + ], + "rust_tests": [ + "gateway-rs/src/routes/platform.rs::tests::tools_cors_checker_matches_pinned_python_matrix", + "gateway-rs/tests/platform_native.rs::tools_permissions_and_required_models_match_python", + "gateway-rs/tests/python_parity_suite.rs::parity_test_developer_tools_chaos_and_simulator", + "gateway-rs/tests/security_settings_parity.rs::live_tools_cors_check_matches_python" + ], + "source": { + "kind": "field", + "line": 325, + "path": "backend-services/routes/tools_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tools_routes.py::field:ChaosToggleRequest.enabled", + "notes": "The CORS checker, gRPC environment report, and backend chaos controls are implemented natively. Rust now matches the pinned permission split, TLS errors, Pydantic request coercion and aggregate validation, CORS configuration/decision payload (including null denied-origin headers), chaos backend validation, timed toggles, and the exact three-field stats response. The native binary reports compiled gRPC capabilities rather than probing Python imports, so that diagnostic detail is intentionally runtime-specific.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::cors_check_config_from", + "gateway-rs/src/routes/platform.rs::cors_check", + "gateway-rs/src/routes/platform.rs::normalize_cors_check", + "gateway-rs/src/routes/platform.rs::normalize_chaos_toggle" + ], + "rust_tests": [ + "gateway-rs/src/routes/platform.rs::tests::tools_cors_checker_matches_pinned_python_matrix", + "gateway-rs/tests/platform_native.rs::tools_permissions_and_required_models_match_python", + "gateway-rs/tests/python_parity_suite.rs::parity_test_developer_tools_chaos_and_simulator", + "gateway-rs/tests/security_settings_parity.rs::live_tools_cors_check_matches_python" + ], + "source": { + "kind": "field", + "line": 326, + "path": "backend-services/routes/tools_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/tools_routes.py::field:ChaosToggleRequest.duration_ms", + "notes": "The CORS checker, gRPC environment report, and backend chaos controls are implemented natively. Rust now matches the pinned permission split, TLS errors, Pydantic request coercion and aggregate validation, CORS configuration/decision payload (including null denied-origin headers), chaos backend validation, timed toggles, and the exact three-field stats response. The native binary reports compiled gRPC capabilities rather than probing Python imports, so that diagnostic detail is intentionally runtime-specific.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::cors_check_config_from", + "gateway-rs/src/routes/platform.rs::cors_check", + "gateway-rs/src/routes/platform.rs::normalize_cors_check", + "gateway-rs/src/routes/platform.rs::normalize_chaos_toggle" + ], + "rust_tests": [ + "gateway-rs/src/routes/platform.rs::tests::tools_cors_checker_matches_pinned_python_matrix", + "gateway-rs/tests/platform_native.rs::tools_permissions_and_required_models_match_python", + "gateway-rs/tests/python_parity_suite.rs::parity_test_developer_tools_chaos_and_simulator", + "gateway-rs/tests/security_settings_parity.rs::live_tools_cors_check_matches_python" + ], + "source": { + "kind": "field", + "line": 327, + "path": "backend-services/routes/tools_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "tools_router.post('/chaos/toggle', description='Toggle simulated backend outages (redis|mongo)', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/tools_routes.py::async_function:chaos_toggle", + "notes": "The CORS checker, gRPC environment report, and backend chaos controls are implemented natively. Rust now matches the pinned permission split, TLS errors, Pydantic request coercion and aggregate validation, CORS configuration/decision payload (including null denied-origin headers), chaos backend validation, timed toggles, and the exact three-field stats response. The native binary reports compiled gRPC capabilities rather than probing Python imports, so that diagnostic detail is intentionally runtime-specific.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::cors_check_config_from", + "gateway-rs/src/routes/platform.rs::cors_check", + "gateway-rs/src/routes/platform.rs::normalize_cors_check", + "gateway-rs/src/routes/platform.rs::normalize_chaos_toggle" + ], + "rust_tests": [ + "gateway-rs/src/routes/platform.rs::tests::tools_cors_checker_matches_pinned_python_matrix", + "gateway-rs/tests/platform_native.rs::tools_permissions_and_required_models_match_python", + "gateway-rs/tests/python_parity_suite.rs::parity_test_developer_tools_chaos_and_simulator", + "gateway-rs/tests/security_settings_parity.rs::live_tools_cors_check_matches_python" + ], + "source": { + "kind": "async_function", + "line": 337, + "path": "backend-services/routes/tools_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "tools_router.get('/chaos/stats', description='Get chaos simulation stats', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/tools_routes.py::async_function:chaos_stats", + "notes": "The CORS checker, gRPC environment report, and backend chaos controls are implemented natively. Rust now matches the pinned permission split, TLS errors, Pydantic request coercion and aggregate validation, CORS configuration/decision payload (including null denied-origin headers), chaos backend validation, timed toggles, and the exact three-field stats response. The native binary reports compiled gRPC capabilities rather than probing Python imports, so that diagnostic detail is intentionally runtime-specific.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::cors_check_config_from", + "gateway-rs/src/routes/platform.rs::cors_check", + "gateway-rs/src/routes/platform.rs::normalize_cors_check", + "gateway-rs/src/routes/platform.rs::normalize_chaos_toggle" + ], + "rust_tests": [ + "gateway-rs/src/routes/platform.rs::tests::tools_cors_checker_matches_pinned_python_matrix", + "gateway-rs/tests/platform_native.rs::tools_permissions_and_required_models_match_python", + "gateway-rs/tests/python_parity_suite.rs::parity_test_developer_tools_chaos_and_simulator", + "gateway-rs/tests/security_settings_parity.rs::live_tools_cors_check_matches_python" + ], + "source": { + "kind": "async_function", + "line": 397, + "path": "backend-services/routes/tools_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/user_routes.py::module:user_routes", + "notes": "Every user route and both safe administrator checks are mapped to native Rust. Rust now matches public authenticated listing with administrator filtering, core CRUD permission ordering, bootstrap-admin protections, route-specific USR codes/messages, model validation, and role-change subscription pruning. Exact self-service restricted-field text and some auth/storage exceptional envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::user_routes", + "gateway-rs/src/routes/platform.rs::user_by", + "gateway-rs/src/routes/platform.rs::create_user" + ], + "rust_tests": [ + "gateway-rs/tests/user_lifecycle_parity.rs::self_service_updates_cannot_escalate_privileges", + "gateway-rs/tests/user_lifecycle_parity.rs::python_test_user_me_and_crud", + "gateway-rs/tests/user_lifecycle_parity.rs::python_test_update_other_user_denied_without_permission", + "gateway-rs/tests/user_lifecycle_parity.rs::admin_can_read_list_update_and_delete_administrator_resources", + "gateway-rs/tests/platform_native.rs::user_role_change_prunes_subscriptions_with_python_iteration_behavior" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/routes/user_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/user_routes.py::async_function:_safe_is_admin_user", + "notes": "Every user route and both safe administrator checks are mapped to native Rust. Rust now matches public authenticated listing with administrator filtering, core CRUD permission ordering, bootstrap-admin protections, route-specific USR codes/messages, model validation, and role-change subscription pruning. Exact self-service restricted-field text and some auth/storage exceptional envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::user_routes", + "gateway-rs/src/routes/platform.rs::user_by", + "gateway-rs/src/routes/platform.rs::create_user" + ], + "rust_tests": [ + "gateway-rs/tests/user_lifecycle_parity.rs::self_service_updates_cannot_escalate_privileges", + "gateway-rs/tests/user_lifecycle_parity.rs::python_test_user_me_and_crud", + "gateway-rs/tests/user_lifecycle_parity.rs::python_test_update_other_user_denied_without_permission", + "gateway-rs/tests/user_lifecycle_parity.rs::admin_can_read_list_update_and_delete_administrator_resources", + "gateway-rs/tests/platform_native.rs::user_role_change_prunes_subscriptions_with_python_iteration_behavior" + ], + "source": { + "kind": "async_function", + "line": 30, + "path": "backend-services/routes/user_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/user_routes.py::async_function:_safe_is_admin_role", + "notes": "Every user route and both safe administrator checks are mapped to native Rust. Rust now matches public authenticated listing with administrator filtering, core CRUD permission ordering, bootstrap-admin protections, route-specific USR codes/messages, model validation, and role-change subscription pruning. Exact self-service restricted-field text and some auth/storage exceptional envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::user_routes", + "gateway-rs/src/routes/platform.rs::user_by", + "gateway-rs/src/routes/platform.rs::create_user" + ], + "rust_tests": [ + "gateway-rs/tests/user_lifecycle_parity.rs::self_service_updates_cannot_escalate_privileges", + "gateway-rs/tests/user_lifecycle_parity.rs::python_test_user_me_and_crud", + "gateway-rs/tests/user_lifecycle_parity.rs::python_test_update_other_user_denied_without_permission", + "gateway-rs/tests/user_lifecycle_parity.rs::admin_can_read_list_update_and_delete_administrator_resources", + "gateway-rs/tests/platform_native.rs::user_role_change_prunes_subscriptions_with_python_iteration_behavior" + ], + "source": { + "kind": "async_function", + "line": 37, + "path": "backend-services/routes/user_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "user_router.post('', description='Add user', response_model=ResponseModel, responses={200: {'description': 'Successful Response', 'content': {'application/json': {'example': {'message': 'User created successfully'}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/user_routes.py::async_function:create_user", + "notes": "Every user route and both safe administrator checks are mapped to native Rust. Rust now matches public authenticated listing with administrator filtering, core CRUD permission ordering, bootstrap-admin protections, route-specific USR codes/messages, model validation, and role-change subscription pruning. Exact self-service restricted-field text and some auth/storage exceptional envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::user_routes", + "gateway-rs/src/routes/platform.rs::user_by", + "gateway-rs/src/routes/platform.rs::create_user" + ], + "rust_tests": [ + "gateway-rs/tests/user_lifecycle_parity.rs::self_service_updates_cannot_escalate_privileges", + "gateway-rs/tests/user_lifecycle_parity.rs::python_test_user_me_and_crud", + "gateway-rs/tests/user_lifecycle_parity.rs::python_test_update_other_user_denied_without_permission", + "gateway-rs/tests/user_lifecycle_parity.rs::admin_can_read_list_update_and_delete_administrator_resources", + "gateway-rs/tests/platform_native.rs::user_role_change_prunes_subscriptions_with_python_iteration_behavior" + ], + "source": { + "kind": "async_function", + "line": 65, + "path": "backend-services/routes/user_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "user_router.put('/{username}', description='Update user', response_model=ResponseModel, responses={200: {'description': 'Successful Response', 'content': {'application/json': {'example': {'message': 'User updated successfully'}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/user_routes.py::async_function:update_user", + "notes": "Every user route and both safe administrator checks are mapped to native Rust. Rust now matches public authenticated listing with administrator filtering, core CRUD permission ordering, bootstrap-admin protections, route-specific USR codes/messages, model validation, and role-change subscription pruning. Exact self-service restricted-field text and some auth/storage exceptional envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::user_routes", + "gateway-rs/src/routes/platform.rs::user_by", + "gateway-rs/src/routes/platform.rs::create_user" + ], + "rust_tests": [ + "gateway-rs/tests/user_lifecycle_parity.rs::self_service_updates_cannot_escalate_privileges", + "gateway-rs/tests/user_lifecycle_parity.rs::python_test_user_me_and_crud", + "gateway-rs/tests/user_lifecycle_parity.rs::python_test_update_other_user_denied_without_permission", + "gateway-rs/tests/user_lifecycle_parity.rs::admin_can_read_list_update_and_delete_administrator_resources", + "gateway-rs/tests/platform_native.rs::user_role_change_prunes_subscriptions_with_python_iteration_behavior" + ], + "source": { + "kind": "async_function", + "line": 130, + "path": "backend-services/routes/user_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "user_router.delete('/{username}', description='Delete user', response_model=ResponseModel, responses={200: {'description': 'Successful Response', 'content': {'application/json': {'example': {'message': 'User deleted successfully'}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/user_routes.py::async_function:delete_user", + "notes": "Every user route and both safe administrator checks are mapped to native Rust. Rust now matches public authenticated listing with administrator filtering, core CRUD permission ordering, bootstrap-admin protections, route-specific USR codes/messages, model validation, and role-change subscription pruning. Exact self-service restricted-field text and some auth/storage exceptional envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::user_routes", + "gateway-rs/src/routes/platform.rs::user_by", + "gateway-rs/src/routes/platform.rs::create_user" + ], + "rust_tests": [ + "gateway-rs/tests/user_lifecycle_parity.rs::self_service_updates_cannot_escalate_privileges", + "gateway-rs/tests/user_lifecycle_parity.rs::python_test_user_me_and_crud", + "gateway-rs/tests/user_lifecycle_parity.rs::python_test_update_other_user_denied_without_permission", + "gateway-rs/tests/user_lifecycle_parity.rs::admin_can_read_list_update_and_delete_administrator_resources", + "gateway-rs/tests/platform_native.rs::user_role_change_prunes_subscriptions_with_python_iteration_behavior" + ], + "source": { + "kind": "async_function", + "line": 258, + "path": "backend-services/routes/user_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "user_router.put('/{username}/update-password', description='Update user password', response_model=ResponseModel, responses={200: {'description': 'Successful Response', 'content': {'application/json': {'example': {'message': 'Password updated successfully'}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/user_routes.py::async_function:update_user_password", + "notes": "Every user route and both safe administrator checks are mapped to native Rust. Rust now matches public authenticated listing with administrator filtering, core CRUD permission ordering, bootstrap-admin protections, route-specific USR codes/messages, model validation, and role-change subscription pruning. Exact self-service restricted-field text and some auth/storage exceptional envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::user_routes", + "gateway-rs/src/routes/platform.rs::user_by", + "gateway-rs/src/routes/platform.rs::create_user" + ], + "rust_tests": [ + "gateway-rs/tests/user_lifecycle_parity.rs::self_service_updates_cannot_escalate_privileges", + "gateway-rs/tests/user_lifecycle_parity.rs::python_test_user_me_and_crud", + "gateway-rs/tests/user_lifecycle_parity.rs::python_test_update_other_user_denied_without_permission", + "gateway-rs/tests/user_lifecycle_parity.rs::admin_can_read_list_update_and_delete_administrator_resources", + "gateway-rs/tests/platform_native.rs::user_role_change_prunes_subscriptions_with_python_iteration_behavior" + ], + "source": { + "kind": "async_function", + "line": 335, + "path": "backend-services/routes/user_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "user_router.get('/me', description='Get user by username', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/user_routes.py::async_function:get_user_by_username", + "notes": "Every user route and both safe administrator checks are mapped to native Rust. Rust now matches public authenticated listing with administrator filtering, core CRUD permission ordering, bootstrap-admin protections, route-specific USR codes/messages, model validation, and role-change subscription pruning. Exact self-service restricted-field text and some auth/storage exceptional envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::user_routes", + "gateway-rs/src/routes/platform.rs::user_by", + "gateway-rs/src/routes/platform.rs::create_user" + ], + "rust_tests": [ + "gateway-rs/tests/user_lifecycle_parity.rs::self_service_updates_cannot_escalate_privileges", + "gateway-rs/tests/user_lifecycle_parity.rs::python_test_user_me_and_crud", + "gateway-rs/tests/user_lifecycle_parity.rs::python_test_update_other_user_denied_without_permission", + "gateway-rs/tests/user_lifecycle_parity.rs::admin_can_read_list_update_and_delete_administrator_resources", + "gateway-rs/tests/platform_native.rs::user_role_change_prunes_subscriptions_with_python_iteration_behavior" + ], + "source": { + "kind": "async_function", + "line": 394, + "path": "backend-services/routes/user_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "user_router.get('/all', description='Get all users', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/user_routes.py::async_function:get_all_users", + "notes": "Every user route and both safe administrator checks are mapped to native Rust. Rust now matches public authenticated listing with administrator filtering, core CRUD permission ordering, bootstrap-admin protections, route-specific USR codes/messages, model validation, and role-change subscription pruning. Exact self-service restricted-field text and some auth/storage exceptional envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::user_routes", + "gateway-rs/src/routes/platform.rs::user_by", + "gateway-rs/src/routes/platform.rs::create_user" + ], + "rust_tests": [ + "gateway-rs/tests/user_lifecycle_parity.rs::self_service_updates_cannot_escalate_privileges", + "gateway-rs/tests/user_lifecycle_parity.rs::python_test_user_me_and_crud", + "gateway-rs/tests/user_lifecycle_parity.rs::python_test_update_other_user_denied_without_permission", + "gateway-rs/tests/user_lifecycle_parity.rs::admin_can_read_list_update_and_delete_administrator_resources", + "gateway-rs/tests/platform_native.rs::user_role_change_prunes_subscriptions_with_python_iteration_behavior" + ], + "source": { + "kind": "async_function", + "line": 440, + "path": "backend-services/routes/user_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "user_router.get('/{username}', description='Get user by username', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/user_routes.py::async_function:get_user_by_username#2", + "notes": "Every user route and both safe administrator checks are mapped to native Rust. Rust now matches public authenticated listing with administrator filtering, core CRUD permission ordering, bootstrap-admin protections, route-specific USR codes/messages, model validation, and role-change subscription pruning. Exact self-service restricted-field text and some auth/storage exceptional envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::user_routes", + "gateway-rs/src/routes/platform.rs::user_by", + "gateway-rs/src/routes/platform.rs::create_user" + ], + "rust_tests": [ + "gateway-rs/tests/user_lifecycle_parity.rs::self_service_updates_cannot_escalate_privileges", + "gateway-rs/tests/user_lifecycle_parity.rs::python_test_user_me_and_crud", + "gateway-rs/tests/user_lifecycle_parity.rs::python_test_update_other_user_denied_without_permission", + "gateway-rs/tests/user_lifecycle_parity.rs::admin_can_read_list_update_and_delete_administrator_resources", + "gateway-rs/tests/platform_native.rs::user_role_change_prunes_subscriptions_with_python_iteration_behavior" + ], + "source": { + "kind": "async_function", + "line": 508, + "path": "backend-services/routes/user_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "user_router.get('/email/{email}', description='Get user by email', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/user_routes.py::async_function:get_user_by_email", + "notes": "Every user route and both safe administrator checks are mapped to native Rust. Rust now matches public authenticated listing with administrator filtering, core CRUD permission ordering, bootstrap-admin protections, route-specific USR codes/messages, model validation, and role-change subscription pruning. Exact self-service restricted-field text and some auth/storage exceptional envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::user_routes", + "gateway-rs/src/routes/platform.rs::user_by", + "gateway-rs/src/routes/platform.rs::create_user" + ], + "rust_tests": [ + "gateway-rs/tests/user_lifecycle_parity.rs::self_service_updates_cannot_escalate_privileges", + "gateway-rs/tests/user_lifecycle_parity.rs::python_test_user_me_and_crud", + "gateway-rs/tests/user_lifecycle_parity.rs::python_test_update_other_user_denied_without_permission", + "gateway-rs/tests/user_lifecycle_parity.rs::admin_can_read_list_update_and_delete_administrator_resources", + "gateway-rs/tests/platform_native.rs::user_role_change_prunes_subscriptions_with_python_iteration_behavior" + ], + "source": { + "kind": "async_function", + "line": 585, + "path": "backend-services/routes/user_routes.py" + }, + "status": "partial" + }, + { + "decorators": [ + "user_router.get('', description='Get all users (base path)', response_model=ResponseModel)" + ], + "domain": "routes", + "id": "backend-services/routes/user_routes.py::async_function:get_all_users_base", + "notes": "Every user route and both safe administrator checks are mapped to native Rust. Rust now matches public authenticated listing with administrator filtering, core CRUD permission ordering, bootstrap-admin protections, route-specific USR codes/messages, model validation, and role-change subscription pruning. Exact self-service restricted-field text and some auth/storage exceptional envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::user_routes", + "gateway-rs/src/routes/platform.rs::user_by", + "gateway-rs/src/routes/platform.rs::create_user" + ], + "rust_tests": [ + "gateway-rs/tests/user_lifecycle_parity.rs::self_service_updates_cannot_escalate_privileges", + "gateway-rs/tests/user_lifecycle_parity.rs::python_test_user_me_and_crud", + "gateway-rs/tests/user_lifecycle_parity.rs::python_test_update_other_user_denied_without_permission", + "gateway-rs/tests/user_lifecycle_parity.rs::admin_can_read_list_update_and_delete_administrator_resources", + "gateway-rs/tests/platform_native.rs::user_role_change_prunes_subscriptions_with_python_iteration_behavior" + ], + "source": { + "kind": "async_function", + "line": 638, + "path": "backend-services/routes/user_routes.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/vault_routes.py::module:vault_routes", + "notes": "Rust preserves authenticated vault CRUD, validation, encryption-at-rest, duplicate/not-found errors, description-only updates, secret suppression, and the pinned empty read-body quirk.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::vault_routes", + "gateway-rs/src/storage/vault.rs" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::vault_lifecycle_encrypts_at_rest_and_never_returns_the_secret" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/routes/vault_routes.py" + }, + "status": "translated" + }, + { + "decorators": [ + "vault_router.post('', description='Create a new vault entry', response_model=ResponseModel, responses={201: {'description': 'Vault entry created successfully', 'content': {'application/json': {'example': {'message': 'Vault entry created successfully', 'data': {'key_name': 'api_key_production'}}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/vault_routes.py::async_function:create_vault_entry", + "notes": "Rust preserves authenticated vault CRUD, validation, encryption-at-rest, duplicate/not-found errors, description-only updates, secret suppression, and the pinned empty read-body quirk.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::vault_routes", + "gateway-rs/src/storage/vault.rs" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::vault_lifecycle_encrypts_at_rest_and_never_returns_the_secret" + ], + "source": { + "kind": "async_function", + "line": 44, + "path": "backend-services/routes/vault_routes.py" + }, + "status": "translated" + }, + { + "decorators": [ + "vault_router.get('', description='List all vault entries for the authenticated user', response_model=ResponseModel, responses={200: {'description': 'Successful Response', 'content': {'application/json': {'example': {'data': {'entries': [{'key_name': 'api_key_production', 'username': 'john_doe', 'description': 'Production API key', 'created_at': '2024-11-22T10:15:30Z', 'updated_at': '2024-11-22T10:15:30Z'}], 'count': 1}}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/vault_routes.py::async_function:list_vault_entries", + "notes": "Rust preserves authenticated vault CRUD, validation, encryption-at-rest, duplicate/not-found errors, description-only updates, secret suppression, and the pinned empty read-body quirk.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::vault_routes", + "gateway-rs/src/storage/vault.rs" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::vault_lifecycle_encrypts_at_rest_and_never_returns_the_secret" + ], + "source": { + "kind": "async_function", + "line": 105, + "path": "backend-services/routes/vault_routes.py" + }, + "status": "translated" + }, + { + "decorators": [ + "vault_router.get('/{key_name}', description='Get a specific vault entry by key name', response_model=ResponseModel, responses={200: {'description': 'Successful Response', 'content': {'application/json': {'example': {'data': {'key_name': 'api_key_production', 'username': 'john_doe', 'description': 'Production API key', 'created_at': '2024-11-22T10:15:30Z', 'updated_at': '2024-11-22T10:15:30Z'}}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/vault_routes.py::async_function:get_vault_entry", + "notes": "Rust preserves authenticated vault CRUD, validation, encryption-at-rest, duplicate/not-found errors, description-only updates, secret suppression, and the pinned empty read-body quirk.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::vault_routes", + "gateway-rs/src/storage/vault.rs" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::vault_lifecycle_encrypts_at_rest_and_never_returns_the_secret" + ], + "source": { + "kind": "async_function", + "line": 161, + "path": "backend-services/routes/vault_routes.py" + }, + "status": "translated" + }, + { + "decorators": [ + "vault_router.put('/{key_name}', description='Update a vault entry (description only)', response_model=ResponseModel, responses={200: {'description': 'Vault entry updated successfully', 'content': {'application/json': {'example': {'message': 'Vault entry updated successfully'}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/vault_routes.py::async_function:update_vault_entry", + "notes": "Rust preserves authenticated vault CRUD, validation, encryption-at-rest, duplicate/not-found errors, description-only updates, secret suppression, and the pinned empty read-body quirk.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::vault_routes", + "gateway-rs/src/storage/vault.rs" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::vault_lifecycle_encrypts_at_rest_and_never_returns_the_secret" + ], + "source": { + "kind": "async_function", + "line": 207, + "path": "backend-services/routes/vault_routes.py" + }, + "status": "translated" + }, + { + "decorators": [ + "vault_router.delete('/{key_name}', description='Delete a vault entry', response_model=ResponseModel, responses={200: {'description': 'Vault entry deleted successfully', 'content': {'application/json': {'example': {'message': 'Vault entry deleted successfully'}}}}})" + ], + "domain": "routes", + "id": "backend-services/routes/vault_routes.py::async_function:delete_vault_entry", + "notes": "Rust preserves authenticated vault CRUD, validation, encryption-at-rest, duplicate/not-found errors, description-only updates, secret suppression, and the pinned empty read-body quirk.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::vault_routes", + "gateway-rs/src/storage/vault.rs" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::vault_lifecycle_encrypts_at_rest_and_never_returns_the_secret" + ], + "source": { + "kind": "async_function", + "line": 255, + "path": "backend-services/routes/vault_routes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "routes", + "id": "backend-services/routes/wsdl_routes.py::module:wsdl_routes", + "notes": "Rust preserves authenticated WSDL fetch/cache/refresh/import and raw parse behavior with native XML processing and pinned errors.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::api_discovery_routes", + "gateway-rs/src/routes/platform.rs::parse_wsdl_document" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::discovery_document_reads_fetch_once_and_reuse_the_python_cache_contract", + "gateway-rs/tests/platform_native.rs::memory_mode_parses_and_imports_wsdl_without_an_external_service" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/routes/wsdl_routes.py" + }, + "status": "translated" + }, + { + "decorators": [ + "wsdl_router.get('/platform/api/{api_name}/{api_version}/wsdl')" + ], + "domain": "routes", + "id": "backend-services/routes/wsdl_routes.py::async_function:get_wsdl", + "notes": "Rust preserves authenticated WSDL fetch/cache/refresh/import and raw parse behavior with native XML processing and pinned errors.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::api_discovery_routes", + "gateway-rs/src/routes/platform.rs::parse_wsdl_document" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::discovery_document_reads_fetch_once_and_reuse_the_python_cache_contract", + "gateway-rs/tests/platform_native.rs::memory_mode_parses_and_imports_wsdl_without_an_external_service" + ], + "source": { + "kind": "async_function", + "line": 41, + "path": "backend-services/routes/wsdl_routes.py" + }, + "status": "translated" + }, + { + "decorators": [ + "wsdl_router.post('/platform/api/{api_name}/{api_version}/wsdl/refresh')" + ], + "domain": "routes", + "id": "backend-services/routes/wsdl_routes.py::async_function:refresh_wsdl", + "notes": "Rust preserves authenticated WSDL fetch/cache/refresh/import and raw parse behavior with native XML processing and pinned errors.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::api_discovery_routes", + "gateway-rs/src/routes/platform.rs::parse_wsdl_document" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::discovery_document_reads_fetch_once_and_reuse_the_python_cache_contract", + "gateway-rs/tests/platform_native.rs::memory_mode_parses_and_imports_wsdl_without_an_external_service" + ], + "source": { + "kind": "async_function", + "line": 125, + "path": "backend-services/routes/wsdl_routes.py" + }, + "status": "translated" + }, + { + "decorators": [ + "wsdl_router.post('/platform/api/{api_name}/{api_version}/wsdl/import')" + ], + "domain": "routes", + "id": "backend-services/routes/wsdl_routes.py::async_function:import_wsdl_operations", + "notes": "Rust preserves authenticated WSDL fetch/cache/refresh/import and raw parse behavior with native XML processing and pinned errors.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::api_discovery_routes", + "gateway-rs/src/routes/platform.rs::parse_wsdl_document" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::discovery_document_reads_fetch_once_and_reuse_the_python_cache_contract", + "gateway-rs/tests/platform_native.rs::memory_mode_parses_and_imports_wsdl_without_an_external_service" + ], + "source": { + "kind": "async_function", + "line": 200, + "path": "backend-services/routes/wsdl_routes.py" + }, + "status": "translated" + }, + { + "decorators": [ + "wsdl_router.post('/platform/wsdl/parse')" + ], + "domain": "routes", + "id": "backend-services/routes/wsdl_routes.py::async_function:parse_wsdl_content", + "notes": "Rust preserves authenticated WSDL fetch/cache/refresh/import and raw parse behavior with native XML processing and pinned errors.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::api_discovery_routes", + "gateway-rs/src/routes/platform.rs::parse_wsdl_document" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::discovery_document_reads_fetch_once_and_reuse_the_python_cache_contract", + "gateway-rs/tests/platform_native.rs::memory_mode_parses_and_imports_wsdl_without_an_external_service" + ], + "source": { + "kind": "async_function", + "line": 303, + "path": "backend-services/routes/wsdl_routes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/api_service.py::module:api_service", + "notes": "Rust maps all API service operations to native CRUD with idempotent creation, generated IDs/paths, public-credit rejection, immutable identity, cache-backed storage, pagination metadata, proto descriptor attachment, and pinned API002/API003/API005/API006/API013 responses. Acknowledgement/cursor failure envelopes and a few cache-warming side effects remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::api_routes", + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_update_api" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts", + "gateway-rs/tests/platform_native.rs::python_api_and_endpoint_crud_lookup_and_missing_contracts" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/services/api_service.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/api_service.py::class:ApiService", + "notes": "Rust maps all API service operations to native CRUD with idempotent creation, generated IDs/paths, public-credit rejection, immutable identity, cache-backed storage, pagination metadata, proto descriptor attachment, and pinned API002/API003/API005/API006/API013 responses. Acknowledgement/cursor failure envelopes and a few cache-warming side effects remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::api_routes", + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_update_api" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts", + "gateway-rs/tests/platform_native.rs::python_api_and_endpoint_crud_lookup_and_missing_contracts" + ], + "source": { + "kind": "class", + "line": 22, + "path": "backend-services/services/api_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/api_service.py::async_method:ApiService.create_api", + "notes": "Rust maps all API service operations to native CRUD with idempotent creation, generated IDs/paths, public-credit rejection, immutable identity, cache-backed storage, pagination metadata, proto descriptor attachment, and pinned API002/API003/API005/API006/API013 responses. Acknowledgement/cursor failure envelopes and a few cache-warming side effects remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::api_routes", + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_update_api" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts", + "gateway-rs/tests/platform_native.rs::python_api_and_endpoint_crud_lookup_and_missing_contracts" + ], + "source": { + "kind": "async_method", + "line": 24, + "path": "backend-services/services/api_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/api_service.py::async_method:ApiService.update_api", + "notes": "Rust maps all API service operations to native CRUD with idempotent creation, generated IDs/paths, public-credit rejection, immutable identity, cache-backed storage, pagination metadata, proto descriptor attachment, and pinned API002/API003/API005/API006/API013 responses. Acknowledgement/cursor failure envelopes and a few cache-warming side effects remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::api_routes", + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_update_api" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts", + "gateway-rs/tests/platform_native.rs::python_api_and_endpoint_crud_lookup_and_missing_contracts" + ], + "source": { + "kind": "async_method", + "line": 122, + "path": "backend-services/services/api_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/api_service.py::async_method:ApiService.delete_api", + "notes": "Rust maps all API service operations to native CRUD with idempotent creation, generated IDs/paths, public-credit rejection, immutable identity, cache-backed storage, pagination metadata, proto descriptor attachment, and pinned API002/API003/API005/API006/API013 responses. Acknowledgement/cursor failure envelopes and a few cache-warming side effects remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::api_routes", + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_update_api" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts", + "gateway-rs/tests/platform_native.rs::python_api_and_endpoint_crud_lookup_and_missing_contracts" + ], + "source": { + "kind": "async_method", + "line": 206, + "path": "backend-services/services/api_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/api_service.py::async_method:ApiService.get_api_by_name_version", + "notes": "Rust maps all API service operations to native CRUD with idempotent creation, generated IDs/paths, public-credit rejection, immutable identity, cache-backed storage, pagination metadata, proto descriptor attachment, and pinned API002/API003/API005/API006/API013 responses. Acknowledgement/cursor failure envelopes and a few cache-warming side effects remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::api_routes", + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_update_api" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts", + "gateway-rs/tests/platform_native.rs::python_api_and_endpoint_crud_lookup_and_missing_contracts" + ], + "source": { + "kind": "async_method", + "line": 243, + "path": "backend-services/services/api_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/api_service.py::async_method:ApiService.get_apis", + "notes": "Rust maps all API service operations to native CRUD with idempotent creation, generated IDs/paths, public-credit rejection, immutable identity, cache-backed storage, pagination metadata, proto descriptor attachment, and pinned API002/API003/API005/API006/API013 responses. Acknowledgement/cursor failure envelopes and a few cache-warming side effects remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::api_routes", + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_update_api" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts", + "gateway-rs/tests/platform_native.rs::python_api_and_endpoint_crud_lookup_and_missing_contracts" + ], + "source": { + "kind": "async_method", + "line": 269, + "path": "backend-services/services/api_service.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/credit_service.py::module:credit_service", + "notes": "Rust preserves credit-definition validation/CRUD/masking, definition and per-user pagination/search, user-credit upsert/read behavior, and key rotation. Credit definition keys and per-user keys are now encrypted on every write with the compatible field cipher, decrypted only for authorized user-credit reads, and rotation stores user_api_key while creating a missing user record as Python does. Some database-driver-specific error distinctions remain consolidated by shared storage.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::credit_routes", + "gateway-rs/src/routes/platform.rs::encrypt_credit_definition", + "gateway-rs/src/routes/platform.rs::transform_user_credit_keys", + "gateway-rs/src/storage/field_encryption.rs" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_credit_definition_masks_secret_key_material", + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision", + "gateway-rs/src/storage/field_encryption.rs::tests::plaintext_values_pass_through_without_an_encryption_marker" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/services/credit_service.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/credit_service.py::class:CreditService", + "notes": "Rust preserves credit-definition validation/CRUD/masking, definition and per-user pagination/search, user-credit upsert/read behavior, and key rotation. Credit definition keys and per-user keys are now encrypted on every write with the compatible field cipher, decrypted only for authorized user-credit reads, and rotation stores user_api_key while creating a missing user record as Python does. Some database-driver-specific error distinctions remain consolidated by shared storage.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::credit_routes", + "gateway-rs/src/routes/platform.rs::encrypt_credit_definition", + "gateway-rs/src/routes/platform.rs::transform_user_credit_keys", + "gateway-rs/src/storage/field_encryption.rs" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_credit_definition_masks_secret_key_material", + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision", + "gateway-rs/src/storage/field_encryption.rs::tests::plaintext_values_pass_through_without_an_encryption_marker" + ], + "source": { + "kind": "class", + "line": 32, + "path": "backend-services/services/credit_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/credit_service.py::method:CreditService._validate_credit_data", + "notes": "Rust preserves credit-definition validation/CRUD/masking, definition and per-user pagination/search, user-credit upsert/read behavior, and key rotation. Credit definition keys and per-user keys are now encrypted on every write with the compatible field cipher, decrypted only for authorized user-credit reads, and rotation stores user_api_key while creating a missing user record as Python does. Some database-driver-specific error distinctions remain consolidated by shared storage.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::credit_routes", + "gateway-rs/src/routes/platform.rs::encrypt_credit_definition", + "gateway-rs/src/routes/platform.rs::transform_user_credit_keys", + "gateway-rs/src/storage/field_encryption.rs" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_credit_definition_masks_secret_key_material", + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision", + "gateway-rs/src/storage/field_encryption.rs::tests::plaintext_values_pass_through_without_an_encryption_marker" + ], + "source": { + "kind": "method", + "line": 34, + "path": "backend-services/services/credit_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/credit_service.py::async_method:CreditService.create_credit", + "notes": "Rust preserves credit-definition validation/CRUD/masking, definition and per-user pagination/search, user-credit upsert/read behavior, and key rotation. Credit definition keys and per-user keys are now encrypted on every write with the compatible field cipher, decrypted only for authorized user-credit reads, and rotation stores user_api_key while creating a missing user record as Python does. Some database-driver-specific error distinctions remain consolidated by shared storage.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::credit_routes", + "gateway-rs/src/routes/platform.rs::encrypt_credit_definition", + "gateway-rs/src/routes/platform.rs::transform_user_credit_keys", + "gateway-rs/src/storage/field_encryption.rs" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_credit_definition_masks_secret_key_material", + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision", + "gateway-rs/src/storage/field_encryption.rs::tests::plaintext_values_pass_through_without_an_encryption_marker" + ], + "source": { + "kind": "async_method", + "line": 49, + "path": "backend-services/services/credit_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/credit_service.py::async_method:CreditService.update_credit", + "notes": "Rust preserves credit-definition validation/CRUD/masking, definition and per-user pagination/search, user-credit upsert/read behavior, and key rotation. Credit definition keys and per-user keys are now encrypted on every write with the compatible field cipher, decrypted only for authorized user-credit reads, and rotation stores user_api_key while creating a missing user record as Python does. Some database-driver-specific error distinctions remain consolidated by shared storage.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::credit_routes", + "gateway-rs/src/routes/platform.rs::encrypt_credit_definition", + "gateway-rs/src/routes/platform.rs::transform_user_credit_keys", + "gateway-rs/src/storage/field_encryption.rs" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_credit_definition_masks_secret_key_material", + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision", + "gateway-rs/src/storage/field_encryption.rs::tests::plaintext_values_pass_through_without_an_encryption_marker" + ], + "source": { + "kind": "async_method", + "line": 100, + "path": "backend-services/services/credit_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/credit_service.py::async_method:CreditService.delete_credit", + "notes": "Rust preserves credit-definition validation/CRUD/masking, definition and per-user pagination/search, user-credit upsert/read behavior, and key rotation. Credit definition keys and per-user keys are now encrypted on every write with the compatible field cipher, decrypted only for authorized user-credit reads, and rotation stores user_api_key while creating a missing user record as Python does. Some database-driver-specific error distinctions remain consolidated by shared storage.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::credit_routes", + "gateway-rs/src/routes/platform.rs::encrypt_credit_definition", + "gateway-rs/src/routes/platform.rs::transform_user_credit_keys", + "gateway-rs/src/storage/field_encryption.rs" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_credit_definition_masks_secret_key_material", + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision", + "gateway-rs/src/storage/field_encryption.rs::tests::plaintext_values_pass_through_without_an_encryption_marker" + ], + "source": { + "kind": "async_method", + "line": 167, + "path": "backend-services/services/credit_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/credit_service.py::async_method:CreditService.list_credit_defs", + "notes": "Rust preserves credit-definition validation/CRUD/masking, definition and per-user pagination/search, user-credit upsert/read behavior, and key rotation. Credit definition keys and per-user keys are now encrypted on every write with the compatible field cipher, decrypted only for authorized user-credit reads, and rotation stores user_api_key while creating a missing user record as Python does. Some database-driver-specific error distinctions remain consolidated by shared storage.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::credit_routes", + "gateway-rs/src/routes/platform.rs::encrypt_credit_definition", + "gateway-rs/src/routes/platform.rs::transform_user_credit_keys", + "gateway-rs/src/storage/field_encryption.rs" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_credit_definition_masks_secret_key_material", + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision", + "gateway-rs/src/storage/field_encryption.rs::tests::plaintext_values_pass_through_without_an_encryption_marker" + ], + "source": { + "kind": "async_method", + "line": 208, + "path": "backend-services/services/credit_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/credit_service.py::async_method:CreditService.get_credit_def", + "notes": "Rust preserves credit-definition validation/CRUD/masking, definition and per-user pagination/search, user-credit upsert/read behavior, and key rotation. Credit definition keys and per-user keys are now encrypted on every write with the compatible field cipher, decrypted only for authorized user-credit reads, and rotation stores user_api_key while creating a missing user record as Python does. Some database-driver-specific error distinctions remain consolidated by shared storage.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::credit_routes", + "gateway-rs/src/routes/platform.rs::encrypt_credit_definition", + "gateway-rs/src/routes/platform.rs::transform_user_credit_keys", + "gateway-rs/src/storage/field_encryption.rs" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_credit_definition_masks_secret_key_material", + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision", + "gateway-rs/src/storage/field_encryption.rs::tests::plaintext_values_pass_through_without_an_encryption_marker" + ], + "source": { + "kind": "async_method", + "line": 272, + "path": "backend-services/services/credit_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/credit_service.py::async_method:CreditService.add_credits", + "notes": "Rust preserves credit-definition validation/CRUD/masking, definition and per-user pagination/search, user-credit upsert/read behavior, and key rotation. Credit definition keys and per-user keys are now encrypted on every write with the compatible field cipher, decrypted only for authorized user-credit reads, and rotation stores user_api_key while creating a missing user record as Python does. Some database-driver-specific error distinctions remain consolidated by shared storage.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::credit_routes", + "gateway-rs/src/routes/platform.rs::encrypt_credit_definition", + "gateway-rs/src/routes/platform.rs::transform_user_credit_keys", + "gateway-rs/src/storage/field_encryption.rs" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_credit_definition_masks_secret_key_material", + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision", + "gateway-rs/src/storage/field_encryption.rs::tests::plaintext_values_pass_through_without_an_encryption_marker" + ], + "source": { + "kind": "async_method", + "line": 301, + "path": "backend-services/services/credit_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/credit_service.py::async_method:CreditService.get_all_credits", + "notes": "Rust preserves credit-definition validation/CRUD/masking, definition and per-user pagination/search, user-credit upsert/read behavior, and key rotation. Credit definition keys and per-user keys are now encrypted on every write with the compatible field cipher, decrypted only for authorized user-credit reads, and rotation stores user_api_key while creating a missing user record as Python does. Some database-driver-specific error distinctions remain consolidated by shared storage.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::credit_routes", + "gateway-rs/src/routes/platform.rs::encrypt_credit_definition", + "gateway-rs/src/routes/platform.rs::transform_user_credit_keys", + "gateway-rs/src/storage/field_encryption.rs" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_credit_definition_masks_secret_key_material", + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision", + "gateway-rs/src/storage/field_encryption.rs::tests::plaintext_values_pass_through_without_an_encryption_marker" + ], + "source": { + "kind": "async_method", + "line": 338, + "path": "backend-services/services/credit_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/credit_service.py::async_method:CreditService.get_user_credits", + "notes": "Rust preserves credit-definition validation/CRUD/masking, definition and per-user pagination/search, user-credit upsert/read behavior, and key rotation. Credit definition keys and per-user keys are now encrypted on every write with the compatible field cipher, decrypted only for authorized user-credit reads, and rotation stores user_api_key while creating a missing user record as Python does. Some database-driver-specific error distinctions remain consolidated by shared storage.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::credit_routes", + "gateway-rs/src/routes/platform.rs::encrypt_credit_definition", + "gateway-rs/src/routes/platform.rs::transform_user_credit_keys", + "gateway-rs/src/storage/field_encryption.rs" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_credit_definition_masks_secret_key_material", + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision", + "gateway-rs/src/storage/field_encryption.rs::tests::plaintext_values_pass_through_without_an_encryption_marker" + ], + "source": { + "kind": "async_method", + "line": 434, + "path": "backend-services/services/credit_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/credit_service.py::async_method:CreditService.rotate_api_key", + "notes": "Rust preserves credit-definition validation/CRUD/masking, definition and per-user pagination/search, user-credit upsert/read behavior, and key rotation. Credit definition keys and per-user keys are now encrypted on every write with the compatible field cipher, decrypted only for authorized user-credit reads, and rotation stores user_api_key while creating a missing user record as Python does. Some database-driver-specific error distinctions remain consolidated by shared storage.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::credit_routes", + "gateway-rs/src/routes/platform.rs::encrypt_credit_definition", + "gateway-rs/src/routes/platform.rs::transform_user_credit_keys", + "gateway-rs/src/storage/field_encryption.rs" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_credit_definition_masks_secret_key_material", + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision", + "gateway-rs/src/storage/field_encryption.rs::tests::plaintext_values_pass_through_without_an_encryption_marker" + ], + "source": { + "kind": "async_method", + "line": 460, + "path": "backend-services/services/credit_service.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/crud_service.py::module:crud_service", + "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults, and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation now matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. Generated discovery document formatting and some exceptional non-object payload paths are not byte-identical.", + "rust_symbols": [ + "gateway-rs/src/routes/rest.rs::execute_crud", + "gateway-rs/src/routes/rest.rs::validate_crud_schema", + "gateway-rs/src/protocol/crud.rs::execute" + ], + "rust_tests": [ + "gateway-rs/src/routes/rest.rs::tests::validates_crud_schema_and_extracts_resource_ids", + "gateway-rs/src/protocol/crud.rs::tests::discovers_all_crud_operations", + "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/services/crud_service.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/crud_service.py::class:CrudService", + "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults, and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation now matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. Generated discovery document formatting and some exceptional non-object payload paths are not byte-identical.", + "rust_symbols": [ + "gateway-rs/src/routes/rest.rs::execute_crud", + "gateway-rs/src/routes/rest.rs::validate_crud_schema", + "gateway-rs/src/protocol/crud.rs::execute" + ], + "rust_tests": [ + "gateway-rs/src/routes/rest.rs::tests::validates_crud_schema_and_extracts_resource_ids", + "gateway-rs/src/protocol/crud.rs::tests::discovers_all_crud_operations", + "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows" + ], + "source": { + "kind": "class", + "line": 18, + "path": "backend-services/services/crud_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/crud_service.py::method:CrudService._get_collection", + "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults, and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation now matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. Generated discovery document formatting and some exceptional non-object payload paths are not byte-identical.", + "rust_symbols": [ + "gateway-rs/src/routes/rest.rs::execute_crud", + "gateway-rs/src/routes/rest.rs::validate_crud_schema", + "gateway-rs/src/protocol/crud.rs::execute" + ], + "rust_tests": [ + "gateway-rs/src/routes/rest.rs::tests::validates_crud_schema_and_extracts_resource_ids", + "gateway-rs/src/protocol/crud.rs::tests::discovers_all_crud_operations", + "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows" + ], + "source": { + "kind": "method", + "line": 20, + "path": "backend-services/services/crud_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/crud_service.py::method:CrudService._validate_schema", + "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults, and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation now matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. Generated discovery document formatting and some exceptional non-object payload paths are not byte-identical.", + "rust_symbols": [ + "gateway-rs/src/routes/rest.rs::execute_crud", + "gateway-rs/src/routes/rest.rs::validate_crud_schema", + "gateway-rs/src/protocol/crud.rs::execute" + ], + "rust_tests": [ + "gateway-rs/src/routes/rest.rs::tests::validates_crud_schema_and_extracts_resource_ids", + "gateway-rs/src/protocol/crud.rs::tests::discovers_all_crud_operations", + "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows" + ], + "source": { + "kind": "method", + "line": 44, + "path": "backend-services/services/crud_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/crud_service.py::async_method:CrudService.handle_rest", + "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults, and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation now matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. Generated discovery document formatting and some exceptional non-object payload paths are not byte-identical.", + "rust_symbols": [ + "gateway-rs/src/routes/rest.rs::execute_crud", + "gateway-rs/src/routes/rest.rs::validate_crud_schema", + "gateway-rs/src/protocol/crud.rs::execute" + ], + "rust_tests": [ + "gateway-rs/src/routes/rest.rs::tests::validates_crud_schema_and_extracts_resource_ids", + "gateway-rs/src/protocol/crud.rs::tests::discovers_all_crud_operations", + "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows" + ], + "source": { + "kind": "async_method", + "line": 126, + "path": "backend-services/services/crud_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/crud_service.py::method:CrudService._generate_sdl", + "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults, and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation now matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. Generated discovery document formatting and some exceptional non-object payload paths are not byte-identical.", + "rust_symbols": [ + "gateway-rs/src/routes/rest.rs::execute_crud", + "gateway-rs/src/routes/rest.rs::validate_crud_schema", + "gateway-rs/src/protocol/crud.rs::execute" + ], + "rust_tests": [ + "gateway-rs/src/routes/rest.rs::tests::validates_crud_schema_and_extracts_resource_ids", + "gateway-rs/src/protocol/crud.rs::tests::discovers_all_crud_operations", + "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows" + ], + "source": { + "kind": "method", + "line": 287, + "path": "backend-services/services/crud_service.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/crud_service.py::function:CrudService._generate_sdl.build_fields", + "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults, and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation now matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. Generated discovery document formatting and some exceptional non-object payload paths are not byte-identical.", + "rust_symbols": [ + "gateway-rs/src/routes/rest.rs::execute_crud", + "gateway-rs/src/routes/rest.rs::validate_crud_schema", + "gateway-rs/src/protocol/crud.rs::execute" + ], + "rust_tests": [ + "gateway-rs/src/routes/rest.rs::tests::validates_crud_schema_and_extracts_resource_ids", + "gateway-rs/src/protocol/crud.rs::tests::discovers_all_crud_operations", + "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows" + ], + "source": { + "kind": "function", + "line": 300, + "path": "backend-services/services/crud_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/crud_service.py::async_method:CrudService.handle_graphql", + "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults, and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation now matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. Generated discovery document formatting and some exceptional non-object payload paths are not byte-identical.", + "rust_symbols": [ + "gateway-rs/src/routes/rest.rs::execute_crud", + "gateway-rs/src/routes/rest.rs::validate_crud_schema", + "gateway-rs/src/protocol/crud.rs::execute" + ], + "rust_tests": [ + "gateway-rs/src/routes/rest.rs::tests::validates_crud_schema_and_extracts_resource_ids", + "gateway-rs/src/protocol/crud.rs::tests::discovers_all_crud_operations", + "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows" + ], + "source": { + "kind": "async_method", + "line": 347, + "path": "backend-services/services/crud_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "query_type.field('listItems')" + ], + "domain": "services", + "id": "backend-services/services/crud_service.py::async_function:CrudService.handle_graphql.resolve_list", + "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults, and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation now matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. Generated discovery document formatting and some exceptional non-object payload paths are not byte-identical.", + "rust_symbols": [ + "gateway-rs/src/routes/rest.rs::execute_crud", + "gateway-rs/src/routes/rest.rs::validate_crud_schema", + "gateway-rs/src/protocol/crud.rs::execute" + ], + "rust_tests": [ + "gateway-rs/src/routes/rest.rs::tests::validates_crud_schema_and_extracts_resource_ids", + "gateway-rs/src/protocol/crud.rs::tests::discovers_all_crud_operations", + "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows" + ], + "source": { + "kind": "async_function", + "line": 365, + "path": "backend-services/services/crud_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "query_type.field('getItem')" + ], + "domain": "services", + "id": "backend-services/services/crud_service.py::async_function:CrudService.handle_graphql.resolve_get", + "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults, and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation now matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. Generated discovery document formatting and some exceptional non-object payload paths are not byte-identical.", + "rust_symbols": [ + "gateway-rs/src/routes/rest.rs::execute_crud", + "gateway-rs/src/routes/rest.rs::validate_crud_schema", + "gateway-rs/src/protocol/crud.rs::execute" + ], + "rust_tests": [ + "gateway-rs/src/routes/rest.rs::tests::validates_crud_schema_and_extracts_resource_ids", + "gateway-rs/src/protocol/crud.rs::tests::discovers_all_crud_operations", + "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows" + ], + "source": { + "kind": "async_function", + "line": 372, + "path": "backend-services/services/crud_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "mutation_type.field('createItem')" + ], + "domain": "services", + "id": "backend-services/services/crud_service.py::async_function:CrudService.handle_graphql.resolve_create", + "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults, and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation now matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. Generated discovery document formatting and some exceptional non-object payload paths are not byte-identical.", + "rust_symbols": [ + "gateway-rs/src/routes/rest.rs::execute_crud", + "gateway-rs/src/routes/rest.rs::validate_crud_schema", + "gateway-rs/src/protocol/crud.rs::execute" + ], + "rust_tests": [ + "gateway-rs/src/routes/rest.rs::tests::validates_crud_schema_and_extracts_resource_ids", + "gateway-rs/src/protocol/crud.rs::tests::discovers_all_crud_operations", + "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows" + ], + "source": { + "kind": "async_function", + "line": 378, + "path": "backend-services/services/crud_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "mutation_type.field('updateItem')" + ], + "domain": "services", + "id": "backend-services/services/crud_service.py::async_function:CrudService.handle_graphql.resolve_update", + "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults, and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation now matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. Generated discovery document formatting and some exceptional non-object payload paths are not byte-identical.", + "rust_symbols": [ + "gateway-rs/src/routes/rest.rs::execute_crud", + "gateway-rs/src/routes/rest.rs::validate_crud_schema", + "gateway-rs/src/protocol/crud.rs::execute" + ], + "rust_tests": [ + "gateway-rs/src/routes/rest.rs::tests::validates_crud_schema_and_extracts_resource_ids", + "gateway-rs/src/protocol/crud.rs::tests::discovers_all_crud_operations", + "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows" + ], + "source": { + "kind": "async_function", + "line": 393, + "path": "backend-services/services/crud_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "mutation_type.field('deleteItem')" + ], + "domain": "services", + "id": "backend-services/services/crud_service.py::async_function:CrudService.handle_graphql.resolve_delete", + "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults, and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation now matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. Generated discovery document formatting and some exceptional non-object payload paths are not byte-identical.", + "rust_symbols": [ + "gateway-rs/src/routes/rest.rs::execute_crud", + "gateway-rs/src/routes/rest.rs::validate_crud_schema", + "gateway-rs/src/protocol/crud.rs::execute" + ], + "rust_tests": [ + "gateway-rs/src/routes/rest.rs::tests::validates_crud_schema_and_extracts_resource_ids", + "gateway-rs/src/protocol/crud.rs::tests::discovers_all_crud_operations", + "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows" + ], + "source": { + "kind": "async_function", + "line": 407, + "path": "backend-services/services/crud_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/crud_service.py::method:CrudService._generate_wsdl", + "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults, and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation now matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. Generated discovery document formatting and some exceptional non-object payload paths are not byte-identical.", + "rust_symbols": [ + "gateway-rs/src/routes/rest.rs::execute_crud", + "gateway-rs/src/routes/rest.rs::validate_crud_schema", + "gateway-rs/src/protocol/crud.rs::execute" + ], + "rust_tests": [ + "gateway-rs/src/routes/rest.rs::tests::validates_crud_schema_and_extracts_resource_ids", + "gateway-rs/src/protocol/crud.rs::tests::discovers_all_crud_operations", + "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows" + ], + "source": { + "kind": "method", + "line": 435, + "path": "backend-services/services/crud_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/crud_service.py::async_method:CrudService.handle_soap", + "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults, and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation now matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. Generated discovery document formatting and some exceptional non-object payload paths are not byte-identical.", + "rust_symbols": [ + "gateway-rs/src/routes/rest.rs::execute_crud", + "gateway-rs/src/routes/rest.rs::validate_crud_schema", + "gateway-rs/src/protocol/crud.rs::execute" + ], + "rust_tests": [ + "gateway-rs/src/routes/rest.rs::tests::validates_crud_schema_and_extracts_resource_ids", + "gateway-rs/src/protocol/crud.rs::tests::discovers_all_crud_operations", + "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows" + ], + "source": { + "kind": "async_method", + "line": 528, + "path": "backend-services/services/crud_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/crud_service.py::method:CrudService._generate_proto", + "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults, and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation now matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. Generated discovery document formatting and some exceptional non-object payload paths are not byte-identical.", + "rust_symbols": [ + "gateway-rs/src/routes/rest.rs::execute_crud", + "gateway-rs/src/routes/rest.rs::validate_crud_schema", + "gateway-rs/src/protocol/crud.rs::execute" + ], + "rust_tests": [ + "gateway-rs/src/routes/rest.rs::tests::validates_crud_schema_and_extracts_resource_ids", + "gateway-rs/src/protocol/crud.rs::tests::discovers_all_crud_operations", + "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows" + ], + "source": { + "kind": "method", + "line": 664, + "path": "backend-services/services/crud_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/crud_service.py::async_method:CrudService.handle_grpc", + "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults, and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation now matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. Generated discovery document formatting and some exceptional non-object payload paths are not byte-identical.", + "rust_symbols": [ + "gateway-rs/src/routes/rest.rs::execute_crud", + "gateway-rs/src/routes/rest.rs::validate_crud_schema", + "gateway-rs/src/protocol/crud.rs::execute" + ], + "rust_tests": [ + "gateway-rs/src/routes/rest.rs::tests::validates_crud_schema_and_extracts_resource_ids", + "gateway-rs/src/protocol/crud.rs::tests::discovers_all_crud_operations", + "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows" + ], + "source": { + "kind": "async_method", + "line": 717, + "path": "backend-services/services/crud_service.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/endpoint_service.py::module:endpoint_service", + "notes": "Rust preserves endpoint and endpoint-validation CRUD, immutable identity fields, duplicate/client-URI conflict detection, API linkage, pagination, masking of storage internals, permissions, and the principal END00x response contracts. Python-only pre-generation of Python gRPC modules is not reproduced, and a few endpoint-validation storage failure codes remain consolidated by the native route layer.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::endpoint_routes", + "gateway-rs/src/routes/platform.rs::normalize_endpoint_validation_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts", + "gateway-rs/tests/live_tests_parity.rs::live_test_41_soap_and_85_endpoint_validation_parity" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/services/endpoint_service.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/endpoint_service.py::class:EndpointService", + "notes": "Rust preserves endpoint and endpoint-validation CRUD, immutable identity fields, duplicate/client-URI conflict detection, API linkage, pagination, masking of storage internals, permissions, and the principal END00x response contracts. Python-only pre-generation of Python gRPC modules is not reproduced, and a few endpoint-validation storage failure codes remain consolidated by the native route layer.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::endpoint_routes", + "gateway-rs/src/routes/platform.rs::normalize_endpoint_validation_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts", + "gateway-rs/tests/live_tests_parity.rs::live_test_41_soap_and_85_endpoint_validation_parity" + ], + "source": { + "kind": "class", + "line": 23, + "path": "backend-services/services/endpoint_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/endpoint_service.py::async_method:EndpointService.create_endpoint", + "notes": "Rust preserves endpoint and endpoint-validation CRUD, immutable identity fields, duplicate/client-URI conflict detection, API linkage, pagination, masking of storage internals, permissions, and the principal END00x response contracts. Python-only pre-generation of Python gRPC modules is not reproduced, and a few endpoint-validation storage failure codes remain consolidated by the native route layer.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::endpoint_routes", + "gateway-rs/src/routes/platform.rs::normalize_endpoint_validation_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts", + "gateway-rs/tests/live_tests_parity.rs::live_test_41_soap_and_85_endpoint_validation_parity" + ], + "source": { + "kind": "async_method", + "line": 25, + "path": "backend-services/services/endpoint_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/endpoint_service.py::async_method:EndpointService.update_endpoint", + "notes": "Rust preserves endpoint and endpoint-validation CRUD, immutable identity fields, duplicate/client-URI conflict detection, API linkage, pagination, masking of storage internals, permissions, and the principal END00x response contracts. Python-only pre-generation of Python gRPC modules is not reproduced, and a few endpoint-validation storage failure codes remain consolidated by the native route layer.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::endpoint_routes", + "gateway-rs/src/routes/platform.rs::normalize_endpoint_validation_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts", + "gateway-rs/tests/live_tests_parity.rs::live_test_41_soap_and_85_endpoint_validation_parity" + ], + "source": { + "kind": "async_method", + "line": 196, + "path": "backend-services/services/endpoint_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/endpoint_service.py::async_method:EndpointService.delete_endpoint", + "notes": "Rust preserves endpoint and endpoint-validation CRUD, immutable identity fields, duplicate/client-URI conflict detection, API linkage, pagination, masking of storage internals, permissions, and the principal END00x response contracts. Python-only pre-generation of Python gRPC modules is not reproduced, and a few endpoint-validation storage failure codes remain consolidated by the native route layer.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::endpoint_routes", + "gateway-rs/src/routes/platform.rs::normalize_endpoint_validation_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts", + "gateway-rs/tests/live_tests_parity.rs::live_test_41_soap_and_85_endpoint_validation_parity" + ], + "source": { + "kind": "async_method", + "line": 291, + "path": "backend-services/services/endpoint_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/endpoint_service.py::async_method:EndpointService.get_endpoint", + "notes": "Rust preserves endpoint and endpoint-validation CRUD, immutable identity fields, duplicate/client-URI conflict detection, API linkage, pagination, masking of storage internals, permissions, and the principal END00x response contracts. Python-only pre-generation of Python gRPC modules is not reproduced, and a few endpoint-validation storage failure codes remain consolidated by the native route layer.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::endpoint_routes", + "gateway-rs/src/routes/platform.rs::normalize_endpoint_validation_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts", + "gateway-rs/tests/live_tests_parity.rs::live_test_41_soap_and_85_endpoint_validation_parity" + ], + "source": { + "kind": "async_method", + "line": 347, + "path": "backend-services/services/endpoint_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/endpoint_service.py::async_method:EndpointService.get_endpoints_by_name_version", + "notes": "Rust preserves endpoint and endpoint-validation CRUD, immutable identity fields, duplicate/client-URI conflict detection, API linkage, pagination, masking of storage internals, permissions, and the principal END00x response contracts. Python-only pre-generation of Python gRPC modules is not reproduced, and a few endpoint-validation storage failure codes remain consolidated by the native route layer.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::endpoint_routes", + "gateway-rs/src/routes/platform.rs::normalize_endpoint_validation_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts", + "gateway-rs/tests/live_tests_parity.rs::live_test_41_soap_and_85_endpoint_validation_parity" + ], + "source": { + "kind": "async_method", + "line": 382, + "path": "backend-services/services/endpoint_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/endpoint_service.py::async_method:EndpointService.create_endpoint_validation", + "notes": "Rust preserves endpoint and endpoint-validation CRUD, immutable identity fields, duplicate/client-URI conflict detection, API linkage, pagination, masking of storage internals, permissions, and the principal END00x response contracts. Python-only pre-generation of Python gRPC modules is not reproduced, and a few endpoint-validation storage failure codes remain consolidated by the native route layer.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::endpoint_routes", + "gateway-rs/src/routes/platform.rs::normalize_endpoint_validation_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts", + "gateway-rs/tests/live_tests_parity.rs::live_test_41_soap_and_85_endpoint_validation_parity" + ], + "source": { + "kind": "async_method", + "line": 408, + "path": "backend-services/services/endpoint_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/endpoint_service.py::async_method:EndpointService.get_endpoint_validation", + "notes": "Rust preserves endpoint and endpoint-validation CRUD, immutable identity fields, duplicate/client-URI conflict detection, API linkage, pagination, masking of storage internals, permissions, and the principal END00x response contracts. Python-only pre-generation of Python gRPC modules is not reproduced, and a few endpoint-validation storage failure codes remain consolidated by the native route layer.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::endpoint_routes", + "gateway-rs/src/routes/platform.rs::normalize_endpoint_validation_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts", + "gateway-rs/tests/live_tests_parity.rs::live_test_41_soap_and_85_endpoint_validation_parity" + ], + "source": { + "kind": "async_method", + "line": 451, + "path": "backend-services/services/endpoint_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/endpoint_service.py::async_method:EndpointService.delete_endpoint_validation", + "notes": "Rust preserves endpoint and endpoint-validation CRUD, immutable identity fields, duplicate/client-URI conflict detection, API linkage, pagination, masking of storage internals, permissions, and the principal END00x response contracts. Python-only pre-generation of Python gRPC modules is not reproduced, and a few endpoint-validation storage failure codes remain consolidated by the native route layer.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::endpoint_routes", + "gateway-rs/src/routes/platform.rs::normalize_endpoint_validation_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts", + "gateway-rs/tests/live_tests_parity.rs::live_test_41_soap_and_85_endpoint_validation_parity" + ], + "source": { + "kind": "async_method", + "line": 472, + "path": "backend-services/services/endpoint_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/endpoint_service.py::async_method:EndpointService.update_endpoint_validation", + "notes": "Rust preserves endpoint and endpoint-validation CRUD, immutable identity fields, duplicate/client-URI conflict detection, API linkage, pagination, masking of storage internals, permissions, and the principal END00x response contracts. Python-only pre-generation of Python gRPC modules is not reproduced, and a few endpoint-validation storage failure codes remain consolidated by the native route layer.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::endpoint_routes", + "gateway-rs/src/routes/platform.rs::normalize_endpoint_validation_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts", + "gateway-rs/tests/live_tests_parity.rs::live_test_41_soap_and_85_endpoint_validation_parity" + ], + "source": { + "kind": "async_method", + "line": 491, + "path": "backend-services/services/endpoint_service.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/gateway_service.py::module:gateway_service", + "notes": "Rust preserves API and endpoint resolution (including distinct GTW002/GTW003 failures), disabled/public/auth policy, CORS and preflight behavior, request identity and allowed-header forwarding, system/user credit precedence, authorization swapping, endpoint validation and transforms, client routing, timeouts, retries/backoff, circuit breaking, upstream status and malformed-JSON mapping, SOAP version and WS-Security processing, GraphQL depth/error handling, and descriptor-driven gRPC unary/client/server/bidirectional streaming with metadata filtering, TLS, limits, and status mapping. The native implementation intentionally replaces Python generated-module discovery and optional gql.Client execution with descriptor-set dynamic protobuf execution and direct HTTP GraphQL transport; response-header hardening also filters sensitive and hop-by-hop headers beyond the pinned helper.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::evaluate_rest_policy", + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/protocol/soap.rs", + "gateway-rs/src/protocol/grpc.rs", + "gateway-rs/src/gateway/resolution.rs", + "gateway-rs/src/gateway/retries.rs", + "gateway-rs/src/gateway/transforms.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::returns_no_endpoints_for_api_without_registered_endpoints", + "gateway-rs/src/routes/rest.rs::tests::rejects_malformed_json_from_rest_upstream_like_python", + "gateway-rs/tests/runtime.rs", + "gateway-rs/tests/grpc_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/services/gateway_service.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/gateway_service.py::function:gql", + "notes": "Rust preserves API and endpoint resolution (including distinct GTW002/GTW003 failures), disabled/public/auth policy, CORS and preflight behavior, request identity and allowed-header forwarding, system/user credit precedence, authorization swapping, endpoint validation and transforms, client routing, timeouts, retries/backoff, circuit breaking, upstream status and malformed-JSON mapping, SOAP version and WS-Security processing, GraphQL depth/error handling, and descriptor-driven gRPC unary/client/server/bidirectional streaming with metadata filtering, TLS, limits, and status mapping. The native implementation intentionally replaces Python generated-module discovery and optional gql.Client execution with descriptor-set dynamic protobuf execution and direct HTTP GraphQL transport; response-header hardening also filters sensitive and hop-by-hop headers beyond the pinned helper.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::evaluate_rest_policy", + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/protocol/soap.rs", + "gateway-rs/src/protocol/grpc.rs", + "gateway-rs/src/gateway/resolution.rs", + "gateway-rs/src/gateway/retries.rs", + "gateway-rs/src/gateway/transforms.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::returns_no_endpoints_for_api_without_registered_endpoints", + "gateway-rs/src/routes/rest.rs::tests::rejects_malformed_json_from_rest_upstream_like_python", + "gateway-rs/tests/runtime.rs", + "gateway-rs/tests/grpc_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "function", + "line": 27, + "path": "backend-services/services/gateway_service.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/gateway_service.py::class:_GqlClient", + "notes": "Rust preserves API and endpoint resolution (including distinct GTW002/GTW003 failures), disabled/public/auth policy, CORS and preflight behavior, request identity and allowed-header forwarding, system/user credit precedence, authorization swapping, endpoint validation and transforms, client routing, timeouts, retries/backoff, circuit breaking, upstream status and malformed-JSON mapping, SOAP version and WS-Security processing, GraphQL depth/error handling, and descriptor-driven gRPC unary/client/server/bidirectional streaming with metadata filtering, TLS, limits, and status mapping. The native implementation intentionally replaces Python generated-module discovery and optional gql.Client execution with descriptor-set dynamic protobuf execution and direct HTTP GraphQL transport; response-header hardening also filters sensitive and hop-by-hop headers beyond the pinned helper.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::evaluate_rest_policy", + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/protocol/soap.rs", + "gateway-rs/src/protocol/grpc.rs", + "gateway-rs/src/gateway/resolution.rs", + "gateway-rs/src/gateway/retries.rs", + "gateway-rs/src/gateway/transforms.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::returns_no_endpoints_for_api_without_registered_endpoints", + "gateway-rs/src/routes/rest.rs::tests::rejects_malformed_json_from_rest_upstream_like_python", + "gateway-rs/tests/runtime.rs", + "gateway-rs/tests/grpc_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "class", + "line": 31, + "path": "backend-services/services/gateway_service.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/gateway_service.py::method:_GqlClient.__init__", + "notes": "Rust preserves API and endpoint resolution (including distinct GTW002/GTW003 failures), disabled/public/auth policy, CORS and preflight behavior, request identity and allowed-header forwarding, system/user credit precedence, authorization swapping, endpoint validation and transforms, client routing, timeouts, retries/backoff, circuit breaking, upstream status and malformed-JSON mapping, SOAP version and WS-Security processing, GraphQL depth/error handling, and descriptor-driven gRPC unary/client/server/bidirectional streaming with metadata filtering, TLS, limits, and status mapping. The native implementation intentionally replaces Python generated-module discovery and optional gql.Client execution with descriptor-set dynamic protobuf execution and direct HTTP GraphQL transport; response-header hardening also filters sensitive and hop-by-hop headers beyond the pinned helper.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::evaluate_rest_policy", + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/protocol/soap.rs", + "gateway-rs/src/protocol/grpc.rs", + "gateway-rs/src/gateway/resolution.rs", + "gateway-rs/src/gateway/retries.rs", + "gateway-rs/src/gateway/transforms.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::returns_no_endpoints_for_api_without_registered_endpoints", + "gateway-rs/src/routes/rest.rs::tests::rejects_malformed_json_from_rest_upstream_like_python", + "gateway-rs/tests/runtime.rs", + "gateway-rs/tests/grpc_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "method", + "line": 32, + "path": "backend-services/services/gateway_service.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/gateway_service.py::function:gql#2", + "notes": "Rust preserves API and endpoint resolution (including distinct GTW002/GTW003 failures), disabled/public/auth policy, CORS and preflight behavior, request identity and allowed-header forwarding, system/user credit precedence, authorization swapping, endpoint validation and transforms, client routing, timeouts, retries/backoff, circuit breaking, upstream status and malformed-JSON mapping, SOAP version and WS-Security processing, GraphQL depth/error handling, and descriptor-driven gRPC unary/client/server/bidirectional streaming with metadata filtering, TLS, limits, and status mapping. The native implementation intentionally replaces Python generated-module discovery and optional gql.Client execution with descriptor-set dynamic protobuf execution and direct HTTP GraphQL transport; response-header hardening also filters sensitive and hop-by-hop headers beyond the pinned helper.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::evaluate_rest_policy", + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/protocol/soap.rs", + "gateway-rs/src/protocol/grpc.rs", + "gateway-rs/src/gateway/resolution.rs", + "gateway-rs/src/gateway/retries.rs", + "gateway-rs/src/gateway/transforms.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::returns_no_endpoints_for_api_without_registered_endpoints", + "gateway-rs/src/routes/rest.rs::tests::rejects_malformed_json_from_rest_upstream_like_python", + "gateway-rs/tests/runtime.rs", + "gateway-rs/tests/grpc_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "function", + "line": 35, + "path": "backend-services/services/gateway_service.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/gateway_service.py::class:GatewayService", + "notes": "Rust preserves API and endpoint resolution (including distinct GTW002/GTW003 failures), disabled/public/auth policy, CORS and preflight behavior, request identity and allowed-header forwarding, system/user credit precedence, authorization swapping, endpoint validation and transforms, client routing, timeouts, retries/backoff, circuit breaking, upstream status and malformed-JSON mapping, SOAP version and WS-Security processing, GraphQL depth/error handling, and descriptor-driven gRPC unary/client/server/bidirectional streaming with metadata filtering, TLS, limits, and status mapping. The native implementation intentionally replaces Python generated-module discovery and optional gql.Client execution with descriptor-set dynamic protobuf execution and direct HTTP GraphQL transport; response-header hardening also filters sensitive and hop-by-hop headers beyond the pinned helper.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::evaluate_rest_policy", + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/protocol/soap.rs", + "gateway-rs/src/protocol/grpc.rs", + "gateway-rs/src/gateway/resolution.rs", + "gateway-rs/src/gateway/retries.rs", + "gateway-rs/src/gateway/transforms.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::returns_no_endpoints_for_api_without_registered_endpoints", + "gateway-rs/src/routes/rest.rs::tests::rejects_malformed_json_from_rest_upstream_like_python", + "gateway-rs/tests/runtime.rs", + "gateway-rs/tests/grpc_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "class", + "line": 58, + "path": "backend-services/services/gateway_service.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/gateway_service.py::field:GatewayService.timeout", + "notes": "Rust preserves API and endpoint resolution (including distinct GTW002/GTW003 failures), disabled/public/auth policy, CORS and preflight behavior, request identity and allowed-header forwarding, system/user credit precedence, authorization swapping, endpoint validation and transforms, client routing, timeouts, retries/backoff, circuit breaking, upstream status and malformed-JSON mapping, SOAP version and WS-Security processing, GraphQL depth/error handling, and descriptor-driven gRPC unary/client/server/bidirectional streaming with metadata filtering, TLS, limits, and status mapping. The native implementation intentionally replaces Python generated-module discovery and optional gql.Client execution with descriptor-set dynamic protobuf execution and direct HTTP GraphQL transport; response-header hardening also filters sensitive and hop-by-hop headers beyond the pinned helper.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::evaluate_rest_policy", + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/protocol/soap.rs", + "gateway-rs/src/protocol/grpc.rs", + "gateway-rs/src/gateway/resolution.rs", + "gateway-rs/src/gateway/retries.rs", + "gateway-rs/src/gateway/transforms.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::returns_no_endpoints_for_api_without_registered_endpoints", + "gateway-rs/src/routes/rest.rs::tests::rejects_malformed_json_from_rest_upstream_like_python", + "gateway-rs/tests/runtime.rs", + "gateway-rs/tests/grpc_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 59, + "path": "backend-services/services/gateway_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/gateway_service.py::method:GatewayService._build_limits", + "notes": "Rust preserves API and endpoint resolution (including distinct GTW002/GTW003 failures), disabled/public/auth policy, CORS and preflight behavior, request identity and allowed-header forwarding, system/user credit precedence, authorization swapping, endpoint validation and transforms, client routing, timeouts, retries/backoff, circuit breaking, upstream status and malformed-JSON mapping, SOAP version and WS-Security processing, GraphQL depth/error handling, and descriptor-driven gRPC unary/client/server/bidirectional streaming with metadata filtering, TLS, limits, and status mapping. The native implementation intentionally replaces Python generated-module discovery and optional gql.Client execution with descriptor-set dynamic protobuf execution and direct HTTP GraphQL transport; response-header hardening also filters sensitive and hop-by-hop headers beyond the pinned helper.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::evaluate_rest_policy", + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/protocol/soap.rs", + "gateway-rs/src/protocol/grpc.rs", + "gateway-rs/src/gateway/resolution.rs", + "gateway-rs/src/gateway/retries.rs", + "gateway-rs/src/gateway/transforms.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::returns_no_endpoints_for_api_without_registered_endpoints", + "gateway-rs/src/routes/rest.rs::tests::rejects_malformed_json_from_rest_upstream_like_python", + "gateway-rs/tests/runtime.rs", + "gateway-rs/tests/grpc_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "method", + "line": 78, + "path": "backend-services/services/gateway_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "classmethod" + ], + "domain": "services", + "id": "backend-services/services/gateway_service.py::method:GatewayService.get_http_client", + "notes": "Rust preserves API and endpoint resolution (including distinct GTW002/GTW003 failures), disabled/public/auth policy, CORS and preflight behavior, request identity and allowed-header forwarding, system/user credit precedence, authorization swapping, endpoint validation and transforms, client routing, timeouts, retries/backoff, circuit breaking, upstream status and malformed-JSON mapping, SOAP version and WS-Security processing, GraphQL depth/error handling, and descriptor-driven gRPC unary/client/server/bidirectional streaming with metadata filtering, TLS, limits, and status mapping. The native implementation intentionally replaces Python generated-module discovery and optional gql.Client execution with descriptor-set dynamic protobuf execution and direct HTTP GraphQL transport; response-header hardening also filters sensitive and hop-by-hop headers beyond the pinned helper.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::evaluate_rest_policy", + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/protocol/soap.rs", + "gateway-rs/src/protocol/grpc.rs", + "gateway-rs/src/gateway/resolution.rs", + "gateway-rs/src/gateway/retries.rs", + "gateway-rs/src/gateway/transforms.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::returns_no_endpoints_for_api_without_registered_endpoints", + "gateway-rs/src/routes/rest.rs::tests::rejects_malformed_json_from_rest_upstream_like_python", + "gateway-rs/tests/runtime.rs", + "gateway-rs/tests/grpc_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "method", + "line": 103, + "path": "backend-services/services/gateway_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "classmethod" + ], + "domain": "services", + "id": "backend-services/services/gateway_service.py::async_method:GatewayService.aclose_http_client", + "notes": "Rust preserves API and endpoint resolution (including distinct GTW002/GTW003 failures), disabled/public/auth policy, CORS and preflight behavior, request identity and allowed-header forwarding, system/user credit precedence, authorization swapping, endpoint validation and transforms, client routing, timeouts, retries/backoff, circuit breaking, upstream status and malformed-JSON mapping, SOAP version and WS-Security processing, GraphQL depth/error handling, and descriptor-driven gRPC unary/client/server/bidirectional streaming with metadata filtering, TLS, limits, and status mapping. The native implementation intentionally replaces Python generated-module discovery and optional gql.Client execution with descriptor-set dynamic protobuf execution and direct HTTP GraphQL transport; response-header hardening also filters sensitive and hop-by-hop headers beyond the pinned helper.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::evaluate_rest_policy", + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/protocol/soap.rs", + "gateway-rs/src/protocol/grpc.rs", + "gateway-rs/src/gateway/resolution.rs", + "gateway-rs/src/gateway/retries.rs", + "gateway-rs/src/gateway/transforms.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::returns_no_endpoints_for_api_without_registered_endpoints", + "gateway-rs/src/routes/rest.rs::tests::rejects_malformed_json_from_rest_upstream_like_python", + "gateway-rs/tests/runtime.rs", + "gateway-rs/tests/grpc_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "async_method", + "line": 157, + "path": "backend-services/services/gateway_service.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/gateway_service.py::method:GatewayService.error_response", + "notes": "Rust preserves API and endpoint resolution (including distinct GTW002/GTW003 failures), disabled/public/auth policy, CORS and preflight behavior, request identity and allowed-header forwarding, system/user credit precedence, authorization swapping, endpoint validation and transforms, client routing, timeouts, retries/backoff, circuit breaking, upstream status and malformed-JSON mapping, SOAP version and WS-Security processing, GraphQL depth/error handling, and descriptor-driven gRPC unary/client/server/bidirectional streaming with metadata filtering, TLS, limits, and status mapping. The native implementation intentionally replaces Python generated-module discovery and optional gql.Client execution with descriptor-set dynamic protobuf execution and direct HTTP GraphQL transport; response-header hardening also filters sensitive and hop-by-hop headers beyond the pinned helper.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::evaluate_rest_policy", + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/protocol/soap.rs", + "gateway-rs/src/protocol/grpc.rs", + "gateway-rs/src/gateway/resolution.rs", + "gateway-rs/src/gateway/retries.rs", + "gateway-rs/src/gateway/transforms.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::returns_no_endpoints_for_api_without_registered_endpoints", + "gateway-rs/src/routes/rest.rs::tests::rejects_malformed_json_from_rest_upstream_like_python", + "gateway-rs/tests/runtime.rs", + "gateway-rs/tests/grpc_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "method", + "line": 166, + "path": "backend-services/services/gateway_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/gateway_service.py::method:GatewayService._compute_api_cors_headers", + "notes": "Rust preserves API and endpoint resolution (including distinct GTW002/GTW003 failures), disabled/public/auth policy, CORS and preflight behavior, request identity and allowed-header forwarding, system/user credit precedence, authorization swapping, endpoint validation and transforms, client routing, timeouts, retries/backoff, circuit breaking, upstream status and malformed-JSON mapping, SOAP version and WS-Security processing, GraphQL depth/error handling, and descriptor-driven gRPC unary/client/server/bidirectional streaming with metadata filtering, TLS, limits, and status mapping. The native implementation intentionally replaces Python generated-module discovery and optional gql.Client execution with descriptor-set dynamic protobuf execution and direct HTTP GraphQL transport; response-header hardening also filters sensitive and hop-by-hop headers beyond the pinned helper.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::evaluate_rest_policy", + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/protocol/soap.rs", + "gateway-rs/src/protocol/grpc.rs", + "gateway-rs/src/gateway/resolution.rs", + "gateway-rs/src/gateway/retries.rs", + "gateway-rs/src/gateway/transforms.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::returns_no_endpoints_for_api_without_registered_endpoints", + "gateway-rs/src/routes/rest.rs::tests::rejects_malformed_json_from_rest_upstream_like_python", + "gateway-rs/tests/runtime.rs", + "gateway-rs/tests/grpc_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "method", + "line": 176, + "path": "backend-services/services/gateway_service.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/gateway_service.py::method:GatewayService.parse_response", + "notes": "Rust preserves API and endpoint resolution (including distinct GTW002/GTW003 failures), disabled/public/auth policy, CORS and preflight behavior, request identity and allowed-header forwarding, system/user credit precedence, authorization swapping, endpoint validation and transforms, client routing, timeouts, retries/backoff, circuit breaking, upstream status and malformed-JSON mapping, SOAP version and WS-Security processing, GraphQL depth/error handling, and descriptor-driven gRPC unary/client/server/bidirectional streaming with metadata filtering, TLS, limits, and status mapping. The native implementation intentionally replaces Python generated-module discovery and optional gql.Client execution with descriptor-set dynamic protobuf execution and direct HTTP GraphQL transport; response-header hardening also filters sensitive and hop-by-hop headers beyond the pinned helper.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::evaluate_rest_policy", + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/protocol/soap.rs", + "gateway-rs/src/protocol/grpc.rs", + "gateway-rs/src/gateway/resolution.rs", + "gateway-rs/src/gateway/retries.rs", + "gateway-rs/src/gateway/transforms.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::returns_no_endpoints_for_api_without_registered_endpoints", + "gateway-rs/src/routes/rest.rs::tests::rejects_malformed_json_from_rest_upstream_like_python", + "gateway-rs/tests/runtime.rs", + "gateway-rs/tests/grpc_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "method", + "line": 261, + "path": "backend-services/services/gateway_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/gateway_service.py::async_method:GatewayService._resolve_api_from_path", + "notes": "Rust preserves API and endpoint resolution (including distinct GTW002/GTW003 failures), disabled/public/auth policy, CORS and preflight behavior, request identity and allowed-header forwarding, system/user credit precedence, authorization swapping, endpoint validation and transforms, client routing, timeouts, retries/backoff, circuit breaking, upstream status and malformed-JSON mapping, SOAP version and WS-Security processing, GraphQL depth/error handling, and descriptor-driven gRPC unary/client/server/bidirectional streaming with metadata filtering, TLS, limits, and status mapping. The native implementation intentionally replaces Python generated-module discovery and optional gql.Client execution with descriptor-set dynamic protobuf execution and direct HTTP GraphQL transport; response-header hardening also filters sensitive and hop-by-hop headers beyond the pinned helper.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::evaluate_rest_policy", + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/protocol/soap.rs", + "gateway-rs/src/protocol/grpc.rs", + "gateway-rs/src/gateway/resolution.rs", + "gateway-rs/src/gateway/retries.rs", + "gateway-rs/src/gateway/transforms.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::returns_no_endpoints_for_api_without_registered_endpoints", + "gateway-rs/src/routes/rest.rs::tests::rejects_malformed_json_from_rest_upstream_like_python", + "gateway-rs/tests/runtime.rs", + "gateway-rs/tests/grpc_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "async_method", + "line": 298, + "path": "backend-services/services/gateway_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/gateway_service.py::async_method:GatewayService._check_and_deduct_credits", + "notes": "Rust preserves API and endpoint resolution (including distinct GTW002/GTW003 failures), disabled/public/auth policy, CORS and preflight behavior, request identity and allowed-header forwarding, system/user credit precedence, authorization swapping, endpoint validation and transforms, client routing, timeouts, retries/backoff, circuit breaking, upstream status and malformed-JSON mapping, SOAP version and WS-Security processing, GraphQL depth/error handling, and descriptor-driven gRPC unary/client/server/bidirectional streaming with metadata filtering, TLS, limits, and status mapping. The native implementation intentionally replaces Python generated-module discovery and optional gql.Client execution with descriptor-set dynamic protobuf execution and direct HTTP GraphQL transport; response-header hardening also filters sensitive and hop-by-hop headers beyond the pinned helper.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::evaluate_rest_policy", + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/protocol/soap.rs", + "gateway-rs/src/protocol/grpc.rs", + "gateway-rs/src/gateway/resolution.rs", + "gateway-rs/src/gateway/retries.rs", + "gateway-rs/src/gateway/transforms.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::returns_no_endpoints_for_api_without_registered_endpoints", + "gateway-rs/src/routes/rest.rs::tests::rejects_malformed_json_from_rest_upstream_like_python", + "gateway-rs/tests/runtime.rs", + "gateway-rs/tests/grpc_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "async_method", + "line": 329, + "path": "backend-services/services/gateway_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/gateway_service.py::async_method:GatewayService._apply_credit_headers", + "notes": "Rust preserves API and endpoint resolution (including distinct GTW002/GTW003 failures), disabled/public/auth policy, CORS and preflight behavior, request identity and allowed-header forwarding, system/user credit precedence, authorization swapping, endpoint validation and transforms, client routing, timeouts, retries/backoff, circuit breaking, upstream status and malformed-JSON mapping, SOAP version and WS-Security processing, GraphQL depth/error handling, and descriptor-driven gRPC unary/client/server/bidirectional streaming with metadata filtering, TLS, limits, and status mapping. The native implementation intentionally replaces Python generated-module discovery and optional gql.Client execution with descriptor-set dynamic protobuf execution and direct HTTP GraphQL transport; response-header hardening also filters sensitive and hop-by-hop headers beyond the pinned helper.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::evaluate_rest_policy", + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/protocol/soap.rs", + "gateway-rs/src/protocol/grpc.rs", + "gateway-rs/src/gateway/resolution.rs", + "gateway-rs/src/gateway/retries.rs", + "gateway-rs/src/gateway/transforms.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::returns_no_endpoints_for_api_without_registered_endpoints", + "gateway-rs/src/routes/rest.rs::tests::rejects_malformed_json_from_rest_upstream_like_python", + "gateway-rs/tests/runtime.rs", + "gateway-rs/tests/grpc_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "async_method", + "line": 355, + "path": "backend-services/services/gateway_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/gateway_service.py::method:GatewayService._sanitize_grpc_metadata", + "notes": "Rust preserves API and endpoint resolution (including distinct GTW002/GTW003 failures), disabled/public/auth policy, CORS and preflight behavior, request identity and allowed-header forwarding, system/user credit precedence, authorization swapping, endpoint validation and transforms, client routing, timeouts, retries/backoff, circuit breaking, upstream status and malformed-JSON mapping, SOAP version and WS-Security processing, GraphQL depth/error handling, and descriptor-driven gRPC unary/client/server/bidirectional streaming with metadata filtering, TLS, limits, and status mapping. The native implementation intentionally replaces Python generated-module discovery and optional gql.Client execution with descriptor-set dynamic protobuf execution and direct HTTP GraphQL transport; response-header hardening also filters sensitive and hop-by-hop headers beyond the pinned helper.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::evaluate_rest_policy", + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/protocol/soap.rs", + "gateway-rs/src/protocol/grpc.rs", + "gateway-rs/src/gateway/resolution.rs", + "gateway-rs/src/gateway/retries.rs", + "gateway-rs/src/gateway/transforms.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::returns_no_endpoints_for_api_without_registered_endpoints", + "gateway-rs/src/routes/rest.rs::tests::rejects_malformed_json_from_rest_upstream_like_python", + "gateway-rs/tests/runtime.rs", + "gateway-rs/tests/grpc_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "method", + "line": 390, + "path": "backend-services/services/gateway_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/gateway_service.py::method:GatewayService._validate_under_base", + "notes": "Rust preserves API and endpoint resolution (including distinct GTW002/GTW003 failures), disabled/public/auth policy, CORS and preflight behavior, request identity and allowed-header forwarding, system/user credit precedence, authorization swapping, endpoint validation and transforms, client routing, timeouts, retries/backoff, circuit breaking, upstream status and malformed-JSON mapping, SOAP version and WS-Security processing, GraphQL depth/error handling, and descriptor-driven gRPC unary/client/server/bidirectional streaming with metadata filtering, TLS, limits, and status mapping. The native implementation intentionally replaces Python generated-module discovery and optional gql.Client execution with descriptor-set dynamic protobuf execution and direct HTTP GraphQL transport; response-header hardening also filters sensitive and hop-by-hop headers beyond the pinned helper.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::evaluate_rest_policy", + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/protocol/soap.rs", + "gateway-rs/src/protocol/grpc.rs", + "gateway-rs/src/gateway/resolution.rs", + "gateway-rs/src/gateway/retries.rs", + "gateway-rs/src/gateway/transforms.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::returns_no_endpoints_for_api_without_registered_endpoints", + "gateway-rs/src/routes/rest.rs::tests::rejects_malformed_json_from_rest_upstream_like_python", + "gateway-rs/tests/runtime.rs", + "gateway-rs/tests/grpc_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "method", + "line": 440, + "path": "backend-services/services/gateway_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/gateway_service.py::method:GatewayService._is_valid_identifier", + "notes": "Rust preserves API and endpoint resolution (including distinct GTW002/GTW003 failures), disabled/public/auth policy, CORS and preflight behavior, request identity and allowed-header forwarding, system/user credit precedence, authorization swapping, endpoint validation and transforms, client routing, timeouts, retries/backoff, circuit breaking, upstream status and malformed-JSON mapping, SOAP version and WS-Security processing, GraphQL depth/error handling, and descriptor-driven gRPC unary/client/server/bidirectional streaming with metadata filtering, TLS, limits, and status mapping. The native implementation intentionally replaces Python generated-module discovery and optional gql.Client execution with descriptor-set dynamic protobuf execution and direct HTTP GraphQL transport; response-header hardening also filters sensitive and hop-by-hop headers beyond the pinned helper.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::evaluate_rest_policy", + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/protocol/soap.rs", + "gateway-rs/src/protocol/grpc.rs", + "gateway-rs/src/gateway/resolution.rs", + "gateway-rs/src/gateway/retries.rs", + "gateway-rs/src/gateway/transforms.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::returns_no_endpoints_for_api_without_registered_endpoints", + "gateway-rs/src/routes/rest.rs::tests::rejects_malformed_json_from_rest_upstream_like_python", + "gateway-rs/tests/runtime.rs", + "gateway-rs/tests/grpc_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "method", + "line": 449, + "path": "backend-services/services/gateway_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/gateway_service.py::method:GatewayService._validate_package_name", + "notes": "Rust preserves API and endpoint resolution (including distinct GTW002/GTW003 failures), disabled/public/auth policy, CORS and preflight behavior, request identity and allowed-header forwarding, system/user credit precedence, authorization swapping, endpoint validation and transforms, client routing, timeouts, retries/backoff, circuit breaking, upstream status and malformed-JSON mapping, SOAP version and WS-Security processing, GraphQL depth/error handling, and descriptor-driven gRPC unary/client/server/bidirectional streaming with metadata filtering, TLS, limits, and status mapping. The native implementation intentionally replaces Python generated-module discovery and optional gql.Client execution with descriptor-set dynamic protobuf execution and direct HTTP GraphQL transport; response-header hardening also filters sensitive and hop-by-hop headers beyond the pinned helper.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::evaluate_rest_policy", + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/protocol/soap.rs", + "gateway-rs/src/protocol/grpc.rs", + "gateway-rs/src/gateway/resolution.rs", + "gateway-rs/src/gateway/retries.rs", + "gateway-rs/src/gateway/transforms.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::returns_no_endpoints_for_api_without_registered_endpoints", + "gateway-rs/src/routes/rest.rs::tests::rejects_malformed_json_from_rest_upstream_like_python", + "gateway-rs/tests/runtime.rs", + "gateway-rs/tests/grpc_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "method", + "line": 466, + "path": "backend-services/services/gateway_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/gateway_service.py::method:GatewayService._parse_and_validate_method", + "notes": "Rust preserves API and endpoint resolution (including distinct GTW002/GTW003 failures), disabled/public/auth policy, CORS and preflight behavior, request identity and allowed-header forwarding, system/user credit precedence, authorization swapping, endpoint validation and transforms, client routing, timeouts, retries/backoff, circuit breaking, upstream status and malformed-JSON mapping, SOAP version and WS-Security processing, GraphQL depth/error handling, and descriptor-driven gRPC unary/client/server/bidirectional streaming with metadata filtering, TLS, limits, and status mapping. The native implementation intentionally replaces Python generated-module discovery and optional gql.Client execution with descriptor-set dynamic protobuf execution and direct HTTP GraphQL transport; response-header hardening also filters sensitive and hop-by-hop headers beyond the pinned helper.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::evaluate_rest_policy", + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/protocol/soap.rs", + "gateway-rs/src/protocol/grpc.rs", + "gateway-rs/src/gateway/resolution.rs", + "gateway-rs/src/gateway/retries.rs", + "gateway-rs/src/gateway/transforms.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::returns_no_endpoints_for_api_without_registered_endpoints", + "gateway-rs/src/routes/rest.rs::tests::rejects_malformed_json_from_rest_upstream_like_python", + "gateway-rs/tests/runtime.rs", + "gateway-rs/tests/grpc_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "method", + "line": 485, + "path": "backend-services/services/gateway_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/gateway_service.py::async_method:GatewayService.rest_gateway", + "notes": "Rust preserves API and endpoint resolution (including distinct GTW002/GTW003 failures), disabled/public/auth policy, CORS and preflight behavior, request identity and allowed-header forwarding, system/user credit precedence, authorization swapping, endpoint validation and transforms, client routing, timeouts, retries/backoff, circuit breaking, upstream status and malformed-JSON mapping, SOAP version and WS-Security processing, GraphQL depth/error handling, and descriptor-driven gRPC unary/client/server/bidirectional streaming with metadata filtering, TLS, limits, and status mapping. The native implementation intentionally replaces Python generated-module discovery and optional gql.Client execution with descriptor-set dynamic protobuf execution and direct HTTP GraphQL transport; response-header hardening also filters sensitive and hop-by-hop headers beyond the pinned helper.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::evaluate_rest_policy", + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/protocol/soap.rs", + "gateway-rs/src/protocol/grpc.rs", + "gateway-rs/src/gateway/resolution.rs", + "gateway-rs/src/gateway/retries.rs", + "gateway-rs/src/gateway/transforms.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::returns_no_endpoints_for_api_without_registered_endpoints", + "gateway-rs/src/routes/rest.rs::tests::rejects_malformed_json_from_rest_upstream_like_python", + "gateway-rs/tests/runtime.rs", + "gateway-rs/tests/grpc_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "async_method", + "line": 506, + "path": "backend-services/services/gateway_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/gateway_service.py::async_method:GatewayService.soap_gateway", + "notes": "Rust preserves API and endpoint resolution (including distinct GTW002/GTW003 failures), disabled/public/auth policy, CORS and preflight behavior, request identity and allowed-header forwarding, system/user credit precedence, authorization swapping, endpoint validation and transforms, client routing, timeouts, retries/backoff, circuit breaking, upstream status and malformed-JSON mapping, SOAP version and WS-Security processing, GraphQL depth/error handling, and descriptor-driven gRPC unary/client/server/bidirectional streaming with metadata filtering, TLS, limits, and status mapping. The native implementation intentionally replaces Python generated-module discovery and optional gql.Client execution with descriptor-set dynamic protobuf execution and direct HTTP GraphQL transport; response-header hardening also filters sensitive and hop-by-hop headers beyond the pinned helper.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::evaluate_rest_policy", + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/protocol/soap.rs", + "gateway-rs/src/protocol/grpc.rs", + "gateway-rs/src/gateway/resolution.rs", + "gateway-rs/src/gateway/retries.rs", + "gateway-rs/src/gateway/transforms.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::returns_no_endpoints_for_api_without_registered_endpoints", + "gateway-rs/src/routes/rest.rs::tests::rejects_malformed_json_from_rest_upstream_like_python", + "gateway-rs/tests/runtime.rs", + "gateway-rs/tests/grpc_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "async_method", + "line": 909, + "path": "backend-services/services/gateway_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/gateway_service.py::async_method:GatewayService.graphql_gateway", + "notes": "Rust preserves API and endpoint resolution (including distinct GTW002/GTW003 failures), disabled/public/auth policy, CORS and preflight behavior, request identity and allowed-header forwarding, system/user credit precedence, authorization swapping, endpoint validation and transforms, client routing, timeouts, retries/backoff, circuit breaking, upstream status and malformed-JSON mapping, SOAP version and WS-Security processing, GraphQL depth/error handling, and descriptor-driven gRPC unary/client/server/bidirectional streaming with metadata filtering, TLS, limits, and status mapping. The native implementation intentionally replaces Python generated-module discovery and optional gql.Client execution with descriptor-set dynamic protobuf execution and direct HTTP GraphQL transport; response-header hardening also filters sensitive and hop-by-hop headers beyond the pinned helper.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::evaluate_rest_policy", + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/protocol/soap.rs", + "gateway-rs/src/protocol/grpc.rs", + "gateway-rs/src/gateway/resolution.rs", + "gateway-rs/src/gateway/retries.rs", + "gateway-rs/src/gateway/transforms.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::returns_no_endpoints_for_api_without_registered_endpoints", + "gateway-rs/src/routes/rest.rs::tests::rejects_malformed_json_from_rest_upstream_like_python", + "gateway-rs/tests/runtime.rs", + "gateway-rs/tests/grpc_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "async_method", + "line": 1211, + "path": "backend-services/services/gateway_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/gateway_service.py::async_method:GatewayService.grpc_gateway", + "notes": "Rust preserves API and endpoint resolution (including distinct GTW002/GTW003 failures), disabled/public/auth policy, CORS and preflight behavior, request identity and allowed-header forwarding, system/user credit precedence, authorization swapping, endpoint validation and transforms, client routing, timeouts, retries/backoff, circuit breaking, upstream status and malformed-JSON mapping, SOAP version and WS-Security processing, GraphQL depth/error handling, and descriptor-driven gRPC unary/client/server/bidirectional streaming with metadata filtering, TLS, limits, and status mapping. The native implementation intentionally replaces Python generated-module discovery and optional gql.Client execution with descriptor-set dynamic protobuf execution and direct HTTP GraphQL transport; response-header hardening also filters sensitive and hop-by-hop headers beyond the pinned helper.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::evaluate_rest_policy", + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/protocol/soap.rs", + "gateway-rs/src/protocol/grpc.rs", + "gateway-rs/src/gateway/resolution.rs", + "gateway-rs/src/gateway/retries.rs", + "gateway-rs/src/gateway/transforms.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::returns_no_endpoints_for_api_without_registered_endpoints", + "gateway-rs/src/routes/rest.rs::tests::rejects_malformed_json_from_rest_upstream_like_python", + "gateway-rs/tests/runtime.rs", + "gateway-rs/tests/grpc_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "async_method", + "line": 1436, + "path": "backend-services/services/gateway_service.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/gateway_service.py::async_function:GatewayService.grpc_gateway._single_req", + "notes": "Rust preserves API and endpoint resolution (including distinct GTW002/GTW003 failures), disabled/public/auth policy, CORS and preflight behavior, request identity and allowed-header forwarding, system/user credit precedence, authorization swapping, endpoint validation and transforms, client routing, timeouts, retries/backoff, circuit breaking, upstream status and malformed-JSON mapping, SOAP version and WS-Security processing, GraphQL depth/error handling, and descriptor-driven gRPC unary/client/server/bidirectional streaming with metadata filtering, TLS, limits, and status mapping. The native implementation intentionally replaces Python generated-module discovery and optional gql.Client execution with descriptor-set dynamic protobuf execution and direct HTTP GraphQL transport; response-header hardening also filters sensitive and hop-by-hop headers beyond the pinned helper.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::evaluate_rest_policy", + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/protocol/soap.rs", + "gateway-rs/src/protocol/grpc.rs", + "gateway-rs/src/gateway/resolution.rs", + "gateway-rs/src/gateway/retries.rs", + "gateway-rs/src/gateway/transforms.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::returns_no_endpoints_for_api_without_registered_endpoints", + "gateway-rs/src/routes/rest.rs::tests::rejects_malformed_json_from_rest_upstream_like_python", + "gateway-rs/tests/runtime.rs", + "gateway-rs/tests/grpc_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "async_function", + "line": 2225, + "path": "backend-services/services/gateway_service.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/gateway_service.py::function:GatewayService.grpc_gateway.req_ser", + "notes": "Rust preserves API and endpoint resolution (including distinct GTW002/GTW003 failures), disabled/public/auth policy, CORS and preflight behavior, request identity and allowed-header forwarding, system/user credit precedence, authorization swapping, endpoint validation and transforms, client routing, timeouts, retries/backoff, circuit breaking, upstream status and malformed-JSON mapping, SOAP version and WS-Security processing, GraphQL depth/error handling, and descriptor-driven gRPC unary/client/server/bidirectional streaming with metadata filtering, TLS, limits, and status mapping. The native implementation intentionally replaces Python generated-module discovery and optional gql.Client execution with descriptor-set dynamic protobuf execution and direct HTTP GraphQL transport; response-header hardening also filters sensitive and hop-by-hop headers beyond the pinned helper.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::evaluate_rest_policy", + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/protocol/soap.rs", + "gateway-rs/src/protocol/grpc.rs", + "gateway-rs/src/gateway/resolution.rs", + "gateway-rs/src/gateway/retries.rs", + "gateway-rs/src/gateway/transforms.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::returns_no_endpoints_for_api_without_registered_endpoints", + "gateway-rs/src/routes/rest.rs::tests::rejects_malformed_json_from_rest_upstream_like_python", + "gateway-rs/tests/runtime.rs", + "gateway-rs/tests/grpc_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "function", + "line": 2382, + "path": "backend-services/services/gateway_service.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/gateway_service.py::async_function:GatewayService.grpc_gateway._gen_client", + "notes": "Rust preserves API and endpoint resolution (including distinct GTW002/GTW003 failures), disabled/public/auth policy, CORS and preflight behavior, request identity and allowed-header forwarding, system/user credit precedence, authorization swapping, endpoint validation and transforms, client routing, timeouts, retries/backoff, circuit breaking, upstream status and malformed-JSON mapping, SOAP version and WS-Security processing, GraphQL depth/error handling, and descriptor-driven gRPC unary/client/server/bidirectional streaming with metadata filtering, TLS, limits, and status mapping. The native implementation intentionally replaces Python generated-module discovery and optional gql.Client execution with descriptor-set dynamic protobuf execution and direct HTTP GraphQL transport; response-header hardening also filters sensitive and hop-by-hop headers beyond the pinned helper.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::evaluate_rest_policy", + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/protocol/soap.rs", + "gateway-rs/src/protocol/grpc.rs", + "gateway-rs/src/gateway/resolution.rs", + "gateway-rs/src/gateway/retries.rs", + "gateway-rs/src/gateway/transforms.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::returns_no_endpoints_for_api_without_registered_endpoints", + "gateway-rs/src/routes/rest.rs::tests::rejects_malformed_json_from_rest_upstream_like_python", + "gateway-rs/tests/runtime.rs", + "gateway-rs/tests/grpc_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "async_function", + "line": 2424, + "path": "backend-services/services/gateway_service.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/gateway_service.py::async_function:GatewayService.grpc_gateway._gen_bidi", + "notes": "Rust preserves API and endpoint resolution (including distinct GTW002/GTW003 failures), disabled/public/auth policy, CORS and preflight behavior, request identity and allowed-header forwarding, system/user credit precedence, authorization swapping, endpoint validation and transforms, client routing, timeouts, retries/backoff, circuit breaking, upstream status and malformed-JSON mapping, SOAP version and WS-Security processing, GraphQL depth/error handling, and descriptor-driven gRPC unary/client/server/bidirectional streaming with metadata filtering, TLS, limits, and status mapping. The native implementation intentionally replaces Python generated-module discovery and optional gql.Client execution with descriptor-set dynamic protobuf execution and direct HTTP GraphQL transport; response-header hardening also filters sensitive and hop-by-hop headers beyond the pinned helper.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::evaluate_rest_policy", + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/protocol/soap.rs", + "gateway-rs/src/protocol/grpc.rs", + "gateway-rs/src/gateway/resolution.rs", + "gateway-rs/src/gateway/retries.rs", + "gateway-rs/src/gateway/transforms.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::returns_no_endpoints_for_api_without_registered_endpoints", + "gateway-rs/src/routes/rest.rs::tests::rejects_malformed_json_from_rest_upstream_like_python", + "gateway-rs/tests/runtime.rs", + "gateway-rs/tests/grpc_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "async_function", + "line": 2471, + "path": "backend-services/services/gateway_service.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/gateway_service.py::function:GatewayService.grpc_gateway.req_ser#2", + "notes": "Rust preserves API and endpoint resolution (including distinct GTW002/GTW003 failures), disabled/public/auth policy, CORS and preflight behavior, request identity and allowed-header forwarding, system/user credit precedence, authorization swapping, endpoint validation and transforms, client routing, timeouts, retries/backoff, circuit breaking, upstream status and malformed-JSON mapping, SOAP version and WS-Security processing, GraphQL depth/error handling, and descriptor-driven gRPC unary/client/server/bidirectional streaming with metadata filtering, TLS, limits, and status mapping. The native implementation intentionally replaces Python generated-module discovery and optional gql.Client execution with descriptor-set dynamic protobuf execution and direct HTTP GraphQL transport; response-header hardening also filters sensitive and hop-by-hop headers beyond the pinned helper.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::evaluate_rest_policy", + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/protocol/soap.rs", + "gateway-rs/src/protocol/grpc.rs", + "gateway-rs/src/gateway/resolution.rs", + "gateway-rs/src/gateway/retries.rs", + "gateway-rs/src/gateway/transforms.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::returns_no_endpoints_for_api_without_registered_endpoints", + "gateway-rs/src/routes/rest.rs::tests::rejects_malformed_json_from_rest_upstream_like_python", + "gateway-rs/tests/runtime.rs", + "gateway-rs/tests/grpc_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "function", + "line": 2565, + "path": "backend-services/services/gateway_service.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/gateway_service.py::async_function:GatewayService.grpc_gateway._gen_client_alt", + "notes": "Rust preserves API and endpoint resolution (including distinct GTW002/GTW003 failures), disabled/public/auth policy, CORS and preflight behavior, request identity and allowed-header forwarding, system/user credit precedence, authorization swapping, endpoint validation and transforms, client routing, timeouts, retries/backoff, circuit breaking, upstream status and malformed-JSON mapping, SOAP version and WS-Security processing, GraphQL depth/error handling, and descriptor-driven gRPC unary/client/server/bidirectional streaming with metadata filtering, TLS, limits, and status mapping. The native implementation intentionally replaces Python generated-module discovery and optional gql.Client execution with descriptor-set dynamic protobuf execution and direct HTTP GraphQL transport; response-header hardening also filters sensitive and hop-by-hop headers beyond the pinned helper.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::evaluate_rest_policy", + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/protocol/soap.rs", + "gateway-rs/src/protocol/grpc.rs", + "gateway-rs/src/gateway/resolution.rs", + "gateway-rs/src/gateway/retries.rs", + "gateway-rs/src/gateway/transforms.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::returns_no_endpoints_for_api_without_registered_endpoints", + "gateway-rs/src/routes/rest.rs::tests::rejects_malformed_json_from_rest_upstream_like_python", + "gateway-rs/tests/runtime.rs", + "gateway-rs/tests/grpc_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "async_function", + "line": 2606, + "path": "backend-services/services/gateway_service.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/gateway_service.py::async_function:GatewayService.grpc_gateway._gen_bidi_alt", + "notes": "Rust preserves API and endpoint resolution (including distinct GTW002/GTW003 failures), disabled/public/auth policy, CORS and preflight behavior, request identity and allowed-header forwarding, system/user credit precedence, authorization swapping, endpoint validation and transforms, client routing, timeouts, retries/backoff, circuit breaking, upstream status and malformed-JSON mapping, SOAP version and WS-Security processing, GraphQL depth/error handling, and descriptor-driven gRPC unary/client/server/bidirectional streaming with metadata filtering, TLS, limits, and status mapping. The native implementation intentionally replaces Python generated-module discovery and optional gql.Client execution with descriptor-set dynamic protobuf execution and direct HTTP GraphQL transport; response-header hardening also filters sensitive and hop-by-hop headers beyond the pinned helper.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::evaluate_rest_policy", + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/protocol/soap.rs", + "gateway-rs/src/protocol/grpc.rs", + "gateway-rs/src/gateway/resolution.rs", + "gateway-rs/src/gateway/retries.rs", + "gateway-rs/src/gateway/transforms.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::returns_no_endpoints_for_api_without_registered_endpoints", + "gateway-rs/src/routes/rest.rs::tests::rejects_malformed_json_from_rest_upstream_like_python", + "gateway-rs/tests/runtime.rs", + "gateway-rs/tests/grpc_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "async_function", + "line": 2655, + "path": "backend-services/services/gateway_service.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/gateway_service.py::async_method:GatewayService._make_graphql_request", + "notes": "Rust preserves API and endpoint resolution (including distinct GTW002/GTW003 failures), disabled/public/auth policy, CORS and preflight behavior, request identity and allowed-header forwarding, system/user credit precedence, authorization swapping, endpoint validation and transforms, client routing, timeouts, retries/backoff, circuit breaking, upstream status and malformed-JSON mapping, SOAP version and WS-Security processing, GraphQL depth/error handling, and descriptor-driven gRPC unary/client/server/bidirectional streaming with metadata filtering, TLS, limits, and status mapping. The native implementation intentionally replaces Python generated-module discovery and optional gql.Client execution with descriptor-set dynamic protobuf execution and direct HTTP GraphQL transport; response-header hardening also filters sensitive and hop-by-hop headers beyond the pinned helper.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::evaluate_rest_policy", + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/protocol/soap.rs", + "gateway-rs/src/protocol/grpc.rs", + "gateway-rs/src/gateway/resolution.rs", + "gateway-rs/src/gateway/retries.rs", + "gateway-rs/src/gateway/transforms.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::returns_no_endpoints_for_api_without_registered_endpoints", + "gateway-rs/src/routes/rest.rs::tests::rejects_malformed_json_from_rest_upstream_like_python", + "gateway-rs/tests/runtime.rs", + "gateway-rs/tests/grpc_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "async_method", + "line": 2951, + "path": "backend-services/services/gateway_service.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/group_service.py::module:group_service", + "notes": "Rust preserves group existence checks, duplicate/create/update/delete/get behavior, immutable names, no-op and empty updates, cache-backed shared storage, sorted pagination metadata, messages, and GRP001-GRP007 errors.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::entity_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates", + "gateway-rs/tests/roles_groups_parity.rs::missing_group_and_role_contracts_match_python_service_codes" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/services/group_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/group_service.py::class:GroupService", + "notes": "Rust preserves group existence checks, duplicate/create/update/delete/get behavior, immutable names, no-op and empty updates, cache-backed shared storage, sorted pagination metadata, messages, and GRP001-GRP007 errors.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::entity_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates", + "gateway-rs/tests/roles_groups_parity.rs::missing_group_and_role_contracts_match_python_service_codes" + ], + "source": { + "kind": "class", + "line": 23, + "path": "backend-services/services/group_service.py" + }, + "status": "translated" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/group_service.py::async_method:GroupService.create_group", + "notes": "Rust preserves group existence checks, duplicate/create/update/delete/get behavior, immutable names, no-op and empty updates, cache-backed shared storage, sorted pagination metadata, messages, and GRP001-GRP007 errors.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::entity_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates", + "gateway-rs/tests/roles_groups_parity.rs::missing_group_and_role_contracts_match_python_service_codes" + ], + "source": { + "kind": "async_method", + "line": 25, + "path": "backend-services/services/group_service.py" + }, + "status": "translated" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/group_service.py::async_method:GroupService.update_group", + "notes": "Rust preserves group existence checks, duplicate/create/update/delete/get behavior, immutable names, no-op and empty updates, cache-backed shared storage, sorted pagination metadata, messages, and GRP001-GRP007 errors.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::entity_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates", + "gateway-rs/tests/roles_groups_parity.rs::missing_group_and_role_contracts_match_python_service_codes" + ], + "source": { + "kind": "async_method", + "line": 59, + "path": "backend-services/services/group_service.py" + }, + "status": "translated" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/group_service.py::async_method:GroupService.delete_group", + "notes": "Rust preserves group existence checks, duplicate/create/update/delete/get behavior, immutable names, no-op and empty updates, cache-backed shared storage, sorted pagination metadata, messages, and GRP001-GRP007 errors.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::entity_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates", + "gateway-rs/tests/roles_groups_parity.rs::missing_group_and_role_contracts_match_python_service_codes" + ], + "source": { + "kind": "async_method", + "line": 103, + "path": "backend-services/services/group_service.py" + }, + "status": "translated" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/group_service.py::async_method:GroupService.group_exists", + "notes": "Rust preserves group existence checks, duplicate/create/update/delete/get behavior, immutable names, no-op and empty updates, cache-backed shared storage, sorted pagination metadata, messages, and GRP001-GRP007 errors.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::entity_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates", + "gateway-rs/tests/roles_groups_parity.rs::missing_group_and_role_contracts_match_python_service_codes" + ], + "source": { + "kind": "async_method", + "line": 134, + "path": "backend-services/services/group_service.py" + }, + "status": "translated" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/group_service.py::async_method:GroupService.get_groups", + "notes": "Rust preserves group existence checks, duplicate/create/update/delete/get behavior, immutable names, no-op and empty updates, cache-backed shared storage, sorted pagination metadata, messages, and GRP001-GRP007 errors.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::entity_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates", + "gateway-rs/tests/roles_groups_parity.rs::missing_group_and_role_contracts_match_python_service_codes" + ], + "source": { + "kind": "async_method", + "line": 145, + "path": "backend-services/services/group_service.py" + }, + "status": "translated" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/group_service.py::async_method:GroupService.get_group", + "notes": "Rust preserves group existence checks, duplicate/create/update/delete/get behavior, immutable names, no-op and empty updates, cache-backed shared storage, sorted pagination metadata, messages, and GRP001-GRP007 errors.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::entity_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates", + "gateway-rs/tests/roles_groups_parity.rs::missing_group_and_role_contracts_match_python_service_codes" + ], + "source": { + "kind": "async_method", + "line": 195, + "path": "backend-services/services/group_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/logging_service.py::module:logging_service", + "notes": "Rust reads file and in-memory structured logs, now continues to the ring buffer when the log directory is absent, parses legacy text records, derives Python-compatible request/user/IP/endpoint/timing/status/type fields, applies date/time, case-insensitive substring, status, timing and exclusion filters, paginates newest-first, computes dashboard statistics, and exports JSON/CSV. File discovery is intentionally bounded and native export/read failure handling is not identical in every filesystem edge case.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::logging_routes", + "gateway-rs/src/routes/platform.rs::read_log_records", + "gateway-rs/src/routes/platform.rs::parse_log_record", + "gateway-rs/src/routes/platform.rs::log_record_matches" + ], + "rust_tests": [ + "gateway-rs/src/routes/platform.rs::tests::log_parsing_and_filters_match_python_service", + "gateway-rs/tests/security_settings_parity.rs::live_logging_endpoints_match_python" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/services/logging_service.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/logging_service.py::class:LoggingService", + "notes": "Rust reads file and in-memory structured logs, now continues to the ring buffer when the log directory is absent, parses legacy text records, derives Python-compatible request/user/IP/endpoint/timing/status/type fields, applies date/time, case-insensitive substring, status, timing and exclusion filters, paginates newest-first, computes dashboard statistics, and exports JSON/CSV. File discovery is intentionally bounded and native export/read failure handling is not identical in every filesystem edge case.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::logging_routes", + "gateway-rs/src/routes/platform.rs::read_log_records", + "gateway-rs/src/routes/platform.rs::parse_log_record", + "gateway-rs/src/routes/platform.rs::log_record_matches" + ], + "rust_tests": [ + "gateway-rs/src/routes/platform.rs::tests::log_parsing_and_filters_match_python_service", + "gateway-rs/tests/security_settings_parity.rs::live_logging_endpoints_match_python" + ], + "source": { + "kind": "class", + "line": 20, + "path": "backend-services/services/logging_service.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/logging_service.py::method:LoggingService.__init__", + "notes": "Rust reads file and in-memory structured logs, now continues to the ring buffer when the log directory is absent, parses legacy text records, derives Python-compatible request/user/IP/endpoint/timing/status/type fields, applies date/time, case-insensitive substring, status, timing and exclusion filters, paginates newest-first, computes dashboard statistics, and exports JSON/CSV. File discovery is intentionally bounded and native export/read failure handling is not identical in every filesystem edge case.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::logging_routes", + "gateway-rs/src/routes/platform.rs::read_log_records", + "gateway-rs/src/routes/platform.rs::parse_log_record", + "gateway-rs/src/routes/platform.rs::log_record_matches" + ], + "rust_tests": [ + "gateway-rs/src/routes/platform.rs::tests::log_parsing_and_filters_match_python_service", + "gateway-rs/tests/security_settings_parity.rs::live_logging_endpoints_match_python" + ], + "source": { + "kind": "method", + "line": 21, + "path": "backend-services/services/logging_service.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/logging_service.py::async_method:LoggingService.get_logs", + "notes": "Rust reads file and in-memory structured logs, now continues to the ring buffer when the log directory is absent, parses legacy text records, derives Python-compatible request/user/IP/endpoint/timing/status/type fields, applies date/time, case-insensitive substring, status, timing and exclusion filters, paginates newest-first, computes dashboard statistics, and exports JSON/CSV. File discovery is intentionally bounded and native export/read failure handling is not identical in every filesystem edge case.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::logging_routes", + "gateway-rs/src/routes/platform.rs::read_log_records", + "gateway-rs/src/routes/platform.rs::parse_log_record", + "gateway-rs/src/routes/platform.rs::log_record_matches" + ], + "rust_tests": [ + "gateway-rs/src/routes/platform.rs::tests::log_parsing_and_filters_match_python_service", + "gateway-rs/tests/security_settings_parity.rs::live_logging_endpoints_match_python" + ], + "source": { + "kind": "async_method", + "line": 45, + "path": "backend-services/services/logging_service.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/logging_service.py::method:LoggingService.get_available_log_files", + "notes": "Rust reads file and in-memory structured logs, now continues to the ring buffer when the log directory is absent, parses legacy text records, derives Python-compatible request/user/IP/endpoint/timing/status/type fields, applies date/time, case-insensitive substring, status, timing and exclusion filters, paginates newest-first, computes dashboard statistics, and exports JSON/CSV. File discovery is intentionally bounded and native export/read failure handling is not identical in every filesystem edge case.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::logging_routes", + "gateway-rs/src/routes/platform.rs::read_log_records", + "gateway-rs/src/routes/platform.rs::parse_log_record", + "gateway-rs/src/routes/platform.rs::log_record_matches" + ], + "rust_tests": [ + "gateway-rs/src/routes/platform.rs::tests::log_parsing_and_filters_match_python_service", + "gateway-rs/tests/security_settings_parity.rs::live_logging_endpoints_match_python" + ], + "source": { + "kind": "method", + "line": 169, + "path": "backend-services/services/logging_service.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/logging_service.py::async_method:LoggingService.get_log_statistics", + "notes": "Rust reads file and in-memory structured logs, now continues to the ring buffer when the log directory is absent, parses legacy text records, derives Python-compatible request/user/IP/endpoint/timing/status/type fields, applies date/time, case-insensitive substring, status, timing and exclusion filters, paginates newest-first, computes dashboard statistics, and exports JSON/CSV. File discovery is intentionally bounded and native export/read failure handling is not identical in every filesystem edge case.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::logging_routes", + "gateway-rs/src/routes/platform.rs::read_log_records", + "gateway-rs/src/routes/platform.rs::parse_log_record", + "gateway-rs/src/routes/platform.rs::log_record_matches" + ], + "rust_tests": [ + "gateway-rs/src/routes/platform.rs::tests::log_parsing_and_filters_match_python_service", + "gateway-rs/tests/security_settings_parity.rs::live_logging_endpoints_match_python" + ], + "source": { + "kind": "async_method", + "line": 180, + "path": "backend-services/services/logging_service.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/logging_service.py::async_method:LoggingService.export_logs", + "notes": "Rust reads file and in-memory structured logs, now continues to the ring buffer when the log directory is absent, parses legacy text records, derives Python-compatible request/user/IP/endpoint/timing/status/type fields, applies date/time, case-insensitive substring, status, timing and exclusion filters, paginates newest-first, computes dashboard statistics, and exports JSON/CSV. File discovery is intentionally bounded and native export/read failure handling is not identical in every filesystem edge case.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::logging_routes", + "gateway-rs/src/routes/platform.rs::read_log_records", + "gateway-rs/src/routes/platform.rs::parse_log_record", + "gateway-rs/src/routes/platform.rs::log_record_matches" + ], + "rust_tests": [ + "gateway-rs/src/routes/platform.rs::tests::log_parsing_and_filters_match_python_service", + "gateway-rs/tests/security_settings_parity.rs::live_logging_endpoints_match_python" + ], + "source": { + "kind": "async_method", + "line": 263, + "path": "backend-services/services/logging_service.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/logging_service.py::method:LoggingService._parse_log_line", + "notes": "Rust reads file and in-memory structured logs, now continues to the ring buffer when the log directory is absent, parses legacy text records, derives Python-compatible request/user/IP/endpoint/timing/status/type fields, applies date/time, case-insensitive substring, status, timing and exclusion filters, paginates newest-first, computes dashboard statistics, and exports JSON/CSV. File discovery is intentionally bounded and native export/read failure handling is not identical in every filesystem edge case.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::logging_routes", + "gateway-rs/src/routes/platform.rs::read_log_records", + "gateway-rs/src/routes/platform.rs::parse_log_record", + "gateway-rs/src/routes/platform.rs::log_record_matches" + ], + "rust_tests": [ + "gateway-rs/src/routes/platform.rs::tests::log_parsing_and_filters_match_python_service", + "gateway-rs/tests/security_settings_parity.rs::live_logging_endpoints_match_python" + ], + "source": { + "kind": "method", + "line": 311, + "path": "backend-services/services/logging_service.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/logging_service.py::method:LoggingService._extract_structured_data", + "notes": "Rust reads file and in-memory structured logs, now continues to the ring buffer when the log directory is absent, parses legacy text records, derives Python-compatible request/user/IP/endpoint/timing/status/type fields, applies date/time, case-insensitive substring, status, timing and exclusion filters, paginates newest-first, computes dashboard statistics, and exports JSON/CSV. File discovery is intentionally bounded and native export/read failure handling is not identical in every filesystem edge case.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::logging_routes", + "gateway-rs/src/routes/platform.rs::read_log_records", + "gateway-rs/src/routes/platform.rs::parse_log_record", + "gateway-rs/src/routes/platform.rs::log_record_matches" + ], + "rust_tests": [ + "gateway-rs/src/routes/platform.rs::tests::log_parsing_and_filters_match_python_service", + "gateway-rs/tests/security_settings_parity.rs::live_logging_endpoints_match_python" + ], + "source": { + "kind": "method", + "line": 393, + "path": "backend-services/services/logging_service.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/logging_service.py::method:LoggingService._accumulate_stats_line", + "notes": "Rust reads file and in-memory structured logs, now continues to the ring buffer when the log directory is absent, parses legacy text records, derives Python-compatible request/user/IP/endpoint/timing/status/type fields, applies date/time, case-insensitive substring, status, timing and exclusion filters, paginates newest-first, computes dashboard statistics, and exports JSON/CSV. File discovery is intentionally bounded and native export/read failure handling is not identical in every filesystem edge case.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::logging_routes", + "gateway-rs/src/routes/platform.rs::read_log_records", + "gateway-rs/src/routes/platform.rs::parse_log_record", + "gateway-rs/src/routes/platform.rs::log_record_matches" + ], + "rust_tests": [ + "gateway-rs/src/routes/platform.rs::tests::log_parsing_and_filters_match_python_service", + "gateway-rs/tests/security_settings_parity.rs::live_logging_endpoints_match_python" + ], + "source": { + "kind": "method", + "line": 459, + "path": "backend-services/services/logging_service.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/logging_service.py::method:LoggingService._matches_filters", + "notes": "Rust reads file and in-memory structured logs, now continues to the ring buffer when the log directory is absent, parses legacy text records, derives Python-compatible request/user/IP/endpoint/timing/status/type fields, applies date/time, case-insensitive substring, status, timing and exclusion filters, paginates newest-first, computes dashboard statistics, and exports JSON/CSV. File discovery is intentionally bounded and native export/read failure handling is not identical in every filesystem edge case.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::logging_routes", + "gateway-rs/src/routes/platform.rs::read_log_records", + "gateway-rs/src/routes/platform.rs::parse_log_record", + "gateway-rs/src/routes/platform.rs::log_record_matches" + ], + "rust_tests": [ + "gateway-rs/src/routes/platform.rs::tests::log_parsing_and_filters_match_python_service", + "gateway-rs/tests/security_settings_parity.rs::live_logging_endpoints_match_python" + ], + "source": { + "kind": "method", + "line": 492, + "path": "backend-services/services/logging_service.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/rate_limit_rule_service.py::module:rate_limit_rule_service", + "notes": "Rust preserves rate-limit rule create/get/list/update/delete, enable/disable, duplicate, priority ordering, filters, case-insensitive search fields, statistics, validation, timestamps, and the pinned router's observable bulk/status shadowing defects. Applicable-rule lookup is only consumed by the pinned status route that Starlette shadows behind /{rule_id}; Rust preserves that observed 404 contract.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/services/rate_limit_rule_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/rate_limit_rule_service.py::class:RateLimitRuleService", + "notes": "Rust preserves rate-limit rule create/get/list/update/delete, enable/disable, duplicate, priority ordering, filters, case-insensitive search fields, statistics, validation, timestamps, and the pinned router's observable bulk/status shadowing defects. Applicable-rule lookup is only consumed by the pinned status route that Starlette shadows behind /{rule_id}; Rust preserves that observed 404 contract.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts" + ], + "source": { + "kind": "class", + "line": 26, + "path": "backend-services/services/rate_limit_rule_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/rate_limit_rule_service.py::method:RateLimitRuleService.__init__", + "notes": "Rust preserves rate-limit rule create/get/list/update/delete, enable/disable, duplicate, priority ordering, filters, case-insensitive search fields, statistics, validation, timestamps, and the pinned router's observable bulk/status shadowing defects. Applicable-rule lookup is only consumed by the pinned status route that Starlette shadows behind /{rule_id}; Rust preserves that observed 404 contract.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts" + ], + "source": { + "kind": "method", + "line": 38, + "path": "backend-services/services/rate_limit_rule_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/rate_limit_rule_service.py::async_method:RateLimitRuleService.create_rule", + "notes": "Rust preserves rate-limit rule create/get/list/update/delete, enable/disable, duplicate, priority ordering, filters, case-insensitive search fields, statistics, validation, timestamps, and the pinned router's observable bulk/status shadowing defects. Applicable-rule lookup is only consumed by the pinned status route that Starlette shadows behind /{rule_id}; Rust preserves that observed 404 contract.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts" + ], + "source": { + "kind": "async_method", + "line": 52, + "path": "backend-services/services/rate_limit_rule_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/rate_limit_rule_service.py::async_method:RateLimitRuleService.get_rule", + "notes": "Rust preserves rate-limit rule create/get/list/update/delete, enable/disable, duplicate, priority ordering, filters, case-insensitive search fields, statistics, validation, timestamps, and the pinned router's observable bulk/status shadowing defects. Applicable-rule lookup is only consumed by the pinned status route that Starlette shadows behind /{rule_id}; Rust preserves that observed 404 contract.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts" + ], + "source": { + "kind": "async_method", + "line": 80, + "path": "backend-services/services/rate_limit_rule_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/rate_limit_rule_service.py::async_method:RateLimitRuleService.list_rules", + "notes": "Rust preserves rate-limit rule create/get/list/update/delete, enable/disable, duplicate, priority ordering, filters, case-insensitive search fields, statistics, validation, timestamps, and the pinned router's observable bulk/status shadowing defects. Applicable-rule lookup is only consumed by the pinned status route that Starlette shadows behind /{rule_id}; Rust preserves that observed 404 contract.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts" + ], + "source": { + "kind": "async_method", + "line": 97, + "path": "backend-services/services/rate_limit_rule_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/rate_limit_rule_service.py::async_method:RateLimitRuleService.update_rule", + "notes": "Rust preserves rate-limit rule create/get/list/update/delete, enable/disable, duplicate, priority ordering, filters, case-insensitive search fields, statistics, validation, timestamps, and the pinned router's observable bulk/status shadowing defects. Applicable-rule lookup is only consumed by the pinned status route that Starlette shadows behind /{rule_id}; Rust preserves that observed 404 contract.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts" + ], + "source": { + "kind": "async_method", + "line": 133, + "path": "backend-services/services/rate_limit_rule_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/rate_limit_rule_service.py::async_method:RateLimitRuleService.delete_rule", + "notes": "Rust preserves rate-limit rule create/get/list/update/delete, enable/disable, duplicate, priority ordering, filters, case-insensitive search fields, statistics, validation, timestamps, and the pinned router's observable bulk/status shadowing defects. Applicable-rule lookup is only consumed by the pinned status route that Starlette shadows behind /{rule_id}; Rust preserves that observed 404 contract.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts" + ], + "source": { + "kind": "async_method", + "line": 157, + "path": "backend-services/services/rate_limit_rule_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/rate_limit_rule_service.py::async_method:RateLimitRuleService.enable_rule", + "notes": "Rust preserves rate-limit rule create/get/list/update/delete, enable/disable, duplicate, priority ordering, filters, case-insensitive search fields, statistics, validation, timestamps, and the pinned router's observable bulk/status shadowing defects. Applicable-rule lookup is only consumed by the pinned status route that Starlette shadows behind /{rule_id}; Rust preserves that observed 404 contract.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts" + ], + "source": { + "kind": "async_method", + "line": 175, + "path": "backend-services/services/rate_limit_rule_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/rate_limit_rule_service.py::async_method:RateLimitRuleService.disable_rule", + "notes": "Rust preserves rate-limit rule create/get/list/update/delete, enable/disable, duplicate, priority ordering, filters, case-insensitive search fields, statistics, validation, timestamps, and the pinned router's observable bulk/status shadowing defects. Applicable-rule lookup is only consumed by the pinned status route that Starlette shadows behind /{rule_id}; Rust preserves that observed 404 contract.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts" + ], + "source": { + "kind": "async_method", + "line": 187, + "path": "backend-services/services/rate_limit_rule_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/rate_limit_rule_service.py::async_method:RateLimitRuleService.get_applicable_rules", + "notes": "Rust preserves rate-limit rule create/get/list/update/delete, enable/disable, duplicate, priority ordering, filters, case-insensitive search fields, statistics, validation, timestamps, and the pinned router's observable bulk/status shadowing defects. Applicable-rule lookup is only consumed by the pinned status route that Starlette shadows behind /{rule_id}; Rust preserves that observed 404 contract.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts" + ], + "source": { + "kind": "async_method", + "line": 203, + "path": "backend-services/services/rate_limit_rule_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/rate_limit_rule_service.py::async_method:RateLimitRuleService.search_rules", + "notes": "Rust preserves rate-limit rule create/get/list/update/delete, enable/disable, duplicate, priority ordering, filters, case-insensitive search fields, statistics, validation, timestamps, and the pinned router's observable bulk/status shadowing defects. Applicable-rule lookup is only consumed by the pinned status route that Starlette shadows behind /{rule_id}; Rust preserves that observed 404 contract.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts" + ], + "source": { + "kind": "async_method", + "line": 266, + "path": "backend-services/services/rate_limit_rule_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/rate_limit_rule_service.py::async_method:RateLimitRuleService.bulk_create_rules", + "notes": "Rust preserves rate-limit rule create/get/list/update/delete, enable/disable, duplicate, priority ordering, filters, case-insensitive search fields, statistics, validation, timestamps, and the pinned router's observable bulk/status shadowing defects. Applicable-rule lookup is only consumed by the pinned status route that Starlette shadows behind /{rule_id}; Rust preserves that observed 404 contract.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts" + ], + "source": { + "kind": "async_method", + "line": 296, + "path": "backend-services/services/rate_limit_rule_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/rate_limit_rule_service.py::async_method:RateLimitRuleService.bulk_delete_rules", + "notes": "Rust preserves rate-limit rule create/get/list/update/delete, enable/disable, duplicate, priority ordering, filters, case-insensitive search fields, statistics, validation, timestamps, and the pinned router's observable bulk/status shadowing defects. Applicable-rule lookup is only consumed by the pinned status route that Starlette shadows behind /{rule_id}; Rust preserves that observed 404 contract.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts" + ], + "source": { + "kind": "async_method", + "line": 323, + "path": "backend-services/services/rate_limit_rule_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/rate_limit_rule_service.py::async_method:RateLimitRuleService.bulk_enable_rules", + "notes": "Rust preserves rate-limit rule create/get/list/update/delete, enable/disable, duplicate, priority ordering, filters, case-insensitive search fields, statistics, validation, timestamps, and the pinned router's observable bulk/status shadowing defects. Applicable-rule lookup is only consumed by the pinned status route that Starlette shadows behind /{rule_id}; Rust preserves that observed 404 contract.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts" + ], + "source": { + "kind": "async_method", + "line": 342, + "path": "backend-services/services/rate_limit_rule_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/rate_limit_rule_service.py::async_method:RateLimitRuleService.bulk_disable_rules", + "notes": "Rust preserves rate-limit rule create/get/list/update/delete, enable/disable, duplicate, priority ordering, filters, case-insensitive search fields, statistics, validation, timestamps, and the pinned router's observable bulk/status shadowing defects. Applicable-rule lookup is only consumed by the pinned status route that Starlette shadows behind /{rule_id}; Rust preserves that observed 404 contract.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts" + ], + "source": { + "kind": "async_method", + "line": 364, + "path": "backend-services/services/rate_limit_rule_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/rate_limit_rule_service.py::async_method:RateLimitRuleService.duplicate_rule", + "notes": "Rust preserves rate-limit rule create/get/list/update/delete, enable/disable, duplicate, priority ordering, filters, case-insensitive search fields, statistics, validation, timestamps, and the pinned router's observable bulk/status shadowing defects. Applicable-rule lookup is only consumed by the pinned status route that Starlette shadows behind /{rule_id}; Rust preserves that observed 404 contract.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts" + ], + "source": { + "kind": "async_method", + "line": 390, + "path": "backend-services/services/rate_limit_rule_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/rate_limit_rule_service.py::async_method:RateLimitRuleService.get_rule_statistics", + "notes": "Rust preserves rate-limit rule create/get/list/update/delete, enable/disable, duplicate, priority ordering, filters, case-insensitive search fields, statistics, validation, timestamps, and the pinned router's observable bulk/status shadowing defects. Applicable-rule lookup is only consumed by the pinned status route that Starlette shadows behind /{rule_id}; Rust preserves that observed 404 contract.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts" + ], + "source": { + "kind": "async_method", + "line": 433, + "path": "backend-services/services/rate_limit_rule_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/rate_limit_rule_service.py::method:RateLimitRuleService.validate_rule", + "notes": "Rust preserves rate-limit rule create/get/list/update/delete, enable/disable, duplicate, priority ordering, filters, case-insensitive search fields, statistics, validation, timestamps, and the pinned router's observable bulk/status shadowing defects. Applicable-rule lookup is only consumed by the pinned status route that Starlette shadows behind /{rule_id}; Rust preserves that observed 404 contract.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts" + ], + "source": { + "kind": "method", + "line": 461, + "path": "backend-services/services/rate_limit_rule_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/rate_limit_rule_service.py::function:get_rate_limit_rule_service", + "notes": "Rust preserves rate-limit rule create/get/list/update/delete, enable/disable, duplicate, priority ordering, filters, case-insensitive search fields, statistics, validation, timestamps, and the pinned router's observable bulk/status shadowing defects. Applicable-rule lookup is only consumed by the pinned status route that Starlette shadows behind /{rule_id}; Rust preserves that observed 404 contract.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts" + ], + "source": { + "kind": "function", + "line": 498, + "path": "backend-services/services/rate_limit_rule_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/role_service.py::module:role_service", + "notes": "Rust preserves role existence checks, duplicate/create/update/delete/get behavior, immutable names, applied no-op updates, returned updated records, shared-cache state, sorted pagination metadata, messages, and ROLE001-ROLE008 errors.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::entity_routes" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::role_route_permissions_visibility_and_admin_codes_match_python", + "gateway-rs/tests/roles_groups_parity.rs::missing_group_and_role_contracts_match_python_service_codes" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/services/role_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/role_service.py::class:RoleService", + "notes": "Rust preserves role existence checks, duplicate/create/update/delete/get behavior, immutable names, applied no-op updates, returned updated records, shared-cache state, sorted pagination metadata, messages, and ROLE001-ROLE008 errors.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::entity_routes" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::role_route_permissions_visibility_and_admin_codes_match_python", + "gateway-rs/tests/roles_groups_parity.rs::missing_group_and_role_contracts_match_python_service_codes" + ], + "source": { + "kind": "class", + "line": 30, + "path": "backend-services/services/role_service.py" + }, + "status": "translated" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/role_service.py::async_method:RoleService.create_role", + "notes": "Rust preserves role existence checks, duplicate/create/update/delete/get behavior, immutable names, applied no-op updates, returned updated records, shared-cache state, sorted pagination metadata, messages, and ROLE001-ROLE008 errors.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::entity_routes" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::role_route_permissions_visibility_and_admin_codes_match_python", + "gateway-rs/tests/roles_groups_parity.rs::missing_group_and_role_contracts_match_python_service_codes" + ], + "source": { + "kind": "async_method", + "line": 32, + "path": "backend-services/services/role_service.py" + }, + "status": "translated" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/role_service.py::async_method:RoleService.update_role", + "notes": "Rust preserves role existence checks, duplicate/create/update/delete/get behavior, immutable names, applied no-op updates, returned updated records, shared-cache state, sorted pagination metadata, messages, and ROLE001-ROLE008 errors.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::entity_routes" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::role_route_permissions_visibility_and_admin_codes_match_python", + "gateway-rs/tests/roles_groups_parity.rs::missing_group_and_role_contracts_match_python_service_codes" + ], + "source": { + "kind": "async_method", + "line": 67, + "path": "backend-services/services/role_service.py" + }, + "status": "translated" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/role_service.py::async_method:RoleService.delete_role", + "notes": "Rust preserves role existence checks, duplicate/create/update/delete/get behavior, immutable names, applied no-op updates, returned updated records, shared-cache state, sorted pagination metadata, messages, and ROLE001-ROLE008 errors.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::entity_routes" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::role_route_permissions_visibility_and_admin_codes_match_python", + "gateway-rs/tests/roles_groups_parity.rs::missing_group_and_role_contracts_match_python_service_codes" + ], + "source": { + "kind": "async_method", + "line": 133, + "path": "backend-services/services/role_service.py" + }, + "status": "translated" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/role_service.py::async_method:RoleService.role_exists", + "notes": "Rust preserves role existence checks, duplicate/create/update/delete/get behavior, immutable names, applied no-op updates, returned updated records, shared-cache state, sorted pagination metadata, messages, and ROLE001-ROLE008 errors.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::entity_routes" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::role_route_permissions_visibility_and_admin_codes_match_python", + "gateway-rs/tests/roles_groups_parity.rs::missing_group_and_role_contracts_match_python_service_codes" + ], + "source": { + "kind": "async_method", + "line": 165, + "path": "backend-services/services/role_service.py" + }, + "status": "translated" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/role_service.py::async_method:RoleService.get_roles", + "notes": "Rust preserves role existence checks, duplicate/create/update/delete/get behavior, immutable names, applied no-op updates, returned updated records, shared-cache state, sorted pagination metadata, messages, and ROLE001-ROLE008 errors.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::entity_routes" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::role_route_permissions_visibility_and_admin_codes_match_python", + "gateway-rs/tests/roles_groups_parity.rs::missing_group_and_role_contracts_match_python_service_codes" + ], + "source": { + "kind": "async_method", + "line": 176, + "path": "backend-services/services/role_service.py" + }, + "status": "translated" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/role_service.py::async_method:RoleService.get_role", + "notes": "Rust preserves role existence checks, duplicate/create/update/delete/get behavior, immutable names, applied no-op updates, returned updated records, shared-cache state, sorted pagination metadata, messages, and ROLE001-ROLE008 errors.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::entity_routes" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::role_route_permissions_visibility_and_admin_codes_match_python", + "gateway-rs/tests/roles_groups_parity.rs::missing_group_and_role_contracts_match_python_service_codes" + ], + "source": { + "kind": "async_method", + "line": 227, + "path": "backend-services/services/role_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/routing_service.py::module:routing_service", + "notes": "Rust preserves generated client keys, duplicate handling, immutable-key checks, CRUD messages/errors, normalized documents, sorted pagination metadata, and shared-cache invalidation through native routing routes.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::entity_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::routing_models_match_pydantic_generation_coercion_and_update_exclusion" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/services/routing_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/routing_service.py::class:RoutingService", + "notes": "Rust preserves generated client keys, duplicate handling, immutable-key checks, CRUD messages/errors, normalized documents, sorted pagination metadata, and shared-cache invalidation through native routing routes.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::entity_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::routing_models_match_pydantic_generation_coercion_and_update_exclusion" + ], + "source": { + "kind": "class", + "line": 23, + "path": "backend-services/services/routing_service.py" + }, + "status": "translated" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/routing_service.py::async_method:RoutingService.create_routing", + "notes": "Rust preserves generated client keys, duplicate handling, immutable-key checks, CRUD messages/errors, normalized documents, sorted pagination metadata, and shared-cache invalidation through native routing routes.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::entity_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::routing_models_match_pydantic_generation_coercion_and_update_exclusion" + ], + "source": { + "kind": "async_method", + "line": 25, + "path": "backend-services/services/routing_service.py" + }, + "status": "translated" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/routing_service.py::async_method:RoutingService.update_routing", + "notes": "Rust preserves generated client keys, duplicate handling, immutable-key checks, CRUD messages/errors, normalized documents, sorted pagination metadata, and shared-cache invalidation through native routing routes.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::entity_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::routing_models_match_pydantic_generation_coercion_and_update_exclusion" + ], + "source": { + "kind": "async_method", + "line": 63, + "path": "backend-services/services/routing_service.py" + }, + "status": "translated" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/routing_service.py::async_method:RoutingService.delete_routing", + "notes": "Rust preserves generated client keys, duplicate handling, immutable-key checks, CRUD messages/errors, normalized documents, sorted pagination metadata, and shared-cache invalidation through native routing routes.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::entity_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::routing_models_match_pydantic_generation_coercion_and_update_exclusion" + ], + "source": { + "kind": "async_method", + "line": 108, + "path": "backend-services/services/routing_service.py" + }, + "status": "translated" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/routing_service.py::async_method:RoutingService.get_routing", + "notes": "Rust preserves generated client keys, duplicate handling, immutable-key checks, CRUD messages/errors, normalized documents, sorted pagination metadata, and shared-cache invalidation through native routing routes.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::entity_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::routing_models_match_pydantic_generation_coercion_and_update_exclusion" + ], + "source": { + "kind": "async_method", + "line": 140, + "path": "backend-services/services/routing_service.py" + }, + "status": "translated" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/routing_service.py::async_method:RoutingService.get_routings", + "notes": "Rust preserves generated client keys, duplicate handling, immutable-key checks, CRUD messages/errors, normalized documents, sorted pagination metadata, and shared-cache invalidation through native routing routes.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::entity_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::routing_models_match_pydantic_generation_coercion_and_update_exclusion" + ], + "source": { + "kind": "async_method", + "line": 159, + "path": "backend-services/services/routing_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/subscription_service.py::module:subscription_service", + "notes": "Rust preserves API existence checks, subscription retrieval including the empty-list special case, subscribe/unsubscribe mutation, cache-backed shared state, request-id errors, messages, and SUB003-SUB006 contracts through native routes.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::subscription_routes" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::live_test_21_subscription_list_unsubscribe_parity", + "gateway-rs/tests/platform_native.rs::subscription_model_coerces_python_scalars_and_ignores_unknown_fields" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/services/subscription_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/subscription_service.py::class:SubscriptionService", + "notes": "Rust preserves API existence checks, subscription retrieval including the empty-list special case, subscribe/unsubscribe mutation, cache-backed shared state, request-id errors, messages, and SUB003-SUB006 contracts through native routes.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::subscription_routes" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::live_test_21_subscription_list_unsubscribe_parity", + "gateway-rs/tests/platform_native.rs::subscription_model_coerces_python_scalars_and_ignores_unknown_fields" + ], + "source": { + "kind": "class", + "line": 17, + "path": "backend-services/services/subscription_service.py" + }, + "status": "translated" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/subscription_service.py::async_method:SubscriptionService.api_exists", + "notes": "Rust preserves API existence checks, subscription retrieval including the empty-list special case, subscribe/unsubscribe mutation, cache-backed shared state, request-id errors, messages, and SUB003-SUB006 contracts through native routes.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::subscription_routes" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::live_test_21_subscription_list_unsubscribe_parity", + "gateway-rs/tests/platform_native.rs::subscription_model_coerces_python_scalars_and_ignores_unknown_fields" + ], + "source": { + "kind": "async_method", + "line": 19, + "path": "backend-services/services/subscription_service.py" + }, + "status": "translated" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/subscription_service.py::async_method:SubscriptionService.get_user_subscriptions", + "notes": "Rust preserves API existence checks, subscription retrieval including the empty-list special case, subscribe/unsubscribe mutation, cache-backed shared state, request-id errors, messages, and SUB003-SUB006 contracts through native routes.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::subscription_routes" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::live_test_21_subscription_list_unsubscribe_parity", + "gateway-rs/tests/platform_native.rs::subscription_model_coerces_python_scalars_and_ignores_unknown_fields" + ], + "source": { + "kind": "async_method", + "line": 58, + "path": "backend-services/services/subscription_service.py" + }, + "status": "translated" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/subscription_service.py::async_method:SubscriptionService.subscribe", + "notes": "Rust preserves API existence checks, subscription retrieval including the empty-list special case, subscribe/unsubscribe mutation, cache-backed shared state, request-id errors, messages, and SUB003-SUB006 contracts through native routes.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::subscription_routes" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::live_test_21_subscription_list_unsubscribe_parity", + "gateway-rs/tests/platform_native.rs::subscription_model_coerces_python_scalars_and_ignores_unknown_fields" + ], + "source": { + "kind": "async_method", + "line": 87, + "path": "backend-services/services/subscription_service.py" + }, + "status": "translated" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/subscription_service.py::async_method:SubscriptionService.unsubscribe", + "notes": "Rust preserves API existence checks, subscription retrieval including the empty-list special case, subscribe/unsubscribe mutation, cache-backed shared state, request-id errors, messages, and SUB003-SUB006 contracts through native routes.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::subscription_routes" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::live_test_21_subscription_list_unsubscribe_parity", + "gateway-rs/tests/platform_native.rs::subscription_model_coerces_python_scalars_and_ignores_unknown_fields" + ], + "source": { + "kind": "async_method", + "line": 142, + "path": "backend-services/services/subscription_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/tier_service.py::module:tier_service", + "notes": "Rust preserves tier CRUD and idempotent creation, enabled filtering/pagination, pinned search failure behavior, assignment replacement/removal/listing, default and effective-date selection, override limits, deletion guards, upgrade/downgrade/temporary/trial/payment-failure transitions, both notification emails, comparisons, and per-tier/all-tier statistics. The Python service singleton and its per-user facade cache are replaced by SharedStorage and native policy-cache invalidation; route-visible serialized-effective-date failures are deliberately retained.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment", + "gateway-rs/src/routes/platform.rs::send_tier_notification", + "gateway-rs/src/policy/tier.rs::assignment_is_effective" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_and_failure_paths_match_python_contracts", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_crud_routes_match_python_contracts" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/services/tier_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/tier_service.py::class:TierService", + "notes": "Rust preserves tier CRUD and idempotent creation, enabled filtering/pagination, pinned search failure behavior, assignment replacement/removal/listing, default and effective-date selection, override limits, deletion guards, upgrade/downgrade/temporary/trial/payment-failure transitions, both notification emails, comparisons, and per-tier/all-tier statistics. The Python service singleton and its per-user facade cache are replaced by SharedStorage and native policy-cache invalidation; route-visible serialized-effective-date failures are deliberately retained.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment", + "gateway-rs/src/routes/platform.rs::send_tier_notification", + "gateway-rs/src/policy/tier.rs::assignment_is_effective" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_and_failure_paths_match_python_contracts", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_crud_routes_match_python_contracts" + ], + "source": { + "kind": "class", + "line": 19, + "path": "backend-services/services/tier_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/tier_service.py::method:TierService.__init__", + "notes": "Rust preserves tier CRUD and idempotent creation, enabled filtering/pagination, pinned search failure behavior, assignment replacement/removal/listing, default and effective-date selection, override limits, deletion guards, upgrade/downgrade/temporary/trial/payment-failure transitions, both notification emails, comparisons, and per-tier/all-tier statistics. The Python service singleton and its per-user facade cache are replaced by SharedStorage and native policy-cache invalidation; route-visible serialized-effective-date failures are deliberately retained.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment", + "gateway-rs/src/routes/platform.rs::send_tier_notification", + "gateway-rs/src/policy/tier.rs::assignment_is_effective" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_and_failure_paths_match_python_contracts", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_crud_routes_match_python_contracts" + ], + "source": { + "kind": "method", + "line": 32, + "path": "backend-services/services/tier_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/tier_service.py::async_method:TierService.create_tier", + "notes": "Rust preserves tier CRUD and idempotent creation, enabled filtering/pagination, pinned search failure behavior, assignment replacement/removal/listing, default and effective-date selection, override limits, deletion guards, upgrade/downgrade/temporary/trial/payment-failure transitions, both notification emails, comparisons, and per-tier/all-tier statistics. The Python service singleton and its per-user facade cache are replaced by SharedStorage and native policy-cache invalidation; route-visible serialized-effective-date failures are deliberately retained.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment", + "gateway-rs/src/routes/platform.rs::send_tier_notification", + "gateway-rs/src/policy/tier.rs::assignment_is_effective" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_and_failure_paths_match_python_contracts", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_crud_routes_match_python_contracts" + ], + "source": { + "kind": "async_method", + "line": 47, + "path": "backend-services/services/tier_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/tier_service.py::async_method:TierService.get_tier", + "notes": "Rust preserves tier CRUD and idempotent creation, enabled filtering/pagination, pinned search failure behavior, assignment replacement/removal/listing, default and effective-date selection, override limits, deletion guards, upgrade/downgrade/temporary/trial/payment-failure transitions, both notification emails, comparisons, and per-tier/all-tier statistics. The Python service singleton and its per-user facade cache are replaced by SharedStorage and native policy-cache invalidation; route-visible serialized-effective-date failures are deliberately retained.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment", + "gateway-rs/src/routes/platform.rs::send_tier_notification", + "gateway-rs/src/policy/tier.rs::assignment_is_effective" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_and_failure_paths_match_python_contracts", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_crud_routes_match_python_contracts" + ], + "source": { + "kind": "async_method", + "line": 75, + "path": "backend-services/services/tier_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/tier_service.py::async_method:TierService.get_tier_by_name", + "notes": "Rust preserves tier CRUD and idempotent creation, enabled filtering/pagination, pinned search failure behavior, assignment replacement/removal/listing, default and effective-date selection, override limits, deletion guards, upgrade/downgrade/temporary/trial/payment-failure transitions, both notification emails, comparisons, and per-tier/all-tier statistics. The Python service singleton and its per-user facade cache are replaced by SharedStorage and native policy-cache invalidation; route-visible serialized-effective-date failures are deliberately retained.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment", + "gateway-rs/src/routes/platform.rs::send_tier_notification", + "gateway-rs/src/policy/tier.rs::assignment_is_effective" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_and_failure_paths_match_python_contracts", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_crud_routes_match_python_contracts" + ], + "source": { + "kind": "async_method", + "line": 92, + "path": "backend-services/services/tier_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/tier_service.py::async_method:TierService.list_tiers", + "notes": "Rust preserves tier CRUD and idempotent creation, enabled filtering/pagination, pinned search failure behavior, assignment replacement/removal/listing, default and effective-date selection, override limits, deletion guards, upgrade/downgrade/temporary/trial/payment-failure transitions, both notification emails, comparisons, and per-tier/all-tier statistics. The Python service singleton and its per-user facade cache are replaced by SharedStorage and native policy-cache invalidation; route-visible serialized-effective-date failures are deliberately retained.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment", + "gateway-rs/src/routes/platform.rs::send_tier_notification", + "gateway-rs/src/policy/tier.rs::assignment_is_effective" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_and_failure_paths_match_python_contracts", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_crud_routes_match_python_contracts" + ], + "source": { + "kind": "async_method", + "line": 109, + "path": "backend-services/services/tier_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/tier_service.py::async_method:TierService.count_tiers", + "notes": "Rust preserves tier CRUD and idempotent creation, enabled filtering/pagination, pinned search failure behavior, assignment replacement/removal/listing, default and effective-date selection, override limits, deletion guards, upgrade/downgrade/temporary/trial/payment-failure transitions, both notification emails, comparisons, and per-tier/all-tier statistics. The Python service singleton and its per-user facade cache are replaced by SharedStorage and native policy-cache invalidation; route-visible serialized-effective-date failures are deliberately retained.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment", + "gateway-rs/src/routes/platform.rs::send_tier_notification", + "gateway-rs/src/policy/tier.rs::assignment_is_effective" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_and_failure_paths_match_python_contracts", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_crud_routes_match_python_contracts" + ], + "source": { + "kind": "async_method", + "line": 149, + "path": "backend-services/services/tier_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/tier_service.py::async_method:TierService.update_tier", + "notes": "Rust preserves tier CRUD and idempotent creation, enabled filtering/pagination, pinned search failure behavior, assignment replacement/removal/listing, default and effective-date selection, override limits, deletion guards, upgrade/downgrade/temporary/trial/payment-failure transitions, both notification emails, comparisons, and per-tier/all-tier statistics. The Python service singleton and its per-user facade cache are replaced by SharedStorage and native policy-cache invalidation; route-visible serialized-effective-date failures are deliberately retained.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment", + "gateway-rs/src/routes/platform.rs::send_tier_notification", + "gateway-rs/src/policy/tier.rs::assignment_is_effective" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_and_failure_paths_match_python_contracts", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_crud_routes_match_python_contracts" + ], + "source": { + "kind": "async_method", + "line": 170, + "path": "backend-services/services/tier_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/tier_service.py::async_method:TierService.delete_tier", + "notes": "Rust preserves tier CRUD and idempotent creation, enabled filtering/pagination, pinned search failure behavior, assignment replacement/removal/listing, default and effective-date selection, override limits, deletion guards, upgrade/downgrade/temporary/trial/payment-failure transitions, both notification emails, comparisons, and per-tier/all-tier statistics. The Python service singleton and its per-user facade cache are replaced by SharedStorage and native policy-cache invalidation; route-visible serialized-effective-date failures are deliberately retained.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment", + "gateway-rs/src/routes/platform.rs::send_tier_notification", + "gateway-rs/src/policy/tier.rs::assignment_is_effective" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_and_failure_paths_match_python_contracts", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_crud_routes_match_python_contracts" + ], + "source": { + "kind": "async_method", + "line": 194, + "path": "backend-services/services/tier_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/tier_service.py::async_method:TierService.get_default_tier", + "notes": "Rust preserves tier CRUD and idempotent creation, enabled filtering/pagination, pinned search failure behavior, assignment replacement/removal/listing, default and effective-date selection, override limits, deletion guards, upgrade/downgrade/temporary/trial/payment-failure transitions, both notification emails, comparisons, and per-tier/all-tier statistics. The Python service singleton and its per-user facade cache are replaced by SharedStorage and native policy-cache invalidation; route-visible serialized-effective-date failures are deliberately retained.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment", + "gateway-rs/src/routes/platform.rs::send_tier_notification", + "gateway-rs/src/policy/tier.rs::assignment_is_effective" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_and_failure_paths_match_python_contracts", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_crud_routes_match_python_contracts" + ], + "source": { + "kind": "async_method", + "line": 218, + "path": "backend-services/services/tier_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/tier_service.py::async_method:TierService.assign_user_to_tier", + "notes": "Rust preserves tier CRUD and idempotent creation, enabled filtering/pagination, pinned search failure behavior, assignment replacement/removal/listing, default and effective-date selection, override limits, deletion guards, upgrade/downgrade/temporary/trial/payment-failure transitions, both notification emails, comparisons, and per-tier/all-tier statistics. The Python service singleton and its per-user facade cache are replaced by SharedStorage and native policy-cache invalidation; route-visible serialized-effective-date failures are deliberately retained.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment", + "gateway-rs/src/routes/platform.rs::send_tier_notification", + "gateway-rs/src/policy/tier.rs::assignment_is_effective" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_and_failure_paths_match_python_contracts", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_crud_routes_match_python_contracts" + ], + "source": { + "kind": "async_method", + "line": 236, + "path": "backend-services/services/tier_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/tier_service.py::async_method:TierService.get_user_assignment", + "notes": "Rust preserves tier CRUD and idempotent creation, enabled filtering/pagination, pinned search failure behavior, assignment replacement/removal/listing, default and effective-date selection, override limits, deletion guards, upgrade/downgrade/temporary/trial/payment-failure transitions, both notification emails, comparisons, and per-tier/all-tier statistics. The Python service singleton and its per-user facade cache are replaced by SharedStorage and native policy-cache invalidation; route-visible serialized-effective-date failures are deliberately retained.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment", + "gateway-rs/src/routes/platform.rs::send_tier_notification", + "gateway-rs/src/policy/tier.rs::assignment_is_effective" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_and_failure_paths_match_python_contracts", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_crud_routes_match_python_contracts" + ], + "source": { + "kind": "async_method", + "line": 299, + "path": "backend-services/services/tier_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/tier_service.py::async_method:TierService.get_user_tier", + "notes": "Rust preserves tier CRUD and idempotent creation, enabled filtering/pagination, pinned search failure behavior, assignment replacement/removal/listing, default and effective-date selection, override limits, deletion guards, upgrade/downgrade/temporary/trial/payment-failure transitions, both notification emails, comparisons, and per-tier/all-tier statistics. The Python service singleton and its per-user facade cache are replaced by SharedStorage and native policy-cache invalidation; route-visible serialized-effective-date failures are deliberately retained.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment", + "gateway-rs/src/routes/platform.rs::send_tier_notification", + "gateway-rs/src/policy/tier.rs::assignment_is_effective" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_and_failure_paths_match_python_contracts", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_crud_routes_match_python_contracts" + ], + "source": { + "kind": "async_method", + "line": 317, + "path": "backend-services/services/tier_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/tier_service.py::async_method:TierService.get_user_limits", + "notes": "Rust preserves tier CRUD and idempotent creation, enabled filtering/pagination, pinned search failure behavior, assignment replacement/removal/listing, default and effective-date selection, override limits, deletion guards, upgrade/downgrade/temporary/trial/payment-failure transitions, both notification emails, comparisons, and per-tier/all-tier statistics. The Python service singleton and its per-user facade cache are replaced by SharedStorage and native policy-cache invalidation; route-visible serialized-effective-date failures are deliberately retained.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment", + "gateway-rs/src/routes/platform.rs::send_tier_notification", + "gateway-rs/src/policy/tier.rs::assignment_is_effective" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_and_failure_paths_match_python_contracts", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_crud_routes_match_python_contracts" + ], + "source": { + "kind": "async_method", + "line": 349, + "path": "backend-services/services/tier_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/tier_service.py::async_method:TierService.remove_user_assignment", + "notes": "Rust preserves tier CRUD and idempotent creation, enabled filtering/pagination, pinned search failure behavior, assignment replacement/removal/listing, default and effective-date selection, override limits, deletion guards, upgrade/downgrade/temporary/trial/payment-failure transitions, both notification emails, comparisons, and per-tier/all-tier statistics. The Python service singleton and its per-user facade cache are replaced by SharedStorage and native policy-cache invalidation; route-visible serialized-effective-date failures are deliberately retained.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment", + "gateway-rs/src/routes/platform.rs::send_tier_notification", + "gateway-rs/src/policy/tier.rs::assignment_is_effective" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_and_failure_paths_match_python_contracts", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_crud_routes_match_python_contracts" + ], + "source": { + "kind": "async_method", + "line": 384, + "path": "backend-services/services/tier_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/tier_service.py::async_method:TierService.list_users_in_tier", + "notes": "Rust preserves tier CRUD and idempotent creation, enabled filtering/pagination, pinned search failure behavior, assignment replacement/removal/listing, default and effective-date selection, override limits, deletion guards, upgrade/downgrade/temporary/trial/payment-failure transitions, both notification emails, comparisons, and per-tier/all-tier statistics. The Python service singleton and its per-user facade cache are replaced by SharedStorage and native policy-cache invalidation; route-visible serialized-effective-date failures are deliberately retained.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment", + "gateway-rs/src/routes/platform.rs::send_tier_notification", + "gateway-rs/src/policy/tier.rs::assignment_is_effective" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_and_failure_paths_match_python_contracts", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_crud_routes_match_python_contracts" + ], + "source": { + "kind": "async_method", + "line": 403, + "path": "backend-services/services/tier_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/tier_service.py::async_method:TierService.upgrade_user_tier", + "notes": "Rust preserves tier CRUD and idempotent creation, enabled filtering/pagination, pinned search failure behavior, assignment replacement/removal/listing, default and effective-date selection, override limits, deletion guards, upgrade/downgrade/temporary/trial/payment-failure transitions, both notification emails, comparisons, and per-tier/all-tier statistics. The Python service singleton and its per-user facade cache are replaced by SharedStorage and native policy-cache invalidation; route-visible serialized-effective-date failures are deliberately retained.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment", + "gateway-rs/src/routes/platform.rs::send_tier_notification", + "gateway-rs/src/policy/tier.rs::assignment_is_effective" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_and_failure_paths_match_python_contracts", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_crud_routes_match_python_contracts" + ], + "source": { + "kind": "async_method", + "line": 429, + "path": "backend-services/services/tier_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/tier_service.py::async_method:TierService.downgrade_user_tier", + "notes": "Rust preserves tier CRUD and idempotent creation, enabled filtering/pagination, pinned search failure behavior, assignment replacement/removal/listing, default and effective-date selection, override limits, deletion guards, upgrade/downgrade/temporary/trial/payment-failure transitions, both notification emails, comparisons, and per-tier/all-tier statistics. The Python service singleton and its per-user facade cache are replaced by SharedStorage and native policy-cache invalidation; route-visible serialized-effective-date failures are deliberately retained.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment", + "gateway-rs/src/routes/platform.rs::send_tier_notification", + "gateway-rs/src/policy/tier.rs::assignment_is_effective" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_and_failure_paths_match_python_contracts", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_crud_routes_match_python_contracts" + ], + "source": { + "kind": "async_method", + "line": 478, + "path": "backend-services/services/tier_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/tier_service.py::async_method:TierService.temporary_tier_upgrade", + "notes": "Rust preserves tier CRUD and idempotent creation, enabled filtering/pagination, pinned search failure behavior, assignment replacement/removal/listing, default and effective-date selection, override limits, deletion guards, upgrade/downgrade/temporary/trial/payment-failure transitions, both notification emails, comparisons, and per-tier/all-tier statistics. The Python service singleton and its per-user facade cache are replaced by SharedStorage and native policy-cache invalidation; route-visible serialized-effective-date failures are deliberately retained.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment", + "gateway-rs/src/routes/platform.rs::send_tier_notification", + "gateway-rs/src/policy/tier.rs::assignment_is_effective" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_and_failure_paths_match_python_contracts", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_crud_routes_match_python_contracts" + ], + "source": { + "kind": "async_method", + "line": 526, + "path": "backend-services/services/tier_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/tier_service.py::async_method:TierService.start_trial", + "notes": "Rust preserves tier CRUD and idempotent creation, enabled filtering/pagination, pinned search failure behavior, assignment replacement/removal/listing, default and effective-date selection, override limits, deletion guards, upgrade/downgrade/temporary/trial/payment-failure transitions, both notification emails, comparisons, and per-tier/all-tier statistics. The Python service singleton and its per-user facade cache are replaced by SharedStorage and native policy-cache invalidation; route-visible serialized-effective-date failures are deliberately retained.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment", + "gateway-rs/src/routes/platform.rs::send_tier_notification", + "gateway-rs/src/policy/tier.rs::assignment_is_effective" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_and_failure_paths_match_python_contracts", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_crud_routes_match_python_contracts" + ], + "source": { + "kind": "async_method", + "line": 569, + "path": "backend-services/services/tier_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/tier_service.py::async_method:TierService.handle_payment_failure", + "notes": "Rust preserves tier CRUD and idempotent creation, enabled filtering/pagination, pinned search failure behavior, assignment replacement/removal/listing, default and effective-date selection, override limits, deletion guards, upgrade/downgrade/temporary/trial/payment-failure transitions, both notification emails, comparisons, and per-tier/all-tier statistics. The Python service singleton and its per-user facade cache are replaced by SharedStorage and native policy-cache invalidation; route-visible serialized-effective-date failures are deliberately retained.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment", + "gateway-rs/src/routes/platform.rs::send_tier_notification", + "gateway-rs/src/policy/tier.rs::assignment_is_effective" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_and_failure_paths_match_python_contracts", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_crud_routes_match_python_contracts" + ], + "source": { + "kind": "async_method", + "line": 578, + "path": "backend-services/services/tier_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/tier_service.py::async_method:TierService.compare_tiers", + "notes": "Rust preserves tier CRUD and idempotent creation, enabled filtering/pagination, pinned search failure behavior, assignment replacement/removal/listing, default and effective-date selection, override limits, deletion guards, upgrade/downgrade/temporary/trial/payment-failure transitions, both notification emails, comparisons, and per-tier/all-tier statistics. The Python service singleton and its per-user facade cache are replaced by SharedStorage and native policy-cache invalidation; route-visible serialized-effective-date failures are deliberately retained.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment", + "gateway-rs/src/routes/platform.rs::send_tier_notification", + "gateway-rs/src/policy/tier.rs::assignment_is_effective" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_and_failure_paths_match_python_contracts", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_crud_routes_match_python_contracts" + ], + "source": { + "kind": "async_method", + "line": 610, + "path": "backend-services/services/tier_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/tier_service.py::async_method:TierService.get_tier_statistics", + "notes": "Rust preserves tier CRUD and idempotent creation, enabled filtering/pagination, pinned search failure behavior, assignment replacement/removal/listing, default and effective-date selection, override limits, deletion guards, upgrade/downgrade/temporary/trial/payment-failure transitions, both notification emails, comparisons, and per-tier/all-tier statistics. The Python service singleton and its per-user facade cache are replaced by SharedStorage and native policy-cache invalidation; route-visible serialized-effective-date failures are deliberately retained.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment", + "gateway-rs/src/routes/platform.rs::send_tier_notification", + "gateway-rs/src/policy/tier.rs::assignment_is_effective" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_and_failure_paths_match_python_contracts", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_crud_routes_match_python_contracts" + ], + "source": { + "kind": "async_method", + "line": 639, + "path": "backend-services/services/tier_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/tier_service.py::async_method:TierService.get_all_tier_statistics", + "notes": "Rust preserves tier CRUD and idempotent creation, enabled filtering/pagination, pinned search failure behavior, assignment replacement/removal/listing, default and effective-date selection, override limits, deletion guards, upgrade/downgrade/temporary/trial/payment-failure transitions, both notification emails, comparisons, and per-tier/all-tier statistics. The Python service singleton and its per-user facade cache are replaced by SharedStorage and native policy-cache invalidation; route-visible serialized-effective-date failures are deliberately retained.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment", + "gateway-rs/src/routes/platform.rs::send_tier_notification", + "gateway-rs/src/policy/tier.rs::assignment_is_effective" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_and_failure_paths_match_python_contracts", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_crud_routes_match_python_contracts" + ], + "source": { + "kind": "async_method", + "line": 671, + "path": "backend-services/services/tier_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/tier_service.py::function:get_tier_service", + "notes": "Rust preserves tier CRUD and idempotent creation, enabled filtering/pagination, pinned search failure behavior, assignment replacement/removal/listing, default and effective-date selection, override limits, deletion guards, upgrade/downgrade/temporary/trial/payment-failure transitions, both notification emails, comparisons, and per-tier/all-tier statistics. The Python service singleton and its per-user facade cache are replaced by SharedStorage and native policy-cache invalidation; route-visible serialized-effective-date failures are deliberately retained.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment", + "gateway-rs/src/routes/platform.rs::send_tier_notification", + "gateway-rs/src/policy/tier.rs::assignment_is_effective" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_and_failure_paths_match_python_contracts", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_crud_routes_match_python_contracts" + ], + "source": { + "kind": "function", + "line": 693, + "path": "backend-services/services/tier_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/user_service.py::module:user_service", + "notes": "Rust preserves username/email lookup and password stripping, bandwidth usage/reset enrichment, duplicate and custom-attribute validation, Unicode-aware password policy and bcrypt hashing, update/delete/password response contracts, Python's role-change subscription purge iteration behavior, and sorted paginated user listing. Native routes also enforce v2 super-admin and self-update protections, while cache and database-driver-specific failure distinctions are consolidated.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::user_routes", + "gateway-rs/src/routes/platform.rs::user_by", + "gateway-rs/src/routes/platform.rs::create_user", + "gateway-rs/src/routes/platform.rs::purge_subscriptions_after_role_change" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/services/user_service.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/user_service.py::class:UserService", + "notes": "Rust preserves username/email lookup and password stripping, bandwidth usage/reset enrichment, duplicate and custom-attribute validation, Unicode-aware password policy and bcrypt hashing, update/delete/password response contracts, Python's role-change subscription purge iteration behavior, and sorted paginated user listing. Native routes also enforce v2 super-admin and self-update protections, while cache and database-driver-specific failure distinctions are consolidated.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::user_routes", + "gateway-rs/src/routes/platform.rs::user_by", + "gateway-rs/src/routes/platform.rs::create_user", + "gateway-rs/src/routes/platform.rs::purge_subscriptions_after_role_change" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "class", + "line": 33, + "path": "backend-services/services/user_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/user_service.py::async_method:UserService.get_user_by_email_with_password_helper", + "notes": "Rust preserves username/email lookup and password stripping, bandwidth usage/reset enrichment, duplicate and custom-attribute validation, Unicode-aware password policy and bcrypt hashing, update/delete/password response contracts, Python's role-change subscription purge iteration behavior, and sorted paginated user listing. Native routes also enforce v2 super-admin and self-update protections, while cache and database-driver-specific failure distinctions are consolidated.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::user_routes", + "gateway-rs/src/routes/platform.rs::user_by", + "gateway-rs/src/routes/platform.rs::create_user", + "gateway-rs/src/routes/platform.rs::purge_subscriptions_after_role_change" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "async_method", + "line": 35, + "path": "backend-services/services/user_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/user_service.py::async_method:UserService.get_user_by_username_helper", + "notes": "Rust preserves username/email lookup and password stripping, bandwidth usage/reset enrichment, duplicate and custom-attribute validation, Unicode-aware password policy and bcrypt hashing, update/delete/password response contracts, Python's role-change subscription purge iteration behavior, and sorted paginated user listing. Native routes also enforce v2 super-admin and self-update protections, while cache and database-driver-specific failure distinctions are consolidated.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::user_routes", + "gateway-rs/src/routes/platform.rs::user_by", + "gateway-rs/src/routes/platform.rs::create_user", + "gateway-rs/src/routes/platform.rs::purge_subscriptions_after_role_change" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "async_method", + "line": 47, + "path": "backend-services/services/user_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/user_service.py::async_method:UserService.get_user_by_username", + "notes": "Rust preserves username/email lookup and password stripping, bandwidth usage/reset enrichment, duplicate and custom-attribute validation, Unicode-aware password policy and bcrypt hashing, update/delete/password response contracts, Python's role-change subscription purge iteration behavior, and sorted paginated user listing. Native routes also enforce v2 super-admin and self-update protections, while cache and database-driver-specific failure distinctions are consolidated.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::user_routes", + "gateway-rs/src/routes/platform.rs::user_by", + "gateway-rs/src/routes/platform.rs::create_user", + "gateway-rs/src/routes/platform.rs::purge_subscriptions_after_role_change" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "async_method", + "line": 69, + "path": "backend-services/services/user_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/user_service.py::async_method:UserService.get_user_by_email", + "notes": "Rust preserves username/email lookup and password stripping, bandwidth usage/reset enrichment, duplicate and custom-attribute validation, Unicode-aware password policy and bcrypt hashing, update/delete/password response contracts, Python's role-change subscription purge iteration behavior, and sorted paginated user listing. Native routes also enforce v2 super-admin and self-update protections, while cache and database-driver-specific failure distinctions are consolidated.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::user_routes", + "gateway-rs/src/routes/platform.rs::user_by", + "gateway-rs/src/routes/platform.rs::create_user", + "gateway-rs/src/routes/platform.rs::purge_subscriptions_after_role_change" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "async_method", + "line": 121, + "path": "backend-services/services/user_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/user_service.py::async_method:UserService.create_user", + "notes": "Rust preserves username/email lookup and password stripping, bandwidth usage/reset enrichment, duplicate and custom-attribute validation, Unicode-aware password policy and bcrypt hashing, update/delete/password response contracts, Python's role-change subscription purge iteration behavior, and sorted paginated user listing. Native routes also enforce v2 super-admin and self-update protections, while cache and database-driver-specific failure distinctions are consolidated.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::user_routes", + "gateway-rs/src/routes/platform.rs::user_by", + "gateway-rs/src/routes/platform.rs::create_user", + "gateway-rs/src/routes/platform.rs::purge_subscriptions_after_role_change" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "async_method", + "line": 152, + "path": "backend-services/services/user_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/user_service.py::async_method:UserService.check_password_return_user", + "notes": "Rust preserves username/email lookup and password stripping, bandwidth usage/reset enrichment, duplicate and custom-attribute validation, Unicode-aware password policy and bcrypt hashing, update/delete/password response contracts, Python's role-change subscription purge iteration behavior, and sorted paginated user listing. Native routes also enforce v2 super-admin and self-update protections, while cache and database-driver-specific failure distinctions are consolidated.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::user_routes", + "gateway-rs/src/routes/platform.rs::user_by", + "gateway-rs/src/routes/platform.rs::create_user", + "gateway-rs/src/routes/platform.rs::purge_subscriptions_after_role_change" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "async_method", + "line": 218, + "path": "backend-services/services/user_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/user_service.py::async_method:UserService.update_user", + "notes": "Rust preserves username/email lookup and password stripping, bandwidth usage/reset enrichment, duplicate and custom-attribute validation, Unicode-aware password policy and bcrypt hashing, update/delete/password response contracts, Python's role-change subscription purge iteration behavior, and sorted paginated user listing. Native routes also enforce v2 super-admin and self-update protections, while cache and database-driver-specific failure distinctions are consolidated.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::user_routes", + "gateway-rs/src/routes/platform.rs::user_by", + "gateway-rs/src/routes/platform.rs::create_user", + "gateway-rs/src/routes/platform.rs::purge_subscriptions_after_role_change" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "async_method", + "line": 238, + "path": "backend-services/services/user_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/user_service.py::async_method:UserService.delete_user", + "notes": "Rust preserves username/email lookup and password stripping, bandwidth usage/reset enrichment, duplicate and custom-attribute validation, Unicode-aware password policy and bcrypt hashing, update/delete/password response contracts, Python's role-change subscription purge iteration behavior, and sorted paginated user listing. Native routes also enforce v2 super-admin and self-update protections, while cache and database-driver-specific failure distinctions are consolidated.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::user_routes", + "gateway-rs/src/routes/platform.rs::user_by", + "gateway-rs/src/routes/platform.rs::create_user", + "gateway-rs/src/routes/platform.rs::purge_subscriptions_after_role_change" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "async_method", + "line": 305, + "path": "backend-services/services/user_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/user_service.py::async_method:UserService.update_password", + "notes": "Rust preserves username/email lookup and password stripping, bandwidth usage/reset enrichment, duplicate and custom-attribute validation, Unicode-aware password policy and bcrypt hashing, update/delete/password response contracts, Python's role-change subscription purge iteration behavior, and sorted paginated user listing. Native routes also enforce v2 super-admin and self-update protections, while cache and database-driver-specific failure distinctions are consolidated.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::user_routes", + "gateway-rs/src/routes/platform.rs::user_by", + "gateway-rs/src/routes/platform.rs::create_user", + "gateway-rs/src/routes/platform.rs::purge_subscriptions_after_role_change" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "async_method", + "line": 337, + "path": "backend-services/services/user_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/user_service.py::async_method:UserService.purge_apis_after_role_change", + "notes": "Rust preserves username/email lookup and password stripping, bandwidth usage/reset enrichment, duplicate and custom-attribute validation, Unicode-aware password policy and bcrypt hashing, update/delete/password response contracts, Python's role-change subscription purge iteration behavior, and sorted paginated user listing. Native routes also enforce v2 super-admin and self-update protections, while cache and database-driver-specific failure distinctions are consolidated.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::user_routes", + "gateway-rs/src/routes/platform.rs::user_by", + "gateway-rs/src/routes/platform.rs::create_user", + "gateway-rs/src/routes/platform.rs::purge_subscriptions_after_role_change" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "async_method", + "line": 386, + "path": "backend-services/services/user_service.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/user_service.py::async_method:UserService.get_all_users", + "notes": "Rust preserves username/email lookup and password stripping, bandwidth usage/reset enrichment, duplicate and custom-attribute validation, Unicode-aware password policy and bcrypt hashing, update/delete/password response contracts, Python's role-change subscription purge iteration behavior, and sorted paginated user listing. Native routes also enforce v2 super-admin and self-update protections, while cache and database-driver-specific failure distinctions are consolidated.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::user_routes", + "gateway-rs/src/routes/platform.rs::user_by", + "gateway-rs/src/routes/platform.rs::create_user", + "gateway-rs/src/routes/platform.rs::purge_subscriptions_after_role_change" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "async_method", + "line": 426, + "path": "backend-services/services/user_service.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/vault_service.py::module:vault_service", + "notes": "Rust preserves all user lookup, email/configuration validation, duplicate handling, encrypted persistence, secret suppression, timestamps, description-only updates, no-change success, deletion, and VAULT001-VAULT008 response behavior.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::vault_routes", + "gateway-rs/src/storage/vault.rs::encrypt" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::vault_lifecycle_encrypts_at_rest_and_never_returns_the_secret" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/services/vault_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "services", + "id": "backend-services/services/vault_service.py::class:VaultService", + "notes": "Rust preserves all user lookup, email/configuration validation, duplicate handling, encrypted persistence, secret suppression, timestamps, description-only updates, no-change success, deletion, and VAULT001-VAULT008 response behavior.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::vault_routes", + "gateway-rs/src/storage/vault.rs::encrypt" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::vault_lifecycle_encrypts_at_rest_and_never_returns_the_secret" + ], + "source": { + "kind": "class", + "line": 26, + "path": "backend-services/services/vault_service.py" + }, + "status": "translated" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/vault_service.py::async_method:VaultService.create_vault_entry", + "notes": "Rust preserves all user lookup, email/configuration validation, duplicate handling, encrypted persistence, secret suppression, timestamps, description-only updates, no-change success, deletion, and VAULT001-VAULT008 response behavior.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::vault_routes", + "gateway-rs/src/storage/vault.rs::encrypt" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::vault_lifecycle_encrypts_at_rest_and_never_returns_the_secret" + ], + "source": { + "kind": "async_method", + "line": 30, + "path": "backend-services/services/vault_service.py" + }, + "status": "translated" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/vault_service.py::async_method:VaultService.get_vault_entry", + "notes": "Rust preserves all user lookup, email/configuration validation, duplicate handling, encrypted persistence, secret suppression, timestamps, description-only updates, no-change success, deletion, and VAULT001-VAULT008 response behavior.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::vault_routes", + "gateway-rs/src/storage/vault.rs::encrypt" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::vault_lifecycle_encrypts_at_rest_and_never_returns_the_secret" + ], + "source": { + "kind": "async_method", + "line": 133, + "path": "backend-services/services/vault_service.py" + }, + "status": "translated" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/vault_service.py::async_method:VaultService.list_vault_entries", + "notes": "Rust preserves all user lookup, email/configuration validation, duplicate handling, encrypted persistence, secret suppression, timestamps, description-only updates, no-change success, deletion, and VAULT001-VAULT008 response behavior.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::vault_routes", + "gateway-rs/src/storage/vault.rs::encrypt" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::vault_lifecycle_encrypts_at_rest_and_never_returns_the_secret" + ], + "source": { + "kind": "async_method", + "line": 166, + "path": "backend-services/services/vault_service.py" + }, + "status": "translated" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/vault_service.py::async_method:VaultService.update_vault_entry", + "notes": "Rust preserves all user lookup, email/configuration validation, duplicate handling, encrypted persistence, secret suppression, timestamps, description-only updates, no-change success, deletion, and VAULT001-VAULT008 response behavior.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::vault_routes", + "gateway-rs/src/storage/vault.rs::encrypt" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::vault_lifecycle_encrypts_at_rest_and_never_returns_the_secret" + ], + "source": { + "kind": "async_method", + "line": 201, + "path": "backend-services/services/vault_service.py" + }, + "status": "translated" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "services", + "id": "backend-services/services/vault_service.py::async_method:VaultService.delete_vault_entry", + "notes": "Rust preserves all user lookup, email/configuration validation, duplicate handling, encrypted persistence, secret suppression, timestamps, description-only updates, no-change success, deletion, and VAULT001-VAULT008 response behavior.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::vault_routes", + "gateway-rs/src/storage/vault.rs::encrypt" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::vault_lifecycle_encrypts_at_rest_and_never_returns_the_secret" + ], + "source": { + "kind": "async_method", + "line": 260, + "path": "backend-services/services/vault_service.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/analytics_aggregator.py::module:analytics_aggregator", + "notes": "Rust retains minute metrics for the longer 30-day MetricsStore contract and aggregates range-query output into Python's five-minute (up to 24h), hourly (up to 7d), and daily (longer) levels, preserving request/error/byte totals and request-weighted latency. Native state does not persist three duplicate rollup deques, and its compact points do not retain Python's raw-latency percentile samples or per-bucket unique-user sets.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_timeseries_range", + "gateway-rs/src/observability/analytics_aggregator.rs::aggregate_points" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::range_queries_use_python_aggregation_levels", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/analytics_aggregator.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/analytics_aggregator.py::class:AnalyticsAggregator", + "notes": "Rust retains minute metrics for the longer 30-day MetricsStore contract and aggregates range-query output into Python's five-minute (up to 24h), hourly (up to 7d), and daily (longer) levels, preserving request/error/byte totals and request-weighted latency. Native state does not persist three duplicate rollup deques, and its compact points do not retain Python's raw-latency percentile samples or per-bucket unique-user sets.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_timeseries_range", + "gateway-rs/src/observability/analytics_aggregator.rs::aggregate_points" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::range_queries_use_python_aggregation_levels", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics" + ], + "source": { + "kind": "class", + "line": 21, + "path": "backend-services/utils/analytics_aggregator.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/analytics_aggregator.py::method:AnalyticsAggregator.__init__", + "notes": "Rust retains minute metrics for the longer 30-day MetricsStore contract and aggregates range-query output into Python's five-minute (up to 24h), hourly (up to 7d), and daily (longer) levels, preserving request/error/byte totals and request-weighted latency. Native state does not persist three duplicate rollup deques, and its compact points do not retain Python's raw-latency percentile samples or per-bucket unique-user sets.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_timeseries_range", + "gateway-rs/src/observability/analytics_aggregator.rs::aggregate_points" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::range_queries_use_python_aggregation_levels", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics" + ], + "source": { + "kind": "method", + "line": 37, + "path": "backend-services/utils/analytics_aggregator.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "utils", + "id": "backend-services/utils/analytics_aggregator.py::method:AnalyticsAggregator._floor_timestamp", + "notes": "Rust retains minute metrics for the longer 30-day MetricsStore contract and aggregates range-query output into Python's five-minute (up to 24h), hourly (up to 7d), and daily (longer) levels, preserving request/error/byte totals and request-weighted latency. Native state does not persist three duplicate rollup deques, and its compact points do not retain Python's raw-latency percentile samples or per-bucket unique-user sets.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_timeseries_range", + "gateway-rs/src/observability/analytics_aggregator.rs::aggregate_points" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::range_queries_use_python_aggregation_levels", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics" + ], + "source": { + "kind": "method", + "line": 49, + "path": "backend-services/utils/analytics_aggregator.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/analytics_aggregator.py::method:AnalyticsAggregator.aggregate_to_5minute", + "notes": "Rust retains minute metrics for the longer 30-day MetricsStore contract and aggregates range-query output into Python's five-minute (up to 24h), hourly (up to 7d), and daily (longer) levels, preserving request/error/byte totals and request-weighted latency. Native state does not persist three duplicate rollup deques, and its compact points do not retain Python's raw-latency percentile samples or per-bucket unique-user sets.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_timeseries_range", + "gateway-rs/src/observability/analytics_aggregator.rs::aggregate_points" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::range_queries_use_python_aggregation_levels", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics" + ], + "source": { + "kind": "method", + "line": 53, + "path": "backend-services/utils/analytics_aggregator.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/analytics_aggregator.py::method:AnalyticsAggregator.aggregate_to_hourly", + "notes": "Rust retains minute metrics for the longer 30-day MetricsStore contract and aggregates range-query output into Python's five-minute (up to 24h), hourly (up to 7d), and daily (longer) levels, preserving request/error/byte totals and request-weighted latency. Native state does not persist three duplicate rollup deques, and its compact points do not retain Python's raw-latency percentile samples or per-bucket unique-user sets.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_timeseries_range", + "gateway-rs/src/observability/analytics_aggregator.rs::aggregate_points" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::range_queries_use_python_aggregation_levels", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics" + ], + "source": { + "kind": "method", + "line": 80, + "path": "backend-services/utils/analytics_aggregator.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/analytics_aggregator.py::method:AnalyticsAggregator.aggregate_to_daily", + "notes": "Rust retains minute metrics for the longer 30-day MetricsStore contract and aggregates range-query output into Python's five-minute (up to 24h), hourly (up to 7d), and daily (longer) levels, preserving request/error/byte totals and request-weighted latency. Native state does not persist three duplicate rollup deques, and its compact points do not retain Python's raw-latency percentile samples or per-bucket unique-user sets.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_timeseries_range", + "gateway-rs/src/observability/analytics_aggregator.rs::aggregate_points" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::range_queries_use_python_aggregation_levels", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics" + ], + "source": { + "kind": "method", + "line": 110, + "path": "backend-services/utils/analytics_aggregator.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/analytics_aggregator.py::method:AnalyticsAggregator._aggregate_buckets", + "notes": "Rust retains minute metrics for the longer 30-day MetricsStore contract and aggregates range-query output into Python's five-minute (up to 24h), hourly (up to 7d), and daily (longer) levels, preserving request/error/byte totals and request-weighted latency. Native state does not persist three duplicate rollup deques, and its compact points do not retain Python's raw-latency percentile samples or per-bucket unique-user sets.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_timeseries_range", + "gateway-rs/src/observability/analytics_aggregator.rs::aggregate_points" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::range_queries_use_python_aggregation_levels", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics" + ], + "source": { + "kind": "method", + "line": 138, + "path": "backend-services/utils/analytics_aggregator.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/analytics_aggregator.py::method:AnalyticsAggregator._aggregate_aggregated_buckets", + "notes": "Rust retains minute metrics for the longer 30-day MetricsStore contract and aggregates range-query output into Python's five-minute (up to 24h), hourly (up to 7d), and daily (longer) levels, preserving request/error/byte totals and request-weighted latency. Native state does not persist three duplicate rollup deques, and its compact points do not retain Python's raw-latency percentile samples or per-bucket unique-user sets.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_timeseries_range", + "gateway-rs/src/observability/analytics_aggregator.rs::aggregate_points" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::range_queries_use_python_aggregation_levels", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics" + ], + "source": { + "kind": "method", + "line": 192, + "path": "backend-services/utils/analytics_aggregator.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/analytics_aggregator.py::method:AnalyticsAggregator._weighted_average_percentiles", + "notes": "Rust retains minute metrics for the longer 30-day MetricsStore contract and aggregates range-query output into Python's five-minute (up to 24h), hourly (up to 7d), and daily (longer) levels, preserving request/error/byte totals and request-weighted latency. Native state does not persist three duplicate rollup deques, and its compact points do not retain Python's raw-latency percentile samples or per-bucket unique-user sets.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_timeseries_range", + "gateway-rs/src/observability/analytics_aggregator.rs::aggregate_points" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::range_queries_use_python_aggregation_levels", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics" + ], + "source": { + "kind": "method", + "line": 246, + "path": "backend-services/utils/analytics_aggregator.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/analytics_aggregator.py::method:AnalyticsAggregator.get_buckets_for_range", + "notes": "Rust retains minute metrics for the longer 30-day MetricsStore contract and aggregates range-query output into Python's five-minute (up to 24h), hourly (up to 7d), and daily (longer) levels, preserving request/error/byte totals and request-weighted latency. Native state does not persist three duplicate rollup deques, and its compact points do not retain Python's raw-latency percentile samples or per-bucket unique-user sets.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_timeseries_range", + "gateway-rs/src/observability/analytics_aggregator.rs::aggregate_points" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::range_queries_use_python_aggregation_levels", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics" + ], + "source": { + "kind": "method", + "line": 277, + "path": "backend-services/utils/analytics_aggregator.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/analytics_aggregator.py::method:AnalyticsAggregator.should_aggregate", + "notes": "Rust retains minute metrics for the longer 30-day MetricsStore contract and aggregates range-query output into Python's five-minute (up to 24h), hourly (up to 7d), and daily (longer) levels, preserving request/error/byte totals and request-weighted latency. Native state does not persist three duplicate rollup deques, and its compact points do not retain Python's raw-latency percentile samples or per-bucket unique-user sets.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_timeseries_range", + "gateway-rs/src/observability/analytics_aggregator.rs::aggregate_points" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::range_queries_use_python_aggregation_levels", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics" + ], + "source": { + "kind": "method", + "line": 311, + "path": "backend-services/utils/analytics_aggregator.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/analytics_aggregator.py::method:AnalyticsAggregator.to_dict", + "notes": "Rust retains minute metrics for the longer 30-day MetricsStore contract and aggregates range-query output into Python's five-minute (up to 24h), hourly (up to 7d), and daily (longer) levels, preserving request/error/byte totals and request-weighted latency. Native state does not persist three duplicate rollup deques, and its compact points do not retain Python's raw-latency percentile samples or per-bucket unique-user sets.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_timeseries_range", + "gateway-rs/src/observability/analytics_aggregator.rs::aggregate_points" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::range_queries_use_python_aggregation_levels", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics" + ], + "source": { + "kind": "method", + "line": 321, + "path": "backend-services/utils/analytics_aggregator.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/analytics_aggregator.py::method:AnalyticsAggregator.load_dict", + "notes": "Rust retains minute metrics for the longer 30-day MetricsStore contract and aggregates range-query output into Python's five-minute (up to 24h), hourly (up to 7d), and daily (longer) levels, preserving request/error/byte totals and request-weighted latency. Native state does not persist three duplicate rollup deques, and its compact points do not retain Python's raw-latency percentile samples or per-bucket unique-user sets.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_timeseries_range", + "gateway-rs/src/observability/analytics_aggregator.rs::aggregate_points" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::range_queries_use_python_aggregation_levels", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics" + ], + "source": { + "kind": "method", + "line": 332, + "path": "backend-services/utils/analytics_aggregator.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/analytics_scheduler.py::module:analytics_scheduler", + "notes": "Rust starts an interval-driven metrics autosave task, restores persisted metrics at startup, writes atomically through the analytics store, and retains minute points for the 30-day MetricsStore contract. It does not maintain Python's separate scheduled five-minute, hourly, and daily deques; native analytics queries aggregate the retained minute series on demand.", + "rust_symbols": [ + "gateway-rs/src/main.rs::spawn_metrics_autosave", + "gateway-rs/src/main.rs::persist_metrics", + "gateway-rs/src/main.rs::restore_metrics", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/analytics_scheduler.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/analytics_scheduler.py::class:AnalyticsScheduler", + "notes": "Rust starts an interval-driven metrics autosave task, restores persisted metrics at startup, writes atomically through the analytics store, and retains minute points for the 30-day MetricsStore contract. It does not maintain Python's separate scheduled five-minute, hourly, and daily deques; native analytics queries aggregate the retained minute series on demand.", + "rust_symbols": [ + "gateway-rs/src/main.rs::spawn_metrics_autosave", + "gateway-rs/src/main.rs::persist_metrics", + "gateway-rs/src/main.rs::restore_metrics", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics" + ], + "source": { + "kind": "class", + "line": 22, + "path": "backend-services/utils/analytics_scheduler.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/analytics_scheduler.py::method:AnalyticsScheduler.__init__", + "notes": "Rust starts an interval-driven metrics autosave task, restores persisted metrics at startup, writes atomically through the analytics store, and retains minute points for the 30-day MetricsStore contract. It does not maintain Python's separate scheduled five-minute, hourly, and daily deques; native analytics queries aggregate the retained minute series on demand.", + "rust_symbols": [ + "gateway-rs/src/main.rs::spawn_metrics_autosave", + "gateway-rs/src/main.rs::persist_metrics", + "gateway-rs/src/main.rs::restore_metrics", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics" + ], + "source": { + "kind": "method", + "line": 34, + "path": "backend-services/utils/analytics_scheduler.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/analytics_scheduler.py::async_method:AnalyticsScheduler.start", + "notes": "Rust starts an interval-driven metrics autosave task, restores persisted metrics at startup, writes atomically through the analytics store, and retains minute points for the 30-day MetricsStore contract. It does not maintain Python's separate scheduled five-minute, hourly, and daily deques; native analytics queries aggregate the retained minute series on demand.", + "rust_symbols": [ + "gateway-rs/src/main.rs::spawn_metrics_autosave", + "gateway-rs/src/main.rs::persist_metrics", + "gateway-rs/src/main.rs::restore_metrics", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics" + ], + "source": { + "kind": "async_method", + "line": 43, + "path": "backend-services/utils/analytics_scheduler.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/analytics_scheduler.py::async_method:AnalyticsScheduler.stop", + "notes": "Rust starts an interval-driven metrics autosave task, restores persisted metrics at startup, writes atomically through the analytics store, and retains minute points for the 30-day MetricsStore contract. It does not maintain Python's separate scheduled five-minute, hourly, and daily deques; native analytics queries aggregate the retained minute series on demand.", + "rust_symbols": [ + "gateway-rs/src/main.rs::spawn_metrics_autosave", + "gateway-rs/src/main.rs::persist_metrics", + "gateway-rs/src/main.rs::restore_metrics", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics" + ], + "source": { + "kind": "async_method", + "line": 53, + "path": "backend-services/utils/analytics_scheduler.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/analytics_scheduler.py::async_method:AnalyticsScheduler._run_loop", + "notes": "Rust starts an interval-driven metrics autosave task, restores persisted metrics at startup, writes atomically through the analytics store, and retains minute points for the 30-day MetricsStore contract. It does not maintain Python's separate scheduled five-minute, hourly, and daily deques; native analytics queries aggregate the retained minute series on demand.", + "rust_symbols": [ + "gateway-rs/src/main.rs::spawn_metrics_autosave", + "gateway-rs/src/main.rs::persist_metrics", + "gateway-rs/src/main.rs::restore_metrics", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics" + ], + "source": { + "kind": "async_method", + "line": 68, + "path": "backend-services/utils/analytics_scheduler.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/analytics_scheduler.py::async_method:AnalyticsScheduler._check_and_run_jobs", + "notes": "Rust starts an interval-driven metrics autosave task, restores persisted metrics at startup, writes atomically through the analytics store, and retains minute points for the 30-day MetricsStore contract. It does not maintain Python's separate scheduled five-minute, hourly, and daily deques; native analytics queries aggregate the retained minute series on demand.", + "rust_symbols": [ + "gateway-rs/src/main.rs::spawn_metrics_autosave", + "gateway-rs/src/main.rs::persist_metrics", + "gateway-rs/src/main.rs::restore_metrics", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics" + ], + "source": { + "kind": "async_method", + "line": 81, + "path": "backend-services/utils/analytics_scheduler.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/analytics_scheduler.py::async_method:AnalyticsScheduler._run_5minute_aggregation", + "notes": "Rust starts an interval-driven metrics autosave task, restores persisted metrics at startup, writes atomically through the analytics store, and retains minute points for the 30-day MetricsStore contract. It does not maintain Python's separate scheduled five-minute, hourly, and daily deques; native analytics queries aggregate the retained minute series on demand.", + "rust_symbols": [ + "gateway-rs/src/main.rs::spawn_metrics_autosave", + "gateway-rs/src/main.rs::persist_metrics", + "gateway-rs/src/main.rs::restore_metrics", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics" + ], + "source": { + "kind": "async_method", + "line": 110, + "path": "backend-services/utils/analytics_scheduler.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/analytics_scheduler.py::async_method:AnalyticsScheduler._run_hourly_aggregation", + "notes": "Rust starts an interval-driven metrics autosave task, restores persisted metrics at startup, writes atomically through the analytics store, and retains minute points for the 30-day MetricsStore contract. It does not maintain Python's separate scheduled five-minute, hourly, and daily deques; native analytics queries aggregate the retained minute series on demand.", + "rust_symbols": [ + "gateway-rs/src/main.rs::spawn_metrics_autosave", + "gateway-rs/src/main.rs::persist_metrics", + "gateway-rs/src/main.rs::restore_metrics", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics" + ], + "source": { + "kind": "async_method", + "line": 130, + "path": "backend-services/utils/analytics_scheduler.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/analytics_scheduler.py::async_method:AnalyticsScheduler._run_daily_aggregation", + "notes": "Rust starts an interval-driven metrics autosave task, restores persisted metrics at startup, writes atomically through the analytics store, and retains minute points for the 30-day MetricsStore contract. It does not maintain Python's separate scheduled five-minute, hourly, and daily deques; native analytics queries aggregate the retained minute series on demand.", + "rust_symbols": [ + "gateway-rs/src/main.rs::spawn_metrics_autosave", + "gateway-rs/src/main.rs::persist_metrics", + "gateway-rs/src/main.rs::restore_metrics", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics" + ], + "source": { + "kind": "async_method", + "line": 144, + "path": "backend-services/utils/analytics_scheduler.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/analytics_scheduler.py::async_method:AnalyticsScheduler._persist_metrics", + "notes": "Rust starts an interval-driven metrics autosave task, restores persisted metrics at startup, writes atomically through the analytics store, and retains minute points for the 30-day MetricsStore contract. It does not maintain Python's separate scheduled five-minute, hourly, and daily deques; native analytics queries aggregate the retained minute series on demand.", + "rust_symbols": [ + "gateway-rs/src/main.rs::spawn_metrics_autosave", + "gateway-rs/src/main.rs::persist_metrics", + "gateway-rs/src/main.rs::restore_metrics", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics" + ], + "source": { + "kind": "async_method", + "line": 158, + "path": "backend-services/utils/analytics_scheduler.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/analytics_scheduler.py::async_method:AnalyticsScheduler._cleanup_old_data", + "notes": "Rust starts an interval-driven metrics autosave task, restores persisted metrics at startup, writes atomically through the analytics store, and retains minute points for the 30-day MetricsStore contract. It does not maintain Python's separate scheduled five-minute, hourly, and daily deques; native analytics queries aggregate the retained minute series on demand.", + "rust_symbols": [ + "gateway-rs/src/main.rs::spawn_metrics_autosave", + "gateway-rs/src/main.rs::persist_metrics", + "gateway-rs/src/main.rs::restore_metrics", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics" + ], + "source": { + "kind": "async_method", + "line": 186, + "path": "backend-services/utils/analytics_scheduler.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/api_resolution_util.py::module:api_resolution_util", + "notes": "The pinned module is dead production code, but native GraphQL and gRPC handlers implement required-version validation, API name/version policy paths, and storage resolution. Exact behavior for direct calls with nested or empty arbitrary path strings is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/graphql.rs::graphql_policy_then_execute", + "gateway-rs/src/routes/grpc.rs::grpc_policy_then_execute", + "gateway-rs/src/policy/evaluator.rs::evaluate_request" + ], + "rust_tests": [ + "gateway-rs/src/routes/grpc.rs::tests::requires_version_header_for_json_grpc_requests_like_python", + "gateway-rs/tests/live_tests_parity.rs::live_test_66_graphql_missing_version_header_parity" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/api_resolution_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/api_resolution_util.py::function:parse_graphql_grpc_path", + "notes": "The pinned module is dead production code, but native GraphQL and gRPC handlers implement required-version validation, API name/version policy paths, and storage resolution. Exact behavior for direct calls with nested or empty arbitrary path strings is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/graphql.rs::graphql_policy_then_execute", + "gateway-rs/src/routes/grpc.rs::grpc_policy_then_execute", + "gateway-rs/src/policy/evaluator.rs::evaluate_request" + ], + "rust_tests": [ + "gateway-rs/src/routes/grpc.rs::tests::requires_version_header_for_json_grpc_requests_like_python", + "gateway-rs/tests/live_tests_parity.rs::live_test_66_graphql_missing_version_header_parity" + ], + "source": { + "kind": "function", + "line": 15, + "path": "backend-services/utils/api_resolution_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/api_resolution_util.py::async_function:resolve_api", + "notes": "The pinned module is dead production code, but native GraphQL and gRPC handlers implement required-version validation, API name/version policy paths, and storage resolution. Exact behavior for direct calls with nested or empty arbitrary path strings is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/graphql.rs::graphql_policy_then_execute", + "gateway-rs/src/routes/grpc.rs::grpc_policy_then_execute", + "gateway-rs/src/policy/evaluator.rs::evaluate_request" + ], + "rust_tests": [ + "gateway-rs/src/routes/grpc.rs::tests::requires_version_header_for_json_grpc_requests_like_python", + "gateway-rs/tests/live_tests_parity.rs::live_test_66_graphql_missing_version_header_parity" + ], + "source": { + "kind": "async_function", + "line": 44, + "path": "backend-services/utils/api_resolution_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/api_resolution_util.py::async_function:resolve_api_from_request", + "notes": "The pinned module is dead production code, but native GraphQL and gRPC handlers implement required-version validation, API name/version policy paths, and storage resolution. Exact behavior for direct calls with nested or empty arbitrary path strings is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/graphql.rs::graphql_policy_then_execute", + "gateway-rs/src/routes/grpc.rs::grpc_policy_then_execute", + "gateway-rs/src/policy/evaluator.rs::evaluate_request" + ], + "rust_tests": [ + "gateway-rs/src/routes/grpc.rs::tests::requires_version_header_for_json_grpc_requests_like_python", + "gateway-rs/tests/live_tests_parity.rs::live_test_66_graphql_missing_version_header_parity" + ], + "source": { + "kind": "async_function", + "line": 59, + "path": "backend-services/utils/api_resolution_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/api_util.py::module:api_util", + "notes": "Rust policy document loading resolves APIs by name/version or ID, locates endpoint documents by client/endpoint URI, and maintains shared routing state. Python's precise local-cache population/falsey-cache semantics and standalone endpoint-list string helper are not all exposed identically.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.load_policy_documents", + "gateway-rs/src/policy/evaluator.rs::evaluate_request" + ], + "rust_tests": [ + "gateway-rs/tests/runtime.rs::rest_head_uses_a_registered_get_endpoint_like_python" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/api_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/api_util.py::async_function:get_api", + "notes": "Rust policy document loading resolves APIs by name/version or ID, locates endpoint documents by client/endpoint URI, and maintains shared routing state. Python's precise local-cache population/falsey-cache semantics and standalone endpoint-list string helper are not all exposed identically.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.load_policy_documents", + "gateway-rs/src/policy/evaluator.rs::evaluate_request" + ], + "rust_tests": [ + "gateway-rs/tests/runtime.rs::rest_head_uses_a_registered_get_endpoint_like_python" + ], + "source": { + "kind": "async_function", + "line": 6, + "path": "backend-services/utils/api_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/api_util.py::async_function:get_api_endpoints", + "notes": "Rust policy document loading resolves APIs by name/version or ID, locates endpoint documents by client/endpoint URI, and maintains shared routing state. Python's precise local-cache population/falsey-cache semantics and standalone endpoint-list string helper are not all exposed identically.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.load_policy_documents", + "gateway-rs/src/policy/evaluator.rs::evaluate_request" + ], + "rust_tests": [ + "gateway-rs/tests/runtime.rs::rest_head_uses_a_registered_get_endpoint_like_python" + ], + "source": { + "kind": "async_function", + "line": 34, + "path": "backend-services/utils/api_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/api_util.py::async_function:get_endpoint", + "notes": "Rust policy document loading resolves APIs by name/version or ID, locates endpoint documents by client/endpoint URI, and maintains shared routing state. Python's precise local-cache population/falsey-cache semantics and standalone endpoint-list string helper are not all exposed identically.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.load_policy_documents", + "gateway-rs/src/policy/evaluator.rs::evaluate_request" + ], + "rust_tests": [ + "gateway-rs/tests/runtime.rs::rest_head_uses_a_registered_get_endpoint_like_python" + ], + "source": { + "kind": "async_function", + "line": 57, + "path": "backend-services/utils/api_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/async_db.py::module:async_db", + "notes": "Rust storage calls are async at the SharedStorage boundary and expose native find-one/find-many/insert/update/delete operations across memory, MongoDB, and PostgreSQL backends. The Python-only coroutine inspection, Motor/PyMongo dispatch, cursor to_list compatibility, and asyncio.to_thread shim have no role after removal of Python database drivers.", + "rationale": "Language- and driver-specific async compatibility adapter made obsolete by Rust's typed async storage layer.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.find_many", + "gateway-rs/src/storage/runtime.rs::SharedStorage.find_one", + "gateway-rs/src/storage/runtime.rs::SharedStorage.insert_one", + "gateway-rs/src/storage/runtime.rs::SharedStorage.update_one", + "gateway-rs/src/storage/runtime.rs::SharedStorage.delete_one" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/async_db.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/async_db.py::async_function:_call_collection_method", + "notes": "Rust storage calls are async at the SharedStorage boundary and expose native find-one/find-many/insert/update/delete operations across memory, MongoDB, and PostgreSQL backends. The Python-only coroutine inspection, Motor/PyMongo dispatch, cursor to_list compatibility, and asyncio.to_thread shim have no role after removal of Python database drivers.", + "rationale": "Language- and driver-specific async compatibility adapter made obsolete by Rust's typed async storage layer.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.find_many", + "gateway-rs/src/storage/runtime.rs::SharedStorage.find_one", + "gateway-rs/src/storage/runtime.rs::SharedStorage.insert_one", + "gateway-rs/src/storage/runtime.rs::SharedStorage.update_one", + "gateway-rs/src/storage/runtime.rs::SharedStorage.delete_one" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart" + ], + "source": { + "kind": "async_function", + "line": 15, + "path": "backend-services/utils/async_db.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/async_db.py::async_function:_cursor_to_list", + "notes": "Rust storage calls are async at the SharedStorage boundary and expose native find-one/find-many/insert/update/delete operations across memory, MongoDB, and PostgreSQL backends. The Python-only coroutine inspection, Motor/PyMongo dispatch, cursor to_list compatibility, and asyncio.to_thread shim have no role after removal of Python database drivers.", + "rationale": "Language- and driver-specific async compatibility adapter made obsolete by Rust's typed async storage layer.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.find_many", + "gateway-rs/src/storage/runtime.rs::SharedStorage.find_one", + "gateway-rs/src/storage/runtime.rs::SharedStorage.insert_one", + "gateway-rs/src/storage/runtime.rs::SharedStorage.update_one", + "gateway-rs/src/storage/runtime.rs::SharedStorage.delete_one" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart" + ], + "source": { + "kind": "async_function", + "line": 35, + "path": "backend-services/utils/async_db.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/async_db.py::async_function:db_find_one", + "notes": "Rust storage calls are async at the SharedStorage boundary and expose native find-one/find-many/insert/update/delete operations across memory, MongoDB, and PostgreSQL backends. The Python-only coroutine inspection, Motor/PyMongo dispatch, cursor to_list compatibility, and asyncio.to_thread shim have no role after removal of Python database drivers.", + "rationale": "Language- and driver-specific async compatibility adapter made obsolete by Rust's typed async storage layer.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.find_many", + "gateway-rs/src/storage/runtime.rs::SharedStorage.find_one", + "gateway-rs/src/storage/runtime.rs::SharedStorage.insert_one", + "gateway-rs/src/storage/runtime.rs::SharedStorage.update_one", + "gateway-rs/src/storage/runtime.rs::SharedStorage.delete_one" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart" + ], + "source": { + "kind": "async_function", + "line": 50, + "path": "backend-services/utils/async_db.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/async_db.py::async_function:db_insert_one", + "notes": "Rust storage calls are async at the SharedStorage boundary and expose native find-one/find-many/insert/update/delete operations across memory, MongoDB, and PostgreSQL backends. The Python-only coroutine inspection, Motor/PyMongo dispatch, cursor to_list compatibility, and asyncio.to_thread shim have no role after removal of Python database drivers.", + "rationale": "Language- and driver-specific async compatibility adapter made obsolete by Rust's typed async storage layer.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.find_many", + "gateway-rs/src/storage/runtime.rs::SharedStorage.find_one", + "gateway-rs/src/storage/runtime.rs::SharedStorage.insert_one", + "gateway-rs/src/storage/runtime.rs::SharedStorage.update_one", + "gateway-rs/src/storage/runtime.rs::SharedStorage.delete_one" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart" + ], + "source": { + "kind": "async_function", + "line": 54, + "path": "backend-services/utils/async_db.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/async_db.py::async_function:db_update_one", + "notes": "Rust storage calls are async at the SharedStorage boundary and expose native find-one/find-many/insert/update/delete operations across memory, MongoDB, and PostgreSQL backends. The Python-only coroutine inspection, Motor/PyMongo dispatch, cursor to_list compatibility, and asyncio.to_thread shim have no role after removal of Python database drivers.", + "rationale": "Language- and driver-specific async compatibility adapter made obsolete by Rust's typed async storage layer.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.find_many", + "gateway-rs/src/storage/runtime.rs::SharedStorage.find_one", + "gateway-rs/src/storage/runtime.rs::SharedStorage.insert_one", + "gateway-rs/src/storage/runtime.rs::SharedStorage.update_one", + "gateway-rs/src/storage/runtime.rs::SharedStorage.delete_one" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart" + ], + "source": { + "kind": "async_function", + "line": 58, + "path": "backend-services/utils/async_db.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/async_db.py::async_function:db_delete_one", + "notes": "Rust storage calls are async at the SharedStorage boundary and expose native find-one/find-many/insert/update/delete operations across memory, MongoDB, and PostgreSQL backends. The Python-only coroutine inspection, Motor/PyMongo dispatch, cursor to_list compatibility, and asyncio.to_thread shim have no role after removal of Python database drivers.", + "rationale": "Language- and driver-specific async compatibility adapter made obsolete by Rust's typed async storage layer.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.find_many", + "gateway-rs/src/storage/runtime.rs::SharedStorage.find_one", + "gateway-rs/src/storage/runtime.rs::SharedStorage.insert_one", + "gateway-rs/src/storage/runtime.rs::SharedStorage.update_one", + "gateway-rs/src/storage/runtime.rs::SharedStorage.delete_one" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart" + ], + "source": { + "kind": "async_function", + "line": 62, + "path": "backend-services/utils/async_db.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/async_db.py::async_function:db_find_list", + "notes": "Rust storage calls are async at the SharedStorage boundary and expose native find-one/find-many/insert/update/delete operations across memory, MongoDB, and PostgreSQL backends. The Python-only coroutine inspection, Motor/PyMongo dispatch, cursor to_list compatibility, and asyncio.to_thread shim have no role after removal of Python database drivers.", + "rationale": "Language- and driver-specific async compatibility adapter made obsolete by Rust's typed async storage layer.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.find_many", + "gateway-rs/src/storage/runtime.rs::SharedStorage.find_one", + "gateway-rs/src/storage/runtime.rs::SharedStorage.insert_one", + "gateway-rs/src/storage/runtime.rs::SharedStorage.update_one", + "gateway-rs/src/storage/runtime.rs::SharedStorage.delete_one" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart" + ], + "source": { + "kind": "async_function", + "line": 66, + "path": "backend-services/utils/async_db.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/async_db.py::async_function:db_aggregate_list", + "notes": "Rust storage calls are async at the SharedStorage boundary and expose native find-one/find-many/insert/update/delete operations across memory, MongoDB, and PostgreSQL backends. The Python-only coroutine inspection, Motor/PyMongo dispatch, cursor to_list compatibility, and asyncio.to_thread shim have no role after removal of Python database drivers.", + "rationale": "Language- and driver-specific async compatibility adapter made obsolete by Rust's typed async storage layer.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.find_many", + "gateway-rs/src/storage/runtime.rs::SharedStorage.find_one", + "gateway-rs/src/storage/runtime.rs::SharedStorage.insert_one", + "gateway-rs/src/storage/runtime.rs::SharedStorage.update_one", + "gateway-rs/src/storage/runtime.rs::SharedStorage.delete_one" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart" + ], + "source": { + "kind": "async_function", + "line": 82, + "path": "backend-services/utils/async_db.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/async_db.py::async_function:db_find_paginated", + "notes": "Rust storage calls are async at the SharedStorage boundary and expose native find-one/find-many/insert/update/delete operations across memory, MongoDB, and PostgreSQL backends. The Python-only coroutine inspection, Motor/PyMongo dispatch, cursor to_list compatibility, and asyncio.to_thread shim have no role after removal of Python database drivers.", + "rationale": "Language- and driver-specific async compatibility adapter made obsolete by Rust's typed async storage layer.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.find_many", + "gateway-rs/src/storage/runtime.rs::SharedStorage.find_one", + "gateway-rs/src/storage/runtime.rs::SharedStorage.insert_one", + "gateway-rs/src/storage/runtime.rs::SharedStorage.update_one", + "gateway-rs/src/storage/runtime.rs::SharedStorage.delete_one" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart" + ], + "source": { + "kind": "async_function", + "line": 91, + "path": "backend-services/utils/async_db.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/async_db.py::function:db_find_paginated._build_cursor", + "notes": "Rust storage calls are async at the SharedStorage boundary and expose native find-one/find-many/insert/update/delete operations across memory, MongoDB, and PostgreSQL backends. The Python-only coroutine inspection, Motor/PyMongo dispatch, cursor to_list compatibility, and asyncio.to_thread shim have no role after removal of Python database drivers.", + "rationale": "Language- and driver-specific async compatibility adapter made obsolete by Rust's typed async storage layer.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.find_many", + "gateway-rs/src/storage/runtime.rs::SharedStorage.find_one", + "gateway-rs/src/storage/runtime.rs::SharedStorage.insert_one", + "gateway-rs/src/storage/runtime.rs::SharedStorage.update_one", + "gateway-rs/src/storage/runtime.rs::SharedStorage.delete_one" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart" + ], + "source": { + "kind": "function", + "line": 103, + "path": "backend-services/utils/async_db.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/async_db.py::async_function:db_count", + "notes": "Rust storage calls are async at the SharedStorage boundary and expose native find-one/find-many/insert/update/delete operations across memory, MongoDB, and PostgreSQL backends. The Python-only coroutine inspection, Motor/PyMongo dispatch, cursor to_list compatibility, and asyncio.to_thread shim have no role after removal of Python database drivers.", + "rationale": "Language- and driver-specific async compatibility adapter made obsolete by Rust's typed async storage layer.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.find_many", + "gateway-rs/src/storage/runtime.rs::SharedStorage.find_one", + "gateway-rs/src/storage/runtime.rs::SharedStorage.insert_one", + "gateway-rs/src/storage/runtime.rs::SharedStorage.update_one", + "gateway-rs/src/storage/runtime.rs::SharedStorage.delete_one" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart" + ], + "source": { + "kind": "async_function", + "line": 131, + "path": "backend-services/utils/async_db.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/async_db.py::async_function:db_delete_many", + "notes": "Rust storage calls are async at the SharedStorage boundary and expose native find-one/find-many/insert/update/delete operations across memory, MongoDB, and PostgreSQL backends. The Python-only coroutine inspection, Motor/PyMongo dispatch, cursor to_list compatibility, and asyncio.to_thread shim have no role after removal of Python database drivers.", + "rationale": "Language- and driver-specific async compatibility adapter made obsolete by Rust's typed async storage layer.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.find_many", + "gateway-rs/src/storage/runtime.rs::SharedStorage.find_one", + "gateway-rs/src/storage/runtime.rs::SharedStorage.insert_one", + "gateway-rs/src/storage/runtime.rs::SharedStorage.update_one", + "gateway-rs/src/storage/runtime.rs::SharedStorage.delete_one" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart" + ], + "source": { + "kind": "async_function", + "line": 143, + "path": "backend-services/utils/async_db.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/async_db.py::async_function:db_insert_many", + "notes": "Rust storage calls are async at the SharedStorage boundary and expose native find-one/find-many/insert/update/delete operations across memory, MongoDB, and PostgreSQL backends. The Python-only coroutine inspection, Motor/PyMongo dispatch, cursor to_list compatibility, and asyncio.to_thread shim have no role after removal of Python database drivers.", + "rationale": "Language- and driver-specific async compatibility adapter made obsolete by Rust's typed async storage layer.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.find_many", + "gateway-rs/src/storage/runtime.rs::SharedStorage.find_one", + "gateway-rs/src/storage/runtime.rs::SharedStorage.insert_one", + "gateway-rs/src/storage/runtime.rs::SharedStorage.update_one", + "gateway-rs/src/storage/runtime.rs::SharedStorage.delete_one" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart" + ], + "source": { + "kind": "async_function", + "line": 147, + "path": "backend-services/utils/async_db.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/audit_util.py::module:audit_util", + "notes": "Rust emits structured management and IP audit events and now matches Python's recursive sensitive-key exception rules plus JWT, authorization, API-key, hex, and private-key value redaction. Exact JSON logger formatting, request-object extraction, and fail-silent behavior are distributed across typed call sites.", + "rust_symbols": [ + "gateway-rs/src/observability/audit.rs::redact_record", + "gateway-rs/src/observability/audit.rs::management_mutation", + "gateway-rs/src/observability/audit.rs::global_ip_deny" + ], + "rust_tests": [ + "gateway-rs/src/observability/audit.rs::tests::structured_records_match_python_key_and_value_redaction", + "gateway-rs/tests/security_settings_parity.rs::log_export_filters_records_and_redacts_nested_credentials" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/audit_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/audit_util.py::function:_is_sensitive_key", + "notes": "Rust emits structured management and IP audit events and now matches Python's recursive sensitive-key exception rules plus JWT, authorization, API-key, hex, and private-key value redaction. Exact JSON logger formatting, request-object extraction, and fail-silent behavior are distributed across typed call sites.", + "rust_symbols": [ + "gateway-rs/src/observability/audit.rs::redact_record", + "gateway-rs/src/observability/audit.rs::management_mutation", + "gateway-rs/src/observability/audit.rs::global_ip_deny" + ], + "rust_tests": [ + "gateway-rs/src/observability/audit.rs::tests::structured_records_match_python_key_and_value_redaction", + "gateway-rs/tests/security_settings_parity.rs::log_export_filters_records_and_redacts_nested_credentials" + ], + "source": { + "kind": "function", + "line": 82, + "path": "backend-services/utils/audit_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/audit_util.py::function:_is_sensitive_value", + "notes": "Rust emits structured management and IP audit events and now matches Python's recursive sensitive-key exception rules plus JWT, authorization, API-key, hex, and private-key value redaction. Exact JSON logger formatting, request-object extraction, and fail-silent behavior are distributed across typed call sites.", + "rust_symbols": [ + "gateway-rs/src/observability/audit.rs::redact_record", + "gateway-rs/src/observability/audit.rs::management_mutation", + "gateway-rs/src/observability/audit.rs::global_ip_deny" + ], + "rust_tests": [ + "gateway-rs/src/observability/audit.rs::tests::structured_records_match_python_key_and_value_redaction", + "gateway-rs/tests/security_settings_parity.rs::log_export_filters_records_and_redacts_nested_credentials" + ], + "source": { + "kind": "function", + "line": 96, + "path": "backend-services/utils/audit_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/audit_util.py::function:_sanitize", + "notes": "Rust emits structured management and IP audit events and now matches Python's recursive sensitive-key exception rules plus JWT, authorization, API-key, hex, and private-key value redaction. Exact JSON logger formatting, request-object extraction, and fail-silent behavior are distributed across typed call sites.", + "rust_symbols": [ + "gateway-rs/src/observability/audit.rs::redact_record", + "gateway-rs/src/observability/audit.rs::management_mutation", + "gateway-rs/src/observability/audit.rs::global_ip_deny" + ], + "rust_tests": [ + "gateway-rs/src/observability/audit.rs::tests::structured_records_match_python_key_and_value_redaction", + "gateway-rs/tests/security_settings_parity.rs::log_export_filters_records_and_redacts_nested_credentials" + ], + "source": { + "kind": "function", + "line": 106, + "path": "backend-services/utils/audit_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/audit_util.py::function:audit", + "notes": "Rust emits structured management and IP audit events and now matches Python's recursive sensitive-key exception rules plus JWT, authorization, API-key, hex, and private-key value redaction. Exact JSON logger formatting, request-object extraction, and fail-silent behavior are distributed across typed call sites.", + "rust_symbols": [ + "gateway-rs/src/observability/audit.rs::redact_record", + "gateway-rs/src/observability/audit.rs::management_mutation", + "gateway-rs/src/observability/audit.rs::global_ip_deny" + ], + "rust_tests": [ + "gateway-rs/src/observability/audit.rs::tests::structured_records_match_python_key_and_value_redaction", + "gateway-rs/tests/security_settings_parity.rs::log_export_filters_records_and_redacts_nested_credentials" + ], + "source": { + "kind": "function", + "line": 134, + "path": "backend-services/utils/audit_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/auth_blacklist.py::module:auth_blacklist", + "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery. Native bulk purge currently preserves malformed or missing-expiry JTI rows in external storage even though request-time checks safely ignore them.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::is_revoked", + "gateway-rs/src/routes/platform.rs::authorize", + "gateway-rs/src/storage/runtime.rs::SharedStorage.purge_expired_revocations", + "gateway-rs/src/main.rs::run_revocation_purge" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::expired_or_malformed_jti_revocations_do_not_block_requests", + "gateway-rs/tests/platform_native.rs::authorization_admin_lifecycle_and_revoke_match_python", + "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/auth_blacklist.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/auth_blacklist.py::function:_init_redis_if_possible", + "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery. Native bulk purge currently preserves malformed or missing-expiry JTI rows in external storage even though request-time checks safely ignore them.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::is_revoked", + "gateway-rs/src/routes/platform.rs::authorize", + "gateway-rs/src/storage/runtime.rs::SharedStorage.purge_expired_revocations", + "gateway-rs/src/main.rs::run_revocation_purge" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::expired_or_malformed_jti_revocations_do_not_block_requests", + "gateway-rs/tests/platform_native.rs::authorization_admin_lifecycle_and_revoke_match_python", + "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all" + ], + "source": { + "kind": "function", + "line": 70, + "path": "backend-services/utils/auth_blacklist.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/auth_blacklist.py::function:_revoked_jti_key", + "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery. Native bulk purge currently preserves malformed or missing-expiry JTI rows in external storage even though request-time checks safely ignore them.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::is_revoked", + "gateway-rs/src/routes/platform.rs::authorize", + "gateway-rs/src/storage/runtime.rs::SharedStorage.purge_expired_revocations", + "gateway-rs/src/main.rs::run_revocation_purge" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::expired_or_malformed_jti_revocations_do_not_block_requests", + "gateway-rs/tests/platform_native.rs::authorization_admin_lifecycle_and_revoke_match_python", + "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all" + ], + "source": { + "kind": "function", + "line": 102, + "path": "backend-services/utils/auth_blacklist.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/auth_blacklist.py::function:_revoke_all_key", + "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery. Native bulk purge currently preserves malformed or missing-expiry JTI rows in external storage even though request-time checks safely ignore them.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::is_revoked", + "gateway-rs/src/routes/platform.rs::authorize", + "gateway-rs/src/storage/runtime.rs::SharedStorage.purge_expired_revocations", + "gateway-rs/src/main.rs::run_revocation_purge" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::expired_or_malformed_jti_revocations_do_not_block_requests", + "gateway-rs/tests/platform_native.rs::authorization_admin_lifecycle_and_revoke_match_python", + "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all" + ], + "source": { + "kind": "function", + "line": 106, + "path": "backend-services/utils/auth_blacklist.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/auth_blacklist.py::function:revoke_all_for_user", + "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery. Native bulk purge currently preserves malformed or missing-expiry JTI rows in external storage even though request-time checks safely ignore them.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::is_revoked", + "gateway-rs/src/routes/platform.rs::authorize", + "gateway-rs/src/storage/runtime.rs::SharedStorage.purge_expired_revocations", + "gateway-rs/src/main.rs::run_revocation_purge" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::expired_or_malformed_jti_revocations_do_not_block_requests", + "gateway-rs/tests/platform_native.rs::authorization_admin_lifecycle_and_revoke_match_python", + "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all" + ], + "source": { + "kind": "function", + "line": 110, + "path": "backend-services/utils/auth_blacklist.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/auth_blacklist.py::function:unrevoke_all_for_user", + "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery. Native bulk purge currently preserves malformed or missing-expiry JTI rows in external storage even though request-time checks safely ignore them.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::is_revoked", + "gateway-rs/src/routes/platform.rs::authorize", + "gateway-rs/src/storage/runtime.rs::SharedStorage.purge_expired_revocations", + "gateway-rs/src/main.rs::run_revocation_purge" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::expired_or_malformed_jti_revocations_do_not_block_requests", + "gateway-rs/tests/platform_native.rs::authorization_admin_lifecycle_and_revoke_match_python", + "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all" + ], + "source": { + "kind": "function", + "line": 142, + "path": "backend-services/utils/auth_blacklist.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/auth_blacklist.py::function:is_user_revoked", + "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery. Native bulk purge currently preserves malformed or missing-expiry JTI rows in external storage even though request-time checks safely ignore them.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::is_revoked", + "gateway-rs/src/routes/platform.rs::authorize", + "gateway-rs/src/storage/runtime.rs::SharedStorage.purge_expired_revocations", + "gateway-rs/src/main.rs::run_revocation_purge" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::expired_or_malformed_jti_revocations_do_not_block_requests", + "gateway-rs/tests/platform_native.rs::authorization_admin_lifecycle_and_revoke_match_python", + "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all" + ], + "source": { + "kind": "function", + "line": 164, + "path": "backend-services/utils/auth_blacklist.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/auth_blacklist.py::class:TimedHeap", + "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery. Native bulk purge currently preserves malformed or missing-expiry JTI rows in external storage even though request-time checks safely ignore them.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::is_revoked", + "gateway-rs/src/routes/platform.rs::authorize", + "gateway-rs/src/storage/runtime.rs::SharedStorage.purge_expired_revocations", + "gateway-rs/src/main.rs::run_revocation_purge" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::expired_or_malformed_jti_revocations_do_not_block_requests", + "gateway-rs/tests/platform_native.rs::authorization_admin_lifecycle_and_revoke_match_python", + "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all" + ], + "source": { + "kind": "class", + "line": 185, + "path": "backend-services/utils/auth_blacklist.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/auth_blacklist.py::method:TimedHeap.__init__", + "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery. Native bulk purge currently preserves malformed or missing-expiry JTI rows in external storage even though request-time checks safely ignore them.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::is_revoked", + "gateway-rs/src/routes/platform.rs::authorize", + "gateway-rs/src/storage/runtime.rs::SharedStorage.purge_expired_revocations", + "gateway-rs/src/main.rs::run_revocation_purge" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::expired_or_malformed_jti_revocations_do_not_block_requests", + "gateway-rs/tests/platform_native.rs::authorization_admin_lifecycle_and_revoke_match_python", + "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all" + ], + "source": { + "kind": "method", + "line": 186, + "path": "backend-services/utils/auth_blacklist.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/auth_blacklist.py::method:TimedHeap.push", + "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery. Native bulk purge currently preserves malformed or missing-expiry JTI rows in external storage even though request-time checks safely ignore them.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::is_revoked", + "gateway-rs/src/routes/platform.rs::authorize", + "gateway-rs/src/storage/runtime.rs::SharedStorage.purge_expired_revocations", + "gateway-rs/src/main.rs::run_revocation_purge" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::expired_or_malformed_jti_revocations_do_not_block_requests", + "gateway-rs/tests/platform_native.rs::authorization_admin_lifecycle_and_revoke_match_python", + "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all" + ], + "source": { + "kind": "method", + "line": 190, + "path": "backend-services/utils/auth_blacklist.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/auth_blacklist.py::method:TimedHeap.pop", + "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery. Native bulk purge currently preserves malformed or missing-expiry JTI rows in external storage even though request-time checks safely ignore them.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::is_revoked", + "gateway-rs/src/routes/platform.rs::authorize", + "gateway-rs/src/storage/runtime.rs::SharedStorage.purge_expired_revocations", + "gateway-rs/src/main.rs::run_revocation_purge" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::expired_or_malformed_jti_revocations_do_not_block_requests", + "gateway-rs/tests/platform_native.rs::authorization_admin_lifecycle_and_revoke_match_python", + "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all" + ], + "source": { + "kind": "method", + "line": 194, + "path": "backend-services/utils/auth_blacklist.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/auth_blacklist.py::method:TimedHeap.purge", + "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery. Native bulk purge currently preserves malformed or missing-expiry JTI rows in external storage even though request-time checks safely ignore them.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::is_revoked", + "gateway-rs/src/routes/platform.rs::authorize", + "gateway-rs/src/storage/runtime.rs::SharedStorage.purge_expired_revocations", + "gateway-rs/src/main.rs::run_revocation_purge" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::expired_or_malformed_jti_revocations_do_not_block_requests", + "gateway-rs/tests/platform_native.rs::authorization_admin_lifecycle_and_revoke_match_python", + "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all" + ], + "source": { + "kind": "method", + "line": 200, + "path": "backend-services/utils/auth_blacklist.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/auth_blacklist.py::method:TimedHeap.peek", + "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery. Native bulk purge currently preserves malformed or missing-expiry JTI rows in external storage even though request-time checks safely ignore them.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::is_revoked", + "gateway-rs/src/routes/platform.rs::authorize", + "gateway-rs/src/storage/runtime.rs::SharedStorage.purge_expired_revocations", + "gateway-rs/src/main.rs::run_revocation_purge" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::expired_or_malformed_jti_revocations_do_not_block_requests", + "gateway-rs/tests/platform_native.rs::authorization_admin_lifecycle_and_revoke_match_python", + "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all" + ], + "source": { + "kind": "method", + "line": 205, + "path": "backend-services/utils/auth_blacklist.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/auth_blacklist.py::function:add_revoked_jti", + "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery. Native bulk purge currently preserves malformed or missing-expiry JTI rows in external storage even though request-time checks safely ignore them.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::is_revoked", + "gateway-rs/src/routes/platform.rs::authorize", + "gateway-rs/src/storage/runtime.rs::SharedStorage.purge_expired_revocations", + "gateway-rs/src/main.rs::run_revocation_purge" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::expired_or_malformed_jti_revocations_do_not_block_requests", + "gateway-rs/tests/platform_native.rs::authorization_admin_lifecycle_and_revoke_match_python", + "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all" + ], + "source": { + "kind": "function", + "line": 212, + "path": "backend-services/utils/auth_blacklist.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/auth_blacklist.py::function:is_jti_revoked", + "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery. Native bulk purge currently preserves malformed or missing-expiry JTI rows in external storage even though request-time checks safely ignore them.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::is_revoked", + "gateway-rs/src/routes/platform.rs::authorize", + "gateway-rs/src/storage/runtime.rs::SharedStorage.purge_expired_revocations", + "gateway-rs/src/main.rs::run_revocation_purge" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::expired_or_malformed_jti_revocations_do_not_block_requests", + "gateway-rs/tests/platform_native.rs::authorization_admin_lifecycle_and_revoke_match_python", + "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all" + ], + "source": { + "kind": "function", + "line": 258, + "path": "backend-services/utils/auth_blacklist.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/auth_blacklist.py::async_function:purge_expired_tokens", + "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery. Native bulk purge currently preserves malformed or missing-expiry JTI rows in external storage even though request-time checks safely ignore them.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::is_revoked", + "gateway-rs/src/routes/platform.rs::authorize", + "gateway-rs/src/storage/runtime.rs::SharedStorage.purge_expired_revocations", + "gateway-rs/src/main.rs::run_revocation_purge" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::expired_or_malformed_jti_revocations_do_not_block_requests", + "gateway-rs/tests/platform_native.rs::authorization_admin_lifecycle_and_revoke_match_python", + "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all" + ], + "source": { + "kind": "async_function", + "line": 298, + "path": "backend-services/utils/auth_blacklist.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/auth_util.py::module:auth_util", + "notes": "Rust implements JWT configuration detection, positive expiry parsing and unit aliases, CSRF double-submit/cache fallback, cookie and bearer extraction, kid-based key selection, signature/claim/revocation/user checks, active-user enforcement, permission claims, UUID jti, and access/refresh expiry. Some backend-outage detail mappings, testserver HTTPS heuristics, and legacy helper return conventions remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/policy/auth.rs::verify_request_token", + "gateway-rs/src/routes/platform.rs::login", + "gateway-rs/src/routes/platform.rs::auth_expiry_seconds", + "gateway-rs/src/routes/platform.rs::refresh_expiry_seconds", + "gateway-rs/src/routes/operations.rs::require_manage_gateway" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::authorization_refresh_and_invalidate_match_python", + "gateway-rs/tests/platform_native.rs::https_mode_requires_matching_csrf_and_preserves_request_id" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/auth_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/auth_util.py::function:is_jwt_configured", + "notes": "Rust implements JWT configuration detection, positive expiry parsing and unit aliases, CSRF double-submit/cache fallback, cookie and bearer extraction, kid-based key selection, signature/claim/revocation/user checks, active-user enforcement, permission claims, UUID jti, and access/refresh expiry. Some backend-outage detail mappings, testserver HTTPS heuristics, and legacy helper return conventions remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/policy/auth.rs::verify_request_token", + "gateway-rs/src/routes/platform.rs::login", + "gateway-rs/src/routes/platform.rs::auth_expiry_seconds", + "gateway-rs/src/routes/platform.rs::refresh_expiry_seconds", + "gateway-rs/src/routes/operations.rs::require_manage_gateway" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::authorization_refresh_and_invalidate_match_python", + "gateway-rs/tests/platform_native.rs::https_mode_requires_matching_csrf_and_preserves_request_id" + ], + "source": { + "kind": "function", + "line": 35, + "path": "backend-services/utils/auth_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/auth_util.py::function:_read_int_env", + "notes": "Rust implements JWT configuration detection, positive expiry parsing and unit aliases, CSRF double-submit/cache fallback, cookie and bearer extraction, kid-based key selection, signature/claim/revocation/user checks, active-user enforcement, permission claims, UUID jti, and access/refresh expiry. Some backend-outage detail mappings, testserver HTTPS heuristics, and legacy helper return conventions remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/policy/auth.rs::verify_request_token", + "gateway-rs/src/routes/platform.rs::login", + "gateway-rs/src/routes/platform.rs::auth_expiry_seconds", + "gateway-rs/src/routes/platform.rs::refresh_expiry_seconds", + "gateway-rs/src/routes/operations.rs::require_manage_gateway" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::authorization_refresh_and_invalidate_match_python", + "gateway-rs/tests/platform_native.rs::https_mode_requires_matching_csrf_and_preserves_request_id" + ], + "source": { + "kind": "function", + "line": 40, + "path": "backend-services/utils/auth_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/auth_util.py::function:_normalize_unit", + "notes": "Rust implements JWT configuration detection, positive expiry parsing and unit aliases, CSRF double-submit/cache fallback, cookie and bearer extraction, kid-based key selection, signature/claim/revocation/user checks, active-user enforcement, permission claims, UUID jti, and access/refresh expiry. Some backend-outage detail mappings, testserver HTTPS heuristics, and legacy helper return conventions remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/policy/auth.rs::verify_request_token", + "gateway-rs/src/routes/platform.rs::login", + "gateway-rs/src/routes/platform.rs::auth_expiry_seconds", + "gateway-rs/src/routes/platform.rs::refresh_expiry_seconds", + "gateway-rs/src/routes/operations.rs::require_manage_gateway" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::authorization_refresh_and_invalidate_match_python", + "gateway-rs/tests/platform_native.rs::https_mode_requires_matching_csrf_and_preserves_request_id" + ], + "source": { + "kind": "function", + "line": 55, + "path": "backend-services/utils/auth_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/auth_util.py::function:_expiry_from_env", + "notes": "Rust implements JWT configuration detection, positive expiry parsing and unit aliases, CSRF double-submit/cache fallback, cookie and bearer extraction, kid-based key selection, signature/claim/revocation/user checks, active-user enforcement, permission claims, UUID jti, and access/refresh expiry. Some backend-outage detail mappings, testserver HTTPS heuristics, and legacy helper return conventions remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/policy/auth.rs::verify_request_token", + "gateway-rs/src/routes/platform.rs::login", + "gateway-rs/src/routes/platform.rs::auth_expiry_seconds", + "gateway-rs/src/routes/platform.rs::refresh_expiry_seconds", + "gateway-rs/src/routes/operations.rs::require_manage_gateway" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::authorization_refresh_and_invalidate_match_python", + "gateway-rs/tests/platform_native.rs::https_mode_requires_matching_csrf_and_preserves_request_id" + ], + "source": { + "kind": "function", + "line": 81, + "path": "backend-services/utils/auth_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/auth_util.py::async_function:validate_csrf_double_submit", + "notes": "Rust implements JWT configuration detection, positive expiry parsing and unit aliases, CSRF double-submit/cache fallback, cookie and bearer extraction, kid-based key selection, signature/claim/revocation/user checks, active-user enforcement, permission claims, UUID jti, and access/refresh expiry. Some backend-outage detail mappings, testserver HTTPS heuristics, and legacy helper return conventions remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/policy/auth.rs::verify_request_token", + "gateway-rs/src/routes/platform.rs::login", + "gateway-rs/src/routes/platform.rs::auth_expiry_seconds", + "gateway-rs/src/routes/platform.rs::refresh_expiry_seconds", + "gateway-rs/src/routes/operations.rs::require_manage_gateway" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::authorization_refresh_and_invalidate_match_python", + "gateway-rs/tests/platform_native.rs::https_mode_requires_matching_csrf_and_preserves_request_id" + ], + "source": { + "kind": "async_function", + "line": 95, + "path": "backend-services/utils/auth_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/auth_util.py::function:_get_secret_key", + "notes": "Rust implements JWT configuration detection, positive expiry parsing and unit aliases, CSRF double-submit/cache fallback, cookie and bearer extraction, kid-based key selection, signature/claim/revocation/user checks, active-user enforcement, permission claims, UUID jti, and access/refresh expiry. Some backend-outage detail mappings, testserver HTTPS heuristics, and legacy helper return conventions remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/policy/auth.rs::verify_request_token", + "gateway-rs/src/routes/platform.rs::login", + "gateway-rs/src/routes/platform.rs::auth_expiry_seconds", + "gateway-rs/src/routes/platform.rs::refresh_expiry_seconds", + "gateway-rs/src/routes/operations.rs::require_manage_gateway" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::authorization_refresh_and_invalidate_match_python", + "gateway-rs/tests/platform_native.rs::https_mode_requires_matching_csrf_and_preserves_request_id" + ], + "source": { + "kind": "function", + "line": 105, + "path": "backend-services/utils/auth_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/auth_util.py::async_function:auth_required", + "notes": "Rust implements JWT configuration detection, positive expiry parsing and unit aliases, CSRF double-submit/cache fallback, cookie and bearer extraction, kid-based key selection, signature/claim/revocation/user checks, active-user enforcement, permission claims, UUID jti, and access/refresh expiry. Some backend-outage detail mappings, testserver HTTPS heuristics, and legacy helper return conventions remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/policy/auth.rs::verify_request_token", + "gateway-rs/src/routes/platform.rs::login", + "gateway-rs/src/routes/platform.rs::auth_expiry_seconds", + "gateway-rs/src/routes/platform.rs::refresh_expiry_seconds", + "gateway-rs/src/routes/operations.rs::require_manage_gateway" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::authorization_refresh_and_invalidate_match_python", + "gateway-rs/tests/platform_native.rs::https_mode_requires_matching_csrf_and_preserves_request_id" + ], + "source": { + "kind": "async_function", + "line": 111, + "path": "backend-services/utils/auth_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/auth_util.py::function:create_access_token", + "notes": "Rust implements JWT configuration detection, positive expiry parsing and unit aliases, CSRF double-submit/cache fallback, cookie and bearer extraction, kid-based key selection, signature/claim/revocation/user checks, active-user enforcement, permission claims, UUID jti, and access/refresh expiry. Some backend-outage detail mappings, testserver HTTPS heuristics, and legacy helper return conventions remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/policy/auth.rs::verify_request_token", + "gateway-rs/src/routes/platform.rs::login", + "gateway-rs/src/routes/platform.rs::auth_expiry_seconds", + "gateway-rs/src/routes/platform.rs::refresh_expiry_seconds", + "gateway-rs/src/routes/operations.rs::require_manage_gateway" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::authorization_refresh_and_invalidate_match_python", + "gateway-rs/tests/platform_native.rs::https_mode_requires_matching_csrf_and_preserves_request_id" + ], + "source": { + "kind": "function", + "line": 258, + "path": "backend-services/utils/auth_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/bandwidth_util.py::module:bandwidth_util", + "notes": "Rust preserves window aliases/defaults, bucket keys, shared current usage, request-plus-response byte accounting, disabled/zero/missing-user bypass, and the pinned used-at-limit or content-length-over-limit 429 boundary. Storage failures are fail-closed in native external mode rather than Python's best-effort local fallback.", + "rust_symbols": [ + "gateway-rs/src/storage/redis.rs::bandwidth_key", + "gateway-rs/src/policy/bandwidth.rs::enforce_pre_request_limit", + "gateway-rs/src/policy/evaluator.rs::evaluate_request", + "gateway-rs/src/routes/rest.rs::proxy_request" + ], + "rust_tests": [ + "gateway-rs/src/policy/bandwidth.rs::tests::python_bandwidth_limit_blocks_after_usage_reaches_limit", + "gateway-rs/src/policy/bandwidth.rs::tests::python_bandwidth_limit_resets_in_the_next_window" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/bandwidth_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/bandwidth_util.py::function:_window_to_seconds", + "notes": "Rust preserves window aliases/defaults, bucket keys, shared current usage, request-plus-response byte accounting, disabled/zero/missing-user bypass, and the pinned used-at-limit or content-length-over-limit 429 boundary. Storage failures are fail-closed in native external mode rather than Python's best-effort local fallback.", + "rust_symbols": [ + "gateway-rs/src/storage/redis.rs::bandwidth_key", + "gateway-rs/src/policy/bandwidth.rs::enforce_pre_request_limit", + "gateway-rs/src/policy/evaluator.rs::evaluate_request", + "gateway-rs/src/routes/rest.rs::proxy_request" + ], + "rust_tests": [ + "gateway-rs/src/policy/bandwidth.rs::tests::python_bandwidth_limit_blocks_after_usage_reaches_limit", + "gateway-rs/src/policy/bandwidth.rs::tests::python_bandwidth_limit_resets_in_the_next_window" + ], + "source": { + "kind": "function", + "line": 11, + "path": "backend-services/utils/bandwidth_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/bandwidth_util.py::function:_bucket_key", + "notes": "Rust preserves window aliases/defaults, bucket keys, shared current usage, request-plus-response byte accounting, disabled/zero/missing-user bypass, and the pinned used-at-limit or content-length-over-limit 429 boundary. Storage failures are fail-closed in native external mode rather than Python's best-effort local fallback.", + "rust_symbols": [ + "gateway-rs/src/storage/redis.rs::bandwidth_key", + "gateway-rs/src/policy/bandwidth.rs::enforce_pre_request_limit", + "gateway-rs/src/policy/evaluator.rs::evaluate_request", + "gateway-rs/src/routes/rest.rs::proxy_request" + ], + "rust_tests": [ + "gateway-rs/src/policy/bandwidth.rs::tests::python_bandwidth_limit_blocks_after_usage_reaches_limit", + "gateway-rs/src/policy/bandwidth.rs::tests::python_bandwidth_limit_resets_in_the_next_window" + ], + "source": { + "kind": "function", + "line": 26, + "path": "backend-services/utils/bandwidth_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/bandwidth_util.py::function:_get_user", + "notes": "Rust preserves window aliases/defaults, bucket keys, shared current usage, request-plus-response byte accounting, disabled/zero/missing-user bypass, and the pinned used-at-limit or content-length-over-limit 429 boundary. Storage failures are fail-closed in native external mode rather than Python's best-effort local fallback.", + "rust_symbols": [ + "gateway-rs/src/storage/redis.rs::bandwidth_key", + "gateway-rs/src/policy/bandwidth.rs::enforce_pre_request_limit", + "gateway-rs/src/policy/evaluator.rs::evaluate_request", + "gateway-rs/src/routes/rest.rs::proxy_request" + ], + "rust_tests": [ + "gateway-rs/src/policy/bandwidth.rs::tests::python_bandwidth_limit_blocks_after_usage_reaches_limit", + "gateway-rs/src/policy/bandwidth.rs::tests::python_bandwidth_limit_resets_in_the_next_window" + ], + "source": { + "kind": "function", + "line": 34, + "path": "backend-services/utils/bandwidth_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/bandwidth_util.py::function:_get_client", + "notes": "Rust preserves window aliases/defaults, bucket keys, shared current usage, request-plus-response byte accounting, disabled/zero/missing-user bypass, and the pinned used-at-limit or content-length-over-limit 429 boundary. Storage failures are fail-closed in native external mode rather than Python's best-effort local fallback.", + "rust_symbols": [ + "gateway-rs/src/storage/redis.rs::bandwidth_key", + "gateway-rs/src/policy/bandwidth.rs::enforce_pre_request_limit", + "gateway-rs/src/policy/evaluator.rs::evaluate_request", + "gateway-rs/src/routes/rest.rs::proxy_request" + ], + "rust_tests": [ + "gateway-rs/src/policy/bandwidth.rs::tests::python_bandwidth_limit_blocks_after_usage_reaches_limit", + "gateway-rs/src/policy/bandwidth.rs::tests::python_bandwidth_limit_resets_in_the_next_window" + ], + "source": { + "kind": "function", + "line": 43, + "path": "backend-services/utils/bandwidth_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/bandwidth_util.py::function:get_current_usage", + "notes": "Rust preserves window aliases/defaults, bucket keys, shared current usage, request-plus-response byte accounting, disabled/zero/missing-user bypass, and the pinned used-at-limit or content-length-over-limit 429 boundary. Storage failures are fail-closed in native external mode rather than Python's best-effort local fallback.", + "rust_symbols": [ + "gateway-rs/src/storage/redis.rs::bandwidth_key", + "gateway-rs/src/policy/bandwidth.rs::enforce_pre_request_limit", + "gateway-rs/src/policy/evaluator.rs::evaluate_request", + "gateway-rs/src/routes/rest.rs::proxy_request" + ], + "rust_tests": [ + "gateway-rs/src/policy/bandwidth.rs::tests::python_bandwidth_limit_blocks_after_usage_reaches_limit", + "gateway-rs/src/policy/bandwidth.rs::tests::python_bandwidth_limit_resets_in_the_next_window" + ], + "source": { + "kind": "function", + "line": 47, + "path": "backend-services/utils/bandwidth_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/bandwidth_util.py::function:add_usage", + "notes": "Rust preserves window aliases/defaults, bucket keys, shared current usage, request-plus-response byte accounting, disabled/zero/missing-user bypass, and the pinned used-at-limit or content-length-over-limit 429 boundary. Storage failures are fail-closed in native external mode rather than Python's best-effort local fallback.", + "rust_symbols": [ + "gateway-rs/src/storage/redis.rs::bandwidth_key", + "gateway-rs/src/policy/bandwidth.rs::enforce_pre_request_limit", + "gateway-rs/src/policy/evaluator.rs::evaluate_request", + "gateway-rs/src/routes/rest.rs::proxy_request" + ], + "rust_tests": [ + "gateway-rs/src/policy/bandwidth.rs::tests::python_bandwidth_limit_blocks_after_usage_reaches_limit", + "gateway-rs/src/policy/bandwidth.rs::tests::python_bandwidth_limit_resets_in_the_next_window" + ], + "source": { + "kind": "function", + "line": 64, + "path": "backend-services/utils/bandwidth_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/bandwidth_util.py::async_function:enforce_pre_request_limit", + "notes": "Rust preserves window aliases/defaults, bucket keys, shared current usage, request-plus-response byte accounting, disabled/zero/missing-user bypass, and the pinned used-at-limit or content-length-over-limit 429 boundary. Storage failures are fail-closed in native external mode rather than Python's best-effort local fallback.", + "rust_symbols": [ + "gateway-rs/src/storage/redis.rs::bandwidth_key", + "gateway-rs/src/policy/bandwidth.rs::enforce_pre_request_limit", + "gateway-rs/src/policy/evaluator.rs::evaluate_request", + "gateway-rs/src/routes/rest.rs::proxy_request" + ], + "rust_tests": [ + "gateway-rs/src/policy/bandwidth.rs::tests::python_bandwidth_limit_blocks_after_usage_reaches_limit", + "gateway-rs/src/policy/bandwidth.rs::tests::python_bandwidth_limit_resets_in_the_next_window" + ], + "source": { + "kind": "async_function", + "line": 85, + "path": "backend-services/utils/bandwidth_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/cache_manager_util.py::module:cache_manager_util", + "notes": "The aiocache decorator factory is initialized and attached to FastAPI state but is never consumed by pinned production code; Rust uses its native shared storage/cache implementation directly.", + "rationale": "Unused FastAPI/aiocache framework adapter made obsolete with removal of the Python application runtime.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/cache_manager_util.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/cache_manager_util.py::class:CacheManager", + "notes": "The aiocache decorator factory is initialized and attached to FastAPI state but is never consumed by pinned production code; Rust uses its native shared storage/cache implementation directly.", + "rationale": "Unused FastAPI/aiocache framework adapter made obsolete with removal of the Python application runtime.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "class", + "line": 23, + "path": "backend-services/utils/cache_manager_util.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/cache_manager_util.py::method:CacheManager.__init__", + "notes": "The aiocache decorator factory is initialized and attached to FastAPI state but is never consumed by pinned production code; Rust uses its native shared storage/cache implementation directly.", + "rationale": "Unused FastAPI/aiocache framework adapter made obsolete with removal of the Python application runtime.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "method", + "line": 24, + "path": "backend-services/utils/cache_manager_util.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/cache_manager_util.py::method:CacheManager.init_app", + "notes": "The aiocache decorator factory is initialized and attached to FastAPI state but is never consumed by pinned production code; Rust uses its native shared storage/cache implementation directly.", + "rationale": "Unused FastAPI/aiocache framework adapter made obsolete with removal of the Python application runtime.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "method", + "line": 52, + "path": "backend-services/utils/cache_manager_util.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/cache_manager_util.py::method:CacheManager.cached", + "notes": "The aiocache decorator factory is initialized and attached to FastAPI state but is never consumed by pinned production code; Rust uses its native shared storage/cache implementation directly.", + "rationale": "Unused FastAPI/aiocache framework adapter made obsolete with removal of the Python application runtime.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "method", + "line": 56, + "path": "backend-services/utils/cache_manager_util.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/chaos_util.py::module:chaos_util", + "notes": "Rust has thread-safe Redis/Mongo outage flags, duration-based automatic clearing, an atomic error-budget counter, stats, and matching management routes. The flags are not yet consulted by native storage operations, so toggling them does not reproduce Python's injected backend failures.", + "rust_symbols": [ + "gateway-rs/src/middleware/chaos.rs::CHAOS_REDIS_OUTAGE", + "gateway-rs/src/middleware/chaos.rs::CHAOS_MONGO_OUTAGE", + "gateway-rs/src/middleware/chaos.rs::CHAOS_ERROR_BUDGET_BURN", + "gateway-rs/src/routes/platform.rs::platform_dispatch" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract", + "gateway-rs/tests/platform_native.rs::tools_permissions_and_required_models_match_python" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/chaos_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/chaos_util.py::function:enable", + "notes": "Rust has thread-safe Redis/Mongo outage flags, duration-based automatic clearing, an atomic error-budget counter, stats, and matching management routes. The flags are not yet consulted by native storage operations, so toggling them does not reproduce Python's injected backend failures.", + "rust_symbols": [ + "gateway-rs/src/middleware/chaos.rs::CHAOS_REDIS_OUTAGE", + "gateway-rs/src/middleware/chaos.rs::CHAOS_MONGO_OUTAGE", + "gateway-rs/src/middleware/chaos.rs::CHAOS_ERROR_BUDGET_BURN", + "gateway-rs/src/routes/platform.rs::platform_dispatch" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract", + "gateway-rs/tests/platform_native.rs::tools_permissions_and_required_models_match_python" + ], + "source": { + "kind": "function", + "line": 10, + "path": "backend-services/utils/chaos_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/chaos_util.py::function:enable_for", + "notes": "Rust has thread-safe Redis/Mongo outage flags, duration-based automatic clearing, an atomic error-budget counter, stats, and matching management routes. The flags are not yet consulted by native storage operations, so toggling them does not reproduce Python's injected backend failures.", + "rust_symbols": [ + "gateway-rs/src/middleware/chaos.rs::CHAOS_REDIS_OUTAGE", + "gateway-rs/src/middleware/chaos.rs::CHAOS_MONGO_OUTAGE", + "gateway-rs/src/middleware/chaos.rs::CHAOS_ERROR_BUDGET_BURN", + "gateway-rs/src/routes/platform.rs::platform_dispatch" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract", + "gateway-rs/tests/platform_native.rs::tools_permissions_and_required_models_match_python" + ], + "source": { + "kind": "function", + "line": 18, + "path": "backend-services/utils/chaos_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/chaos_util.py::function:_key_for", + "notes": "Rust has thread-safe Redis/Mongo outage flags, duration-based automatic clearing, an atomic error-budget counter, stats, and matching management routes. The flags are not yet consulted by native storage operations, so toggling them does not reproduce Python's injected backend failures.", + "rust_symbols": [ + "gateway-rs/src/middleware/chaos.rs::CHAOS_REDIS_OUTAGE", + "gateway-rs/src/middleware/chaos.rs::CHAOS_MONGO_OUTAGE", + "gateway-rs/src/middleware/chaos.rs::CHAOS_ERROR_BUDGET_BURN", + "gateway-rs/src/routes/platform.rs::platform_dispatch" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract", + "gateway-rs/tests/platform_native.rs::tools_permissions_and_required_models_match_python" + ], + "source": { + "kind": "function", + "line": 25, + "path": "backend-services/utils/chaos_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/chaos_util.py::function:should_fail", + "notes": "Rust has thread-safe Redis/Mongo outage flags, duration-based automatic clearing, an atomic error-budget counter, stats, and matching management routes. The flags are not yet consulted by native storage operations, so toggling them does not reproduce Python's injected backend failures.", + "rust_symbols": [ + "gateway-rs/src/middleware/chaos.rs::CHAOS_REDIS_OUTAGE", + "gateway-rs/src/middleware/chaos.rs::CHAOS_MONGO_OUTAGE", + "gateway-rs/src/middleware/chaos.rs::CHAOS_ERROR_BUDGET_BURN", + "gateway-rs/src/routes/platform.rs::platform_dispatch" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract", + "gateway-rs/tests/platform_native.rs::tools_permissions_and_required_models_match_python" + ], + "source": { + "kind": "function", + "line": 34, + "path": "backend-services/utils/chaos_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/chaos_util.py::function:burn_error_budget", + "notes": "Rust has thread-safe Redis/Mongo outage flags, duration-based automatic clearing, an atomic error-budget counter, stats, and matching management routes. The flags are not yet consulted by native storage operations, so toggling them does not reproduce Python's injected backend failures.", + "rust_symbols": [ + "gateway-rs/src/middleware/chaos.rs::CHAOS_REDIS_OUTAGE", + "gateway-rs/src/middleware/chaos.rs::CHAOS_MONGO_OUTAGE", + "gateway-rs/src/middleware/chaos.rs::CHAOS_ERROR_BUDGET_BURN", + "gateway-rs/src/routes/platform.rs::platform_dispatch" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract", + "gateway-rs/tests/platform_native.rs::tools_permissions_and_required_models_match_python" + ], + "source": { + "kind": "function", + "line": 42, + "path": "backend-services/utils/chaos_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/chaos_util.py::function:stats", + "notes": "Rust has thread-safe Redis/Mongo outage flags, duration-based automatic clearing, an atomic error-budget counter, stats, and matching management routes. The flags are not yet consulted by native storage operations, so toggling them does not reproduce Python's injected backend failures.", + "rust_symbols": [ + "gateway-rs/src/middleware/chaos.rs::CHAOS_REDIS_OUTAGE", + "gateway-rs/src/middleware/chaos.rs::CHAOS_MONGO_OUTAGE", + "gateway-rs/src/middleware/chaos.rs::CHAOS_ERROR_BUDGET_BURN", + "gateway-rs/src/routes/platform.rs::platform_dispatch" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract", + "gateway-rs/tests/platform_native.rs::tools_permissions_and_required_models_match_python" + ], + "source": { + "kind": "function", + "line": 50, + "path": "backend-services/utils/chaos_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/constants.py::module:constants", + "notes": "Rust now defines every pinned header, pagination, multipart, permission, error-code, and message constant with the exact Python value. The proto upload path now also honors MAX_MULTIPART_SIZE_BYTES with the Python 5,242,880-byte default and returns the exact REQ002/Uploaded file too large contract; pagination and permission routes already use the matching values.", + "rust_symbols": [ + "gateway-rs/src/constants.rs::Headers", + "gateway-rs/src/constants.rs::Defaults", + "gateway-rs/src/constants.rs::Roles", + "gateway-rs/src/constants.rs::ErrorCodes", + "gateway-rs/src/constants.rs::Messages", + "gateway-rs/src/routes/platform.rs::proto_routes" + ], + "rust_tests": [ + "gateway-rs/src/constants.rs::tests::preserves_python_defaults_and_wire_constants", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/constants.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/constants.py::class:Headers", + "notes": "Rust now defines every pinned header, pagination, multipart, permission, error-code, and message constant with the exact Python value. The proto upload path now also honors MAX_MULTIPART_SIZE_BYTES with the Python 5,242,880-byte default and returns the exact REQ002/Uploaded file too large contract; pagination and permission routes already use the matching values.", + "rust_symbols": [ + "gateway-rs/src/constants.rs::Headers", + "gateway-rs/src/constants.rs::Defaults", + "gateway-rs/src/constants.rs::Roles", + "gateway-rs/src/constants.rs::ErrorCodes", + "gateway-rs/src/constants.rs::Messages", + "gateway-rs/src/routes/platform.rs::proto_routes" + ], + "rust_tests": [ + "gateway-rs/src/constants.rs::tests::preserves_python_defaults_and_wire_constants", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract" + ], + "source": { + "kind": "class", + "line": 1, + "path": "backend-services/utils/constants.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/constants.py::field:Headers.REQUEST_ID", + "notes": "Rust now defines every pinned header, pagination, multipart, permission, error-code, and message constant with the exact Python value. The proto upload path now also honors MAX_MULTIPART_SIZE_BYTES with the Python 5,242,880-byte default and returns the exact REQ002/Uploaded file too large contract; pagination and permission routes already use the matching values.", + "rust_symbols": [ + "gateway-rs/src/constants.rs::Headers", + "gateway-rs/src/constants.rs::Defaults", + "gateway-rs/src/constants.rs::Roles", + "gateway-rs/src/constants.rs::ErrorCodes", + "gateway-rs/src/constants.rs::Messages", + "gateway-rs/src/routes/platform.rs::proto_routes" + ], + "rust_tests": [ + "gateway-rs/src/constants.rs::tests::preserves_python_defaults_and_wire_constants", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract" + ], + "source": { + "kind": "field", + "line": 2, + "path": "backend-services/utils/constants.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/constants.py::class:Defaults", + "notes": "Rust now defines every pinned header, pagination, multipart, permission, error-code, and message constant with the exact Python value. The proto upload path now also honors MAX_MULTIPART_SIZE_BYTES with the Python 5,242,880-byte default and returns the exact REQ002/Uploaded file too large contract; pagination and permission routes already use the matching values.", + "rust_symbols": [ + "gateway-rs/src/constants.rs::Headers", + "gateway-rs/src/constants.rs::Defaults", + "gateway-rs/src/constants.rs::Roles", + "gateway-rs/src/constants.rs::ErrorCodes", + "gateway-rs/src/constants.rs::Messages", + "gateway-rs/src/routes/platform.rs::proto_routes" + ], + "rust_tests": [ + "gateway-rs/src/constants.rs::tests::preserves_python_defaults_and_wire_constants", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract" + ], + "source": { + "kind": "class", + "line": 5, + "path": "backend-services/utils/constants.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/constants.py::field:Defaults.PAGE", + "notes": "Rust now defines every pinned header, pagination, multipart, permission, error-code, and message constant with the exact Python value. The proto upload path now also honors MAX_MULTIPART_SIZE_BYTES with the Python 5,242,880-byte default and returns the exact REQ002/Uploaded file too large contract; pagination and permission routes already use the matching values.", + "rust_symbols": [ + "gateway-rs/src/constants.rs::Headers", + "gateway-rs/src/constants.rs::Defaults", + "gateway-rs/src/constants.rs::Roles", + "gateway-rs/src/constants.rs::ErrorCodes", + "gateway-rs/src/constants.rs::Messages", + "gateway-rs/src/routes/platform.rs::proto_routes" + ], + "rust_tests": [ + "gateway-rs/src/constants.rs::tests::preserves_python_defaults_and_wire_constants", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract" + ], + "source": { + "kind": "field", + "line": 6, + "path": "backend-services/utils/constants.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/constants.py::field:Defaults.PAGE_SIZE", + "notes": "Rust now defines every pinned header, pagination, multipart, permission, error-code, and message constant with the exact Python value. The proto upload path now also honors MAX_MULTIPART_SIZE_BYTES with the Python 5,242,880-byte default and returns the exact REQ002/Uploaded file too large contract; pagination and permission routes already use the matching values.", + "rust_symbols": [ + "gateway-rs/src/constants.rs::Headers", + "gateway-rs/src/constants.rs::Defaults", + "gateway-rs/src/constants.rs::Roles", + "gateway-rs/src/constants.rs::ErrorCodes", + "gateway-rs/src/constants.rs::Messages", + "gateway-rs/src/routes/platform.rs::proto_routes" + ], + "rust_tests": [ + "gateway-rs/src/constants.rs::tests::preserves_python_defaults_and_wire_constants", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract" + ], + "source": { + "kind": "field", + "line": 7, + "path": "backend-services/utils/constants.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/constants.py::field:Defaults.MAX_PAGE_SIZE_ENV", + "notes": "Rust now defines every pinned header, pagination, multipart, permission, error-code, and message constant with the exact Python value. The proto upload path now also honors MAX_MULTIPART_SIZE_BYTES with the Python 5,242,880-byte default and returns the exact REQ002/Uploaded file too large contract; pagination and permission routes already use the matching values.", + "rust_symbols": [ + "gateway-rs/src/constants.rs::Headers", + "gateway-rs/src/constants.rs::Defaults", + "gateway-rs/src/constants.rs::Roles", + "gateway-rs/src/constants.rs::ErrorCodes", + "gateway-rs/src/constants.rs::Messages", + "gateway-rs/src/routes/platform.rs::proto_routes" + ], + "rust_tests": [ + "gateway-rs/src/constants.rs::tests::preserves_python_defaults_and_wire_constants", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract" + ], + "source": { + "kind": "field", + "line": 8, + "path": "backend-services/utils/constants.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/constants.py::field:Defaults.MAX_PAGE_SIZE_DEFAULT", + "notes": "Rust now defines every pinned header, pagination, multipart, permission, error-code, and message constant with the exact Python value. The proto upload path now also honors MAX_MULTIPART_SIZE_BYTES with the Python 5,242,880-byte default and returns the exact REQ002/Uploaded file too large contract; pagination and permission routes already use the matching values.", + "rust_symbols": [ + "gateway-rs/src/constants.rs::Headers", + "gateway-rs/src/constants.rs::Defaults", + "gateway-rs/src/constants.rs::Roles", + "gateway-rs/src/constants.rs::ErrorCodes", + "gateway-rs/src/constants.rs::Messages", + "gateway-rs/src/routes/platform.rs::proto_routes" + ], + "rust_tests": [ + "gateway-rs/src/constants.rs::tests::preserves_python_defaults_and_wire_constants", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract" + ], + "source": { + "kind": "field", + "line": 9, + "path": "backend-services/utils/constants.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/constants.py::field:Defaults.MAX_MULTIPART_SIZE_BYTES_ENV", + "notes": "Rust now defines every pinned header, pagination, multipart, permission, error-code, and message constant with the exact Python value. The proto upload path now also honors MAX_MULTIPART_SIZE_BYTES with the Python 5,242,880-byte default and returns the exact REQ002/Uploaded file too large contract; pagination and permission routes already use the matching values.", + "rust_symbols": [ + "gateway-rs/src/constants.rs::Headers", + "gateway-rs/src/constants.rs::Defaults", + "gateway-rs/src/constants.rs::Roles", + "gateway-rs/src/constants.rs::ErrorCodes", + "gateway-rs/src/constants.rs::Messages", + "gateway-rs/src/routes/platform.rs::proto_routes" + ], + "rust_tests": [ + "gateway-rs/src/constants.rs::tests::preserves_python_defaults_and_wire_constants", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract" + ], + "source": { + "kind": "field", + "line": 10, + "path": "backend-services/utils/constants.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/constants.py::field:Defaults.MAX_MULTIPART_SIZE_BYTES_DEFAULT", + "notes": "Rust now defines every pinned header, pagination, multipart, permission, error-code, and message constant with the exact Python value. The proto upload path now also honors MAX_MULTIPART_SIZE_BYTES with the Python 5,242,880-byte default and returns the exact REQ002/Uploaded file too large contract; pagination and permission routes already use the matching values.", + "rust_symbols": [ + "gateway-rs/src/constants.rs::Headers", + "gateway-rs/src/constants.rs::Defaults", + "gateway-rs/src/constants.rs::Roles", + "gateway-rs/src/constants.rs::ErrorCodes", + "gateway-rs/src/constants.rs::Messages", + "gateway-rs/src/routes/platform.rs::proto_routes" + ], + "rust_tests": [ + "gateway-rs/src/constants.rs::tests::preserves_python_defaults_and_wire_constants", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract" + ], + "source": { + "kind": "field", + "line": 11, + "path": "backend-services/utils/constants.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/constants.py::class:Roles", + "notes": "Rust now defines every pinned header, pagination, multipart, permission, error-code, and message constant with the exact Python value. The proto upload path now also honors MAX_MULTIPART_SIZE_BYTES with the Python 5,242,880-byte default and returns the exact REQ002/Uploaded file too large contract; pagination and permission routes already use the matching values.", + "rust_symbols": [ + "gateway-rs/src/constants.rs::Headers", + "gateway-rs/src/constants.rs::Defaults", + "gateway-rs/src/constants.rs::Roles", + "gateway-rs/src/constants.rs::ErrorCodes", + "gateway-rs/src/constants.rs::Messages", + "gateway-rs/src/routes/platform.rs::proto_routes" + ], + "rust_tests": [ + "gateway-rs/src/constants.rs::tests::preserves_python_defaults_and_wire_constants", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract" + ], + "source": { + "kind": "class", + "line": 14, + "path": "backend-services/utils/constants.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/constants.py::field:Roles.MANAGE_USERS", + "notes": "Rust now defines every pinned header, pagination, multipart, permission, error-code, and message constant with the exact Python value. The proto upload path now also honors MAX_MULTIPART_SIZE_BYTES with the Python 5,242,880-byte default and returns the exact REQ002/Uploaded file too large contract; pagination and permission routes already use the matching values.", + "rust_symbols": [ + "gateway-rs/src/constants.rs::Headers", + "gateway-rs/src/constants.rs::Defaults", + "gateway-rs/src/constants.rs::Roles", + "gateway-rs/src/constants.rs::ErrorCodes", + "gateway-rs/src/constants.rs::Messages", + "gateway-rs/src/routes/platform.rs::proto_routes" + ], + "rust_tests": [ + "gateway-rs/src/constants.rs::tests::preserves_python_defaults_and_wire_constants", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract" + ], + "source": { + "kind": "field", + "line": 15, + "path": "backend-services/utils/constants.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/constants.py::field:Roles.MANAGE_APIS", + "notes": "Rust now defines every pinned header, pagination, multipart, permission, error-code, and message constant with the exact Python value. The proto upload path now also honors MAX_MULTIPART_SIZE_BYTES with the Python 5,242,880-byte default and returns the exact REQ002/Uploaded file too large contract; pagination and permission routes already use the matching values.", + "rust_symbols": [ + "gateway-rs/src/constants.rs::Headers", + "gateway-rs/src/constants.rs::Defaults", + "gateway-rs/src/constants.rs::Roles", + "gateway-rs/src/constants.rs::ErrorCodes", + "gateway-rs/src/constants.rs::Messages", + "gateway-rs/src/routes/platform.rs::proto_routes" + ], + "rust_tests": [ + "gateway-rs/src/constants.rs::tests::preserves_python_defaults_and_wire_constants", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract" + ], + "source": { + "kind": "field", + "line": 16, + "path": "backend-services/utils/constants.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/constants.py::field:Roles.MANAGE_GROUPS", + "notes": "Rust now defines every pinned header, pagination, multipart, permission, error-code, and message constant with the exact Python value. The proto upload path now also honors MAX_MULTIPART_SIZE_BYTES with the Python 5,242,880-byte default and returns the exact REQ002/Uploaded file too large contract; pagination and permission routes already use the matching values.", + "rust_symbols": [ + "gateway-rs/src/constants.rs::Headers", + "gateway-rs/src/constants.rs::Defaults", + "gateway-rs/src/constants.rs::Roles", + "gateway-rs/src/constants.rs::ErrorCodes", + "gateway-rs/src/constants.rs::Messages", + "gateway-rs/src/routes/platform.rs::proto_routes" + ], + "rust_tests": [ + "gateway-rs/src/constants.rs::tests::preserves_python_defaults_and_wire_constants", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract" + ], + "source": { + "kind": "field", + "line": 17, + "path": "backend-services/utils/constants.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/constants.py::field:Roles.MANAGE_ENDPOINTS", + "notes": "Rust now defines every pinned header, pagination, multipart, permission, error-code, and message constant with the exact Python value. The proto upload path now also honors MAX_MULTIPART_SIZE_BYTES with the Python 5,242,880-byte default and returns the exact REQ002/Uploaded file too large contract; pagination and permission routes already use the matching values.", + "rust_symbols": [ + "gateway-rs/src/constants.rs::Headers", + "gateway-rs/src/constants.rs::Defaults", + "gateway-rs/src/constants.rs::Roles", + "gateway-rs/src/constants.rs::ErrorCodes", + "gateway-rs/src/constants.rs::Messages", + "gateway-rs/src/routes/platform.rs::proto_routes" + ], + "rust_tests": [ + "gateway-rs/src/constants.rs::tests::preserves_python_defaults_and_wire_constants", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract" + ], + "source": { + "kind": "field", + "line": 18, + "path": "backend-services/utils/constants.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/constants.py::field:Roles.VIEW_LOGS", + "notes": "Rust now defines every pinned header, pagination, multipart, permission, error-code, and message constant with the exact Python value. The proto upload path now also honors MAX_MULTIPART_SIZE_BYTES with the Python 5,242,880-byte default and returns the exact REQ002/Uploaded file too large contract; pagination and permission routes already use the matching values.", + "rust_symbols": [ + "gateway-rs/src/constants.rs::Headers", + "gateway-rs/src/constants.rs::Defaults", + "gateway-rs/src/constants.rs::Roles", + "gateway-rs/src/constants.rs::ErrorCodes", + "gateway-rs/src/constants.rs::Messages", + "gateway-rs/src/routes/platform.rs::proto_routes" + ], + "rust_tests": [ + "gateway-rs/src/constants.rs::tests::preserves_python_defaults_and_wire_constants", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract" + ], + "source": { + "kind": "field", + "line": 19, + "path": "backend-services/utils/constants.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/constants.py::field:Roles.EXPORT_LOGS", + "notes": "Rust now defines every pinned header, pagination, multipart, permission, error-code, and message constant with the exact Python value. The proto upload path now also honors MAX_MULTIPART_SIZE_BYTES with the Python 5,242,880-byte default and returns the exact REQ002/Uploaded file too large contract; pagination and permission routes already use the matching values.", + "rust_symbols": [ + "gateway-rs/src/constants.rs::Headers", + "gateway-rs/src/constants.rs::Defaults", + "gateway-rs/src/constants.rs::Roles", + "gateway-rs/src/constants.rs::ErrorCodes", + "gateway-rs/src/constants.rs::Messages", + "gateway-rs/src/routes/platform.rs::proto_routes" + ], + "rust_tests": [ + "gateway-rs/src/constants.rs::tests::preserves_python_defaults_and_wire_constants", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract" + ], + "source": { + "kind": "field", + "line": 20, + "path": "backend-services/utils/constants.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/constants.py::field:Roles.MANAGE_ROLES", + "notes": "Rust now defines every pinned header, pagination, multipart, permission, error-code, and message constant with the exact Python value. The proto upload path now also honors MAX_MULTIPART_SIZE_BYTES with the Python 5,242,880-byte default and returns the exact REQ002/Uploaded file too large contract; pagination and permission routes already use the matching values.", + "rust_symbols": [ + "gateway-rs/src/constants.rs::Headers", + "gateway-rs/src/constants.rs::Defaults", + "gateway-rs/src/constants.rs::Roles", + "gateway-rs/src/constants.rs::ErrorCodes", + "gateway-rs/src/constants.rs::Messages", + "gateway-rs/src/routes/platform.rs::proto_routes" + ], + "rust_tests": [ + "gateway-rs/src/constants.rs::tests::preserves_python_defaults_and_wire_constants", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract" + ], + "source": { + "kind": "field", + "line": 21, + "path": "backend-services/utils/constants.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/constants.py::class:ErrorCodes", + "notes": "Rust now defines every pinned header, pagination, multipart, permission, error-code, and message constant with the exact Python value. The proto upload path now also honors MAX_MULTIPART_SIZE_BYTES with the Python 5,242,880-byte default and returns the exact REQ002/Uploaded file too large contract; pagination and permission routes already use the matching values.", + "rust_symbols": [ + "gateway-rs/src/constants.rs::Headers", + "gateway-rs/src/constants.rs::Defaults", + "gateway-rs/src/constants.rs::Roles", + "gateway-rs/src/constants.rs::ErrorCodes", + "gateway-rs/src/constants.rs::Messages", + "gateway-rs/src/routes/platform.rs::proto_routes" + ], + "rust_tests": [ + "gateway-rs/src/constants.rs::tests::preserves_python_defaults_and_wire_constants", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract" + ], + "source": { + "kind": "class", + "line": 24, + "path": "backend-services/utils/constants.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/constants.py::field:ErrorCodes.UNEXPECTED", + "notes": "Rust now defines every pinned header, pagination, multipart, permission, error-code, and message constant with the exact Python value. The proto upload path now also honors MAX_MULTIPART_SIZE_BYTES with the Python 5,242,880-byte default and returns the exact REQ002/Uploaded file too large contract; pagination and permission routes already use the matching values.", + "rust_symbols": [ + "gateway-rs/src/constants.rs::Headers", + "gateway-rs/src/constants.rs::Defaults", + "gateway-rs/src/constants.rs::Roles", + "gateway-rs/src/constants.rs::ErrorCodes", + "gateway-rs/src/constants.rs::Messages", + "gateway-rs/src/routes/platform.rs::proto_routes" + ], + "rust_tests": [ + "gateway-rs/src/constants.rs::tests::preserves_python_defaults_and_wire_constants", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract" + ], + "source": { + "kind": "field", + "line": 25, + "path": "backend-services/utils/constants.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/constants.py::field:ErrorCodes.HTTP_EXCEPTION", + "notes": "Rust now defines every pinned header, pagination, multipart, permission, error-code, and message constant with the exact Python value. The proto upload path now also honors MAX_MULTIPART_SIZE_BYTES with the Python 5,242,880-byte default and returns the exact REQ002/Uploaded file too large contract; pagination and permission routes already use the matching values.", + "rust_symbols": [ + "gateway-rs/src/constants.rs::Headers", + "gateway-rs/src/constants.rs::Defaults", + "gateway-rs/src/constants.rs::Roles", + "gateway-rs/src/constants.rs::ErrorCodes", + "gateway-rs/src/constants.rs::Messages", + "gateway-rs/src/routes/platform.rs::proto_routes" + ], + "rust_tests": [ + "gateway-rs/src/constants.rs::tests::preserves_python_defaults_and_wire_constants", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract" + ], + "source": { + "kind": "field", + "line": 26, + "path": "backend-services/utils/constants.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/constants.py::field:ErrorCodes.GRPC_GENERATION_FAILED", + "notes": "Rust now defines every pinned header, pagination, multipart, permission, error-code, and message constant with the exact Python value. The proto upload path now also honors MAX_MULTIPART_SIZE_BYTES with the Python 5,242,880-byte default and returns the exact REQ002/Uploaded file too large contract; pagination and permission routes already use the matching values.", + "rust_symbols": [ + "gateway-rs/src/constants.rs::Headers", + "gateway-rs/src/constants.rs::Defaults", + "gateway-rs/src/constants.rs::Roles", + "gateway-rs/src/constants.rs::ErrorCodes", + "gateway-rs/src/constants.rs::Messages", + "gateway-rs/src/routes/platform.rs::proto_routes" + ], + "rust_tests": [ + "gateway-rs/src/constants.rs::tests::preserves_python_defaults_and_wire_constants", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract" + ], + "source": { + "kind": "field", + "line": 27, + "path": "backend-services/utils/constants.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/constants.py::field:ErrorCodes.PATH_VALIDATION", + "notes": "Rust now defines every pinned header, pagination, multipart, permission, error-code, and message constant with the exact Python value. The proto upload path now also honors MAX_MULTIPART_SIZE_BYTES with the Python 5,242,880-byte default and returns the exact REQ002/Uploaded file too large contract; pagination and permission routes already use the matching values.", + "rust_symbols": [ + "gateway-rs/src/constants.rs::Headers", + "gateway-rs/src/constants.rs::Defaults", + "gateway-rs/src/constants.rs::Roles", + "gateway-rs/src/constants.rs::ErrorCodes", + "gateway-rs/src/constants.rs::Messages", + "gateway-rs/src/routes/platform.rs::proto_routes" + ], + "rust_tests": [ + "gateway-rs/src/constants.rs::tests::preserves_python_defaults_and_wire_constants", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract" + ], + "source": { + "kind": "field", + "line": 28, + "path": "backend-services/utils/constants.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/constants.py::field:ErrorCodes.API_NOT_FOUND", + "notes": "Rust now defines every pinned header, pagination, multipart, permission, error-code, and message constant with the exact Python value. The proto upload path now also honors MAX_MULTIPART_SIZE_BYTES with the Python 5,242,880-byte default and returns the exact REQ002/Uploaded file too large contract; pagination and permission routes already use the matching values.", + "rust_symbols": [ + "gateway-rs/src/constants.rs::Headers", + "gateway-rs/src/constants.rs::Defaults", + "gateway-rs/src/constants.rs::Roles", + "gateway-rs/src/constants.rs::ErrorCodes", + "gateway-rs/src/constants.rs::Messages", + "gateway-rs/src/routes/platform.rs::proto_routes" + ], + "rust_tests": [ + "gateway-rs/src/constants.rs::tests::preserves_python_defaults_and_wire_constants", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract" + ], + "source": { + "kind": "field", + "line": 29, + "path": "backend-services/utils/constants.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/constants.py::field:ErrorCodes.AUTH_REQUIRED", + "notes": "Rust now defines every pinned header, pagination, multipart, permission, error-code, and message constant with the exact Python value. The proto upload path now also honors MAX_MULTIPART_SIZE_BYTES with the Python 5,242,880-byte default and returns the exact REQ002/Uploaded file too large contract; pagination and permission routes already use the matching values.", + "rust_symbols": [ + "gateway-rs/src/constants.rs::Headers", + "gateway-rs/src/constants.rs::Defaults", + "gateway-rs/src/constants.rs::Roles", + "gateway-rs/src/constants.rs::ErrorCodes", + "gateway-rs/src/constants.rs::Messages", + "gateway-rs/src/routes/platform.rs::proto_routes" + ], + "rust_tests": [ + "gateway-rs/src/constants.rs::tests::preserves_python_defaults_and_wire_constants", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract" + ], + "source": { + "kind": "field", + "line": 30, + "path": "backend-services/utils/constants.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/constants.py::field:ErrorCodes.REQUEST_TOO_LARGE", + "notes": "Rust now defines every pinned header, pagination, multipart, permission, error-code, and message constant with the exact Python value. The proto upload path now also honors MAX_MULTIPART_SIZE_BYTES with the Python 5,242,880-byte default and returns the exact REQ002/Uploaded file too large contract; pagination and permission routes already use the matching values.", + "rust_symbols": [ + "gateway-rs/src/constants.rs::Headers", + "gateway-rs/src/constants.rs::Defaults", + "gateway-rs/src/constants.rs::Roles", + "gateway-rs/src/constants.rs::ErrorCodes", + "gateway-rs/src/constants.rs::Messages", + "gateway-rs/src/routes/platform.rs::proto_routes" + ], + "rust_tests": [ + "gateway-rs/src/constants.rs::tests::preserves_python_defaults_and_wire_constants", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract" + ], + "source": { + "kind": "field", + "line": 31, + "path": "backend-services/utils/constants.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/constants.py::field:ErrorCodes.REQUEST_FILE_TYPE", + "notes": "Rust now defines every pinned header, pagination, multipart, permission, error-code, and message constant with the exact Python value. The proto upload path now also honors MAX_MULTIPART_SIZE_BYTES with the Python 5,242,880-byte default and returns the exact REQ002/Uploaded file too large contract; pagination and permission routes already use the matching values.", + "rust_symbols": [ + "gateway-rs/src/constants.rs::Headers", + "gateway-rs/src/constants.rs::Defaults", + "gateway-rs/src/constants.rs::Roles", + "gateway-rs/src/constants.rs::ErrorCodes", + "gateway-rs/src/constants.rs::Messages", + "gateway-rs/src/routes/platform.rs::proto_routes" + ], + "rust_tests": [ + "gateway-rs/src/constants.rs::tests::preserves_python_defaults_and_wire_constants", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract" + ], + "source": { + "kind": "field", + "line": 32, + "path": "backend-services/utils/constants.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/constants.py::field:ErrorCodes.PAGE_SIZE", + "notes": "Rust now defines every pinned header, pagination, multipart, permission, error-code, and message constant with the exact Python value. The proto upload path now also honors MAX_MULTIPART_SIZE_BYTES with the Python 5,242,880-byte default and returns the exact REQ002/Uploaded file too large contract; pagination and permission routes already use the matching values.", + "rust_symbols": [ + "gateway-rs/src/constants.rs::Headers", + "gateway-rs/src/constants.rs::Defaults", + "gateway-rs/src/constants.rs::Roles", + "gateway-rs/src/constants.rs::ErrorCodes", + "gateway-rs/src/constants.rs::Messages", + "gateway-rs/src/routes/platform.rs::proto_routes" + ], + "rust_tests": [ + "gateway-rs/src/constants.rs::tests::preserves_python_defaults_and_wire_constants", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract" + ], + "source": { + "kind": "field", + "line": 33, + "path": "backend-services/utils/constants.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/constants.py::class:Messages", + "notes": "Rust now defines every pinned header, pagination, multipart, permission, error-code, and message constant with the exact Python value. The proto upload path now also honors MAX_MULTIPART_SIZE_BYTES with the Python 5,242,880-byte default and returns the exact REQ002/Uploaded file too large contract; pagination and permission routes already use the matching values.", + "rust_symbols": [ + "gateway-rs/src/constants.rs::Headers", + "gateway-rs/src/constants.rs::Defaults", + "gateway-rs/src/constants.rs::Roles", + "gateway-rs/src/constants.rs::ErrorCodes", + "gateway-rs/src/constants.rs::Messages", + "gateway-rs/src/routes/platform.rs::proto_routes" + ], + "rust_tests": [ + "gateway-rs/src/constants.rs::tests::preserves_python_defaults_and_wire_constants", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract" + ], + "source": { + "kind": "class", + "line": 36, + "path": "backend-services/utils/constants.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/constants.py::field:Messages.UNEXPECTED", + "notes": "Rust now defines every pinned header, pagination, multipart, permission, error-code, and message constant with the exact Python value. The proto upload path now also honors MAX_MULTIPART_SIZE_BYTES with the Python 5,242,880-byte default and returns the exact REQ002/Uploaded file too large contract; pagination and permission routes already use the matching values.", + "rust_symbols": [ + "gateway-rs/src/constants.rs::Headers", + "gateway-rs/src/constants.rs::Defaults", + "gateway-rs/src/constants.rs::Roles", + "gateway-rs/src/constants.rs::ErrorCodes", + "gateway-rs/src/constants.rs::Messages", + "gateway-rs/src/routes/platform.rs::proto_routes" + ], + "rust_tests": [ + "gateway-rs/src/constants.rs::tests::preserves_python_defaults_and_wire_constants", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract" + ], + "source": { + "kind": "field", + "line": 37, + "path": "backend-services/utils/constants.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/constants.py::field:Messages.FILE_TOO_LARGE", + "notes": "Rust now defines every pinned header, pagination, multipart, permission, error-code, and message constant with the exact Python value. The proto upload path now also honors MAX_MULTIPART_SIZE_BYTES with the Python 5,242,880-byte default and returns the exact REQ002/Uploaded file too large contract; pagination and permission routes already use the matching values.", + "rust_symbols": [ + "gateway-rs/src/constants.rs::Headers", + "gateway-rs/src/constants.rs::Defaults", + "gateway-rs/src/constants.rs::Roles", + "gateway-rs/src/constants.rs::ErrorCodes", + "gateway-rs/src/constants.rs::Messages", + "gateway-rs/src/routes/platform.rs::proto_routes" + ], + "rust_tests": [ + "gateway-rs/src/constants.rs::tests::preserves_python_defaults_and_wire_constants", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract" + ], + "source": { + "kind": "field", + "line": 38, + "path": "backend-services/utils/constants.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/constants.py::field:Messages.ONLY_PROTO_ALLOWED", + "notes": "Rust now defines every pinned header, pagination, multipart, permission, error-code, and message constant with the exact Python value. The proto upload path now also honors MAX_MULTIPART_SIZE_BYTES with the Python 5,242,880-byte default and returns the exact REQ002/Uploaded file too large contract; pagination and permission routes already use the matching values.", + "rust_symbols": [ + "gateway-rs/src/constants.rs::Headers", + "gateway-rs/src/constants.rs::Defaults", + "gateway-rs/src/constants.rs::Roles", + "gateway-rs/src/constants.rs::ErrorCodes", + "gateway-rs/src/constants.rs::Messages", + "gateway-rs/src/routes/platform.rs::proto_routes" + ], + "rust_tests": [ + "gateway-rs/src/constants.rs::tests::preserves_python_defaults_and_wire_constants", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract" + ], + "source": { + "kind": "field", + "line": 39, + "path": "backend-services/utils/constants.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/constants.py::field:Messages.PERMISSION_MANAGE_APIS", + "notes": "Rust now defines every pinned header, pagination, multipart, permission, error-code, and message constant with the exact Python value. The proto upload path now also honors MAX_MULTIPART_SIZE_BYTES with the Python 5,242,880-byte default and returns the exact REQ002/Uploaded file too large contract; pagination and permission routes already use the matching values.", + "rust_symbols": [ + "gateway-rs/src/constants.rs::Headers", + "gateway-rs/src/constants.rs::Defaults", + "gateway-rs/src/constants.rs::Roles", + "gateway-rs/src/constants.rs::ErrorCodes", + "gateway-rs/src/constants.rs::Messages", + "gateway-rs/src/routes/platform.rs::proto_routes" + ], + "rust_tests": [ + "gateway-rs/src/constants.rs::tests::preserves_python_defaults_and_wire_constants", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract" + ], + "source": { + "kind": "field", + "line": 40, + "path": "backend-services/utils/constants.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/constants.py::field:Messages.GRPC_GEN_FAILED", + "notes": "Rust now defines every pinned header, pagination, multipart, permission, error-code, and message constant with the exact Python value. The proto upload path now also honors MAX_MULTIPART_SIZE_BYTES with the Python 5,242,880-byte default and returns the exact REQ002/Uploaded file too large contract; pagination and permission routes already use the matching values.", + "rust_symbols": [ + "gateway-rs/src/constants.rs::Headers", + "gateway-rs/src/constants.rs::Defaults", + "gateway-rs/src/constants.rs::Roles", + "gateway-rs/src/constants.rs::ErrorCodes", + "gateway-rs/src/constants.rs::Messages", + "gateway-rs/src/routes/platform.rs::proto_routes" + ], + "rust_tests": [ + "gateway-rs/src/constants.rs::tests::preserves_python_defaults_and_wire_constants", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract" + ], + "source": { + "kind": "field", + "line": 41, + "path": "backend-services/utils/constants.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/constants.py::field:Messages.PAGE_TOO_LARGE", + "notes": "Rust now defines every pinned header, pagination, multipart, permission, error-code, and message constant with the exact Python value. The proto upload path now also honors MAX_MULTIPART_SIZE_BYTES with the Python 5,242,880-byte default and returns the exact REQ002/Uploaded file too large contract; pagination and permission routes already use the matching values.", + "rust_symbols": [ + "gateway-rs/src/constants.rs::Headers", + "gateway-rs/src/constants.rs::Defaults", + "gateway-rs/src/constants.rs::Roles", + "gateway-rs/src/constants.rs::ErrorCodes", + "gateway-rs/src/constants.rs::Messages", + "gateway-rs/src/routes/platform.rs::proto_routes" + ], + "rust_tests": [ + "gateway-rs/src/constants.rs::tests::preserves_python_defaults_and_wire_constants", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract" + ], + "source": { + "kind": "field", + "line": 42, + "path": "backend-services/utils/constants.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/constants.py::field:Messages.INVALID_PAGING", + "notes": "Rust now defines every pinned header, pagination, multipart, permission, error-code, and message constant with the exact Python value. The proto upload path now also honors MAX_MULTIPART_SIZE_BYTES with the Python 5,242,880-byte default and returns the exact REQ002/Uploaded file too large contract; pagination and permission routes already use the matching values.", + "rust_symbols": [ + "gateway-rs/src/constants.rs::Headers", + "gateway-rs/src/constants.rs::Defaults", + "gateway-rs/src/constants.rs::Roles", + "gateway-rs/src/constants.rs::ErrorCodes", + "gateway-rs/src/constants.rs::Messages", + "gateway-rs/src/routes/platform.rs::proto_routes" + ], + "rust_tests": [ + "gateway-rs/src/constants.rs::tests::preserves_python_defaults_and_wire_constants", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract" + ], + "source": { + "kind": "field", + "line": 43, + "path": "backend-services/utils/constants.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/correlation_util.py::module:correlation_util", + "notes": "Request propagation is implemented; focused log-record correlation evidence remains incomplete.", + "rust_symbols": [ + "gateway-rs/src/middleware/request_id.rs", + "gateway-rs/src/middleware/activity.rs" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::request_id_is_forwarded_to_authenticated_rest_upstream_and_response" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/correlation_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/correlation_util.py::function:get_correlation_id", + "notes": "Axum request extensions replace contextvars for request-scoped lookup.", + "rust_symbols": [ + "gateway-rs/src/middleware/request_id.rs::RequestId" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::request_id_is_forwarded_to_authenticated_rest_upstream_and_response" + ], + "source": { + "kind": "function", + "line": 16, + "path": "backend-services/utils/correlation_util.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/correlation_util.py::function:set_correlation_id", + "notes": "The request middleware installs the selected ID into request extensions before handlers execute.", + "rust_symbols": [ + "gateway-rs/src/middleware/request_id.rs::request_id" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::request_id_is_forwarded_to_authenticated_rest_upstream_and_response", + "gateway-rs/tests/platform_native.rs::platform_security_headers_csp_hsts_and_request_ids_match_python" + ], + "source": { + "kind": "function", + "line": 23, + "path": "backend-services/utils/correlation_util.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/correlation_util.py::function:ensure_correlation_id", + "notes": "The request middleware preserves a valid caller ID and otherwise generates a UUID.", + "rust_symbols": [ + "gateway-rs/src/middleware/request_id.rs::request_id" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::request_id_is_forwarded_to_authenticated_rest_upstream_and_response", + "gateway-rs/tests/platform_native.rs::platform_security_headers_csp_hsts_and_request_ids_match_python" + ], + "source": { + "kind": "function", + "line": 30, + "path": "backend-services/utils/correlation_util.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/correlation_util.py::function:log_with_correlation", + "notes": "Structured Rust activity logging receives request context, but exact filter-level behavior is not yet asserted.", + "rust_symbols": [ + "gateway-rs/src/middleware/activity.rs::activity" + ], + "rust_tests": [], + "source": { + "kind": "function", + "line": 41, + "path": "backend-services/utils/correlation_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/correlation_util.py::async_function:run_with_correlation", + "notes": "The helper is not referenced by pinned production code; Rust futures carry request state explicitly.", + "rationale": "Unused Python contextvars convenience wrapper with no externally observable contract.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "async_function", + "line": 50, + "path": "backend-services/utils/correlation_util.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/correlation_util.py::class:CorrelationContext", + "notes": "No pinned production caller constructs this context manager.", + "rationale": "Unused Python context-manager abstraction; request scoping is native middleware state in Rust.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "class", + "line": 63, + "path": "backend-services/utils/correlation_util.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/correlation_util.py::method:CorrelationContext.__init__", + "notes": "No pinned production caller constructs this context manager.", + "rationale": "Unused Python context-manager initializer with no externally observable contract.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "method", + "line": 68, + "path": "backend-services/utils/correlation_util.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/correlation_util.py::method:CorrelationContext.__enter__", + "notes": "No pinned production caller enters this context manager.", + "rationale": "Unused Python context-manager method with no externally observable contract.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "method", + "line": 72, + "path": "backend-services/utils/correlation_util.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/correlation_util.py::method:CorrelationContext.__exit__", + "notes": "No pinned production caller exits this context manager.", + "rationale": "Unused Python context-manager method with no externally observable contract.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "method", + "line": 76, + "path": "backend-services/utils/correlation_util.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/correlation_util.py::async_function:run_async_with_correlation", + "notes": "The helper is not referenced by pinned production code; Rust async tasks pass request context explicitly.", + "rationale": "Unused Python convenience wrapper with no externally observable contract.", + "rust_symbols": [], + "rust_tests": [], + "source": { + "kind": "async_function", + "line": 81, + "path": "backend-services/utils/correlation_util.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/correlation_util.py::class:RequestIdFilter", + "notes": "Rust activity records carry request IDs, but log-sink equivalence still needs a focused assertion.", + "rust_symbols": [ + "gateway-rs/src/middleware/activity.rs::activity", + "gateway-rs/src/middleware/request_id.rs::RequestId" + ], + "rust_tests": [], + "source": { + "kind": "class", + "line": 97, + "path": "backend-services/utils/correlation_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/correlation_util.py::method:RequestIdFilter.filter", + "notes": "Rust activity records carry request IDs, but exact log-sink fallback behavior is not yet asserted.", + "rust_symbols": [ + "gateway-rs/src/middleware/activity.rs::activity" + ], + "rust_tests": [], + "source": { + "kind": "method", + "line": 103, + "path": "backend-services/utils/correlation_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/credit_util.py::module:credit_util", + "notes": "Rust atomically deducts credits, resolves user and definition headers, decrypts legacy enc: values, and implements old/new key rotation timing. Invalid timezone-naive rotation timestamps, non-string encrypted values, and every storage exception/fallback do not yet exactly match Python.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.deduct_credit", + "gateway-rs/src/policy/credits.rs::credit_header_values", + "gateway-rs/src/policy/credits.rs::evaluate_credits" + ], + "rust_tests": [ + "gateway-rs/src/policy/credits.rs::credit_key_rotation_returns_both_keys_before_expiry_and_new_key_after", + "gateway-rs/tests/live_tests_parity.rs::live_test_30_rest_gateway_basic_crud_and_subscription_parity" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/credit_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/credit_util.py::async_function:deduct_credit", + "notes": "Rust atomically deducts credits, resolves user and definition headers, decrypts legacy enc: values, and implements old/new key rotation timing. Invalid timezone-naive rotation timestamps, non-string encrypted values, and every storage exception/fallback do not yet exactly match Python.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.deduct_credit", + "gateway-rs/src/policy/credits.rs::credit_header_values", + "gateway-rs/src/policy/credits.rs::evaluate_credits" + ], + "rust_tests": [ + "gateway-rs/src/policy/credits.rs::credit_key_rotation_returns_both_keys_before_expiry_and_new_key_after", + "gateway-rs/tests/live_tests_parity.rs::live_test_30_rest_gateway_basic_crud_and_subscription_parity" + ], + "source": { + "kind": "async_function", + "line": 8, + "path": "backend-services/utils/credit_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/credit_util.py::async_function:get_user_api_key", + "notes": "Rust atomically deducts credits, resolves user and definition headers, decrypts legacy enc: values, and implements old/new key rotation timing. Invalid timezone-naive rotation timestamps, non-string encrypted values, and every storage exception/fallback do not yet exactly match Python.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.deduct_credit", + "gateway-rs/src/policy/credits.rs::credit_header_values", + "gateway-rs/src/policy/credits.rs::evaluate_credits" + ], + "rust_tests": [ + "gateway-rs/src/policy/credits.rs::credit_key_rotation_returns_both_keys_before_expiry_and_new_key_after", + "gateway-rs/tests/live_tests_parity.rs::live_test_30_rest_gateway_basic_crud_and_subscription_parity" + ], + "source": { + "kind": "async_function", + "line": 27, + "path": "backend-services/utils/credit_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/credit_util.py::async_function:get_credit_api_header", + "notes": "Rust atomically deducts credits, resolves user and definition headers, decrypts legacy enc: values, and implements old/new key rotation timing. Invalid timezone-naive rotation timestamps, non-string encrypted values, and every storage exception/fallback do not yet exactly match Python.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.deduct_credit", + "gateway-rs/src/policy/credits.rs::credit_header_values", + "gateway-rs/src/policy/credits.rs::evaluate_credits" + ], + "rust_tests": [ + "gateway-rs/src/policy/credits.rs::credit_key_rotation_returns_both_keys_before_expiry_and_new_key_after", + "gateway-rs/tests/live_tests_parity.rs::live_test_30_rest_gateway_basic_crud_and_subscription_parity" + ], + "source": { + "kind": "async_function", + "line": 40, + "path": "backend-services/utils/credit_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::module:database", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::function:_build_admin_seed_doc", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "function", + "line": 29, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::class:Database", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "class", + "line": 55, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::method:Database.__init__", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 56, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::method:Database.get_collection", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 97, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::method:Database.initialize_collections", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 102, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::function:Database.initialize_collections.admin_seed_credentials", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "function", + "line": 103, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::method:Database.create_indexes", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 248, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::method:Database.is_memory_only", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 309, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::method:Database.get_mode_info", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 312, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::class:InMemoryInsertResult", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "class", + "line": 321, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::method:InMemoryInsertResult.__init__", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 322, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::class:InMemoryUpdateResult", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "class", + "line": 327, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::method:InMemoryUpdateResult.__init__", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 328, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::class:InMemoryDeleteResult", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "class", + "line": 333, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::method:InMemoryDeleteResult.__init__", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 334, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::class:InMemoryCursor", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "class", + "line": 339, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::method:InMemoryCursor.__init__", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 340, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::method:InMemoryCursor.sort", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 344, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::method:InMemoryCursor.skip", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 349, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::method:InMemoryCursor.limit", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 353, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::method:InMemoryCursor.__iter__", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 358, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::method:InMemoryCursor.__aiter__", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 361, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::async_method:InMemoryCursor.__anext__", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "async_method", + "line": 366, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::method:InMemoryCursor.to_list", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 374, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::class:InMemoryCollection", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "class", + "line": 384, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::method:InMemoryCollection.__init__", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 385, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::method:InMemoryCollection._match", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 390, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::method:InMemoryCollection.find_one", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 417, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::field:InMemoryCollection.find_one_sync", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "field", + "line": 430, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::method:InMemoryCollection.find", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 432, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::method:InMemoryCollection.insert_one", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 441, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::field:InMemoryCollection.insert_one_sync", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "field", + "line": 454, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::method:InMemoryCollection.update_one", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 456, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::field:InMemoryCollection.update_one_sync", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "field", + "line": 495, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::method:InMemoryCollection.delete_one", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 497, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::method:InMemoryCollection.count_documents", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 508, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::method:InMemoryCollection.replace_one", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 516, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::method:InMemoryCollection.find_one_and_update", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 532, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::method:InMemoryCollection.create_indexes", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 560, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::class:AsyncInMemoryCollection", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "class", + "line": 564, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::method:AsyncInMemoryCollection.__init__", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 567, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::async_method:AsyncInMemoryCollection.find_one", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "async_method", + "line": 571, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::method:AsyncInMemoryCollection.find", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 575, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::async_method:AsyncInMemoryCollection.insert_one", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "async_method", + "line": 579, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::async_method:AsyncInMemoryCollection.update_one", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "async_method", + "line": 583, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::async_method:AsyncInMemoryCollection.delete_one", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "async_method", + "line": 587, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::async_method:AsyncInMemoryCollection.count_documents", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "async_method", + "line": 591, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::async_method:AsyncInMemoryCollection.replace_one", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "async_method", + "line": 595, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::async_method:AsyncInMemoryCollection.find_one_and_update", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "async_method", + "line": 599, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::method:AsyncInMemoryCollection.create_indexes", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 603, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::class:InMemoryDB", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "class", + "line": 607, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::method:InMemoryDB.__init__", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 608, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::method:InMemoryDB.list_collection_names", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 665, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::method:InMemoryDB.create_collection", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 695, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::method:InMemoryDB.__getitem__", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 701, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::method:InMemoryDB.get_database", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 704, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::method:InMemoryDB.dump_data", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 707, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::function:InMemoryDB.dump_data.coll_docs", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "function", + "line": 708, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::method:InMemoryDB.load_data", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 729, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::function:InMemoryDB.load_data.load_coll", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "function", + "line": 730, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database.py::function:close_database_connections", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "function", + "line": 791, + "path": "backend-services/utils/database.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database_async.py::module:database_async", + "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language-specific; native external mode also validates its Redis dependency during the same connection phase.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/state.rs::AppState.from_config" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart", + "gateway-rs/tests/platform_native.rs::memory_mode_login_crud_import_and_rollback_are_native" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/database_async.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database_async.py::class:AsyncDatabase", + "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language-specific; native external mode also validates its Redis dependency during the same connection phase.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/state.rs::AppState.from_config" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart", + "gateway-rs/tests/platform_native.rs::memory_mode_login_crud_import_and_rollback_are_native" + ], + "source": { + "kind": "class", + "line": 32, + "path": "backend-services/utils/database_async.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database_async.py::method:AsyncDatabase.__init__", + "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language-specific; native external mode also validates its Redis dependency during the same connection phase.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/state.rs::AppState.from_config" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart", + "gateway-rs/tests/platform_native.rs::memory_mode_login_crud_import_and_rollback_are_native" + ], + "source": { + "kind": "method", + "line": 35, + "path": "backend-services/utils/database_async.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database_async.py::class:AsyncDatabase.__init__._AsyncDBView", + "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language-specific; native external mode also validates its Redis dependency during the same connection phase.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/state.rs::AppState.from_config" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart", + "gateway-rs/tests/platform_native.rs::memory_mode_login_crud_import_and_rollback_are_native" + ], + "source": { + "kind": "class", + "line": 51, + "path": "backend-services/utils/database_async.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database_async.py::method:AsyncDatabase.__init__._AsyncDBView.__init__", + "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language-specific; native external mode also validates its Redis dependency during the same connection phase.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/state.rs::AppState.from_config" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart", + "gateway-rs/tests/platform_native.rs::memory_mode_login_crud_import_and_rollback_are_native" + ], + "source": { + "kind": "method", + "line": 52, + "path": "backend-services/utils/database_async.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database_async.py::method:AsyncDatabase.__init__._AsyncDBView.get_collection", + "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language-specific; native external mode also validates its Redis dependency during the same connection phase.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/state.rs::AppState.from_config" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart", + "gateway-rs/tests/platform_native.rs::memory_mode_login_crud_import_and_rollback_are_native" + ], + "source": { + "kind": "method", + "line": 74, + "path": "backend-services/utils/database_async.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database_async.py::method:AsyncDatabase.__init__._AsyncDBView.__getitem__", + "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language-specific; native external mode also validates its Redis dependency during the same connection phase.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/state.rs::AppState.from_config" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart", + "gateway-rs/tests/platform_native.rs::memory_mode_login_crud_import_and_rollback_are_native" + ], + "source": { + "kind": "method", + "line": 85, + "path": "backend-services/utils/database_async.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database_async.py::method:AsyncDatabase.__init__._AsyncDBView.__getattr__", + "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language-specific; native external mode also validates its Redis dependency during the same connection phase.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/state.rs::AppState.from_config" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart", + "gateway-rs/tests/platform_native.rs::memory_mode_login_crud_import_and_rollback_are_native" + ], + "source": { + "kind": "method", + "line": 88, + "path": "backend-services/utils/database_async.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database_async.py::method:AsyncDatabase.__init__._AsyncDBView.list_collection_names", + "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language-specific; native external mode also validates its Redis dependency during the same connection phase.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/state.rs::AppState.from_config" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart", + "gateway-rs/tests/platform_native.rs::memory_mode_login_crud_import_and_rollback_are_native" + ], + "source": { + "kind": "method", + "line": 94, + "path": "backend-services/utils/database_async.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database_async.py::method:AsyncDatabase.__init__._AsyncDBView.get_database", + "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language-specific; native external mode also validates its Redis dependency during the same connection phase.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/state.rs::AppState.from_config" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart", + "gateway-rs/tests/platform_native.rs::memory_mode_login_crud_import_and_rollback_are_native" + ], + "source": { + "kind": "method", + "line": 97, + "path": "backend-services/utils/database_async.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database_async.py::method:AsyncDatabase.get_collection", + "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language-specific; native external mode also validates its Redis dependency during the same connection phase.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/state.rs::AppState.from_config" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart", + "gateway-rs/tests/platform_native.rs::memory_mode_login_crud_import_and_rollback_are_native" + ], + "source": { + "kind": "method", + "line": 145, + "path": "backend-services/utils/database_async.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database_async.py::async_method:AsyncDatabase.initialize_collections", + "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language-specific; native external mode also validates its Redis dependency during the same connection phase.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/state.rs::AppState.from_config" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart", + "gateway-rs/tests/platform_native.rs::memory_mode_login_crud_import_and_rollback_are_native" + ], + "source": { + "kind": "async_method", + "line": 151, + "path": "backend-services/utils/database_async.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database_async.py::async_method:AsyncDatabase.create_indexes", + "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language-specific; native external mode also validates its Redis dependency during the same connection phase.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/state.rs::AppState.from_config" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart", + "gateway-rs/tests/platform_native.rs::memory_mode_login_crud_import_and_rollback_are_native" + ], + "source": { + "kind": "async_method", + "line": 281, + "path": "backend-services/utils/database_async.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database_async.py::method:AsyncDatabase.is_memory_only", + "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language-specific; native external mode also validates its Redis dependency during the same connection phase.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/state.rs::AppState.from_config" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart", + "gateway-rs/tests/platform_native.rs::memory_mode_login_crud_import_and_rollback_are_native" + ], + "source": { + "kind": "method", + "line": 347, + "path": "backend-services/utils/database_async.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database_async.py::method:AsyncDatabase.get_mode_info", + "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language-specific; native external mode also validates its Redis dependency during the same connection phase.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/state.rs::AppState.from_config" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart", + "gateway-rs/tests/platform_native.rs::memory_mode_login_crud_import_and_rollback_are_native" + ], + "source": { + "kind": "method", + "line": 351, + "path": "backend-services/utils/database_async.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database_async.py::async_method:AsyncDatabase.close", + "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language-specific; native external mode also validates its Redis dependency during the same connection phase.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/state.rs::AppState.from_config" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart", + "gateway-rs/tests/platform_native.rs::memory_mode_login_crud_import_and_rollback_are_native" + ], + "source": { + "kind": "async_method", + "line": 360, + "path": "backend-services/utils/database_async.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/database_async.py::async_function:close_async_database_connections", + "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language-specific; native external mode also validates its Redis dependency during the same connection phase.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/state.rs::AppState.from_config" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart", + "gateway-rs/tests/platform_native.rs::memory_mode_login_crud_import_and_rollback_are_native" + ], + "source": { + "kind": "async_function", + "line": 411, + "path": "backend-services/utils/database_async.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/demo_seed_util.py::module:demo_seed_util", + "notes": "Rust now implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, metrics, deterministic seeds, and collection-count results, in addition to the admin-only memory-mode demo endpoint. The seeded Rust RNG is reproducible but does not reproduce CPython's Mersenne Twister byte-for-byte, and the compact native analytics aggregator records generated metrics in the current minute rather than reconstructing 400 historical Python MinuteBucket timestamps.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::demo_seed", + "gateway-rs/src/demo_seed.rs::run_seed", + "gateway-rs/src/demo_seed.rs::SeedOptions" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs", + "gateway-rs/src/demo_seed.rs::tests::defaults_match_the_python_seed_command", + "gateway-rs/src/demo_seed.rs::tests::seeded_generators_are_reproducible", + "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/demo_seed_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/demo_seed_util.py::function:_rand_choice", + "notes": "Rust now implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, metrics, deterministic seeds, and collection-count results, in addition to the admin-only memory-mode demo endpoint. The seeded Rust RNG is reproducible but does not reproduce CPython's Mersenne Twister byte-for-byte, and the compact native analytics aggregator records generated metrics in the current minute rather than reconstructing 400 historical Python MinuteBucket timestamps.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::demo_seed", + "gateway-rs/src/demo_seed.rs::run_seed", + "gateway-rs/src/demo_seed.rs::SeedOptions" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs", + "gateway-rs/src/demo_seed.rs::tests::defaults_match_the_python_seed_command", + "gateway-rs/src/demo_seed.rs::tests::seeded_generators_are_reproducible", + "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults" + ], + "source": { + "kind": "function", + "line": 24, + "path": "backend-services/utils/demo_seed_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/demo_seed_util.py::function:_rand_word", + "notes": "Rust now implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, metrics, deterministic seeds, and collection-count results, in addition to the admin-only memory-mode demo endpoint. The seeded Rust RNG is reproducible but does not reproduce CPython's Mersenne Twister byte-for-byte, and the compact native analytics aggregator records generated metrics in the current minute rather than reconstructing 400 historical Python MinuteBucket timestamps.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::demo_seed", + "gateway-rs/src/demo_seed.rs::run_seed", + "gateway-rs/src/demo_seed.rs::SeedOptions" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs", + "gateway-rs/src/demo_seed.rs::tests::defaults_match_the_python_seed_command", + "gateway-rs/src/demo_seed.rs::tests::seeded_generators_are_reproducible", + "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults" + ], + "source": { + "kind": "function", + "line": 28, + "path": "backend-services/utils/demo_seed_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/demo_seed_util.py::function:_rand_name", + "notes": "Rust now implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, metrics, deterministic seeds, and collection-count results, in addition to the admin-only memory-mode demo endpoint. The seeded Rust RNG is reproducible but does not reproduce CPython's Mersenne Twister byte-for-byte, and the compact native analytics aggregator records generated metrics in the current minute rather than reconstructing 400 historical Python MinuteBucket timestamps.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::demo_seed", + "gateway-rs/src/demo_seed.rs::run_seed", + "gateway-rs/src/demo_seed.rs::SeedOptions" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs", + "gateway-rs/src/demo_seed.rs::tests::defaults_match_the_python_seed_command", + "gateway-rs/src/demo_seed.rs::tests::seeded_generators_are_reproducible", + "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults" + ], + "source": { + "kind": "function", + "line": 33, + "path": "backend-services/utils/demo_seed_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/demo_seed_util.py::function:_rand_domain", + "notes": "Rust now implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, metrics, deterministic seeds, and collection-count results, in addition to the admin-only memory-mode demo endpoint. The seeded Rust RNG is reproducible but does not reproduce CPython's Mersenne Twister byte-for-byte, and the compact native analytics aggregator records generated metrics in the current minute rather than reconstructing 400 historical Python MinuteBucket timestamps.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::demo_seed", + "gateway-rs/src/demo_seed.rs::run_seed", + "gateway-rs/src/demo_seed.rs::SeedOptions" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs", + "gateway-rs/src/demo_seed.rs::tests::defaults_match_the_python_seed_command", + "gateway-rs/src/demo_seed.rs::tests::seeded_generators_are_reproducible", + "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults" + ], + "source": { + "kind": "function", + "line": 68, + "path": "backend-services/utils/demo_seed_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/demo_seed_util.py::function:_rand_password", + "notes": "Rust now implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, metrics, deterministic seeds, and collection-count results, in addition to the admin-only memory-mode demo endpoint. The seeded Rust RNG is reproducible but does not reproduce CPython's Mersenne Twister byte-for-byte, and the compact native analytics aggregator records generated metrics in the current minute rather than reconstructing 400 historical Python MinuteBucket timestamps.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::demo_seed", + "gateway-rs/src/demo_seed.rs::run_seed", + "gateway-rs/src/demo_seed.rs::SeedOptions" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs", + "gateway-rs/src/demo_seed.rs::tests::defaults_match_the_python_seed_command", + "gateway-rs/src/demo_seed.rs::tests::seeded_generators_are_reproducible", + "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults" + ], + "source": { + "kind": "function", + "line": 72, + "path": "backend-services/utils/demo_seed_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/demo_seed_util.py::function:ensure_roles", + "notes": "Rust now implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, metrics, deterministic seeds, and collection-count results, in addition to the admin-only memory-mode demo endpoint. The seeded Rust RNG is reproducible but does not reproduce CPython's Mersenne Twister byte-for-byte, and the compact native analytics aggregator records generated metrics in the current minute rather than reconstructing 400 historical Python MinuteBucket timestamps.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::demo_seed", + "gateway-rs/src/demo_seed.rs::run_seed", + "gateway-rs/src/demo_seed.rs::SeedOptions" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs", + "gateway-rs/src/demo_seed.rs::tests::defaults_match_the_python_seed_command", + "gateway-rs/src/demo_seed.rs::tests::seeded_generators_are_reproducible", + "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults" + ], + "source": { + "kind": "function", + "line": 82, + "path": "backend-services/utils/demo_seed_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/demo_seed_util.py::function:seed_groups", + "notes": "Rust now implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, metrics, deterministic seeds, and collection-count results, in addition to the admin-only memory-mode demo endpoint. The seeded Rust RNG is reproducible but does not reproduce CPython's Mersenne Twister byte-for-byte, and the compact native analytics aggregator records generated metrics in the current minute rather than reconstructing 400 historical Python MinuteBucket timestamps.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::demo_seed", + "gateway-rs/src/demo_seed.rs::run_seed", + "gateway-rs/src/demo_seed.rs::SeedOptions" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs", + "gateway-rs/src/demo_seed.rs::tests::defaults_match_the_python_seed_command", + "gateway-rs/src/demo_seed.rs::tests::seeded_generators_are_reproducible", + "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults" + ], + "source": { + "kind": "function", + "line": 108, + "path": "backend-services/utils/demo_seed_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/demo_seed_util.py::function:seed_users", + "notes": "Rust now implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, metrics, deterministic seeds, and collection-count results, in addition to the admin-only memory-mode demo endpoint. The seeded Rust RNG is reproducible but does not reproduce CPython's Mersenne Twister byte-for-byte, and the compact native analytics aggregator records generated metrics in the current minute rather than reconstructing 400 historical Python MinuteBucket timestamps.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::demo_seed", + "gateway-rs/src/demo_seed.rs::run_seed", + "gateway-rs/src/demo_seed.rs::SeedOptions" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs", + "gateway-rs/src/demo_seed.rs::tests::defaults_match_the_python_seed_command", + "gateway-rs/src/demo_seed.rs::tests::seeded_generators_are_reproducible", + "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults" + ], + "source": { + "kind": "function", + "line": 141, + "path": "backend-services/utils/demo_seed_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/demo_seed_util.py::function:seed_apis", + "notes": "Rust now implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, metrics, deterministic seeds, and collection-count results, in addition to the admin-only memory-mode demo endpoint. The seeded Rust RNG is reproducible but does not reproduce CPython's Mersenne Twister byte-for-byte, and the compact native analytics aggregator records generated metrics in the current minute rather than reconstructing 400 historical Python MinuteBucket timestamps.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::demo_seed", + "gateway-rs/src/demo_seed.rs::run_seed", + "gateway-rs/src/demo_seed.rs::SeedOptions" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs", + "gateway-rs/src/demo_seed.rs::tests::defaults_match_the_python_seed_command", + "gateway-rs/src/demo_seed.rs::tests::seeded_generators_are_reproducible", + "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults" + ], + "source": { + "kind": "function", + "line": 180, + "path": "backend-services/utils/demo_seed_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/demo_seed_util.py::function:seed_endpoints", + "notes": "Rust now implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, metrics, deterministic seeds, and collection-count results, in addition to the admin-only memory-mode demo endpoint. The seeded Rust RNG is reproducible but does not reproduce CPython's Mersenne Twister byte-for-byte, and the compact native analytics aggregator records generated metrics in the current minute rather than reconstructing 400 historical Python MinuteBucket timestamps.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::demo_seed", + "gateway-rs/src/demo_seed.rs::run_seed", + "gateway-rs/src/demo_seed.rs::SeedOptions" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs", + "gateway-rs/src/demo_seed.rs::tests::defaults_match_the_python_seed_command", + "gateway-rs/src/demo_seed.rs::tests::seeded_generators_are_reproducible", + "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults" + ], + "source": { + "kind": "function", + "line": 233, + "path": "backend-services/utils/demo_seed_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/demo_seed_util.py::function:seed_credits", + "notes": "Rust now implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, metrics, deterministic seeds, and collection-count results, in addition to the admin-only memory-mode demo endpoint. The seeded Rust RNG is reproducible but does not reproduce CPython's Mersenne Twister byte-for-byte, and the compact native analytics aggregator records generated metrics in the current minute rather than reconstructing 400 historical Python MinuteBucket timestamps.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::demo_seed", + "gateway-rs/src/demo_seed.rs::run_seed", + "gateway-rs/src/demo_seed.rs::SeedOptions" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs", + "gateway-rs/src/demo_seed.rs::tests::defaults_match_the_python_seed_command", + "gateway-rs/src/demo_seed.rs::tests::seeded_generators_are_reproducible", + "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults" + ], + "source": { + "kind": "function", + "line": 275, + "path": "backend-services/utils/demo_seed_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/demo_seed_util.py::function:seed_user_credits", + "notes": "Rust now implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, metrics, deterministic seeds, and collection-count results, in addition to the admin-only memory-mode demo endpoint. The seeded Rust RNG is reproducible but does not reproduce CPython's Mersenne Twister byte-for-byte, and the compact native analytics aggregator records generated metrics in the current minute rather than reconstructing 400 historical Python MinuteBucket timestamps.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::demo_seed", + "gateway-rs/src/demo_seed.rs::run_seed", + "gateway-rs/src/demo_seed.rs::SeedOptions" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs", + "gateway-rs/src/demo_seed.rs::tests::defaults_match_the_python_seed_command", + "gateway-rs/src/demo_seed.rs::tests::seeded_generators_are_reproducible", + "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults" + ], + "source": { + "kind": "function", + "line": 318, + "path": "backend-services/utils/demo_seed_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/demo_seed_util.py::function:seed_subscriptions", + "notes": "Rust now implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, metrics, deterministic seeds, and collection-count results, in addition to the admin-only memory-mode demo endpoint. The seeded Rust RNG is reproducible but does not reproduce CPython's Mersenne Twister byte-for-byte, and the compact native analytics aggregator records generated metrics in the current minute rather than reconstructing 400 historical Python MinuteBucket timestamps.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::demo_seed", + "gateway-rs/src/demo_seed.rs::run_seed", + "gateway-rs/src/demo_seed.rs::SeedOptions" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs", + "gateway-rs/src/demo_seed.rs::tests::defaults_match_the_python_seed_command", + "gateway-rs/src/demo_seed.rs::tests::seeded_generators_are_reproducible", + "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults" + ], + "source": { + "kind": "function", + "line": 344, + "path": "backend-services/utils/demo_seed_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/demo_seed_util.py::function:seed_logs", + "notes": "Rust now implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, metrics, deterministic seeds, and collection-count results, in addition to the admin-only memory-mode demo endpoint. The seeded Rust RNG is reproducible but does not reproduce CPython's Mersenne Twister byte-for-byte, and the compact native analytics aggregator records generated metrics in the current minute rather than reconstructing 400 historical Python MinuteBucket timestamps.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::demo_seed", + "gateway-rs/src/demo_seed.rs::run_seed", + "gateway-rs/src/demo_seed.rs::SeedOptions" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs", + "gateway-rs/src/demo_seed.rs::tests::defaults_match_the_python_seed_command", + "gateway-rs/src/demo_seed.rs::tests::seeded_generators_are_reproducible", + "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults" + ], + "source": { + "kind": "function", + "line": 359, + "path": "backend-services/utils/demo_seed_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/demo_seed_util.py::function:seed_protos", + "notes": "Rust now implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, metrics, deterministic seeds, and collection-count results, in addition to the admin-only memory-mode demo endpoint. The seeded Rust RNG is reproducible but does not reproduce CPython's Mersenne Twister byte-for-byte, and the compact native analytics aggregator records generated metrics in the current minute rather than reconstructing 400 historical Python MinuteBucket timestamps.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::demo_seed", + "gateway-rs/src/demo_seed.rs::run_seed", + "gateway-rs/src/demo_seed.rs::SeedOptions" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs", + "gateway-rs/src/demo_seed.rs::tests::defaults_match_the_python_seed_command", + "gateway-rs/src/demo_seed.rs::tests::seeded_generators_are_reproducible", + "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults" + ], + "source": { + "kind": "function", + "line": 383, + "path": "backend-services/utils/demo_seed_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/demo_seed_util.py::function:seed_metrics", + "notes": "Rust now implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, metrics, deterministic seeds, and collection-count results, in addition to the admin-only memory-mode demo endpoint. The seeded Rust RNG is reproducible but does not reproduce CPython's Mersenne Twister byte-for-byte, and the compact native analytics aggregator records generated metrics in the current minute rather than reconstructing 400 historical Python MinuteBucket timestamps.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::demo_seed", + "gateway-rs/src/demo_seed.rs::run_seed", + "gateway-rs/src/demo_seed.rs::SeedOptions" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs", + "gateway-rs/src/demo_seed.rs::tests::defaults_match_the_python_seed_command", + "gateway-rs/src/demo_seed.rs::tests::seeded_generators_are_reproducible", + "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults" + ], + "source": { + "kind": "function", + "line": 416, + "path": "backend-services/utils/demo_seed_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/demo_seed_util.py::function:run_seed", + "notes": "Rust now implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, metrics, deterministic seeds, and collection-count results, in addition to the admin-only memory-mode demo endpoint. The seeded Rust RNG is reproducible but does not reproduce CPython's Mersenne Twister byte-for-byte, and the compact native analytics aggregator records generated metrics in the current minute rather than reconstructing 400 historical Python MinuteBucket timestamps.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::demo_seed", + "gateway-rs/src/demo_seed.rs::run_seed", + "gateway-rs/src/demo_seed.rs::SeedOptions" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs", + "gateway-rs/src/demo_seed.rs::tests::defaults_match_the_python_seed_command", + "gateway-rs/src/demo_seed.rs::tests::seeded_generators_are_reproducible", + "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults" + ], + "source": { + "kind": "function", + "line": 437, + "path": "backend-services/utils/demo_seed_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/doorman_cache_async.py::module:doorman_cache_async", + "notes": "The pinned async cache manager is not imported by production code; it exists for standalone compatibility tests. Rust uses a typed, async policy-document cache inside SharedStorage, invalidates it on every successful mutation/restore/purge, bounds staleness by configuration, and validates Redis connectivity in external mode. Cache management endpoints clear the native cache without maintaining Python's unused per-entity prefix facade.", + "rationale": "Unused Python async Redis/memory compatibility facade made obsolete by the native shared-storage policy cache.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.load_policy_documents", + "gateway-rs/src/storage/runtime.rs::SharedStorage.invalidate_policy_cache", + "gateway-rs/src/routes/operations.rs" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart", + "gateway-rs/tests/memory_routes_parity.rs" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/doorman_cache_async.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/doorman_cache_async.py::class:AsyncDoormanCacheManager", + "notes": "The pinned async cache manager is not imported by production code; it exists for standalone compatibility tests. Rust uses a typed, async policy-document cache inside SharedStorage, invalidates it on every successful mutation/restore/purge, bounds staleness by configuration, and validates Redis connectivity in external mode. Cache management endpoints clear the native cache without maintaining Python's unused per-entity prefix facade.", + "rationale": "Unused Python async Redis/memory compatibility facade made obsolete by the native shared-storage policy cache.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.load_policy_documents", + "gateway-rs/src/storage/runtime.rs::SharedStorage.invalidate_policy_cache", + "gateway-rs/src/routes/operations.rs" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart", + "gateway-rs/tests/memory_routes_parity.rs" + ], + "source": { + "kind": "class", + "line": 21, + "path": "backend-services/utils/doorman_cache_async.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/doorman_cache_async.py::method:AsyncDoormanCacheManager.__init__", + "notes": "The pinned async cache manager is not imported by production code; it exists for standalone compatibility tests. Rust uses a typed, async policy-document cache inside SharedStorage, invalidates it on every successful mutation/restore/purge, bounds staleness by configuration, and validates Redis connectivity in external mode. Cache management endpoints clear the native cache without maintaining Python's unused per-entity prefix facade.", + "rationale": "Unused Python async Redis/memory compatibility facade made obsolete by the native shared-storage policy cache.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.load_policy_documents", + "gateway-rs/src/storage/runtime.rs::SharedStorage.invalidate_policy_cache", + "gateway-rs/src/routes/operations.rs" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart", + "gateway-rs/tests/memory_routes_parity.rs" + ], + "source": { + "kind": "method", + "line": 24, + "path": "backend-services/utils/doorman_cache_async.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/doorman_cache_async.py::method:AsyncDoormanCacheManager._to_json_serializable", + "notes": "The pinned async cache manager is not imported by production code; it exists for standalone compatibility tests. Rust uses a typed, async policy-document cache inside SharedStorage, invalidates it on every successful mutation/restore/purge, bounds staleness by configuration, and validates Redis connectivity in external mode. Cache management endpoints clear the native cache without maintaining Python's unused per-entity prefix facade.", + "rationale": "Unused Python async Redis/memory compatibility facade made obsolete by the native shared-storage policy cache.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.load_policy_documents", + "gateway-rs/src/storage/runtime.rs::SharedStorage.invalidate_policy_cache", + "gateway-rs/src/routes/operations.rs" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart", + "gateway-rs/tests/memory_routes_parity.rs" + ], + "source": { + "kind": "method", + "line": 78, + "path": "backend-services/utils/doorman_cache_async.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/doorman_cache_async.py::async_method:AsyncDoormanCacheManager._ensure_redis_connection", + "notes": "The pinned async cache manager is not imported by production code; it exists for standalone compatibility tests. Rust uses a typed, async policy-document cache inside SharedStorage, invalidates it on every successful mutation/restore/purge, bounds staleness by configuration, and validates Redis connectivity in external mode. Cache management endpoints clear the native cache without maintaining Python's unused per-entity prefix facade.", + "rationale": "Unused Python async Redis/memory compatibility facade made obsolete by the native shared-storage policy cache.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.load_policy_documents", + "gateway-rs/src/storage/runtime.rs::SharedStorage.invalidate_policy_cache", + "gateway-rs/src/routes/operations.rs" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart", + "gateway-rs/tests/memory_routes_parity.rs" + ], + "source": { + "kind": "async_method", + "line": 97, + "path": "backend-services/utils/doorman_cache_async.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/doorman_cache_async.py::method:AsyncDoormanCacheManager._get_key", + "notes": "The pinned async cache manager is not imported by production code; it exists for standalone compatibility tests. Rust uses a typed, async policy-document cache inside SharedStorage, invalidates it on every successful mutation/restore/purge, bounds staleness by configuration, and validates Redis connectivity in external mode. Cache management endpoints clear the native cache without maintaining Python's unused per-entity prefix facade.", + "rationale": "Unused Python async Redis/memory compatibility facade made obsolete by the native shared-storage policy cache.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.load_policy_documents", + "gateway-rs/src/storage/runtime.rs::SharedStorage.invalidate_policy_cache", + "gateway-rs/src/routes/operations.rs" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart", + "gateway-rs/tests/memory_routes_parity.rs" + ], + "source": { + "kind": "method", + "line": 136, + "path": "backend-services/utils/doorman_cache_async.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/doorman_cache_async.py::async_method:AsyncDoormanCacheManager.set_cache", + "notes": "The pinned async cache manager is not imported by production code; it exists for standalone compatibility tests. Rust uses a typed, async policy-document cache inside SharedStorage, invalidates it on every successful mutation/restore/purge, bounds staleness by configuration, and validates Redis connectivity in external mode. Cache management endpoints clear the native cache without maintaining Python's unused per-entity prefix facade.", + "rationale": "Unused Python async Redis/memory compatibility facade made obsolete by the native shared-storage policy cache.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.load_policy_documents", + "gateway-rs/src/storage/runtime.rs::SharedStorage.invalidate_policy_cache", + "gateway-rs/src/routes/operations.rs" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart", + "gateway-rs/tests/memory_routes_parity.rs" + ], + "source": { + "kind": "async_method", + "line": 140, + "path": "backend-services/utils/doorman_cache_async.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/doorman_cache_async.py::async_method:AsyncDoormanCacheManager.get_cache", + "notes": "The pinned async cache manager is not imported by production code; it exists for standalone compatibility tests. Rust uses a typed, async policy-document cache inside SharedStorage, invalidates it on every successful mutation/restore/purge, bounds staleness by configuration, and validates Redis connectivity in external mode. Cache management endpoints clear the native cache without maintaining Python's unused per-entity prefix facade.", + "rationale": "Unused Python async Redis/memory compatibility facade made obsolete by the native shared-storage policy cache.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.load_policy_documents", + "gateway-rs/src/storage/runtime.rs::SharedStorage.invalidate_policy_cache", + "gateway-rs/src/routes/operations.rs" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart", + "gateway-rs/tests/memory_routes_parity.rs" + ], + "source": { + "kind": "async_method", + "line": 154, + "path": "backend-services/utils/doorman_cache_async.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/doorman_cache_async.py::async_method:AsyncDoormanCacheManager.delete_cache", + "notes": "The pinned async cache manager is not imported by production code; it exists for standalone compatibility tests. Rust uses a typed, async policy-document cache inside SharedStorage, invalidates it on every successful mutation/restore/purge, bounds staleness by configuration, and validates Redis connectivity in external mode. Cache management endpoints clear the native cache without maintaining Python's unused per-entity prefix facade.", + "rationale": "Unused Python async Redis/memory compatibility facade made obsolete by the native shared-storage policy cache.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.load_policy_documents", + "gateway-rs/src/storage/runtime.rs::SharedStorage.invalidate_policy_cache", + "gateway-rs/src/routes/operations.rs" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart", + "gateway-rs/tests/memory_routes_parity.rs" + ], + "source": { + "kind": "async_method", + "line": 173, + "path": "backend-services/utils/doorman_cache_async.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/doorman_cache_async.py::async_method:AsyncDoormanCacheManager.clear_cache", + "notes": "The pinned async cache manager is not imported by production code; it exists for standalone compatibility tests. Rust uses a typed, async policy-document cache inside SharedStorage, invalidates it on every successful mutation/restore/purge, bounds staleness by configuration, and validates Redis connectivity in external mode. Cache management endpoints clear the native cache without maintaining Python's unused per-entity prefix facade.", + "rationale": "Unused Python async Redis/memory compatibility facade made obsolete by the native shared-storage policy cache.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.load_policy_documents", + "gateway-rs/src/storage/runtime.rs::SharedStorage.invalidate_policy_cache", + "gateway-rs/src/routes/operations.rs" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart", + "gateway-rs/tests/memory_routes_parity.rs" + ], + "source": { + "kind": "async_method", + "line": 185, + "path": "backend-services/utils/doorman_cache_async.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/doorman_cache_async.py::async_method:AsyncDoormanCacheManager.clear_all_caches", + "notes": "The pinned async cache manager is not imported by production code; it exists for standalone compatibility tests. Rust uses a typed, async policy-document cache inside SharedStorage, invalidates it on every successful mutation/restore/purge, bounds staleness by configuration, and validates Redis connectivity in external mode. Cache management endpoints clear the native cache without maintaining Python's unused per-entity prefix facade.", + "rationale": "Unused Python async Redis/memory compatibility facade made obsolete by the native shared-storage policy cache.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.load_policy_documents", + "gateway-rs/src/storage/runtime.rs::SharedStorage.invalidate_policy_cache", + "gateway-rs/src/routes/operations.rs" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart", + "gateway-rs/tests/memory_routes_parity.rs" + ], + "source": { + "kind": "async_method", + "line": 201, + "path": "backend-services/utils/doorman_cache_async.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/doorman_cache_async.py::async_method:AsyncDoormanCacheManager.get_cache_info", + "notes": "The pinned async cache manager is not imported by production code; it exists for standalone compatibility tests. Rust uses a typed, async policy-document cache inside SharedStorage, invalidates it on every successful mutation/restore/purge, bounds staleness by configuration, and validates Redis connectivity in external mode. Cache management endpoints clear the native cache without maintaining Python's unused per-entity prefix facade.", + "rationale": "Unused Python async Redis/memory compatibility facade made obsolete by the native shared-storage policy cache.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.load_policy_documents", + "gateway-rs/src/storage/runtime.rs::SharedStorage.invalidate_policy_cache", + "gateway-rs/src/routes/operations.rs" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart", + "gateway-rs/tests/memory_routes_parity.rs" + ], + "source": { + "kind": "async_method", + "line": 206, + "path": "backend-services/utils/doorman_cache_async.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/doorman_cache_async.py::async_method:AsyncDoormanCacheManager.cleanup_expired_entries", + "notes": "The pinned async cache manager is not imported by production code; it exists for standalone compatibility tests. Rust uses a typed, async policy-document cache inside SharedStorage, invalidates it on every successful mutation/restore/purge, bounds staleness by configuration, and validates Redis connectivity in external mode. Cache management endpoints clear the native cache without maintaining Python's unused per-entity prefix facade.", + "rationale": "Unused Python async Redis/memory compatibility facade made obsolete by the native shared-storage policy cache.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.load_policy_documents", + "gateway-rs/src/storage/runtime.rs::SharedStorage.invalidate_policy_cache", + "gateway-rs/src/routes/operations.rs" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart", + "gateway-rs/tests/memory_routes_parity.rs" + ], + "source": { + "kind": "async_method", + "line": 220, + "path": "backend-services/utils/doorman_cache_async.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/doorman_cache_async.py::async_method:AsyncDoormanCacheManager.is_operational", + "notes": "The pinned async cache manager is not imported by production code; it exists for standalone compatibility tests. Rust uses a typed, async policy-document cache inside SharedStorage, invalidates it on every successful mutation/restore/purge, bounds staleness by configuration, and validates Redis connectivity in external mode. Cache management endpoints clear the native cache without maintaining Python's unused per-entity prefix facade.", + "rationale": "Unused Python async Redis/memory compatibility facade made obsolete by the native shared-storage policy cache.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.load_policy_documents", + "gateway-rs/src/storage/runtime.rs::SharedStorage.invalidate_policy_cache", + "gateway-rs/src/routes/operations.rs" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart", + "gateway-rs/tests/memory_routes_parity.rs" + ], + "source": { + "kind": "async_method", + "line": 225, + "path": "backend-services/utils/doorman_cache_async.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/doorman_cache_async.py::async_method:AsyncDoormanCacheManager.invalidate_on_db_failure", + "notes": "The pinned async cache manager is not imported by production code; it exists for standalone compatibility tests. Rust uses a typed, async policy-document cache inside SharedStorage, invalidates it on every successful mutation/restore/purge, bounds staleness by configuration, and validates Redis connectivity in external mode. Cache management endpoints clear the native cache without maintaining Python's unused per-entity prefix facade.", + "rationale": "Unused Python async Redis/memory compatibility facade made obsolete by the native shared-storage policy cache.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.load_policy_documents", + "gateway-rs/src/storage/runtime.rs::SharedStorage.invalidate_policy_cache", + "gateway-rs/src/routes/operations.rs" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart", + "gateway-rs/tests/memory_routes_parity.rs" + ], + "source": { + "kind": "async_method", + "line": 237, + "path": "backend-services/utils/doorman_cache_async.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/doorman_cache_async.py::async_method:AsyncDoormanCacheManager.close", + "notes": "The pinned async cache manager is not imported by production code; it exists for standalone compatibility tests. Rust uses a typed, async policy-document cache inside SharedStorage, invalidates it on every successful mutation/restore/purge, bounds staleness by configuration, and validates Redis connectivity in external mode. Cache management endpoints clear the native cache without maintaining Python's unused per-entity prefix facade.", + "rationale": "Unused Python async Redis/memory compatibility facade made obsolete by the native shared-storage policy cache.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.load_policy_documents", + "gateway-rs/src/storage/runtime.rs::SharedStorage.invalidate_policy_cache", + "gateway-rs/src/routes/operations.rs" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart", + "gateway-rs/tests/memory_routes_parity.rs" + ], + "source": { + "kind": "async_method", + "line": 279, + "path": "backend-services/utils/doorman_cache_async.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/doorman_cache_async.py::async_function:close_async_cache_connections", + "notes": "The pinned async cache manager is not imported by production code; it exists for standalone compatibility tests. Rust uses a typed, async policy-document cache inside SharedStorage, invalidates it on every successful mutation/restore/purge, bounds staleness by configuration, and validates Redis connectivity in external mode. Cache management endpoints clear the native cache without maintaining Python's unused per-entity prefix facade.", + "rationale": "Unused Python async Redis/memory compatibility facade made obsolete by the native shared-storage policy cache.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.load_policy_documents", + "gateway-rs/src/storage/runtime.rs::SharedStorage.invalidate_policy_cache", + "gateway-rs/src/routes/operations.rs" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart", + "gateway-rs/tests/memory_routes_parity.rs" + ], + "source": { + "kind": "async_function", + "line": 291, + "path": "backend-services/utils/doorman_cache_async.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/doorman_cache_util.py::module:doorman_cache_util", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::CacheName", + "gateway-rs/src/storage/memory.rs::MemoryStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.clear_gateway_state", + "gateway-rs/src/routes/operations.rs::clear_caches" + ], + "rust_tests": [ + "gateway-rs/src/storage/cache.rs::tests::preserves_python_cache_prefixes", + "gateway-rs/src/storage/cache.rs::tests::expires_window_counters", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/doorman_cache_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/doorman_cache_util.py::class:MemoryCache", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::CacheName", + "gateway-rs/src/storage/memory.rs::MemoryStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.clear_gateway_state", + "gateway-rs/src/routes/operations.rs::clear_caches" + ], + "rust_tests": [ + "gateway-rs/src/storage/cache.rs::tests::preserves_python_cache_prefixes", + "gateway-rs/src/storage/cache.rs::tests::expires_window_counters", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "source": { + "kind": "class", + "line": 19, + "path": "backend-services/utils/doorman_cache_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/doorman_cache_util.py::method:MemoryCache.__init__", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::CacheName", + "gateway-rs/src/storage/memory.rs::MemoryStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.clear_gateway_state", + "gateway-rs/src/routes/operations.rs::clear_caches" + ], + "rust_tests": [ + "gateway-rs/src/storage/cache.rs::tests::preserves_python_cache_prefixes", + "gateway-rs/src/storage/cache.rs::tests::expires_window_counters", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "source": { + "kind": "method", + "line": 20, + "path": "backend-services/utils/doorman_cache_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/doorman_cache_util.py::method:MemoryCache.setex", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::CacheName", + "gateway-rs/src/storage/memory.rs::MemoryStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.clear_gateway_state", + "gateway-rs/src/routes/operations.rs::clear_caches" + ], + "rust_tests": [ + "gateway-rs/src/storage/cache.rs::tests::preserves_python_cache_prefixes", + "gateway-rs/src/storage/cache.rs::tests::expires_window_counters", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "source": { + "kind": "method", + "line": 26, + "path": "backend-services/utils/doorman_cache_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/doorman_cache_util.py::method:MemoryCache.get", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::CacheName", + "gateway-rs/src/storage/memory.rs::MemoryStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.clear_gateway_state", + "gateway-rs/src/routes/operations.rs::clear_caches" + ], + "rust_tests": [ + "gateway-rs/src/storage/cache.rs::tests::preserves_python_cache_prefixes", + "gateway-rs/src/storage/cache.rs::tests::expires_window_counters", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "source": { + "kind": "method", + "line": 41, + "path": "backend-services/utils/doorman_cache_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/doorman_cache_util.py::method:MemoryCache.delete", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::CacheName", + "gateway-rs/src/storage/memory.rs::MemoryStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.clear_gateway_state", + "gateway-rs/src/routes/operations.rs::clear_caches" + ], + "rust_tests": [ + "gateway-rs/src/storage/cache.rs::tests::preserves_python_cache_prefixes", + "gateway-rs/src/storage/cache.rs::tests::expires_window_counters", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "source": { + "kind": "method", + "line": 56, + "path": "backend-services/utils/doorman_cache_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/doorman_cache_util.py::method:MemoryCache.keys", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::CacheName", + "gateway-rs/src/storage/memory.rs::MemoryStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.clear_gateway_state", + "gateway-rs/src/routes/operations.rs::clear_caches" + ], + "rust_tests": [ + "gateway-rs/src/storage/cache.rs::tests::preserves_python_cache_prefixes", + "gateway-rs/src/storage/cache.rs::tests::expires_window_counters", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "source": { + "kind": "method", + "line": 64, + "path": "backend-services/utils/doorman_cache_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/doorman_cache_util.py::method:MemoryCache._get_current_time", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::CacheName", + "gateway-rs/src/storage/memory.rs::MemoryStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.clear_gateway_state", + "gateway-rs/src/routes/operations.rs::clear_caches" + ], + "rust_tests": [ + "gateway-rs/src/storage/cache.rs::tests::preserves_python_cache_prefixes", + "gateway-rs/src/storage/cache.rs::tests::expires_window_counters", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "source": { + "kind": "method", + "line": 71, + "path": "backend-services/utils/doorman_cache_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/doorman_cache_util.py::method:MemoryCache.get_cache_stats", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::CacheName", + "gateway-rs/src/storage/memory.rs::MemoryStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.clear_gateway_state", + "gateway-rs/src/routes/operations.rs::clear_caches" + ], + "rust_tests": [ + "gateway-rs/src/storage/cache.rs::tests::preserves_python_cache_prefixes", + "gateway-rs/src/storage/cache.rs::tests::expires_window_counters", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "source": { + "kind": "method", + "line": 76, + "path": "backend-services/utils/doorman_cache_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/doorman_cache_util.py::method:MemoryCache._cleanup_expired", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::CacheName", + "gateway-rs/src/storage/memory.rs::MemoryStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.clear_gateway_state", + "gateway-rs/src/routes/operations.rs::clear_caches" + ], + "rust_tests": [ + "gateway-rs/src/storage/cache.rs::tests::preserves_python_cache_prefixes", + "gateway-rs/src/storage/cache.rs::tests::expires_window_counters", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "source": { + "kind": "method", + "line": 92, + "path": "backend-services/utils/doorman_cache_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/doorman_cache_util.py::method:MemoryCache.stop_auto_save", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::CacheName", + "gateway-rs/src/storage/memory.rs::MemoryStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.clear_gateway_state", + "gateway-rs/src/routes/operations.rs::clear_caches" + ], + "rust_tests": [ + "gateway-rs/src/storage/cache.rs::tests::preserves_python_cache_prefixes", + "gateway-rs/src/storage/cache.rs::tests::expires_window_counters", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "source": { + "kind": "method", + "line": 106, + "path": "backend-services/utils/doorman_cache_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/doorman_cache_util.py::class:DoormanCacheManager", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::CacheName", + "gateway-rs/src/storage/memory.rs::MemoryStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.clear_gateway_state", + "gateway-rs/src/routes/operations.rs::clear_caches" + ], + "rust_tests": [ + "gateway-rs/src/storage/cache.rs::tests::preserves_python_cache_prefixes", + "gateway-rs/src/storage/cache.rs::tests::expires_window_counters", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "source": { + "kind": "class", + "line": 110, + "path": "backend-services/utils/doorman_cache_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/doorman_cache_util.py::method:DoormanCacheManager.__init__", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::CacheName", + "gateway-rs/src/storage/memory.rs::MemoryStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.clear_gateway_state", + "gateway-rs/src/routes/operations.rs::clear_caches" + ], + "rust_tests": [ + "gateway-rs/src/storage/cache.rs::tests::preserves_python_cache_prefixes", + "gateway-rs/src/storage/cache.rs::tests::expires_window_counters", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "source": { + "kind": "method", + "line": 111, + "path": "backend-services/utils/doorman_cache_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/doorman_cache_util.py::method:DoormanCacheManager._get_key", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::CacheName", + "gateway-rs/src/storage/memory.rs::MemoryStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.clear_gateway_state", + "gateway-rs/src/routes/operations.rs::clear_caches" + ], + "rust_tests": [ + "gateway-rs/src/storage/cache.rs::tests::preserves_python_cache_prefixes", + "gateway-rs/src/storage/cache.rs::tests::expires_window_counters", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "source": { + "kind": "method", + "line": 186, + "path": "backend-services/utils/doorman_cache_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/doorman_cache_util.py::method:DoormanCacheManager._to_json_serializable", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::CacheName", + "gateway-rs/src/storage/memory.rs::MemoryStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.clear_gateway_state", + "gateway-rs/src/routes/operations.rs::clear_caches" + ], + "rust_tests": [ + "gateway-rs/src/storage/cache.rs::tests::preserves_python_cache_prefixes", + "gateway-rs/src/storage/cache.rs::tests::expires_window_counters", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "source": { + "kind": "method", + "line": 189, + "path": "backend-services/utils/doorman_cache_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/doorman_cache_util.py::method:DoormanCacheManager.set_cache", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::CacheName", + "gateway-rs/src/storage/memory.rs::MemoryStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.clear_gateway_state", + "gateway-rs/src/routes/operations.rs::clear_caches" + ], + "rust_tests": [ + "gateway-rs/src/storage/cache.rs::tests::preserves_python_cache_prefixes", + "gateway-rs/src/storage/cache.rs::tests::expires_window_counters", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "source": { + "kind": "method", + "line": 211, + "path": "backend-services/utils/doorman_cache_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/doorman_cache_util.py::method:DoormanCacheManager.get_cache", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::CacheName", + "gateway-rs/src/storage/memory.rs::MemoryStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.clear_gateway_state", + "gateway-rs/src/routes/operations.rs::clear_caches" + ], + "rust_tests": [ + "gateway-rs/src/storage/cache.rs::tests::preserves_python_cache_prefixes", + "gateway-rs/src/storage/cache.rs::tests::expires_window_counters", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "source": { + "kind": "method", + "line": 228, + "path": "backend-services/utils/doorman_cache_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/doorman_cache_util.py::method:DoormanCacheManager.delete_cache", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::CacheName", + "gateway-rs/src/storage/memory.rs::MemoryStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.clear_gateway_state", + "gateway-rs/src/routes/operations.rs::clear_caches" + ], + "rust_tests": [ + "gateway-rs/src/storage/cache.rs::tests::preserves_python_cache_prefixes", + "gateway-rs/src/storage/cache.rs::tests::expires_window_counters", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "source": { + "kind": "method", + "line": 241, + "path": "backend-services/utils/doorman_cache_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/doorman_cache_util.py::method:DoormanCacheManager.clear_cache", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::CacheName", + "gateway-rs/src/storage/memory.rs::MemoryStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.clear_gateway_state", + "gateway-rs/src/routes/operations.rs::clear_caches" + ], + "rust_tests": [ + "gateway-rs/src/storage/cache.rs::tests::preserves_python_cache_prefixes", + "gateway-rs/src/storage/cache.rs::tests::expires_window_counters", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "source": { + "kind": "method", + "line": 248, + "path": "backend-services/utils/doorman_cache_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/doorman_cache_util.py::method:DoormanCacheManager.clear_all_caches", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::CacheName", + "gateway-rs/src/storage/memory.rs::MemoryStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.clear_gateway_state", + "gateway-rs/src/routes/operations.rs::clear_caches" + ], + "rust_tests": [ + "gateway-rs/src/storage/cache.rs::tests::preserves_python_cache_prefixes", + "gateway-rs/src/storage/cache.rs::tests::expires_window_counters", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "source": { + "kind": "method", + "line": 262, + "path": "backend-services/utils/doorman_cache_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/doorman_cache_util.py::method:DoormanCacheManager.get_cache_info", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::CacheName", + "gateway-rs/src/storage/memory.rs::MemoryStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.clear_gateway_state", + "gateway-rs/src/routes/operations.rs::clear_caches" + ], + "rust_tests": [ + "gateway-rs/src/storage/cache.rs::tests::preserves_python_cache_prefixes", + "gateway-rs/src/storage/cache.rs::tests::expires_window_counters", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "source": { + "kind": "method", + "line": 266, + "path": "backend-services/utils/doorman_cache_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/doorman_cache_util.py::method:DoormanCacheManager.cleanup_expired_entries", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::CacheName", + "gateway-rs/src/storage/memory.rs::MemoryStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.clear_gateway_state", + "gateway-rs/src/routes/operations.rs::clear_caches" + ], + "rust_tests": [ + "gateway-rs/src/storage/cache.rs::tests::preserves_python_cache_prefixes", + "gateway-rs/src/storage/cache.rs::tests::expires_window_counters", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "source": { + "kind": "method", + "line": 278, + "path": "backend-services/utils/doorman_cache_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/doorman_cache_util.py::method:DoormanCacheManager.force_save_cache", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::CacheName", + "gateway-rs/src/storage/memory.rs::MemoryStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.clear_gateway_state", + "gateway-rs/src/routes/operations.rs::clear_caches" + ], + "rust_tests": [ + "gateway-rs/src/storage/cache.rs::tests::preserves_python_cache_prefixes", + "gateway-rs/src/storage/cache.rs::tests::expires_window_counters", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "source": { + "kind": "method", + "line": 282, + "path": "backend-services/utils/doorman_cache_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/doorman_cache_util.py::method:DoormanCacheManager.stop_cache_persistence", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::CacheName", + "gateway-rs/src/storage/memory.rs::MemoryStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.clear_gateway_state", + "gateway-rs/src/routes/operations.rs::clear_caches" + ], + "rust_tests": [ + "gateway-rs/src/storage/cache.rs::tests::preserves_python_cache_prefixes", + "gateway-rs/src/storage/cache.rs::tests::expires_window_counters", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "source": { + "kind": "method", + "line": 285, + "path": "backend-services/utils/doorman_cache_util.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "utils", + "id": "backend-services/utils/doorman_cache_util.py::method:DoormanCacheManager.is_operational", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::CacheName", + "gateway-rs/src/storage/memory.rs::MemoryStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.clear_gateway_state", + "gateway-rs/src/routes/operations.rs::clear_caches" + ], + "rust_tests": [ + "gateway-rs/src/storage/cache.rs::tests::preserves_python_cache_prefixes", + "gateway-rs/src/storage/cache.rs::tests::expires_window_counters", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "source": { + "kind": "method", + "line": 290, + "path": "backend-services/utils/doorman_cache_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/doorman_cache_util.py::method:DoormanCacheManager.invalidate_on_db_failure", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::CacheName", + "gateway-rs/src/storage/memory.rs::MemoryStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.clear_gateway_state", + "gateway-rs/src/routes/operations.rs::clear_caches" + ], + "rust_tests": [ + "gateway-rs/src/storage/cache.rs::tests::preserves_python_cache_prefixes", + "gateway-rs/src/storage/cache.rs::tests::expires_window_counters", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "source": { + "kind": "method", + "line": 301, + "path": "backend-services/utils/doorman_cache_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/email_util.py::module:email_util", + "notes": "Rust provides the same always-successful mock email logger and tier lifecycle actions invoke it with the pinned recipients, subjects, bodies, and payment-failure follow-up notification.", + "rust_symbols": [ + "gateway-rs/src/observability/email.rs::send_email", + "gateway-rs/src/routes/platform.rs::send_tier_notification" + ], + "rust_tests": [ + "gateway-rs/src/observability/email.rs::tests::mock_email_always_succeeds", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/email_util.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/email_util.py::async_function:send_email", + "notes": "Rust provides the same always-successful mock email logger and tier lifecycle actions invoke it with the pinned recipients, subjects, bodies, and payment-failure follow-up notification.", + "rust_symbols": [ + "gateway-rs/src/observability/email.rs::send_email", + "gateway-rs/src/routes/platform.rs::send_tier_notification" + ], + "rust_tests": [ + "gateway-rs/src/observability/email.rs::tests::mock_email_always_succeeds", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records" + ], + "source": { + "kind": "async_function", + "line": 14, + "path": "backend-services/utils/email_util.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/encryption_util.py::module:encryption_util", + "notes": "Rust implements TOKEN_ENCRYPTION_KEY/MEM_ENCRYPTION_KEY precedence, Fernet-key validation with SHA-256 URL-safe derivation fallback, plaintext compatibility, enc: marking, and fail-closed decryption. Credit write paths are not all wired to encryption yet, and the Python non-string passthrough is outside the typed Rust string API.", + "rust_symbols": [ + "gateway-rs/src/storage/field_encryption.rs::encrypt_value", + "gateway-rs/src/storage/field_encryption.rs::decrypt_value" + ], + "rust_tests": [ + "gateway-rs/src/storage/field_encryption.rs::tests::plaintext_values_pass_through_without_an_encryption_marker" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/encryption_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/encryption_util.py::function:_get_cipher", + "notes": "Rust implements TOKEN_ENCRYPTION_KEY/MEM_ENCRYPTION_KEY precedence, Fernet-key validation with SHA-256 URL-safe derivation fallback, plaintext compatibility, enc: marking, and fail-closed decryption. Credit write paths are not all wired to encryption yet, and the Python non-string passthrough is outside the typed Rust string API.", + "rust_symbols": [ + "gateway-rs/src/storage/field_encryption.rs::encrypt_value", + "gateway-rs/src/storage/field_encryption.rs::decrypt_value" + ], + "rust_tests": [ + "gateway-rs/src/storage/field_encryption.rs::tests::plaintext_values_pass_through_without_an_encryption_marker" + ], + "source": { + "kind": "function", + "line": 8, + "path": "backend-services/utils/encryption_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/encryption_util.py::function:encrypt_value", + "notes": "Rust implements TOKEN_ENCRYPTION_KEY/MEM_ENCRYPTION_KEY precedence, Fernet-key validation with SHA-256 URL-safe derivation fallback, plaintext compatibility, enc: marking, and fail-closed decryption. Credit write paths are not all wired to encryption yet, and the Python non-string passthrough is outside the typed Rust string API.", + "rust_symbols": [ + "gateway-rs/src/storage/field_encryption.rs::encrypt_value", + "gateway-rs/src/storage/field_encryption.rs::decrypt_value" + ], + "rust_tests": [ + "gateway-rs/src/storage/field_encryption.rs::tests::plaintext_values_pass_through_without_an_encryption_marker" + ], + "source": { + "kind": "function", + "line": 24, + "path": "backend-services/utils/encryption_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/encryption_util.py::function:decrypt_value", + "notes": "Rust implements TOKEN_ENCRYPTION_KEY/MEM_ENCRYPTION_KEY precedence, Fernet-key validation with SHA-256 URL-safe derivation fallback, plaintext compatibility, enc: marking, and fail-closed decryption. Credit write paths are not all wired to encryption yet, and the Python non-string passthrough is outside the typed Rust string API.", + "rust_symbols": [ + "gateway-rs/src/storage/field_encryption.rs::encrypt_value", + "gateway-rs/src/storage/field_encryption.rs::decrypt_value" + ], + "rust_tests": [ + "gateway-rs/src/storage/field_encryption.rs::tests::plaintext_values_pass_through_without_an_encryption_marker" + ], + "source": { + "kind": "function", + "line": 34, + "path": "backend-services/utils/encryption_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/enhanced_metrics_util.py::module:enhanced_metrics_util", + "notes": "Rust records minute-bucket request/error/latency/byte totals, global status/API/user/endpoint counters, retry and timeout runtime counters, bounded retention, persistence/restore, range summaries, top entities, status distributions, and multi-level range output. Native buckets currently retain weighted latency averages rather than every raw latency sample, so percentile and per-endpoint latency output is approximate; top/status entity counters are process-global rather than reconstructed per requested range.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/routes/platform.rs::analytics_overview", + "gateway-rs/src/routes/platform.rs::analytics_timeseries" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/enhanced_metrics_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/enhanced_metrics_util.py::class:EnhancedMetricsStore", + "notes": "Rust records minute-bucket request/error/latency/byte totals, global status/API/user/endpoint counters, retry and timeout runtime counters, bounded retention, persistence/restore, range summaries, top entities, status distributions, and multi-level range output. Native buckets currently retain weighted latency averages rather than every raw latency sample, so percentile and per-endpoint latency output is approximate; top/status entity counters are process-global rather than reconstructed per requested range.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/routes/platform.rs::analytics_overview", + "gateway-rs/src/routes/platform.rs::analytics_timeseries" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts" + ], + "source": { + "kind": "class", + "line": 22, + "path": "backend-services/utils/enhanced_metrics_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/enhanced_metrics_util.py::method:EnhancedMetricsStore.__init__", + "notes": "Rust records minute-bucket request/error/latency/byte totals, global status/API/user/endpoint counters, retry and timeout runtime counters, bounded retention, persistence/restore, range summaries, top entities, status distributions, and multi-level range output. Native buckets currently retain weighted latency averages rather than every raw latency sample, so percentile and per-endpoint latency output is approximate; top/status entity counters are process-global rather than reconstructed per requested range.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/routes/platform.rs::analytics_overview", + "gateway-rs/src/routes/platform.rs::analytics_timeseries" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts" + ], + "source": { + "kind": "method", + "line": 33, + "path": "backend-services/utils/enhanced_metrics_util.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "utils", + "id": "backend-services/utils/enhanced_metrics_util.py::method:EnhancedMetricsStore._minute_floor", + "notes": "Rust records minute-bucket request/error/latency/byte totals, global status/API/user/endpoint counters, retry and timeout runtime counters, bounded retention, persistence/restore, range summaries, top entities, status distributions, and multi-level range output. Native buckets currently retain weighted latency averages rather than every raw latency sample, so percentile and per-endpoint latency output is approximate; top/status entity counters are process-global rather than reconstructed per requested range.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/routes/platform.rs::analytics_overview", + "gateway-rs/src/routes/platform.rs::analytics_timeseries" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts" + ], + "source": { + "kind": "method", + "line": 53, + "path": "backend-services/utils/enhanced_metrics_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/enhanced_metrics_util.py::method:EnhancedMetricsStore._ensure_bucket", + "notes": "Rust records minute-bucket request/error/latency/byte totals, global status/API/user/endpoint counters, retry and timeout runtime counters, bounded retention, persistence/restore, range summaries, top entities, status distributions, and multi-level range output. Native buckets currently retain weighted latency averages rather than every raw latency sample, so percentile and per-endpoint latency output is approximate; top/status entity counters are process-global rather than reconstructed per requested range.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/routes/platform.rs::analytics_overview", + "gateway-rs/src/routes/platform.rs::analytics_timeseries" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts" + ], + "source": { + "kind": "method", + "line": 57, + "path": "backend-services/utils/enhanced_metrics_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/enhanced_metrics_util.py::method:EnhancedMetricsStore.record", + "notes": "Rust records minute-bucket request/error/latency/byte totals, global status/API/user/endpoint counters, retry and timeout runtime counters, bounded retention, persistence/restore, range summaries, top entities, status distributions, and multi-level range output. Native buckets currently retain weighted latency averages rather than every raw latency sample, so percentile and per-endpoint latency output is approximate; top/status entity counters are process-global rather than reconstructed per requested range.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/routes/platform.rs::analytics_overview", + "gateway-rs/src/routes/platform.rs::analytics_timeseries" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts" + ], + "source": { + "kind": "method", + "line": 74, + "path": "backend-services/utils/enhanced_metrics_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/enhanced_metrics_util.py::method:EnhancedMetricsStore.record_retry", + "notes": "Rust records minute-bucket request/error/latency/byte totals, global status/API/user/endpoint counters, retry and timeout runtime counters, bounded retention, persistence/restore, range summaries, top entities, status distributions, and multi-level range output. Native buckets currently retain weighted latency averages rather than every raw latency sample, so percentile and per-endpoint latency output is approximate; top/status entity counters are process-global rather than reconstructed per requested range.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/routes/platform.rs::analytics_overview", + "gateway-rs/src/routes/platform.rs::analytics_timeseries" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts" + ], + "source": { + "kind": "method", + "line": 125, + "path": "backend-services/utils/enhanced_metrics_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/enhanced_metrics_util.py::method:EnhancedMetricsStore.record_upstream_timeout", + "notes": "Rust records minute-bucket request/error/latency/byte totals, global status/API/user/endpoint counters, retry and timeout runtime counters, bounded retention, persistence/restore, range summaries, top entities, status distributions, and multi-level range output. Native buckets currently retain weighted latency averages rather than every raw latency sample, so percentile and per-endpoint latency output is approximate; top/status entity counters are process-global rather than reconstructed per requested range.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/routes/platform.rs::analytics_overview", + "gateway-rs/src/routes/platform.rs::analytics_timeseries" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts" + ], + "source": { + "kind": "method", + "line": 136, + "path": "backend-services/utils/enhanced_metrics_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/enhanced_metrics_util.py::method:EnhancedMetricsStore._maybe_aggregate", + "notes": "Rust records minute-bucket request/error/latency/byte totals, global status/API/user/endpoint counters, retry and timeout runtime counters, bounded retention, persistence/restore, range summaries, top entities, status distributions, and multi-level range output. Native buckets currently retain weighted latency averages rather than every raw latency sample, so percentile and per-endpoint latency output is approximate; top/status entity counters are process-global rather than reconstructed per requested range.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/routes/platform.rs::analytics_overview", + "gateway-rs/src/routes/platform.rs::analytics_timeseries" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts" + ], + "source": { + "kind": "method", + "line": 147, + "path": "backend-services/utils/enhanced_metrics_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/enhanced_metrics_util.py::method:EnhancedMetricsStore.get_snapshot", + "notes": "Rust records minute-bucket request/error/latency/byte totals, global status/API/user/endpoint counters, retry and timeout runtime counters, bounded retention, persistence/restore, range summaries, top entities, status distributions, and multi-level range output. Native buckets currently retain weighted latency averages rather than every raw latency sample, so percentile and per-endpoint latency output is approximate; top/status entity counters are process-global rather than reconstructed per requested range.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/routes/platform.rs::analytics_overview", + "gateway-rs/src/routes/platform.rs::analytics_timeseries" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts" + ], + "source": { + "kind": "method", + "line": 179, + "path": "backend-services/utils/enhanced_metrics_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/enhanced_metrics_util.py::method:EnhancedMetricsStore.snapshot", + "notes": "Rust records minute-bucket request/error/latency/byte totals, global status/API/user/endpoint counters, retry and timeout runtime counters, bounded retention, persistence/restore, range summaries, top entities, status distributions, and multi-level range output. Native buckets currently retain weighted latency averages rather than every raw latency sample, so percentile and per-endpoint latency output is approximate; top/status entity counters are process-global rather than reconstructed per requested range.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/routes/platform.rs::analytics_overview", + "gateway-rs/src/routes/platform.rs::analytics_timeseries" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts" + ], + "source": { + "kind": "method", + "line": 402, + "path": "backend-services/utils/enhanced_metrics_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/enhanced_metrics_util.py::method:EnhancedMetricsStore.save_to_file", + "notes": "Rust records minute-bucket request/error/latency/byte totals, global status/API/user/endpoint counters, retry and timeout runtime counters, bounded retention, persistence/restore, range summaries, top entities, status distributions, and multi-level range output. Native buckets currently retain weighted latency averages rather than every raw latency sample, so percentile and per-endpoint latency output is approximate; top/status entity counters are process-global rather than reconstructed per requested range.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/routes/platform.rs::analytics_overview", + "gateway-rs/src/routes/platform.rs::analytics_timeseries" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts" + ], + "source": { + "kind": "method", + "line": 536, + "path": "backend-services/utils/enhanced_metrics_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/enhanced_metrics_util.py::method:EnhancedMetricsStore.load_dict", + "notes": "Rust records minute-bucket request/error/latency/byte totals, global status/API/user/endpoint counters, retry and timeout runtime counters, bounded retention, persistence/restore, range summaries, top entities, status distributions, and multi-level range output. Native buckets currently retain weighted latency averages rather than every raw latency sample, so percentile and per-endpoint latency output is approximate; top/status entity counters are process-global rather than reconstructed per requested range.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/routes/platform.rs::analytics_overview", + "gateway-rs/src/routes/platform.rs::analytics_timeseries" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts" + ], + "source": { + "kind": "method", + "line": 563, + "path": "backend-services/utils/enhanced_metrics_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/enhanced_metrics_util.py::method:EnhancedMetricsStore.load_from_file", + "notes": "Rust records minute-bucket request/error/latency/byte totals, global status/API/user/endpoint counters, retry and timeout runtime counters, bounded retention, persistence/restore, range summaries, top entities, status distributions, and multi-level range output. Native buckets currently retain weighted latency averages rather than every raw latency sample, so percentile and per-endpoint latency output is approximate; top/status entity counters are process-global rather than reconstructed per requested range.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/routes/platform.rs::analytics_overview", + "gateway-rs/src/routes/platform.rs::analytics_timeseries" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts" + ], + "source": { + "kind": "method", + "line": 584, + "path": "backend-services/utils/enhanced_metrics_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::module:error_codes", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::class:ErrorCode", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "class", + "line": 26, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.AUTH_MISSING_CREDENTIALS", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 41, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.AUTH_INVALID_CREDENTIALS", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 42, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.AUTH_TOKEN_INVALID", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 43, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.AUTH_TOKEN_MISSING", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 44, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.AUTH_TOKEN_EXPIRED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 45, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.AUTH_USER_INACTIVE", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 46, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.AUTH_UNEXPECTED_ERROR", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 47, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.USR_ALREADY_EXISTS", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 49, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.USR_NOT_FOUND", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 50, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.USR_DELETE_FAILED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 51, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.USR_UPDATE_FAILED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 52, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.USR_WEAK_PASSWORD", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 53, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.USR_UNAUTHORIZED_ACCESS", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 54, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.USR_INVALID_OPERATION", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 55, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.USR_PERMISSION_DENIED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 56, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.USR_USERNAME_INVALID", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 57, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.USR_EMAIL_INVALID", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 58, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.USR_TOO_MANY_ATTRIBUTES", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 59, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.API_ALREADY_EXISTS", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 61, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.API_CREATE_FAILED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 62, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.API_NOT_FOUND", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 63, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.API_UPDATE_NAME_FORBIDDEN", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 64, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.API_NO_DATA_TO_UPDATE", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 65, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.API_PERMISSION_DENIED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 66, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.API_INVALID_REQUEST", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 67, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.API_PROTO_INVALID", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 68, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.API_PUBLIC_CREDITS_CONFLICT", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 69, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.END_ALREADY_EXISTS", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 71, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.END_CREATE_FAILED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 72, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.END_NOT_FOUND", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 73, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.END_UPDATE_FAILED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 74, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.END_DELETE_FAILED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 75, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.END_INVALID_TYPE", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 76, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.END_VALIDATION_FAILED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 77, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.END_SERVERS_REQUIRED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 78, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.END_CIRCULAR_DEPENDENCY", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 79, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.END_PERMISSION_DENIED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 80, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.END_INVALID_REQUEST", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 81, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.END_MISSING_PROTO", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 82, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.END_PATH_CONFLICT", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 83, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.END_METHOD_CONFLICT", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 84, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.END_SERVER_INVALID", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 85, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.END_TIMEOUT_INVALID", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 86, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.END_RETRIES_INVALID", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 87, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.END_HEADERS_INVALID", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 88, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.END_BODY_TRANSFORM_INVALID", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 89, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.END_RESPONSE_TRANSFORM_INVALID", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 90, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.END_LOAD_BALANCER_INVALID", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 91, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.END_CIRCUIT_BREAKER_INVALID", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 92, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.END_RATE_LIMIT_INVALID", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 93, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.ROLE_ALREADY_EXISTS", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 95, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.ROLE_CREATE_FAILED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 96, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.ROLE_NOT_FOUND", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 97, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.ROLE_NAME_IMMUTABLE", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 98, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.ROLE_UPDATE_FAILED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 99, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.ROLE_NO_DATA_TO_UPDATE", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 100, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.ROLE_DELETE_FAILED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 101, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.ROLE_PERMISSION_DENIED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 102, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.ROLE_INVALID_REQUEST", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 103, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.ROLE_IN_USE", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 104, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.ROLE_PERMISSION_INVALID", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 105, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.ROLE_NAME_INVALID", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 106, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.ROLE_RESERVED_NAME", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 107, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.ROLE_DESCRIPTION_REQUIRED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 108, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.GRP_ALREADY_EXISTS", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 110, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.GRP_CREATE_FAILED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 111, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.GRP_NOT_FOUND", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 112, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.GRP_UPDATE_FAILED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 113, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.GRP_DELETE_FAILED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 114, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.GRP_NAME_IMMUTABLE", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 115, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.GRP_NO_DATA_TO_UPDATE", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 116, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.GRP_PERMISSION_DENIED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 117, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.GRP_INVALID_REQUEST", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 118, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.GRP_IN_USE", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 119, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.SUB_INVALID_API", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 121, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.SUB_ALREADY_EXISTS", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 122, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.SUB_NOT_FOUND", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 123, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.SUB_CREATE_FAILED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 124, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.SUB_PERMISSION_DENIED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 125, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.SUB_INVALID_REQUEST", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 126, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.SUB_DELETE_FAILED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 127, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.RTG_ALREADY_EXISTS", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 129, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.RTG_CREATE_FAILED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 130, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.RTG_NOT_FOUND", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 131, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.RTG_UPDATE_FAILED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 132, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.RTG_DELETE_FAILED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 133, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.RTG_NO_DATA_TO_UPDATE", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 134, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.RTG_NAME_IMMUTABLE", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 135, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.RTG_PERMISSION_DENIED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 136, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.RTG_INVALID_REQUEST", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 137, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.RTG_PRIORITY_CONFLICT", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 138, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.RTG_PATH_INVALID", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 139, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.RTG_CONDITION_INVALID", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 140, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.CRD_GROUP_EXISTS", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 142, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.CRD_CREATE_FAILED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 143, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.CRD_GROUP_IMMUTABLE", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 144, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.CRD_NOT_FOUND", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 145, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.CRD_UPDATE_FAILED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 146, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.CRD_NO_DATA_TO_UPDATE", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 147, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.CRD_DELETE_NOT_FOUND", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 148, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.CRD_DELETE_FAILED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 149, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.CRD_GROUP_NAME_REQUIRED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 150, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.CRD_API_KEY_REQUIRED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 151, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.CRD_DATABASE_ERROR", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 152, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.CRD_DATABASE_ERROR_UPDATE", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 153, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.CRD_DATABASE_ERROR_DELETE", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 154, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.CRD_USERNAME_MISMATCH", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 155, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.CRD_USER_CREDITS_ERROR", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 156, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.CRD_GET_ALL_ERROR", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 157, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.CRD_USER_NOT_FOUND", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 158, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.CRD_GET_USER_ERROR", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 159, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.CRD_LIST_ERROR", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 160, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.CRD_FETCH_ERROR", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 161, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.CRD_RETRIEVE_ERROR", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 162, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.GTW_UPSTREAM_ERROR", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 164, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.GTW_TIMEOUT", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 165, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.GTW_NO_AVAILABLE_SERVERS", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 166, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.GTW_INVALID_REQUEST", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 167, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.GTW_RATE_LIMIT_EXCEEDED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 168, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.GTW_SERVICE_UNAVAILABLE", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 169, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.GTW_AUTHENTICATION_REQUIRED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 170, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.GTW_SUBSCRIPTION_REQUIRED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 171, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.GTW_CIRCUIT_BREAKER_OPEN", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 172, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.GTW_INVALID_ENDPOINT", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 173, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.GTW_PROTO_DECODE_ERROR", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 174, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.GTW_UNEXPECTED_ERROR", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 175, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.CFG_PERMISSION_DENIED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 177, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.CFG_API_PERMISSION_DENIED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 178, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.CFG_ENDPOINT_PERMISSION_DENIED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 179, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.CFG_GROUP_PERMISSION_DENIED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 180, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.CFG_ROLE_PERMISSION_DENIED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 181, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.CFG_ROUTING_PERMISSION_DENIED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 182, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.CFG_SUBSCRIPTION_PERMISSION_DENIED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 183, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.CFG_NOT_FOUND", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 184, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.SEC_PERMISSION_DENIED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 186, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.SEC_UPDATE_FAILED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 187, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.SEC_INVALID_IP", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 188, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.SEC_INVALID_SETTING", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 189, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.SEC_PROTECTED_SETTING", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 190, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.LOG_PERMISSION_DENIED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 192, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.LOG_INVALID_LEVEL", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 193, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.LOG_UPDATE_FAILED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 194, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.LOG_QUERY_FAILED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 195, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.LOG_EXPORT_FAILED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 196, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.MON_PERMISSION_DENIED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 198, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.MON_QUERY_FAILED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 199, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.MON_UNEXPECTED_ERROR", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 200, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.MEM_PERMISSION_DENIED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 202, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.MEM_DUMP_FAILED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 203, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.MEM_OPERATION_FAILED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 204, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.DEMO_ALREADY_SEEDED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 206, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.DEMO_SEED_FAILED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 207, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.TLS_PERMISSION_DENIED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 208, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.TLS_UNEXPECTED_ERROR", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 209, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.GEN_INVALID_REQUEST", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 211, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.GEN_VALIDATION_ERROR", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 212, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.ISE_INTERNAL_ERROR", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 213, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.REQ_BODY_TOO_LARGE", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 215, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.VAL_INVALID_JSON", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 216, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.JWT_DECODE_ERROR", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 217, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::field:ErrorCode.RATE_LIMIT_EXCEEDED", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "field", + "line": 219, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_codes.py::class:ErrorCodes", + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "source": { + "kind": "class", + "line": 223, + "path": "backend-services/utils/error_codes.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_util.py::module:error_util", + "notes": "Rust constructs the same request-id-aware success and error envelopes throughout the control plane and converts policy failures for every data-plane protocol. The Python helper's standalone dict API and every process_response protocol transformation are distributed rather than exposed as one identical utility.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::success", + "gateway-rs/src/routes/platform.rs::error", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/tests/runtime.rs::rust_rejects_unported_health_methods_in_rust" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/error_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_util.py::function:create_error_response", + "notes": "Rust constructs the same request-id-aware success and error envelopes throughout the control plane and converts policy failures for every data-plane protocol. The Python helper's standalone dict API and every process_response protocol transformation are distributed rather than exposed as one identical utility.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::success", + "gateway-rs/src/routes/platform.rs::error", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/tests/runtime.rs::rust_rejects_unported_health_methods_in_rust" + ], + "source": { + "kind": "function", + "line": 11, + "path": "backend-services/utils/error_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/error_util.py::function:success_response", + "notes": "Rust constructs the same request-id-aware success and error envelopes throughout the control plane and converts policy failures for every data-plane protocol. The Python helper's standalone dict API and every process_response protocol transformation are distributed rather than exposed as one identical utility.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::success", + "gateway-rs/src/routes/platform.rs::error", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/tests/runtime.rs::rust_rejects_unported_health_methods_in_rust" + ], + "source": { + "kind": "function", + "line": 35, + "path": "backend-services/utils/error_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/gateway_utils.py::module:gateway_utils", + "notes": "Rust preserves the sensitive-header denylist, CR/LF/NUL and HTML-tag removal, 8192-character truncation marker, case-insensitive allowlist, and never-forwards-sensitive behavior. Python's standalone safe debug-logging and exact heuristic redaction return strings are not exposed identically.", + "rust_symbols": [ + "gateway-rs/src/gateway/headers.rs::SENSITIVE_HEADERS", + "gateway-rs/src/routes/rest.rs::sanitize_forwarded_header_value" + ], + "rust_tests": [ + "gateway-rs/src/routes/rest.rs::tests::sanitizes_and_bounds_forwarded_header_values_like_python", + "gateway-rs/src/routes/rest.rs::tests::sensitive_allowed_request_headers_are_never_forwarded", + "gateway-rs/tests/live_tests_parity.rs::rest_request_and_response_header_allowlists_real_upstream_parity" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/gateway_utils.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/gateway_utils.py::function:sanitize_headers", + "notes": "Rust preserves the sensitive-header denylist, CR/LF/NUL and HTML-tag removal, 8192-character truncation marker, case-insensitive allowlist, and never-forwards-sensitive behavior. Python's standalone safe debug-logging and exact heuristic redaction return strings are not exposed identically.", + "rust_symbols": [ + "gateway-rs/src/gateway/headers.rs::SENSITIVE_HEADERS", + "gateway-rs/src/routes/rest.rs::sanitize_forwarded_header_value" + ], + "rust_tests": [ + "gateway-rs/src/routes/rest.rs::tests::sanitizes_and_bounds_forwarded_header_values_like_python", + "gateway-rs/src/routes/rest.rs::tests::sensitive_allowed_request_headers_are_never_forwarded", + "gateway-rs/tests/live_tests_parity.rs::rest_request_and_response_header_allowlists_real_upstream_parity" + ], + "source": { + "kind": "function", + "line": 21, + "path": "backend-services/utils/gateway_utils.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/gateway_utils.py::function:redact_sensitive_header", + "notes": "Rust preserves the sensitive-header denylist, CR/LF/NUL and HTML-tag removal, 8192-character truncation marker, case-insensitive allowlist, and never-forwards-sensitive behavior. Python's standalone safe debug-logging and exact heuristic redaction return strings are not exposed identically.", + "rust_symbols": [ + "gateway-rs/src/gateway/headers.rs::SENSITIVE_HEADERS", + "gateway-rs/src/routes/rest.rs::sanitize_forwarded_header_value" + ], + "rust_tests": [ + "gateway-rs/src/routes/rest.rs::tests::sanitizes_and_bounds_forwarded_header_values_like_python", + "gateway-rs/src/routes/rest.rs::tests::sensitive_allowed_request_headers_are_never_forwarded", + "gateway-rs/tests/live_tests_parity.rs::rest_request_and_response_header_allowlists_real_upstream_parity" + ], + "source": { + "kind": "function", + "line": 42, + "path": "backend-services/utils/gateway_utils.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/gateway_utils.py::function:log_headers_safely", + "notes": "Rust preserves the sensitive-header denylist, CR/LF/NUL and HTML-tag removal, 8192-character truncation marker, case-insensitive allowlist, and never-forwards-sensitive behavior. Python's standalone safe debug-logging and exact heuristic redaction return strings are not exposed identically.", + "rust_symbols": [ + "gateway-rs/src/gateway/headers.rs::SENSITIVE_HEADERS", + "gateway-rs/src/routes/rest.rs::sanitize_forwarded_header_value" + ], + "rust_tests": [ + "gateway-rs/src/routes/rest.rs::tests::sanitizes_and_bounds_forwarded_header_values_like_python", + "gateway-rs/src/routes/rest.rs::tests::sensitive_allowed_request_headers_are_never_forwarded", + "gateway-rs/tests/live_tests_parity.rs::rest_request_and_response_header_allowlists_real_upstream_parity" + ], + "source": { + "kind": "function", + "line": 75, + "path": "backend-services/utils/gateway_utils.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/gateway_utils.py::async_function:get_headers", + "notes": "Rust preserves the sensitive-header denylist, CR/LF/NUL and HTML-tag removal, 8192-character truncation marker, case-insensitive allowlist, and never-forwards-sensitive behavior. Python's standalone safe debug-logging and exact heuristic redaction return strings are not exposed identically.", + "rust_symbols": [ + "gateway-rs/src/gateway/headers.rs::SENSITIVE_HEADERS", + "gateway-rs/src/routes/rest.rs::sanitize_forwarded_header_value" + ], + "rust_tests": [ + "gateway-rs/src/routes/rest.rs::tests::sanitizes_and_bounds_forwarded_header_values_like_python", + "gateway-rs/src/routes/rest.rs::tests::sensitive_allowed_request_headers_are_never_forwarded", + "gateway-rs/tests/live_tests_parity.rs::rest_request_and_response_header_allowlists_real_upstream_parity" + ], + "source": { + "kind": "async_function", + "line": 112, + "path": "backend-services/utils/gateway_utils.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/geo_lookup.py::module:geo_lookup", + "notes": "Rust now preserves the pinned placeholder lookup (cached UNKNOWN with 24-hour TTL), cached location fields, fail-open unknown/error policy, country block and allow lists, country-specific limits, exact access-denial reasons, sliding 24-hour country counters, sorted geographic distribution, and list retrieval. The native utility uses synchronized typed memory because the pinned module has no production callers; it can be replaced by an external GeoIP/storage provider without changing this contract.", + "rust_symbols": [ + "gateway-rs/src/policy/geo.rs::GeoLocation", + "gateway-rs/src/policy/geo.rs::GeoLookup.lookup_ip", + "gateway-rs/src/policy/geo.rs::GeoLookup.check_geographic_access", + "gateway-rs/src/policy/geo.rs::GeoLookup.get_geographic_distribution" + ], + "rust_tests": [ + "gateway-rs/src/policy/geo.rs::tests::unknown_locations_fail_open_like_python", + "gateway-rs/src/policy/geo.rs::tests::country_lists_limits_and_distribution_match_python" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/geo_lookup.py" + }, + "status": "translated" + }, + { + "decorators": [ + "dataclass" + ], + "domain": "utils", + "id": "backend-services/utils/geo_lookup.py::class:GeoLocation", + "notes": "Rust now preserves the pinned placeholder lookup (cached UNKNOWN with 24-hour TTL), cached location fields, fail-open unknown/error policy, country block and allow lists, country-specific limits, exact access-denial reasons, sliding 24-hour country counters, sorted geographic distribution, and list retrieval. The native utility uses synchronized typed memory because the pinned module has no production callers; it can be replaced by an external GeoIP/storage provider without changing this contract.", + "rust_symbols": [ + "gateway-rs/src/policy/geo.rs::GeoLocation", + "gateway-rs/src/policy/geo.rs::GeoLookup.lookup_ip", + "gateway-rs/src/policy/geo.rs::GeoLookup.check_geographic_access", + "gateway-rs/src/policy/geo.rs::GeoLookup.get_geographic_distribution" + ], + "rust_tests": [ + "gateway-rs/src/policy/geo.rs::tests::unknown_locations_fail_open_like_python", + "gateway-rs/src/policy/geo.rs::tests::country_lists_limits_and_distribution_match_python" + ], + "source": { + "kind": "class", + "line": 17, + "path": "backend-services/utils/geo_lookup.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/geo_lookup.py::field:GeoLocation.ip", + "notes": "Rust now preserves the pinned placeholder lookup (cached UNKNOWN with 24-hour TTL), cached location fields, fail-open unknown/error policy, country block and allow lists, country-specific limits, exact access-denial reasons, sliding 24-hour country counters, sorted geographic distribution, and list retrieval. The native utility uses synchronized typed memory because the pinned module has no production callers; it can be replaced by an external GeoIP/storage provider without changing this contract.", + "rust_symbols": [ + "gateway-rs/src/policy/geo.rs::GeoLocation", + "gateway-rs/src/policy/geo.rs::GeoLookup.lookup_ip", + "gateway-rs/src/policy/geo.rs::GeoLookup.check_geographic_access", + "gateway-rs/src/policy/geo.rs::GeoLookup.get_geographic_distribution" + ], + "rust_tests": [ + "gateway-rs/src/policy/geo.rs::tests::unknown_locations_fail_open_like_python", + "gateway-rs/src/policy/geo.rs::tests::country_lists_limits_and_distribution_match_python" + ], + "source": { + "kind": "field", + "line": 20, + "path": "backend-services/utils/geo_lookup.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/geo_lookup.py::field:GeoLocation.country_code", + "notes": "Rust now preserves the pinned placeholder lookup (cached UNKNOWN with 24-hour TTL), cached location fields, fail-open unknown/error policy, country block and allow lists, country-specific limits, exact access-denial reasons, sliding 24-hour country counters, sorted geographic distribution, and list retrieval. The native utility uses synchronized typed memory because the pinned module has no production callers; it can be replaced by an external GeoIP/storage provider without changing this contract.", + "rust_symbols": [ + "gateway-rs/src/policy/geo.rs::GeoLocation", + "gateway-rs/src/policy/geo.rs::GeoLookup.lookup_ip", + "gateway-rs/src/policy/geo.rs::GeoLookup.check_geographic_access", + "gateway-rs/src/policy/geo.rs::GeoLookup.get_geographic_distribution" + ], + "rust_tests": [ + "gateway-rs/src/policy/geo.rs::tests::unknown_locations_fail_open_like_python", + "gateway-rs/src/policy/geo.rs::tests::country_lists_limits_and_distribution_match_python" + ], + "source": { + "kind": "field", + "line": 21, + "path": "backend-services/utils/geo_lookup.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/geo_lookup.py::field:GeoLocation.country_name", + "notes": "Rust now preserves the pinned placeholder lookup (cached UNKNOWN with 24-hour TTL), cached location fields, fail-open unknown/error policy, country block and allow lists, country-specific limits, exact access-denial reasons, sliding 24-hour country counters, sorted geographic distribution, and list retrieval. The native utility uses synchronized typed memory because the pinned module has no production callers; it can be replaced by an external GeoIP/storage provider without changing this contract.", + "rust_symbols": [ + "gateway-rs/src/policy/geo.rs::GeoLocation", + "gateway-rs/src/policy/geo.rs::GeoLookup.lookup_ip", + "gateway-rs/src/policy/geo.rs::GeoLookup.check_geographic_access", + "gateway-rs/src/policy/geo.rs::GeoLookup.get_geographic_distribution" + ], + "rust_tests": [ + "gateway-rs/src/policy/geo.rs::tests::unknown_locations_fail_open_like_python", + "gateway-rs/src/policy/geo.rs::tests::country_lists_limits_and_distribution_match_python" + ], + "source": { + "kind": "field", + "line": 22, + "path": "backend-services/utils/geo_lookup.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/geo_lookup.py::field:GeoLocation.region", + "notes": "Rust now preserves the pinned placeholder lookup (cached UNKNOWN with 24-hour TTL), cached location fields, fail-open unknown/error policy, country block and allow lists, country-specific limits, exact access-denial reasons, sliding 24-hour country counters, sorted geographic distribution, and list retrieval. The native utility uses synchronized typed memory because the pinned module has no production callers; it can be replaced by an external GeoIP/storage provider without changing this contract.", + "rust_symbols": [ + "gateway-rs/src/policy/geo.rs::GeoLocation", + "gateway-rs/src/policy/geo.rs::GeoLookup.lookup_ip", + "gateway-rs/src/policy/geo.rs::GeoLookup.check_geographic_access", + "gateway-rs/src/policy/geo.rs::GeoLookup.get_geographic_distribution" + ], + "rust_tests": [ + "gateway-rs/src/policy/geo.rs::tests::unknown_locations_fail_open_like_python", + "gateway-rs/src/policy/geo.rs::tests::country_lists_limits_and_distribution_match_python" + ], + "source": { + "kind": "field", + "line": 23, + "path": "backend-services/utils/geo_lookup.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/geo_lookup.py::field:GeoLocation.city", + "notes": "Rust now preserves the pinned placeholder lookup (cached UNKNOWN with 24-hour TTL), cached location fields, fail-open unknown/error policy, country block and allow lists, country-specific limits, exact access-denial reasons, sliding 24-hour country counters, sorted geographic distribution, and list retrieval. The native utility uses synchronized typed memory because the pinned module has no production callers; it can be replaced by an external GeoIP/storage provider without changing this contract.", + "rust_symbols": [ + "gateway-rs/src/policy/geo.rs::GeoLocation", + "gateway-rs/src/policy/geo.rs::GeoLookup.lookup_ip", + "gateway-rs/src/policy/geo.rs::GeoLookup.check_geographic_access", + "gateway-rs/src/policy/geo.rs::GeoLookup.get_geographic_distribution" + ], + "rust_tests": [ + "gateway-rs/src/policy/geo.rs::tests::unknown_locations_fail_open_like_python", + "gateway-rs/src/policy/geo.rs::tests::country_lists_limits_and_distribution_match_python" + ], + "source": { + "kind": "field", + "line": 24, + "path": "backend-services/utils/geo_lookup.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/geo_lookup.py::field:GeoLocation.latitude", + "notes": "Rust now preserves the pinned placeholder lookup (cached UNKNOWN with 24-hour TTL), cached location fields, fail-open unknown/error policy, country block and allow lists, country-specific limits, exact access-denial reasons, sliding 24-hour country counters, sorted geographic distribution, and list retrieval. The native utility uses synchronized typed memory because the pinned module has no production callers; it can be replaced by an external GeoIP/storage provider without changing this contract.", + "rust_symbols": [ + "gateway-rs/src/policy/geo.rs::GeoLocation", + "gateway-rs/src/policy/geo.rs::GeoLookup.lookup_ip", + "gateway-rs/src/policy/geo.rs::GeoLookup.check_geographic_access", + "gateway-rs/src/policy/geo.rs::GeoLookup.get_geographic_distribution" + ], + "rust_tests": [ + "gateway-rs/src/policy/geo.rs::tests::unknown_locations_fail_open_like_python", + "gateway-rs/src/policy/geo.rs::tests::country_lists_limits_and_distribution_match_python" + ], + "source": { + "kind": "field", + "line": 25, + "path": "backend-services/utils/geo_lookup.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/geo_lookup.py::field:GeoLocation.longitude", + "notes": "Rust now preserves the pinned placeholder lookup (cached UNKNOWN with 24-hour TTL), cached location fields, fail-open unknown/error policy, country block and allow lists, country-specific limits, exact access-denial reasons, sliding 24-hour country counters, sorted geographic distribution, and list retrieval. The native utility uses synchronized typed memory because the pinned module has no production callers; it can be replaced by an external GeoIP/storage provider without changing this contract.", + "rust_symbols": [ + "gateway-rs/src/policy/geo.rs::GeoLocation", + "gateway-rs/src/policy/geo.rs::GeoLookup.lookup_ip", + "gateway-rs/src/policy/geo.rs::GeoLookup.check_geographic_access", + "gateway-rs/src/policy/geo.rs::GeoLookup.get_geographic_distribution" + ], + "rust_tests": [ + "gateway-rs/src/policy/geo.rs::tests::unknown_locations_fail_open_like_python", + "gateway-rs/src/policy/geo.rs::tests::country_lists_limits_and_distribution_match_python" + ], + "source": { + "kind": "field", + "line": 26, + "path": "backend-services/utils/geo_lookup.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/geo_lookup.py::field:GeoLocation.timezone", + "notes": "Rust now preserves the pinned placeholder lookup (cached UNKNOWN with 24-hour TTL), cached location fields, fail-open unknown/error policy, country block and allow lists, country-specific limits, exact access-denial reasons, sliding 24-hour country counters, sorted geographic distribution, and list retrieval. The native utility uses synchronized typed memory because the pinned module has no production callers; it can be replaced by an external GeoIP/storage provider without changing this contract.", + "rust_symbols": [ + "gateway-rs/src/policy/geo.rs::GeoLocation", + "gateway-rs/src/policy/geo.rs::GeoLookup.lookup_ip", + "gateway-rs/src/policy/geo.rs::GeoLookup.check_geographic_access", + "gateway-rs/src/policy/geo.rs::GeoLookup.get_geographic_distribution" + ], + "rust_tests": [ + "gateway-rs/src/policy/geo.rs::tests::unknown_locations_fail_open_like_python", + "gateway-rs/src/policy/geo.rs::tests::country_lists_limits_and_distribution_match_python" + ], + "source": { + "kind": "field", + "line": 27, + "path": "backend-services/utils/geo_lookup.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/geo_lookup.py::class:GeoLookup", + "notes": "Rust now preserves the pinned placeholder lookup (cached UNKNOWN with 24-hour TTL), cached location fields, fail-open unknown/error policy, country block and allow lists, country-specific limits, exact access-denial reasons, sliding 24-hour country counters, sorted geographic distribution, and list retrieval. The native utility uses synchronized typed memory because the pinned module has no production callers; it can be replaced by an external GeoIP/storage provider without changing this contract.", + "rust_symbols": [ + "gateway-rs/src/policy/geo.rs::GeoLocation", + "gateway-rs/src/policy/geo.rs::GeoLookup.lookup_ip", + "gateway-rs/src/policy/geo.rs::GeoLookup.check_geographic_access", + "gateway-rs/src/policy/geo.rs::GeoLookup.get_geographic_distribution" + ], + "rust_tests": [ + "gateway-rs/src/policy/geo.rs::tests::unknown_locations_fail_open_like_python", + "gateway-rs/src/policy/geo.rs::tests::country_lists_limits_and_distribution_match_python" + ], + "source": { + "kind": "class", + "line": 30, + "path": "backend-services/utils/geo_lookup.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/geo_lookup.py::method:GeoLookup.__init__", + "notes": "Rust now preserves the pinned placeholder lookup (cached UNKNOWN with 24-hour TTL), cached location fields, fail-open unknown/error policy, country block and allow lists, country-specific limits, exact access-denial reasons, sliding 24-hour country counters, sorted geographic distribution, and list retrieval. The native utility uses synchronized typed memory because the pinned module has no production callers; it can be replaced by an external GeoIP/storage provider without changing this contract.", + "rust_symbols": [ + "gateway-rs/src/policy/geo.rs::GeoLocation", + "gateway-rs/src/policy/geo.rs::GeoLookup.lookup_ip", + "gateway-rs/src/policy/geo.rs::GeoLookup.check_geographic_access", + "gateway-rs/src/policy/geo.rs::GeoLookup.get_geographic_distribution" + ], + "rust_tests": [ + "gateway-rs/src/policy/geo.rs::tests::unknown_locations_fail_open_like_python", + "gateway-rs/src/policy/geo.rs::tests::country_lists_limits_and_distribution_match_python" + ], + "source": { + "kind": "method", + "line": 40, + "path": "backend-services/utils/geo_lookup.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/geo_lookup.py::method:GeoLookup.lookup_ip", + "notes": "Rust now preserves the pinned placeholder lookup (cached UNKNOWN with 24-hour TTL), cached location fields, fail-open unknown/error policy, country block and allow lists, country-specific limits, exact access-denial reasons, sliding 24-hour country counters, sorted geographic distribution, and list retrieval. The native utility uses synchronized typed memory because the pinned module has no production callers; it can be replaced by an external GeoIP/storage provider without changing this contract.", + "rust_symbols": [ + "gateway-rs/src/policy/geo.rs::GeoLocation", + "gateway-rs/src/policy/geo.rs::GeoLookup.lookup_ip", + "gateway-rs/src/policy/geo.rs::GeoLookup.check_geographic_access", + "gateway-rs/src/policy/geo.rs::GeoLookup.get_geographic_distribution" + ], + "rust_tests": [ + "gateway-rs/src/policy/geo.rs::tests::unknown_locations_fail_open_like_python", + "gateway-rs/src/policy/geo.rs::tests::country_lists_limits_and_distribution_match_python" + ], + "source": { + "kind": "method", + "line": 47, + "path": "backend-services/utils/geo_lookup.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/geo_lookup.py::method:GeoLookup._cache_geo_data", + "notes": "Rust now preserves the pinned placeholder lookup (cached UNKNOWN with 24-hour TTL), cached location fields, fail-open unknown/error policy, country block and allow lists, country-specific limits, exact access-denial reasons, sliding 24-hour country counters, sorted geographic distribution, and list retrieval. The native utility uses synchronized typed memory because the pinned module has no production callers; it can be replaced by an external GeoIP/storage provider without changing this contract.", + "rust_symbols": [ + "gateway-rs/src/policy/geo.rs::GeoLocation", + "gateway-rs/src/policy/geo.rs::GeoLookup.lookup_ip", + "gateway-rs/src/policy/geo.rs::GeoLookup.check_geographic_access", + "gateway-rs/src/policy/geo.rs::GeoLookup.get_geographic_distribution" + ], + "rust_tests": [ + "gateway-rs/src/policy/geo.rs::tests::unknown_locations_fail_open_like_python", + "gateway-rs/src/policy/geo.rs::tests::country_lists_limits_and_distribution_match_python" + ], + "source": { + "kind": "method", + "line": 94, + "path": "backend-services/utils/geo_lookup.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/geo_lookup.py::method:GeoLookup.is_country_blocked", + "notes": "Rust now preserves the pinned placeholder lookup (cached UNKNOWN with 24-hour TTL), cached location fields, fail-open unknown/error policy, country block and allow lists, country-specific limits, exact access-denial reasons, sliding 24-hour country counters, sorted geographic distribution, and list retrieval. The native utility uses synchronized typed memory because the pinned module has no production callers; it can be replaced by an external GeoIP/storage provider without changing this contract.", + "rust_symbols": [ + "gateway-rs/src/policy/geo.rs::GeoLocation", + "gateway-rs/src/policy/geo.rs::GeoLookup.lookup_ip", + "gateway-rs/src/policy/geo.rs::GeoLookup.check_geographic_access", + "gateway-rs/src/policy/geo.rs::GeoLookup.get_geographic_distribution" + ], + "rust_tests": [ + "gateway-rs/src/policy/geo.rs::tests::unknown_locations_fail_open_like_python", + "gateway-rs/src/policy/geo.rs::tests::country_lists_limits_and_distribution_match_python" + ], + "source": { + "kind": "method", + "line": 112, + "path": "backend-services/utils/geo_lookup.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/geo_lookup.py::method:GeoLookup.is_country_allowed", + "notes": "Rust now preserves the pinned placeholder lookup (cached UNKNOWN with 24-hour TTL), cached location fields, fail-open unknown/error policy, country block and allow lists, country-specific limits, exact access-denial reasons, sliding 24-hour country counters, sorted geographic distribution, and list retrieval. The native utility uses synchronized typed memory because the pinned module has no production callers; it can be replaced by an external GeoIP/storage provider without changing this contract.", + "rust_symbols": [ + "gateway-rs/src/policy/geo.rs::GeoLocation", + "gateway-rs/src/policy/geo.rs::GeoLookup.lookup_ip", + "gateway-rs/src/policy/geo.rs::GeoLookup.check_geographic_access", + "gateway-rs/src/policy/geo.rs::GeoLookup.get_geographic_distribution" + ], + "rust_tests": [ + "gateway-rs/src/policy/geo.rs::tests::unknown_locations_fail_open_like_python", + "gateway-rs/src/policy/geo.rs::tests::country_lists_limits_and_distribution_match_python" + ], + "source": { + "kind": "method", + "line": 120, + "path": "backend-services/utils/geo_lookup.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/geo_lookup.py::method:GeoLookup.block_country", + "notes": "Rust now preserves the pinned placeholder lookup (cached UNKNOWN with 24-hour TTL), cached location fields, fail-open unknown/error policy, country block and allow lists, country-specific limits, exact access-denial reasons, sliding 24-hour country counters, sorted geographic distribution, and list retrieval. The native utility uses synchronized typed memory because the pinned module has no production callers; it can be replaced by an external GeoIP/storage provider without changing this contract.", + "rust_symbols": [ + "gateway-rs/src/policy/geo.rs::GeoLocation", + "gateway-rs/src/policy/geo.rs::GeoLookup.lookup_ip", + "gateway-rs/src/policy/geo.rs::GeoLookup.check_geographic_access", + "gateway-rs/src/policy/geo.rs::GeoLookup.get_geographic_distribution" + ], + "rust_tests": [ + "gateway-rs/src/policy/geo.rs::tests::unknown_locations_fail_open_like_python", + "gateway-rs/src/policy/geo.rs::tests::country_lists_limits_and_distribution_match_python" + ], + "source": { + "kind": "method", + "line": 141, + "path": "backend-services/utils/geo_lookup.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/geo_lookup.py::method:GeoLookup.unblock_country", + "notes": "Rust now preserves the pinned placeholder lookup (cached UNKNOWN with 24-hour TTL), cached location fields, fail-open unknown/error policy, country block and allow lists, country-specific limits, exact access-denial reasons, sliding 24-hour country counters, sorted geographic distribution, and list retrieval. The native utility uses synchronized typed memory because the pinned module has no production callers; it can be replaced by an external GeoIP/storage provider without changing this contract.", + "rust_symbols": [ + "gateway-rs/src/policy/geo.rs::GeoLocation", + "gateway-rs/src/policy/geo.rs::GeoLookup.lookup_ip", + "gateway-rs/src/policy/geo.rs::GeoLookup.check_geographic_access", + "gateway-rs/src/policy/geo.rs::GeoLookup.get_geographic_distribution" + ], + "rust_tests": [ + "gateway-rs/src/policy/geo.rs::tests::unknown_locations_fail_open_like_python", + "gateway-rs/src/policy/geo.rs::tests::country_lists_limits_and_distribution_match_python" + ], + "source": { + "kind": "method", + "line": 151, + "path": "backend-services/utils/geo_lookup.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/geo_lookup.py::method:GeoLookup.add_to_allowlist", + "notes": "Rust now preserves the pinned placeholder lookup (cached UNKNOWN with 24-hour TTL), cached location fields, fail-open unknown/error policy, country block and allow lists, country-specific limits, exact access-denial reasons, sliding 24-hour country counters, sorted geographic distribution, and list retrieval. The native utility uses synchronized typed memory because the pinned module has no production callers; it can be replaced by an external GeoIP/storage provider without changing this contract.", + "rust_symbols": [ + "gateway-rs/src/policy/geo.rs::GeoLocation", + "gateway-rs/src/policy/geo.rs::GeoLookup.lookup_ip", + "gateway-rs/src/policy/geo.rs::GeoLookup.check_geographic_access", + "gateway-rs/src/policy/geo.rs::GeoLookup.get_geographic_distribution" + ], + "rust_tests": [ + "gateway-rs/src/policy/geo.rs::tests::unknown_locations_fail_open_like_python", + "gateway-rs/src/policy/geo.rs::tests::country_lists_limits_and_distribution_match_python" + ], + "source": { + "kind": "method", + "line": 161, + "path": "backend-services/utils/geo_lookup.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/geo_lookup.py::method:GeoLookup.remove_from_allowlist", + "notes": "Rust now preserves the pinned placeholder lookup (cached UNKNOWN with 24-hour TTL), cached location fields, fail-open unknown/error policy, country block and allow lists, country-specific limits, exact access-denial reasons, sliding 24-hour country counters, sorted geographic distribution, and list retrieval. The native utility uses synchronized typed memory because the pinned module has no production callers; it can be replaced by an external GeoIP/storage provider without changing this contract.", + "rust_symbols": [ + "gateway-rs/src/policy/geo.rs::GeoLocation", + "gateway-rs/src/policy/geo.rs::GeoLookup.lookup_ip", + "gateway-rs/src/policy/geo.rs::GeoLookup.check_geographic_access", + "gateway-rs/src/policy/geo.rs::GeoLookup.get_geographic_distribution" + ], + "rust_tests": [ + "gateway-rs/src/policy/geo.rs::tests::unknown_locations_fail_open_like_python", + "gateway-rs/src/policy/geo.rs::tests::country_lists_limits_and_distribution_match_python" + ], + "source": { + "kind": "method", + "line": 171, + "path": "backend-services/utils/geo_lookup.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/geo_lookup.py::method:GeoLookup.get_country_rate_limit", + "notes": "Rust now preserves the pinned placeholder lookup (cached UNKNOWN with 24-hour TTL), cached location fields, fail-open unknown/error policy, country block and allow lists, country-specific limits, exact access-denial reasons, sliding 24-hour country counters, sorted geographic distribution, and list retrieval. The native utility uses synchronized typed memory because the pinned module has no production callers; it can be replaced by an external GeoIP/storage provider without changing this contract.", + "rust_symbols": [ + "gateway-rs/src/policy/geo.rs::GeoLocation", + "gateway-rs/src/policy/geo.rs::GeoLookup.lookup_ip", + "gateway-rs/src/policy/geo.rs::GeoLookup.check_geographic_access", + "gateway-rs/src/policy/geo.rs::GeoLookup.get_geographic_distribution" + ], + "rust_tests": [ + "gateway-rs/src/policy/geo.rs::tests::unknown_locations_fail_open_like_python", + "gateway-rs/src/policy/geo.rs::tests::country_lists_limits_and_distribution_match_python" + ], + "source": { + "kind": "method", + "line": 181, + "path": "backend-services/utils/geo_lookup.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/geo_lookup.py::method:GeoLookup.set_country_rate_limit", + "notes": "Rust now preserves the pinned placeholder lookup (cached UNKNOWN with 24-hour TTL), cached location fields, fail-open unknown/error policy, country block and allow lists, country-specific limits, exact access-denial reasons, sliding 24-hour country counters, sorted geographic distribution, and list retrieval. The native utility uses synchronized typed memory because the pinned module has no production callers; it can be replaced by an external GeoIP/storage provider without changing this contract.", + "rust_symbols": [ + "gateway-rs/src/policy/geo.rs::GeoLocation", + "gateway-rs/src/policy/geo.rs::GeoLookup.lookup_ip", + "gateway-rs/src/policy/geo.rs::GeoLookup.check_geographic_access", + "gateway-rs/src/policy/geo.rs::GeoLookup.get_geographic_distribution" + ], + "rust_tests": [ + "gateway-rs/src/policy/geo.rs::tests::unknown_locations_fail_open_like_python", + "gateway-rs/src/policy/geo.rs::tests::country_lists_limits_and_distribution_match_python" + ], + "source": { + "kind": "method", + "line": 195, + "path": "backend-services/utils/geo_lookup.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/geo_lookup.py::method:GeoLookup.check_geographic_access", + "notes": "Rust now preserves the pinned placeholder lookup (cached UNKNOWN with 24-hour TTL), cached location fields, fail-open unknown/error policy, country block and allow lists, country-specific limits, exact access-denial reasons, sliding 24-hour country counters, sorted geographic distribution, and list retrieval. The native utility uses synchronized typed memory because the pinned module has no production callers; it can be replaced by an external GeoIP/storage provider without changing this contract.", + "rust_symbols": [ + "gateway-rs/src/policy/geo.rs::GeoLocation", + "gateway-rs/src/policy/geo.rs::GeoLookup.lookup_ip", + "gateway-rs/src/policy/geo.rs::GeoLookup.check_geographic_access", + "gateway-rs/src/policy/geo.rs::GeoLookup.get_geographic_distribution" + ], + "rust_tests": [ + "gateway-rs/src/policy/geo.rs::tests::unknown_locations_fail_open_like_python", + "gateway-rs/src/policy/geo.rs::tests::country_lists_limits_and_distribution_match_python" + ], + "source": { + "kind": "method", + "line": 206, + "path": "backend-services/utils/geo_lookup.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/geo_lookup.py::method:GeoLookup.track_country_request", + "notes": "Rust now preserves the pinned placeholder lookup (cached UNKNOWN with 24-hour TTL), cached location fields, fail-open unknown/error policy, country block and allow lists, country-specific limits, exact access-denial reasons, sliding 24-hour country counters, sorted geographic distribution, and list retrieval. The native utility uses synchronized typed memory because the pinned module has no production callers; it can be replaced by an external GeoIP/storage provider without changing this contract.", + "rust_symbols": [ + "gateway-rs/src/policy/geo.rs::GeoLocation", + "gateway-rs/src/policy/geo.rs::GeoLookup.lookup_ip", + "gateway-rs/src/policy/geo.rs::GeoLookup.check_geographic_access", + "gateway-rs/src/policy/geo.rs::GeoLookup.get_geographic_distribution" + ], + "rust_tests": [ + "gateway-rs/src/policy/geo.rs::tests::unknown_locations_fail_open_like_python", + "gateway-rs/src/policy/geo.rs::tests::country_lists_limits_and_distribution_match_python" + ], + "source": { + "kind": "method", + "line": 235, + "path": "backend-services/utils/geo_lookup.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/geo_lookup.py::method:GeoLookup.get_geographic_distribution", + "notes": "Rust now preserves the pinned placeholder lookup (cached UNKNOWN with 24-hour TTL), cached location fields, fail-open unknown/error policy, country block and allow lists, country-specific limits, exact access-denial reasons, sliding 24-hour country counters, sorted geographic distribution, and list retrieval. The native utility uses synchronized typed memory because the pinned module has no production callers; it can be replaced by an external GeoIP/storage provider without changing this contract.", + "rust_symbols": [ + "gateway-rs/src/policy/geo.rs::GeoLocation", + "gateway-rs/src/policy/geo.rs::GeoLookup.lookup_ip", + "gateway-rs/src/policy/geo.rs::GeoLookup.check_geographic_access", + "gateway-rs/src/policy/geo.rs::GeoLookup.get_geographic_distribution" + ], + "rust_tests": [ + "gateway-rs/src/policy/geo.rs::tests::unknown_locations_fail_open_like_python", + "gateway-rs/src/policy/geo.rs::tests::country_lists_limits_and_distribution_match_python" + ], + "source": { + "kind": "method", + "line": 244, + "path": "backend-services/utils/geo_lookup.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/geo_lookup.py::method:GeoLookup.get_blocked_countries", + "notes": "Rust now preserves the pinned placeholder lookup (cached UNKNOWN with 24-hour TTL), cached location fields, fail-open unknown/error policy, country block and allow lists, country-specific limits, exact access-denial reasons, sliding 24-hour country counters, sorted geographic distribution, and list retrieval. The native utility uses synchronized typed memory because the pinned module has no production callers; it can be replaced by an external GeoIP/storage provider without changing this contract.", + "rust_symbols": [ + "gateway-rs/src/policy/geo.rs::GeoLocation", + "gateway-rs/src/policy/geo.rs::GeoLookup.lookup_ip", + "gateway-rs/src/policy/geo.rs::GeoLookup.check_geographic_access", + "gateway-rs/src/policy/geo.rs::GeoLookup.get_geographic_distribution" + ], + "rust_tests": [ + "gateway-rs/src/policy/geo.rs::tests::unknown_locations_fail_open_like_python", + "gateway-rs/src/policy/geo.rs::tests::country_lists_limits_and_distribution_match_python" + ], + "source": { + "kind": "method", + "line": 277, + "path": "backend-services/utils/geo_lookup.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/geo_lookup.py::method:GeoLookup.get_allowed_countries", + "notes": "Rust now preserves the pinned placeholder lookup (cached UNKNOWN with 24-hour TTL), cached location fields, fail-open unknown/error policy, country block and allow lists, country-specific limits, exact access-denial reasons, sliding 24-hour country counters, sorted geographic distribution, and list retrieval. The native utility uses synchronized typed memory because the pinned module has no production callers; it can be replaced by an external GeoIP/storage provider without changing this contract.", + "rust_symbols": [ + "gateway-rs/src/policy/geo.rs::GeoLocation", + "gateway-rs/src/policy/geo.rs::GeoLookup.lookup_ip", + "gateway-rs/src/policy/geo.rs::GeoLookup.check_geographic_access", + "gateway-rs/src/policy/geo.rs::GeoLookup.get_geographic_distribution" + ], + "rust_tests": [ + "gateway-rs/src/policy/geo.rs::tests::unknown_locations_fail_open_like_python", + "gateway-rs/src/policy/geo.rs::tests::country_lists_limits_and_distribution_match_python" + ], + "source": { + "kind": "method", + "line": 285, + "path": "backend-services/utils/geo_lookup.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/geo_lookup.py::function:get_geo_lookup", + "notes": "Rust now preserves the pinned placeholder lookup (cached UNKNOWN with 24-hour TTL), cached location fields, fail-open unknown/error policy, country block and allow lists, country-specific limits, exact access-denial reasons, sliding 24-hour country counters, sorted geographic distribution, and list retrieval. The native utility uses synchronized typed memory because the pinned module has no production callers; it can be replaced by an external GeoIP/storage provider without changing this contract.", + "rust_symbols": [ + "gateway-rs/src/policy/geo.rs::GeoLocation", + "gateway-rs/src/policy/geo.rs::GeoLookup.lookup_ip", + "gateway-rs/src/policy/geo.rs::GeoLookup.check_geographic_access", + "gateway-rs/src/policy/geo.rs::GeoLookup.get_geographic_distribution" + ], + "rust_tests": [ + "gateway-rs/src/policy/geo.rs::tests::unknown_locations_fail_open_like_python", + "gateway-rs/src/policy/geo.rs::tests::country_lists_limits_and_distribution_match_python" + ], + "source": { + "kind": "function", + "line": 298, + "path": "backend-services/utils/geo_lookup.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/graphql_util.py::module:graphql_util", + "notes": "Rust now matches Python's line-comment and quote stripping, brace depth, regex word complexity, keyword removal, depth limits, introspection fetching, schema operation/type extraction, and subscription discovery within native GraphQL routes. Some malformed schema shapes and standalone network failure return paths remain distributed rather than identical helper calls.", + "rust_symbols": [ + "gateway-rs/src/validation/graphql.rs::calculate_graphql_depth", + "gateway-rs/src/validation/graphql.rs::calculate_graphql_cost", + "gateway-rs/src/validation/graphql.rs::validate_graphql_query", + "gateway-rs/src/routes/platform.rs::api_discovery_routes" + ], + "rust_tests": [ + "gateway-rs/src/validation/graphql.rs::tests::validates_depth_and_cost", + "gateway-rs/tests/python_parity_suite.rs::parity_test_graphql_validation_and_introspection_policy" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/graphql_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/graphql_util.py::function:calculate_query_depth", + "notes": "Rust now matches Python's line-comment and quote stripping, brace depth, regex word complexity, keyword removal, depth limits, introspection fetching, schema operation/type extraction, and subscription discovery within native GraphQL routes. Some malformed schema shapes and standalone network failure return paths remain distributed rather than identical helper calls.", + "rust_symbols": [ + "gateway-rs/src/validation/graphql.rs::calculate_graphql_depth", + "gateway-rs/src/validation/graphql.rs::calculate_graphql_cost", + "gateway-rs/src/validation/graphql.rs::validate_graphql_query", + "gateway-rs/src/routes/platform.rs::api_discovery_routes" + ], + "rust_tests": [ + "gateway-rs/src/validation/graphql.rs::tests::validates_depth_and_cost", + "gateway-rs/tests/python_parity_suite.rs::parity_test_graphql_validation_and_introspection_policy" + ], + "source": { + "kind": "function", + "line": 23, + "path": "backend-services/utils/graphql_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/graphql_util.py::function:validate_query_depth", + "notes": "Rust now matches Python's line-comment and quote stripping, brace depth, regex word complexity, keyword removal, depth limits, introspection fetching, schema operation/type extraction, and subscription discovery within native GraphQL routes. Some malformed schema shapes and standalone network failure return paths remain distributed rather than identical helper calls.", + "rust_symbols": [ + "gateway-rs/src/validation/graphql.rs::calculate_graphql_depth", + "gateway-rs/src/validation/graphql.rs::calculate_graphql_cost", + "gateway-rs/src/validation/graphql.rs::validate_graphql_query", + "gateway-rs/src/routes/platform.rs::api_discovery_routes" + ], + "rust_tests": [ + "gateway-rs/src/validation/graphql.rs::tests::validates_depth_and_cost", + "gateway-rs/tests/python_parity_suite.rs::parity_test_graphql_validation_and_introspection_policy" + ], + "source": { + "kind": "function", + "line": 61, + "path": "backend-services/utils/graphql_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/graphql_util.py::function:estimate_query_complexity", + "notes": "Rust now matches Python's line-comment and quote stripping, brace depth, regex word complexity, keyword removal, depth limits, introspection fetching, schema operation/type extraction, and subscription discovery within native GraphQL routes. Some malformed schema shapes and standalone network failure return paths remain distributed rather than identical helper calls.", + "rust_symbols": [ + "gateway-rs/src/validation/graphql.rs::calculate_graphql_depth", + "gateway-rs/src/validation/graphql.rs::calculate_graphql_cost", + "gateway-rs/src/validation/graphql.rs::validate_graphql_query", + "gateway-rs/src/routes/platform.rs::api_discovery_routes" + ], + "rust_tests": [ + "gateway-rs/src/validation/graphql.rs::tests::validates_depth_and_cost", + "gateway-rs/tests/python_parity_suite.rs::parity_test_graphql_validation_and_introspection_policy" + ], + "source": { + "kind": "function", + "line": 87, + "path": "backend-services/utils/graphql_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/graphql_util.py::async_function:fetch_introspection_schema", + "notes": "Rust now matches Python's line-comment and quote stripping, brace depth, regex word complexity, keyword removal, depth limits, introspection fetching, schema operation/type extraction, and subscription discovery within native GraphQL routes. Some malformed schema shapes and standalone network failure return paths remain distributed rather than identical helper calls.", + "rust_symbols": [ + "gateway-rs/src/validation/graphql.rs::calculate_graphql_depth", + "gateway-rs/src/validation/graphql.rs::calculate_graphql_cost", + "gateway-rs/src/validation/graphql.rs::validate_graphql_query", + "gateway-rs/src/routes/platform.rs::api_discovery_routes" + ], + "rust_tests": [ + "gateway-rs/src/validation/graphql.rs::tests::validates_depth_and_cost", + "gateway-rs/tests/python_parity_suite.rs::parity_test_graphql_validation_and_introspection_policy" + ], + "source": { + "kind": "async_function", + "line": 142, + "path": "backend-services/utils/graphql_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/graphql_util.py::function:extract_types_from_schema", + "notes": "Rust now matches Python's line-comment and quote stripping, brace depth, regex word complexity, keyword removal, depth limits, introspection fetching, schema operation/type extraction, and subscription discovery within native GraphQL routes. Some malformed schema shapes and standalone network failure return paths remain distributed rather than identical helper calls.", + "rust_symbols": [ + "gateway-rs/src/validation/graphql.rs::calculate_graphql_depth", + "gateway-rs/src/validation/graphql.rs::calculate_graphql_cost", + "gateway-rs/src/validation/graphql.rs::validate_graphql_query", + "gateway-rs/src/routes/platform.rs::api_discovery_routes" + ], + "rust_tests": [ + "gateway-rs/src/validation/graphql.rs::tests::validates_depth_and_cost", + "gateway-rs/tests/python_parity_suite.rs::parity_test_graphql_validation_and_introspection_policy" + ], + "source": { + "kind": "function", + "line": 190, + "path": "backend-services/utils/graphql_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/graphql_util.py::function:get_operation_type", + "notes": "Rust now matches Python's line-comment and quote stripping, brace depth, regex word complexity, keyword removal, depth limits, introspection fetching, schema operation/type extraction, and subscription discovery within native GraphQL routes. Some malformed schema shapes and standalone network failure return paths remain distributed rather than identical helper calls.", + "rust_symbols": [ + "gateway-rs/src/validation/graphql.rs::calculate_graphql_depth", + "gateway-rs/src/validation/graphql.rs::calculate_graphql_cost", + "gateway-rs/src/validation/graphql.rs::validate_graphql_query", + "gateway-rs/src/routes/platform.rs::api_discovery_routes" + ], + "rust_tests": [ + "gateway-rs/src/validation/graphql.rs::tests::validates_depth_and_cost", + "gateway-rs/tests/python_parity_suite.rs::parity_test_graphql_validation_and_introspection_policy" + ], + "source": { + "kind": "function", + "line": 225, + "path": "backend-services/utils/graphql_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/graphql_util.py::function:has_subscription_support", + "notes": "Rust now matches Python's line-comment and quote stripping, brace depth, regex word complexity, keyword removal, depth limits, introspection fetching, schema operation/type extraction, and subscription discovery within native GraphQL routes. Some malformed schema shapes and standalone network failure return paths remain distributed rather than identical helper calls.", + "rust_symbols": [ + "gateway-rs/src/validation/graphql.rs::calculate_graphql_depth", + "gateway-rs/src/validation/graphql.rs::calculate_graphql_cost", + "gateway-rs/src/validation/graphql.rs::validate_graphql_query", + "gateway-rs/src/routes/platform.rs::api_discovery_routes" + ], + "rust_tests": [ + "gateway-rs/src/validation/graphql.rs::tests::validates_depth_and_cost", + "gateway-rs/tests/python_parity_suite.rs::parity_test_graphql_validation_and_introspection_policy" + ], + "source": { + "kind": "function", + "line": 245, + "path": "backend-services/utils/graphql_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/graphql_util.py::function:detect_operation_type", + "notes": "Rust now matches Python's line-comment and quote stripping, brace depth, regex word complexity, keyword removal, depth limits, introspection fetching, schema operation/type extraction, and subscription discovery within native GraphQL routes. Some malformed schema shapes and standalone network failure return paths remain distributed rather than identical helper calls.", + "rust_symbols": [ + "gateway-rs/src/validation/graphql.rs::calculate_graphql_depth", + "gateway-rs/src/validation/graphql.rs::calculate_graphql_cost", + "gateway-rs/src/validation/graphql.rs::validate_graphql_query", + "gateway-rs/src/routes/platform.rs::api_discovery_routes" + ], + "rust_tests": [ + "gateway-rs/src/validation/graphql.rs::tests::validates_depth_and_cost", + "gateway-rs/tests/python_parity_suite.rs::parity_test_graphql_validation_and_introspection_policy" + ], + "source": { + "kind": "function", + "line": 262, + "path": "backend-services/utils/graphql_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/graphql_util.py::function:is_subscription_operation", + "notes": "Rust now matches Python's line-comment and quote stripping, brace depth, regex word complexity, keyword removal, depth limits, introspection fetching, schema operation/type extraction, and subscription discovery within native GraphQL routes. Some malformed schema shapes and standalone network failure return paths remain distributed rather than identical helper calls.", + "rust_symbols": [ + "gateway-rs/src/validation/graphql.rs::calculate_graphql_depth", + "gateway-rs/src/validation/graphql.rs::calculate_graphql_cost", + "gateway-rs/src/validation/graphql.rs::validate_graphql_query", + "gateway-rs/src/routes/platform.rs::api_discovery_routes" + ], + "rust_tests": [ + "gateway-rs/src/validation/graphql.rs::tests::validates_depth_and_cost", + "gateway-rs/tests/python_parity_suite.rs::parity_test_graphql_validation_and_introspection_policy" + ], + "source": { + "kind": "function", + "line": 293, + "path": "backend-services/utils/graphql_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/group_util.py::module:group_util", + "notes": "Rust resolves the authenticated user and API before enforcing the same non-empty group intersection and 401 detail across REST, SOAP, GraphQL, and gRPC. The monolithic evaluator replaces Python's path parsing/cache lookup, but exact malformed-path and missing-user exception fallbacks are not fully identical.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::evaluate_request", + "gateway-rs/src/policy/groups.rs::enforce_group_access" + ], + "rust_tests": [ + "gateway-rs/src/policy/groups.rs::tests::requires_group_intersection_for_legacy_contract" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/group_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/group_util.py::async_function:group_required", + "notes": "Rust resolves the authenticated user and API before enforcing the same non-empty group intersection and 401 detail across REST, SOAP, GraphQL, and gRPC. The monolithic evaluator replaces Python's path parsing/cache lookup, but exact malformed-path and missing-user exception fallbacks are not fully identical.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::evaluate_request", + "gateway-rs/src/policy/groups.rs::enforce_group_access" + ], + "rust_tests": [ + "gateway-rs/src/policy/groups.rs::tests::requires_group_intersection_for_legacy_contract" + ], + "source": { + "kind": "async_function", + "line": 20, + "path": "backend-services/utils/group_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/grpc_util.py::module:grpc_util", + "notes": "Rust natively encodes and decodes big-endian gRPC-Web data/trailer frames, handles split streaming output, and implements the pinned empty reflection fallback within full descriptor-backed gRPC support. The standalone Python parser's incomplete-buffer discard and duplicate default/custom trailer-line quirks are not reproduced byte-for-byte.", + "rust_symbols": [ + "gateway-rs/src/protocol/grpc.rs::decode_web_data_frame", + "gateway-rs/src/protocol/grpc.rs::web_data_frame", + "gateway-rs/src/protocol/grpc.rs::web_trailer_frame" + ], + "rust_tests": [ + "gateway-rs/src/protocol/grpc.rs::tests::grpc_web_frames_round_trip_and_emit_trailers", + "gateway-rs/tests/live_tests_parity.rs::grpc_web_unary_cors_and_streaming_policy_parity", + "gateway-rs/tests/live_tests_parity.rs::live_test_grpc_reflection_no_proto_parity" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/grpc_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/grpc_util.py::function:encode_grpc_web_frame", + "notes": "Rust natively encodes and decodes big-endian gRPC-Web data/trailer frames, handles split streaming output, and implements the pinned empty reflection fallback within full descriptor-backed gRPC support. The standalone Python parser's incomplete-buffer discard and duplicate default/custom trailer-line quirks are not reproduced byte-for-byte.", + "rust_symbols": [ + "gateway-rs/src/protocol/grpc.rs::decode_web_data_frame", + "gateway-rs/src/protocol/grpc.rs::web_data_frame", + "gateway-rs/src/protocol/grpc.rs::web_trailer_frame" + ], + "rust_tests": [ + "gateway-rs/src/protocol/grpc.rs::tests::grpc_web_frames_round_trip_and_emit_trailers", + "gateway-rs/tests/live_tests_parity.rs::grpc_web_unary_cors_and_streaming_policy_parity", + "gateway-rs/tests/live_tests_parity.rs::live_test_grpc_reflection_no_proto_parity" + ], + "source": { + "kind": "function", + "line": 26, + "path": "backend-services/utils/grpc_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/grpc_util.py::function:decode_grpc_web_frame", + "notes": "Rust natively encodes and decodes big-endian gRPC-Web data/trailer frames, handles split streaming output, and implements the pinned empty reflection fallback within full descriptor-backed gRPC support. The standalone Python parser's incomplete-buffer discard and duplicate default/custom trailer-line quirks are not reproduced byte-for-byte.", + "rust_symbols": [ + "gateway-rs/src/protocol/grpc.rs::decode_web_data_frame", + "gateway-rs/src/protocol/grpc.rs::web_data_frame", + "gateway-rs/src/protocol/grpc.rs::web_trailer_frame" + ], + "rust_tests": [ + "gateway-rs/src/protocol/grpc.rs::tests::grpc_web_frames_round_trip_and_emit_trailers", + "gateway-rs/tests/live_tests_parity.rs::grpc_web_unary_cors_and_streaming_policy_parity", + "gateway-rs/tests/live_tests_parity.rs::live_test_grpc_reflection_no_proto_parity" + ], + "source": { + "kind": "function", + "line": 41, + "path": "backend-services/utils/grpc_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/grpc_util.py::async_function:parse_grpc_web_stream", + "notes": "Rust natively encodes and decodes big-endian gRPC-Web data/trailer frames, handles split streaming output, and implements the pinned empty reflection fallback within full descriptor-backed gRPC support. The standalone Python parser's incomplete-buffer discard and duplicate default/custom trailer-line quirks are not reproduced byte-for-byte.", + "rust_symbols": [ + "gateway-rs/src/protocol/grpc.rs::decode_web_data_frame", + "gateway-rs/src/protocol/grpc.rs::web_data_frame", + "gateway-rs/src/protocol/grpc.rs::web_trailer_frame" + ], + "rust_tests": [ + "gateway-rs/src/protocol/grpc.rs::tests::grpc_web_frames_round_trip_and_emit_trailers", + "gateway-rs/tests/live_tests_parity.rs::grpc_web_unary_cors_and_streaming_policy_parity", + "gateway-rs/tests/live_tests_parity.rs::live_test_grpc_reflection_no_proto_parity" + ], + "source": { + "kind": "async_function", + "line": 61, + "path": "backend-services/utils/grpc_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/grpc_util.py::function:create_grpc_web_response", + "notes": "Rust natively encodes and decodes big-endian gRPC-Web data/trailer frames, handles split streaming output, and implements the pinned empty reflection fallback within full descriptor-backed gRPC support. The standalone Python parser's incomplete-buffer discard and duplicate default/custom trailer-line quirks are not reproduced byte-for-byte.", + "rust_symbols": [ + "gateway-rs/src/protocol/grpc.rs::decode_web_data_frame", + "gateway-rs/src/protocol/grpc.rs::web_data_frame", + "gateway-rs/src/protocol/grpc.rs::web_trailer_frame" + ], + "rust_tests": [ + "gateway-rs/src/protocol/grpc.rs::tests::grpc_web_frames_round_trip_and_emit_trailers", + "gateway-rs/tests/live_tests_parity.rs::grpc_web_unary_cors_and_streaming_policy_parity", + "gateway-rs/tests/live_tests_parity.rs::live_test_grpc_reflection_no_proto_parity" + ], + "source": { + "kind": "function", + "line": 91, + "path": "backend-services/utils/grpc_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/grpc_util.py::async_function:fetch_reflection_services", + "notes": "Rust natively encodes and decodes big-endian gRPC-Web data/trailer frames, handles split streaming output, and implements the pinned empty reflection fallback within full descriptor-backed gRPC support. The standalone Python parser's incomplete-buffer discard and duplicate default/custom trailer-line quirks are not reproduced byte-for-byte.", + "rust_symbols": [ + "gateway-rs/src/protocol/grpc.rs::decode_web_data_frame", + "gateway-rs/src/protocol/grpc.rs::web_data_frame", + "gateway-rs/src/protocol/grpc.rs::web_trailer_frame" + ], + "rust_tests": [ + "gateway-rs/src/protocol/grpc.rs::tests::grpc_web_frames_round_trip_and_emit_trailers", + "gateway-rs/tests/live_tests_parity.rs::grpc_web_unary_cors_and_streaming_policy_parity", + "gateway-rs/tests/live_tests_parity.rs::live_test_grpc_reflection_no_proto_parity" + ], + "source": { + "kind": "async_function", + "line": 121, + "path": "backend-services/utils/grpc_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/health_check_util.py::module:health_check_util", + "notes": "Rust checks configured Mongo/Redis health, reports process memory, formats uptime identically, and supplies all detailed gateway status fields. active_connections currently reports active gateway requests instead of psutil network socket count, and OS inspection failure fallbacks differ.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.mongo_healthy", + "gateway-rs/src/storage/runtime.rs::SharedStorage.redis_healthy", + "gateway-rs/src/routes/operations.rs::status", + "gateway-rs/src/routes/operations.rs::memory_usage", + "gateway-rs/src/routes/operations.rs::format_uptime" + ], + "rust_tests": [ + "gateway-rs/src/routes/operations.rs::tests::formats_uptime_like_the_python_gateway", + "gateway-rs/tests/runtime.rs::rust_serves_status_unauthorized_from_rust" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/health_check_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/health_check_util.py::async_function:check_mongodb", + "notes": "Rust checks configured Mongo/Redis health, reports process memory, formats uptime identically, and supplies all detailed gateway status fields. active_connections currently reports active gateway requests instead of psutil network socket count, and OS inspection failure fallbacks differ.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.mongo_healthy", + "gateway-rs/src/storage/runtime.rs::SharedStorage.redis_healthy", + "gateway-rs/src/routes/operations.rs::status", + "gateway-rs/src/routes/operations.rs::memory_usage", + "gateway-rs/src/routes/operations.rs::format_uptime" + ], + "rust_tests": [ + "gateway-rs/src/routes/operations.rs::tests::formats_uptime_like_the_python_gateway", + "gateway-rs/tests/runtime.rs::rust_serves_status_unauthorized_from_rust" + ], + "source": { + "kind": "async_function", + "line": 23, + "path": "backend-services/utils/health_check_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/health_check_util.py::async_function:check_redis", + "notes": "Rust checks configured Mongo/Redis health, reports process memory, formats uptime identically, and supplies all detailed gateway status fields. active_connections currently reports active gateway requests instead of psutil network socket count, and OS inspection failure fallbacks differ.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.mongo_healthy", + "gateway-rs/src/storage/runtime.rs::SharedStorage.redis_healthy", + "gateway-rs/src/routes/operations.rs::status", + "gateway-rs/src/routes/operations.rs::memory_usage", + "gateway-rs/src/routes/operations.rs::format_uptime" + ], + "rust_tests": [ + "gateway-rs/src/routes/operations.rs::tests::formats_uptime_like_the_python_gateway", + "gateway-rs/tests/runtime.rs::rust_serves_status_unauthorized_from_rust" + ], + "source": { + "kind": "async_function", + "line": 36, + "path": "backend-services/utils/health_check_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/health_check_util.py::function:get_memory_usage", + "notes": "Rust checks configured Mongo/Redis health, reports process memory, formats uptime identically, and supplies all detailed gateway status fields. active_connections currently reports active gateway requests instead of psutil network socket count, and OS inspection failure fallbacks differ.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.mongo_healthy", + "gateway-rs/src/storage/runtime.rs::SharedStorage.redis_healthy", + "gateway-rs/src/routes/operations.rs::status", + "gateway-rs/src/routes/operations.rs::memory_usage", + "gateway-rs/src/routes/operations.rs::format_uptime" + ], + "rust_tests": [ + "gateway-rs/src/routes/operations.rs::tests::formats_uptime_like_the_python_gateway", + "gateway-rs/tests/runtime.rs::rust_serves_status_unauthorized_from_rust" + ], + "source": { + "kind": "function", + "line": 58, + "path": "backend-services/utils/health_check_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/health_check_util.py::function:get_active_connections", + "notes": "Rust checks configured Mongo/Redis health, reports process memory, formats uptime identically, and supplies all detailed gateway status fields. active_connections currently reports active gateway requests instead of psutil network socket count, and OS inspection failure fallbacks differ.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.mongo_healthy", + "gateway-rs/src/storage/runtime.rs::SharedStorage.redis_healthy", + "gateway-rs/src/routes/operations.rs::status", + "gateway-rs/src/routes/operations.rs::memory_usage", + "gateway-rs/src/routes/operations.rs::format_uptime" + ], + "rust_tests": [ + "gateway-rs/src/routes/operations.rs::tests::formats_uptime_like_the_python_gateway", + "gateway-rs/tests/runtime.rs::rust_serves_status_unauthorized_from_rust" + ], + "source": { + "kind": "function", + "line": 70, + "path": "backend-services/utils/health_check_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/health_check_util.py::function:get_uptime", + "notes": "Rust checks configured Mongo/Redis health, reports process memory, formats uptime identically, and supplies all detailed gateway status fields. active_connections currently reports active gateway requests instead of psutil network socket count, and OS inspection failure fallbacks differ.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.mongo_healthy", + "gateway-rs/src/storage/runtime.rs::SharedStorage.redis_healthy", + "gateway-rs/src/routes/operations.rs::status", + "gateway-rs/src/routes/operations.rs::memory_usage", + "gateway-rs/src/routes/operations.rs::format_uptime" + ], + "rust_tests": [ + "gateway-rs/src/routes/operations.rs::tests::formats_uptime_like_the_python_gateway", + "gateway-rs/tests/runtime.rs::rust_serves_status_unauthorized_from_rust" + ], + "source": { + "kind": "function", + "line": 80, + "path": "backend-services/utils/health_check_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/hot_reload_config.py::module:hot_reload_config", + "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. Python's generic in-process set/callback API is not used outside this module; dynamic LOG_LEVEL application and most advertised keys still require restart in Rust and are reported as such by the API.", + "rust_symbols": [ + "gateway-rs/src/hot_reload.rs::HotReloadConfig", + "gateway-rs/src/main.rs::spawn_sighup_reload", + "gateway-rs/src/routes/platform.rs::platform_dispatch" + ], + "rust_tests": [ + "gateway-rs/src/hot_reload.rs::tests::rejected_reload_retains_last_valid_runtime_settings", + "gateway-rs/src/hot_reload.rs::tests::flattens_json_configuration_like_the_python_manager", + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/hot_reload_config.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/hot_reload_config.py::class:HotReloadConfig", + "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. Python's generic in-process set/callback API is not used outside this module; dynamic LOG_LEVEL application and most advertised keys still require restart in Rust and are reported as such by the API.", + "rust_symbols": [ + "gateway-rs/src/hot_reload.rs::HotReloadConfig", + "gateway-rs/src/main.rs::spawn_sighup_reload", + "gateway-rs/src/routes/platform.rs::platform_dispatch" + ], + "rust_tests": [ + "gateway-rs/src/hot_reload.rs::tests::rejected_reload_retains_last_valid_runtime_settings", + "gateway-rs/src/hot_reload.rs::tests::flattens_json_configuration_like_the_python_manager", + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests" + ], + "source": { + "kind": "class", + "line": 34, + "path": "backend-services/utils/hot_reload_config.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/hot_reload_config.py::method:HotReloadConfig.__init__", + "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. Python's generic in-process set/callback API is not used outside this module; dynamic LOG_LEVEL application and most advertised keys still require restart in Rust and are reported as such by the API.", + "rust_symbols": [ + "gateway-rs/src/hot_reload.rs::HotReloadConfig", + "gateway-rs/src/main.rs::spawn_sighup_reload", + "gateway-rs/src/routes/platform.rs::platform_dispatch" + ], + "rust_tests": [ + "gateway-rs/src/hot_reload.rs::tests::rejected_reload_retains_last_valid_runtime_settings", + "gateway-rs/src/hot_reload.rs::tests::flattens_json_configuration_like_the_python_manager", + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests" + ], + "source": { + "kind": "method", + "line": 45, + "path": "backend-services/utils/hot_reload_config.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/hot_reload_config.py::method:HotReloadConfig._load_initial_config", + "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. Python's generic in-process set/callback API is not used outside this module; dynamic LOG_LEVEL application and most advertised keys still require restart in Rust and are reported as such by the API.", + "rust_symbols": [ + "gateway-rs/src/hot_reload.rs::HotReloadConfig", + "gateway-rs/src/main.rs::spawn_sighup_reload", + "gateway-rs/src/routes/platform.rs::platform_dispatch" + ], + "rust_tests": [ + "gateway-rs/src/hot_reload.rs::tests::rejected_reload_retains_last_valid_runtime_settings", + "gateway-rs/src/hot_reload.rs::tests::flattens_json_configuration_like_the_python_manager", + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests" + ], + "source": { + "kind": "method", + "line": 52, + "path": "backend-services/utils/hot_reload_config.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/hot_reload_config.py::method:HotReloadConfig._load_from_file", + "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. Python's generic in-process set/callback API is not used outside this module; dynamic LOG_LEVEL application and most advertised keys still require restart in Rust and are reported as such by the API.", + "rust_symbols": [ + "gateway-rs/src/hot_reload.rs::HotReloadConfig", + "gateway-rs/src/main.rs::spawn_sighup_reload", + "gateway-rs/src/routes/platform.rs::platform_dispatch" + ], + "rust_tests": [ + "gateway-rs/src/hot_reload.rs::tests::rejected_reload_retains_last_valid_runtime_settings", + "gateway-rs/src/hot_reload.rs::tests::flattens_json_configuration_like_the_python_manager", + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests" + ], + "source": { + "kind": "method", + "line": 66, + "path": "backend-services/utils/hot_reload_config.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/hot_reload_config.py::method:HotReloadConfig._load_from_env", + "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. Python's generic in-process set/callback API is not used outside this module; dynamic LOG_LEVEL application and most advertised keys still require restart in Rust and are reported as such by the API.", + "rust_symbols": [ + "gateway-rs/src/hot_reload.rs::HotReloadConfig", + "gateway-rs/src/main.rs::spawn_sighup_reload", + "gateway-rs/src/routes/platform.rs::platform_dispatch" + ], + "rust_tests": [ + "gateway-rs/src/hot_reload.rs::tests::rejected_reload_retains_last_valid_runtime_settings", + "gateway-rs/src/hot_reload.rs::tests::flattens_json_configuration_like_the_python_manager", + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests" + ], + "source": { + "kind": "method", + "line": 80, + "path": "backend-services/utils/hot_reload_config.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/hot_reload_config.py::method:HotReloadConfig._flatten_dict", + "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. Python's generic in-process set/callback API is not used outside this module; dynamic LOG_LEVEL application and most advertised keys still require restart in Rust and are reported as such by the API.", + "rust_symbols": [ + "gateway-rs/src/hot_reload.rs::HotReloadConfig", + "gateway-rs/src/main.rs::spawn_sighup_reload", + "gateway-rs/src/routes/platform.rs::platform_dispatch" + ], + "rust_tests": [ + "gateway-rs/src/hot_reload.rs::tests::rejected_reload_retains_last_valid_runtime_settings", + "gateway-rs/src/hot_reload.rs::tests::flattens_json_configuration_like_the_python_manager", + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests" + ], + "source": { + "kind": "method", + "line": 112, + "path": "backend-services/utils/hot_reload_config.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/hot_reload_config.py::method:HotReloadConfig._parse_value", + "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. Python's generic in-process set/callback API is not used outside this module; dynamic LOG_LEVEL application and most advertised keys still require restart in Rust and are reported as such by the API.", + "rust_symbols": [ + "gateway-rs/src/hot_reload.rs::HotReloadConfig", + "gateway-rs/src/main.rs::spawn_sighup_reload", + "gateway-rs/src/routes/platform.rs::platform_dispatch" + ], + "rust_tests": [ + "gateway-rs/src/hot_reload.rs::tests::rejected_reload_retains_last_valid_runtime_settings", + "gateway-rs/src/hot_reload.rs::tests::flattens_json_configuration_like_the_python_manager", + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests" + ], + "source": { + "kind": "method", + "line": 123, + "path": "backend-services/utils/hot_reload_config.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/hot_reload_config.py::method:HotReloadConfig.get", + "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. Python's generic in-process set/callback API is not used outside this module; dynamic LOG_LEVEL application and most advertised keys still require restart in Rust and are reported as such by the API.", + "rust_symbols": [ + "gateway-rs/src/hot_reload.rs::HotReloadConfig", + "gateway-rs/src/main.rs::spawn_sighup_reload", + "gateway-rs/src/routes/platform.rs::platform_dispatch" + ], + "rust_tests": [ + "gateway-rs/src/hot_reload.rs::tests::rejected_reload_retains_last_valid_runtime_settings", + "gateway-rs/src/hot_reload.rs::tests::flattens_json_configuration_like_the_python_manager", + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests" + ], + "source": { + "kind": "method", + "line": 142, + "path": "backend-services/utils/hot_reload_config.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/hot_reload_config.py::method:HotReloadConfig.get_int", + "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. Python's generic in-process set/callback API is not used outside this module; dynamic LOG_LEVEL application and most advertised keys still require restart in Rust and are reported as such by the API.", + "rust_symbols": [ + "gateway-rs/src/hot_reload.rs::HotReloadConfig", + "gateway-rs/src/main.rs::spawn_sighup_reload", + "gateway-rs/src/routes/platform.rs::platform_dispatch" + ], + "rust_tests": [ + "gateway-rs/src/hot_reload.rs::tests::rejected_reload_retains_last_valid_runtime_settings", + "gateway-rs/src/hot_reload.rs::tests::flattens_json_configuration_like_the_python_manager", + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests" + ], + "source": { + "kind": "method", + "line": 158, + "path": "backend-services/utils/hot_reload_config.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/hot_reload_config.py::method:HotReloadConfig.get_float", + "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. Python's generic in-process set/callback API is not used outside this module; dynamic LOG_LEVEL application and most advertised keys still require restart in Rust and are reported as such by the API.", + "rust_symbols": [ + "gateway-rs/src/hot_reload.rs::HotReloadConfig", + "gateway-rs/src/main.rs::spawn_sighup_reload", + "gateway-rs/src/routes/platform.rs::platform_dispatch" + ], + "rust_tests": [ + "gateway-rs/src/hot_reload.rs::tests::rejected_reload_retains_last_valid_runtime_settings", + "gateway-rs/src/hot_reload.rs::tests::flattens_json_configuration_like_the_python_manager", + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests" + ], + "source": { + "kind": "method", + "line": 167, + "path": "backend-services/utils/hot_reload_config.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/hot_reload_config.py::method:HotReloadConfig.get_bool", + "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. Python's generic in-process set/callback API is not used outside this module; dynamic LOG_LEVEL application and most advertised keys still require restart in Rust and are reported as such by the API.", + "rust_symbols": [ + "gateway-rs/src/hot_reload.rs::HotReloadConfig", + "gateway-rs/src/main.rs::spawn_sighup_reload", + "gateway-rs/src/routes/platform.rs::platform_dispatch" + ], + "rust_tests": [ + "gateway-rs/src/hot_reload.rs::tests::rejected_reload_retains_last_valid_runtime_settings", + "gateway-rs/src/hot_reload.rs::tests::flattens_json_configuration_like_the_python_manager", + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests" + ], + "source": { + "kind": "method", + "line": 176, + "path": "backend-services/utils/hot_reload_config.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/hot_reload_config.py::method:HotReloadConfig.set", + "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. Python's generic in-process set/callback API is not used outside this module; dynamic LOG_LEVEL application and most advertised keys still require restart in Rust and are reported as such by the API.", + "rust_symbols": [ + "gateway-rs/src/hot_reload.rs::HotReloadConfig", + "gateway-rs/src/main.rs::spawn_sighup_reload", + "gateway-rs/src/routes/platform.rs::platform_dispatch" + ], + "rust_tests": [ + "gateway-rs/src/hot_reload.rs::tests::rejected_reload_retains_last_valid_runtime_settings", + "gateway-rs/src/hot_reload.rs::tests::flattens_json_configuration_like_the_python_manager", + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests" + ], + "source": { + "kind": "method", + "line": 185, + "path": "backend-services/utils/hot_reload_config.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/hot_reload_config.py::method:HotReloadConfig.register_callback", + "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. Python's generic in-process set/callback API is not used outside this module; dynamic LOG_LEVEL application and most advertised keys still require restart in Rust and are reported as such by the API.", + "rust_symbols": [ + "gateway-rs/src/hot_reload.rs::HotReloadConfig", + "gateway-rs/src/main.rs::spawn_sighup_reload", + "gateway-rs/src/routes/platform.rs::platform_dispatch" + ], + "rust_tests": [ + "gateway-rs/src/hot_reload.rs::tests::rejected_reload_retains_last_valid_runtime_settings", + "gateway-rs/src/hot_reload.rs::tests::flattens_json_configuration_like_the_python_manager", + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests" + ], + "source": { + "kind": "method", + "line": 198, + "path": "backend-services/utils/hot_reload_config.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/hot_reload_config.py::method:HotReloadConfig._trigger_callbacks", + "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. Python's generic in-process set/callback API is not used outside this module; dynamic LOG_LEVEL application and most advertised keys still require restart in Rust and are reported as such by the API.", + "rust_symbols": [ + "gateway-rs/src/hot_reload.rs::HotReloadConfig", + "gateway-rs/src/main.rs::spawn_sighup_reload", + "gateway-rs/src/routes/platform.rs::platform_dispatch" + ], + "rust_tests": [ + "gateway-rs/src/hot_reload.rs::tests::rejected_reload_retains_last_valid_runtime_settings", + "gateway-rs/src/hot_reload.rs::tests::flattens_json_configuration_like_the_python_manager", + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests" + ], + "source": { + "kind": "method", + "line": 210, + "path": "backend-services/utils/hot_reload_config.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/hot_reload_config.py::method:HotReloadConfig.reload", + "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. Python's generic in-process set/callback API is not used outside this module; dynamic LOG_LEVEL application and most advertised keys still require restart in Rust and are reported as such by the API.", + "rust_symbols": [ + "gateway-rs/src/hot_reload.rs::HotReloadConfig", + "gateway-rs/src/main.rs::spawn_sighup_reload", + "gateway-rs/src/routes/platform.rs::platform_dispatch" + ], + "rust_tests": [ + "gateway-rs/src/hot_reload.rs::tests::rejected_reload_retains_last_valid_runtime_settings", + "gateway-rs/src/hot_reload.rs::tests::flattens_json_configuration_like_the_python_manager", + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests" + ], + "source": { + "kind": "method", + "line": 219, + "path": "backend-services/utils/hot_reload_config.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/hot_reload_config.py::method:HotReloadConfig.dump", + "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. Python's generic in-process set/callback API is not used outside this module; dynamic LOG_LEVEL application and most advertised keys still require restart in Rust and are reported as such by the API.", + "rust_symbols": [ + "gateway-rs/src/hot_reload.rs::HotReloadConfig", + "gateway-rs/src/main.rs::spawn_sighup_reload", + "gateway-rs/src/routes/platform.rs::platform_dispatch" + ], + "rust_tests": [ + "gateway-rs/src/hot_reload.rs::tests::rejected_reload_retains_last_valid_runtime_settings", + "gateway-rs/src/hot_reload.rs::tests::flattens_json_configuration_like_the_python_manager", + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests" + ], + "source": { + "kind": "method", + "line": 248, + "path": "backend-services/utils/hot_reload_config.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/hot_reload_config.py::function:get_timeout_config", + "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. Python's generic in-process set/callback API is not used outside this module; dynamic LOG_LEVEL application and most advertised keys still require restart in Rust and are reported as such by the API.", + "rust_symbols": [ + "gateway-rs/src/hot_reload.rs::HotReloadConfig", + "gateway-rs/src/main.rs::spawn_sighup_reload", + "gateway-rs/src/routes/platform.rs::platform_dispatch" + ], + "rust_tests": [ + "gateway-rs/src/hot_reload.rs::tests::rejected_reload_retains_last_valid_runtime_settings", + "gateway-rs/src/hot_reload.rs::tests::flattens_json_configuration_like_the_python_manager", + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests" + ], + "source": { + "kind": "function", + "line": 263, + "path": "backend-services/utils/hot_reload_config.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/hot_reload_config.py::function:get_rate_limit_config", + "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. Python's generic in-process set/callback API is not used outside this module; dynamic LOG_LEVEL application and most advertised keys still require restart in Rust and are reported as such by the API.", + "rust_symbols": [ + "gateway-rs/src/hot_reload.rs::HotReloadConfig", + "gateway-rs/src/main.rs::spawn_sighup_reload", + "gateway-rs/src/routes/platform.rs::platform_dispatch" + ], + "rust_tests": [ + "gateway-rs/src/hot_reload.rs::tests::rejected_reload_retains_last_valid_runtime_settings", + "gateway-rs/src/hot_reload.rs::tests::flattens_json_configuration_like_the_python_manager", + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests" + ], + "source": { + "kind": "function", + "line": 272, + "path": "backend-services/utils/hot_reload_config.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/hot_reload_config.py::function:get_cache_config", + "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. Python's generic in-process set/callback API is not used outside this module; dynamic LOG_LEVEL application and most advertised keys still require restart in Rust and are reported as such by the API.", + "rust_symbols": [ + "gateway-rs/src/hot_reload.rs::HotReloadConfig", + "gateway-rs/src/main.rs::spawn_sighup_reload", + "gateway-rs/src/routes/platform.rs::platform_dispatch" + ], + "rust_tests": [ + "gateway-rs/src/hot_reload.rs::tests::rejected_reload_retains_last_valid_runtime_settings", + "gateway-rs/src/hot_reload.rs::tests::flattens_json_configuration_like_the_python_manager", + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests" + ], + "source": { + "kind": "function", + "line": 281, + "path": "backend-services/utils/hot_reload_config.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/hot_reload_config.py::function:get_circuit_breaker_config", + "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. Python's generic in-process set/callback API is not used outside this module; dynamic LOG_LEVEL application and most advertised keys still require restart in Rust and are reported as such by the API.", + "rust_symbols": [ + "gateway-rs/src/hot_reload.rs::HotReloadConfig", + "gateway-rs/src/main.rs::spawn_sighup_reload", + "gateway-rs/src/routes/platform.rs::platform_dispatch" + ], + "rust_tests": [ + "gateway-rs/src/hot_reload.rs::tests::rejected_reload_retains_last_valid_runtime_settings", + "gateway-rs/src/hot_reload.rs::tests::flattens_json_configuration_like_the_python_manager", + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests" + ], + "source": { + "kind": "function", + "line": 289, + "path": "backend-services/utils/hot_reload_config.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/hot_reload_config.py::function:get_retry_config", + "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. Python's generic in-process set/callback API is not used outside this module; dynamic LOG_LEVEL application and most advertised keys still require restart in Rust and are reported as such by the API.", + "rust_symbols": [ + "gateway-rs/src/hot_reload.rs::HotReloadConfig", + "gateway-rs/src/main.rs::spawn_sighup_reload", + "gateway-rs/src/routes/platform.rs::platform_dispatch" + ], + "rust_tests": [ + "gateway-rs/src/hot_reload.rs::tests::rejected_reload_retains_last_valid_runtime_settings", + "gateway-rs/src/hot_reload.rs::tests::flattens_json_configuration_like_the_python_manager", + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests" + ], + "source": { + "kind": "function", + "line": 298, + "path": "backend-services/utils/hot_reload_config.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/http_client.py::module:http_client", + "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics now count each timed-out attempt as Python does. Reqwest does not expose separate Python httpx write/pool timeout controls, and network exception classes map through native client errors.", + "rust_symbols": [ + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/routes/rest.rs::retry_backoff", + "gateway-rs/src/gateway/circuit_breaker.rs", + "gateway-rs/src/config.rs::python_http_connect_timeout" + ], + "rust_tests": [ + "gateway-rs/src/gateway/circuit_breaker.rs::tests::opens_after_failures_then_half_open_failure_reopens_like_python", + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests", + "gateway-rs/tests/live_tests_parity.rs::soap_content_types_and_retry_real_upstream_parity" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/http_client.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/http_client.py::class:CircuitOpenError", + "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics now count each timed-out attempt as Python does. Reqwest does not expose separate Python httpx write/pool timeout controls, and network exception classes map through native client errors.", + "rust_symbols": [ + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/routes/rest.rs::retry_backoff", + "gateway-rs/src/gateway/circuit_breaker.rs", + "gateway-rs/src/config.rs::python_http_connect_timeout" + ], + "rust_tests": [ + "gateway-rs/src/gateway/circuit_breaker.rs::tests::opens_after_failures_then_half_open_failure_reopens_like_python", + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests", + "gateway-rs/tests/live_tests_parity.rs::soap_content_types_and_retry_real_upstream_parity" + ], + "source": { + "kind": "class", + "line": 33, + "path": "backend-services/utils/http_client.py" + }, + "status": "partial" + }, + { + "decorators": [ + "dataclass" + ], + "domain": "utils", + "id": "backend-services/utils/http_client.py::class:_BreakerState", + "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics now count each timed-out attempt as Python does. Reqwest does not expose separate Python httpx write/pool timeout controls, and network exception classes map through native client errors.", + "rust_symbols": [ + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/routes/rest.rs::retry_backoff", + "gateway-rs/src/gateway/circuit_breaker.rs", + "gateway-rs/src/config.rs::python_http_connect_timeout" + ], + "rust_tests": [ + "gateway-rs/src/gateway/circuit_breaker.rs::tests::opens_after_failures_then_half_open_failure_reopens_like_python", + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests", + "gateway-rs/tests/live_tests_parity.rs::soap_content_types_and_retry_real_upstream_parity" + ], + "source": { + "kind": "class", + "line": 38, + "path": "backend-services/utils/http_client.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/http_client.py::field:_BreakerState.failures", + "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics now count each timed-out attempt as Python does. Reqwest does not expose separate Python httpx write/pool timeout controls, and network exception classes map through native client errors.", + "rust_symbols": [ + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/routes/rest.rs::retry_backoff", + "gateway-rs/src/gateway/circuit_breaker.rs", + "gateway-rs/src/config.rs::python_http_connect_timeout" + ], + "rust_tests": [ + "gateway-rs/src/gateway/circuit_breaker.rs::tests::opens_after_failures_then_half_open_failure_reopens_like_python", + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests", + "gateway-rs/tests/live_tests_parity.rs::soap_content_types_and_retry_real_upstream_parity" + ], + "source": { + "kind": "field", + "line": 39, + "path": "backend-services/utils/http_client.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/http_client.py::field:_BreakerState.opened_at", + "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics now count each timed-out attempt as Python does. Reqwest does not expose separate Python httpx write/pool timeout controls, and network exception classes map through native client errors.", + "rust_symbols": [ + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/routes/rest.rs::retry_backoff", + "gateway-rs/src/gateway/circuit_breaker.rs", + "gateway-rs/src/config.rs::python_http_connect_timeout" + ], + "rust_tests": [ + "gateway-rs/src/gateway/circuit_breaker.rs::tests::opens_after_failures_then_half_open_failure_reopens_like_python", + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests", + "gateway-rs/tests/live_tests_parity.rs::soap_content_types_and_retry_real_upstream_parity" + ], + "source": { + "kind": "field", + "line": 40, + "path": "backend-services/utils/http_client.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/http_client.py::field:_BreakerState.state", + "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics now count each timed-out attempt as Python does. Reqwest does not expose separate Python httpx write/pool timeout controls, and network exception classes map through native client errors.", + "rust_symbols": [ + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/routes/rest.rs::retry_backoff", + "gateway-rs/src/gateway/circuit_breaker.rs", + "gateway-rs/src/config.rs::python_http_connect_timeout" + ], + "rust_tests": [ + "gateway-rs/src/gateway/circuit_breaker.rs::tests::opens_after_failures_then_half_open_failure_reopens_like_python", + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests", + "gateway-rs/tests/live_tests_parity.rs::soap_content_types_and_retry_real_upstream_parity" + ], + "source": { + "kind": "field", + "line": 41, + "path": "backend-services/utils/http_client.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/http_client.py::class:_CircuitManager", + "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics now count each timed-out attempt as Python does. Reqwest does not expose separate Python httpx write/pool timeout controls, and network exception classes map through native client errors.", + "rust_symbols": [ + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/routes/rest.rs::retry_backoff", + "gateway-rs/src/gateway/circuit_breaker.rs", + "gateway-rs/src/config.rs::python_http_connect_timeout" + ], + "rust_tests": [ + "gateway-rs/src/gateway/circuit_breaker.rs::tests::opens_after_failures_then_half_open_failure_reopens_like_python", + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests", + "gateway-rs/tests/live_tests_parity.rs::soap_content_types_and_retry_real_upstream_parity" + ], + "source": { + "kind": "class", + "line": 44, + "path": "backend-services/utils/http_client.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/http_client.py::method:_CircuitManager.__init__", + "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics now count each timed-out attempt as Python does. Reqwest does not expose separate Python httpx write/pool timeout controls, and network exception classes map through native client errors.", + "rust_symbols": [ + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/routes/rest.rs::retry_backoff", + "gateway-rs/src/gateway/circuit_breaker.rs", + "gateway-rs/src/config.rs::python_http_connect_timeout" + ], + "rust_tests": [ + "gateway-rs/src/gateway/circuit_breaker.rs::tests::opens_after_failures_then_half_open_failure_reopens_like_python", + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests", + "gateway-rs/tests/live_tests_parity.rs::soap_content_types_and_retry_real_upstream_parity" + ], + "source": { + "kind": "method", + "line": 45, + "path": "backend-services/utils/http_client.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/http_client.py::method:_CircuitManager.reset", + "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics now count each timed-out attempt as Python does. Reqwest does not expose separate Python httpx write/pool timeout controls, and network exception classes map through native client errors.", + "rust_symbols": [ + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/routes/rest.rs::retry_backoff", + "gateway-rs/src/gateway/circuit_breaker.rs", + "gateway-rs/src/config.rs::python_http_connect_timeout" + ], + "rust_tests": [ + "gateway-rs/src/gateway/circuit_breaker.rs::tests::opens_after_failures_then_half_open_failure_reopens_like_python", + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests", + "gateway-rs/tests/live_tests_parity.rs::soap_content_types_and_retry_real_upstream_parity" + ], + "source": { + "kind": "method", + "line": 48, + "path": "backend-services/utils/http_client.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/http_client.py::method:_CircuitManager.get", + "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics now count each timed-out attempt as Python does. Reqwest does not expose separate Python httpx write/pool timeout controls, and network exception classes map through native client errors.", + "rust_symbols": [ + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/routes/rest.rs::retry_backoff", + "gateway-rs/src/gateway/circuit_breaker.rs", + "gateway-rs/src/config.rs::python_http_connect_timeout" + ], + "rust_tests": [ + "gateway-rs/src/gateway/circuit_breaker.rs::tests::opens_after_failures_then_half_open_failure_reopens_like_python", + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests", + "gateway-rs/tests/live_tests_parity.rs::soap_content_types_and_retry_real_upstream_parity" + ], + "source": { + "kind": "method", + "line": 55, + "path": "backend-services/utils/http_client.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/http_client.py::method:_CircuitManager.now", + "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics now count each timed-out attempt as Python does. Reqwest does not expose separate Python httpx write/pool timeout controls, and network exception classes map through native client errors.", + "rust_symbols": [ + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/routes/rest.rs::retry_backoff", + "gateway-rs/src/gateway/circuit_breaker.rs", + "gateway-rs/src/config.rs::python_http_connect_timeout" + ], + "rust_tests": [ + "gateway-rs/src/gateway/circuit_breaker.rs::tests::opens_after_failures_then_half_open_failure_reopens_like_python", + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests", + "gateway-rs/tests/live_tests_parity.rs::soap_content_types_and_retry_real_upstream_parity" + ], + "source": { + "kind": "method", + "line": 62, + "path": "backend-services/utils/http_client.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/http_client.py::method:_CircuitManager.check", + "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics now count each timed-out attempt as Python does. Reqwest does not expose separate Python httpx write/pool timeout controls, and network exception classes map through native client errors.", + "rust_symbols": [ + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/routes/rest.rs::retry_backoff", + "gateway-rs/src/gateway/circuit_breaker.rs", + "gateway-rs/src/config.rs::python_http_connect_timeout" + ], + "rust_tests": [ + "gateway-rs/src/gateway/circuit_breaker.rs::tests::opens_after_failures_then_half_open_failure_reopens_like_python", + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests", + "gateway-rs/tests/live_tests_parity.rs::soap_content_types_and_retry_real_upstream_parity" + ], + "source": { + "kind": "method", + "line": 65, + "path": "backend-services/utils/http_client.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/http_client.py::method:_CircuitManager.record_success", + "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics now count each timed-out attempt as Python does. Reqwest does not expose separate Python httpx write/pool timeout controls, and network exception classes map through native client errors.", + "rust_symbols": [ + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/routes/rest.rs::retry_backoff", + "gateway-rs/src/gateway/circuit_breaker.rs", + "gateway-rs/src/config.rs::python_http_connect_timeout" + ], + "rust_tests": [ + "gateway-rs/src/gateway/circuit_breaker.rs::tests::opens_after_failures_then_half_open_failure_reopens_like_python", + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests", + "gateway-rs/tests/live_tests_parity.rs::soap_content_types_and_retry_real_upstream_parity" + ], + "source": { + "kind": "method", + "line": 74, + "path": "backend-services/utils/http_client.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/http_client.py::method:_CircuitManager.record_failure", + "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics now count each timed-out attempt as Python does. Reqwest does not expose separate Python httpx write/pool timeout controls, and network exception classes map through native client errors.", + "rust_symbols": [ + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/routes/rest.rs::retry_backoff", + "gateway-rs/src/gateway/circuit_breaker.rs", + "gateway-rs/src/config.rs::python_http_connect_timeout" + ], + "rust_tests": [ + "gateway-rs/src/gateway/circuit_breaker.rs::tests::opens_after_failures_then_half_open_failure_reopens_like_python", + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests", + "gateway-rs/tests/live_tests_parity.rs::soap_content_types_and_retry_real_upstream_parity" + ], + "source": { + "kind": "method", + "line": 79, + "path": "backend-services/utils/http_client.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/http_client.py::function:_build_timeout", + "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics now count each timed-out attempt as Python does. Reqwest does not expose separate Python httpx write/pool timeout controls, and network exception classes map through native client errors.", + "rust_symbols": [ + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/routes/rest.rs::retry_backoff", + "gateway-rs/src/gateway/circuit_breaker.rs", + "gateway-rs/src/config.rs::python_http_connect_timeout" + ], + "rust_tests": [ + "gateway-rs/src/gateway/circuit_breaker.rs::tests::opens_after_failures_then_half_open_failure_reopens_like_python", + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests", + "gateway-rs/tests/live_tests_parity.rs::soap_content_types_and_retry_real_upstream_parity" + ], + "source": { + "kind": "function", + "line": 94, + "path": "backend-services/utils/http_client.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/http_client.py::function:_build_timeout._f", + "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics now count each timed-out attempt as Python does. Reqwest does not expose separate Python httpx write/pool timeout controls, and network exception classes map through native client errors.", + "rust_symbols": [ + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/routes/rest.rs::retry_backoff", + "gateway-rs/src/gateway/circuit_breaker.rs", + "gateway-rs/src/config.rs::python_http_connect_timeout" + ], + "rust_tests": [ + "gateway-rs/src/gateway/circuit_breaker.rs::tests::opens_after_failures_then_half_open_failure_reopens_like_python", + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests", + "gateway-rs/tests/live_tests_parity.rs::soap_content_types_and_retry_real_upstream_parity" + ], + "source": { + "kind": "function", + "line": 96, + "path": "backend-services/utils/http_client.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/http_client.py::function:_should_retry_status", + "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics now count each timed-out attempt as Python does. Reqwest does not expose separate Python httpx write/pool timeout controls, and network exception classes map through native client errors.", + "rust_symbols": [ + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/routes/rest.rs::retry_backoff", + "gateway-rs/src/gateway/circuit_breaker.rs", + "gateway-rs/src/config.rs::python_http_connect_timeout" + ], + "rust_tests": [ + "gateway-rs/src/gateway/circuit_breaker.rs::tests::opens_after_failures_then_half_open_failure_reopens_like_python", + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests", + "gateway-rs/tests/live_tests_parity.rs::soap_content_types_and_retry_real_upstream_parity" + ], + "source": { + "kind": "function", + "line": 111, + "path": "backend-services/utils/http_client.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/http_client.py::function:_backoff_delay", + "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics now count each timed-out attempt as Python does. Reqwest does not expose separate Python httpx write/pool timeout controls, and network exception classes map through native client errors.", + "rust_symbols": [ + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/routes/rest.rs::retry_backoff", + "gateway-rs/src/gateway/circuit_breaker.rs", + "gateway-rs/src/config.rs::python_http_connect_timeout" + ], + "rust_tests": [ + "gateway-rs/src/gateway/circuit_breaker.rs::tests::opens_after_failures_then_half_open_failure_reopens_like_python", + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests", + "gateway-rs/tests/live_tests_parity.rs::soap_content_types_and_retry_real_upstream_parity" + ], + "source": { + "kind": "function", + "line": 115, + "path": "backend-services/utils/http_client.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/http_client.py::async_function:request_with_resilience", + "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics now count each timed-out attempt as Python does. Reqwest does not expose separate Python httpx write/pool timeout controls, and network exception classes map through native client errors.", + "rust_symbols": [ + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/routes/rest.rs::retry_backoff", + "gateway-rs/src/gateway/circuit_breaker.rs", + "gateway-rs/src/config.rs::python_http_connect_timeout" + ], + "rust_tests": [ + "gateway-rs/src/gateway/circuit_breaker.rs::tests::opens_after_failures_then_half_open_failure_reopens_like_python", + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests", + "gateway-rs/tests/live_tests_parity.rs::soap_content_types_and_retry_real_upstream_parity" + ], + "source": { + "kind": "async_function", + "line": 122, + "path": "backend-services/utils/http_client.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/ip_policy_util.py::module:ip_policy_util", + "notes": "Rust matches trusted-proxy resolution, XFF precedence, exact/CIDR/netmask matching, blacklist precedence, whitelist errors, Docker loopback addresses, and per-API trust overrides. Rust intentionally does not let a spoofable Host header alone trigger localhost bypass, and its typed audit/error plumbing differs from Python's broad fail-open catches.", + "rust_symbols": [ + "gateway-rs/src/policy/ip.rs::effective_client_ip_for_settings", + "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy" + ], + "rust_tests": [ + "gateway-rs/src/policy/ip.rs::tests::python_ip_pattern_dotted_masks_and_whitespace_match_reference", + "gateway-rs/src/policy/ip.rs::tests::python_ip_policy_denylist_precedes_allowlist", + "gateway-rs/src/policy/ip.rs::tests::localhost_host_header_cannot_bypass_an_ip_allowlist" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/ip_policy_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/ip_policy_util.py::function:_get_client_ip", + "notes": "Rust matches trusted-proxy resolution, XFF precedence, exact/CIDR/netmask matching, blacklist precedence, whitelist errors, Docker loopback addresses, and per-API trust overrides. Rust intentionally does not let a spoofable Host header alone trigger localhost bypass, and its typed audit/error plumbing differs from Python's broad fail-open catches.", + "rust_symbols": [ + "gateway-rs/src/policy/ip.rs::effective_client_ip_for_settings", + "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy" + ], + "rust_tests": [ + "gateway-rs/src/policy/ip.rs::tests::python_ip_pattern_dotted_masks_and_whitespace_match_reference", + "gateway-rs/src/policy/ip.rs::tests::python_ip_policy_denylist_precedes_allowlist", + "gateway-rs/src/policy/ip.rs::tests::localhost_host_header_cannot_bypass_an_ip_allowlist" + ], + "source": { + "kind": "function", + "line": 11, + "path": "backend-services/utils/ip_policy_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/ip_policy_util.py::function:_get_client_ip._from_trusted_proxy", + "notes": "Rust matches trusted-proxy resolution, XFF precedence, exact/CIDR/netmask matching, blacklist precedence, whitelist errors, Docker loopback addresses, and per-API trust overrides. Rust intentionally does not let a spoofable Host header alone trigger localhost bypass, and its typed audit/error plumbing differs from Python's broad fail-open catches.", + "rust_symbols": [ + "gateway-rs/src/policy/ip.rs::effective_client_ip_for_settings", + "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy" + ], + "rust_tests": [ + "gateway-rs/src/policy/ip.rs::tests::python_ip_pattern_dotted_masks_and_whitespace_match_reference", + "gateway-rs/src/policy/ip.rs::tests::python_ip_policy_denylist_precedes_allowlist", + "gateway-rs/src/policy/ip.rs::tests::localhost_host_header_cannot_bypass_an_ip_allowlist" + ], + "source": { + "kind": "function", + "line": 26, + "path": "backend-services/utils/ip_policy_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/ip_policy_util.py::function:_ip_in_list", + "notes": "Rust matches trusted-proxy resolution, XFF precedence, exact/CIDR/netmask matching, blacklist precedence, whitelist errors, Docker loopback addresses, and per-API trust overrides. Rust intentionally does not let a spoofable Host header alone trigger localhost bypass, and its typed audit/error plumbing differs from Python's broad fail-open catches.", + "rust_symbols": [ + "gateway-rs/src/policy/ip.rs::effective_client_ip_for_settings", + "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy" + ], + "rust_tests": [ + "gateway-rs/src/policy/ip.rs::tests::python_ip_pattern_dotted_masks_and_whitespace_match_reference", + "gateway-rs/src/policy/ip.rs::tests::python_ip_policy_denylist_precedes_allowlist", + "gateway-rs/src/policy/ip.rs::tests::localhost_host_header_cannot_bypass_an_ip_allowlist" + ], + "source": { + "kind": "function", + "line": 51, + "path": "backend-services/utils/ip_policy_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/ip_policy_util.py::function:_is_loopback", + "notes": "Rust matches trusted-proxy resolution, XFF precedence, exact/CIDR/netmask matching, blacklist precedence, whitelist errors, Docker loopback addresses, and per-API trust overrides. Rust intentionally does not let a spoofable Host header alone trigger localhost bypass, and its typed audit/error plumbing differs from Python's broad fail-open catches.", + "rust_symbols": [ + "gateway-rs/src/policy/ip.rs::effective_client_ip_for_settings", + "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy" + ], + "rust_tests": [ + "gateway-rs/src/policy/ip.rs::tests::python_ip_pattern_dotted_masks_and_whitespace_match_reference", + "gateway-rs/src/policy/ip.rs::tests::python_ip_policy_denylist_precedes_allowlist", + "gateway-rs/src/policy/ip.rs::tests::localhost_host_header_cannot_bypass_an_ip_allowlist" + ], + "source": { + "kind": "function", + "line": 75, + "path": "backend-services/utils/ip_policy_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/ip_policy_util.py::function:enforce_api_ip_policy", + "notes": "Rust matches trusted-proxy resolution, XFF precedence, exact/CIDR/netmask matching, blacklist precedence, whitelist errors, Docker loopback addresses, and per-API trust overrides. Rust intentionally does not let a spoofable Host header alone trigger localhost bypass, and its typed audit/error plumbing differs from Python's broad fail-open catches.", + "rust_symbols": [ + "gateway-rs/src/policy/ip.rs::effective_client_ip_for_settings", + "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy" + ], + "rust_tests": [ + "gateway-rs/src/policy/ip.rs::tests::python_ip_pattern_dotted_masks_and_whitespace_match_reference", + "gateway-rs/src/policy/ip.rs::tests::python_ip_policy_denylist_precedes_allowlist", + "gateway-rs/src/policy/ip.rs::tests::localhost_host_header_cannot_bypass_an_ip_allowlist" + ], + "source": { + "kind": "function", + "line": 106, + "path": "backend-services/utils/ip_policy_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/ip_rate_limiter.py::module:ip_rate_limiter", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "rust_symbols": [ + "gateway-rs/src/policy/ip.rs::effective_client_ip", + "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/ip.rs::tests::trusts_forwarding_headers_when_enabled", + "gateway-rs/src/policy/ip.rs::tests::enforces_blacklist_and_whitelist", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/ip_rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [ + "dataclass" + ], + "domain": "utils", + "id": "backend-services/utils/ip_rate_limiter.py::class:IPInfo", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "rust_symbols": [ + "gateway-rs/src/policy/ip.rs::effective_client_ip", + "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/ip.rs::tests::trusts_forwarding_headers_when_enabled", + "gateway-rs/src/policy/ip.rs::tests::enforces_blacklist_and_whitelist", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "class", + "line": 22, + "path": "backend-services/utils/ip_rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/ip_rate_limiter.py::field:IPInfo.ip", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "rust_symbols": [ + "gateway-rs/src/policy/ip.rs::effective_client_ip", + "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/ip.rs::tests::trusts_forwarding_headers_when_enabled", + "gateway-rs/src/policy/ip.rs::tests::enforces_blacklist_and_whitelist", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "field", + "line": 25, + "path": "backend-services/utils/ip_rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/ip_rate_limiter.py::field:IPInfo.is_whitelisted", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "rust_symbols": [ + "gateway-rs/src/policy/ip.rs::effective_client_ip", + "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/ip.rs::tests::trusts_forwarding_headers_when_enabled", + "gateway-rs/src/policy/ip.rs::tests::enforces_blacklist_and_whitelist", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "field", + "line": 26, + "path": "backend-services/utils/ip_rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/ip_rate_limiter.py::field:IPInfo.is_blacklisted", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "rust_symbols": [ + "gateway-rs/src/policy/ip.rs::effective_client_ip", + "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/ip.rs::tests::trusts_forwarding_headers_when_enabled", + "gateway-rs/src/policy/ip.rs::tests::enforces_blacklist_and_whitelist", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "field", + "line": 27, + "path": "backend-services/utils/ip_rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/ip_rate_limiter.py::field:IPInfo.reputation_score", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "rust_symbols": [ + "gateway-rs/src/policy/ip.rs::effective_client_ip", + "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/ip.rs::tests::trusts_forwarding_headers_when_enabled", + "gateway-rs/src/policy/ip.rs::tests::enforces_blacklist_and_whitelist", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "field", + "line": 28, + "path": "backend-services/utils/ip_rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/ip_rate_limiter.py::field:IPInfo.request_count", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "rust_symbols": [ + "gateway-rs/src/policy/ip.rs::effective_client_ip", + "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/ip.rs::tests::trusts_forwarding_headers_when_enabled", + "gateway-rs/src/policy/ip.rs::tests::enforces_blacklist_and_whitelist", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "field", + "line": 29, + "path": "backend-services/utils/ip_rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/ip_rate_limiter.py::field:IPInfo.last_seen", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "rust_symbols": [ + "gateway-rs/src/policy/ip.rs::effective_client_ip", + "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/ip.rs::tests::trusts_forwarding_headers_when_enabled", + "gateway-rs/src/policy/ip.rs::tests::enforces_blacklist_and_whitelist", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "field", + "line": 30, + "path": "backend-services/utils/ip_rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/ip_rate_limiter.py::field:IPInfo.countries", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "rust_symbols": [ + "gateway-rs/src/policy/ip.rs::effective_client_ip", + "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/ip.rs::tests::trusts_forwarding_headers_when_enabled", + "gateway-rs/src/policy/ip.rs::tests::enforces_blacklist_and_whitelist", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "field", + "line": 31, + "path": "backend-services/utils/ip_rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/ip_rate_limiter.py::method:IPInfo.__post_init__", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "rust_symbols": [ + "gateway-rs/src/policy/ip.rs::effective_client_ip", + "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/ip.rs::tests::trusts_forwarding_headers_when_enabled", + "gateway-rs/src/policy/ip.rs::tests::enforces_blacklist_and_whitelist", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "method", + "line": 33, + "path": "backend-services/utils/ip_rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/ip_rate_limiter.py::class:IPRateLimiter", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "rust_symbols": [ + "gateway-rs/src/policy/ip.rs::effective_client_ip", + "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/ip.rs::tests::trusts_forwarding_headers_when_enabled", + "gateway-rs/src/policy/ip.rs::tests::enforces_blacklist_and_whitelist", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "class", + "line": 38, + "path": "backend-services/utils/ip_rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/ip_rate_limiter.py::method:IPRateLimiter.__init__", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "rust_symbols": [ + "gateway-rs/src/policy/ip.rs::effective_client_ip", + "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/ip.rs::tests::trusts_forwarding_headers_when_enabled", + "gateway-rs/src/policy/ip.rs::tests::enforces_blacklist_and_whitelist", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "method", + "line": 43, + "path": "backend-services/utils/ip_rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/ip_rate_limiter.py::method:IPRateLimiter.extract_client_ip", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "rust_symbols": [ + "gateway-rs/src/policy/ip.rs::effective_client_ip", + "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/ip.rs::tests::trusts_forwarding_headers_when_enabled", + "gateway-rs/src/policy/ip.rs::tests::enforces_blacklist_and_whitelist", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "method", + "line": 56, + "path": "backend-services/utils/ip_rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/ip_rate_limiter.py::method:IPRateLimiter.is_whitelisted", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "rust_symbols": [ + "gateway-rs/src/policy/ip.rs::effective_client_ip", + "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/ip.rs::tests::trusts_forwarding_headers_when_enabled", + "gateway-rs/src/policy/ip.rs::tests::enforces_blacklist_and_whitelist", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "method", + "line": 82, + "path": "backend-services/utils/ip_rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/ip_rate_limiter.py::method:IPRateLimiter.is_blacklisted", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "rust_symbols": [ + "gateway-rs/src/policy/ip.rs::effective_client_ip", + "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/ip.rs::tests::trusts_forwarding_headers_when_enabled", + "gateway-rs/src/policy/ip.rs::tests::enforces_blacklist_and_whitelist", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "method", + "line": 90, + "path": "backend-services/utils/ip_rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/ip_rate_limiter.py::method:IPRateLimiter.add_to_whitelist", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "rust_symbols": [ + "gateway-rs/src/policy/ip.rs::effective_client_ip", + "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/ip.rs::tests::trusts_forwarding_headers_when_enabled", + "gateway-rs/src/policy/ip.rs::tests::enforces_blacklist_and_whitelist", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "method", + "line": 98, + "path": "backend-services/utils/ip_rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/ip_rate_limiter.py::method:IPRateLimiter.add_to_blacklist", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "rust_symbols": [ + "gateway-rs/src/policy/ip.rs::effective_client_ip", + "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/ip.rs::tests::trusts_forwarding_headers_when_enabled", + "gateway-rs/src/policy/ip.rs::tests::enforces_blacklist_and_whitelist", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "method", + "line": 108, + "path": "backend-services/utils/ip_rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/ip_rate_limiter.py::method:IPRateLimiter.remove_from_whitelist", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "rust_symbols": [ + "gateway-rs/src/policy/ip.rs::effective_client_ip", + "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/ip.rs::tests::trusts_forwarding_headers_when_enabled", + "gateway-rs/src/policy/ip.rs::tests::enforces_blacklist_and_whitelist", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "method", + "line": 132, + "path": "backend-services/utils/ip_rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/ip_rate_limiter.py::method:IPRateLimiter.remove_from_blacklist", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "rust_symbols": [ + "gateway-rs/src/policy/ip.rs::effective_client_ip", + "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/ip.rs::tests::trusts_forwarding_headers_when_enabled", + "gateway-rs/src/policy/ip.rs::tests::enforces_blacklist_and_whitelist", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "method", + "line": 142, + "path": "backend-services/utils/ip_rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/ip_rate_limiter.py::method:IPRateLimiter.get_reputation_score", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "rust_symbols": [ + "gateway-rs/src/policy/ip.rs::effective_client_ip", + "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/ip.rs::tests::trusts_forwarding_headers_when_enabled", + "gateway-rs/src/policy/ip.rs::tests::enforces_blacklist_and_whitelist", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "method", + "line": 154, + "path": "backend-services/utils/ip_rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/ip_rate_limiter.py::method:IPRateLimiter.update_reputation_score", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "rust_symbols": [ + "gateway-rs/src/policy/ip.rs::effective_client_ip", + "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/ip.rs::tests::trusts_forwarding_headers_when_enabled", + "gateway-rs/src/policy/ip.rs::tests::enforces_blacklist_and_whitelist", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "method", + "line": 168, + "path": "backend-services/utils/ip_rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/ip_rate_limiter.py::method:IPRateLimiter.track_request", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "rust_symbols": [ + "gateway-rs/src/policy/ip.rs::effective_client_ip", + "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/ip.rs::tests::trusts_forwarding_headers_when_enabled", + "gateway-rs/src/policy/ip.rs::tests::enforces_blacklist_and_whitelist", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "method", + "line": 196, + "path": "backend-services/utils/ip_rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/ip_rate_limiter.py::method:IPRateLimiter.get_ip_info", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "rust_symbols": [ + "gateway-rs/src/policy/ip.rs::effective_client_ip", + "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/ip.rs::tests::trusts_forwarding_headers_when_enabled", + "gateway-rs/src/policy/ip.rs::tests::enforces_blacklist_and_whitelist", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "method", + "line": 212, + "path": "backend-services/utils/ip_rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/ip_rate_limiter.py::method:IPRateLimiter.check_ip_rate_limit", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "rust_symbols": [ + "gateway-rs/src/policy/ip.rs::effective_client_ip", + "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/ip.rs::tests::trusts_forwarding_headers_when_enabled", + "gateway-rs/src/policy/ip.rs::tests::enforces_blacklist_and_whitelist", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "method", + "line": 234, + "path": "backend-services/utils/ip_rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/ip_rate_limiter.py::method:IPRateLimiter.get_top_ips", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "rust_symbols": [ + "gateway-rs/src/policy/ip.rs::effective_client_ip", + "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/ip.rs::tests::trusts_forwarding_headers_when_enabled", + "gateway-rs/src/policy/ip.rs::tests::enforces_blacklist_and_whitelist", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "method", + "line": 311, + "path": "backend-services/utils/ip_rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/ip_rate_limiter.py::method:IPRateLimiter.detect_suspicious_activity", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "rust_symbols": [ + "gateway-rs/src/policy/ip.rs::effective_client_ip", + "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/ip.rs::tests::trusts_forwarding_headers_when_enabled", + "gateway-rs/src/policy/ip.rs::tests::enforces_blacklist_and_whitelist", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "method", + "line": 345, + "path": "backend-services/utils/ip_rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/ip_rate_limiter.py::function:get_ip_rate_limiter", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "rust_symbols": [ + "gateway-rs/src/policy/ip.rs::effective_client_ip", + "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/ip.rs::tests::trusts_forwarding_headers_when_enabled", + "gateway-rs/src/policy/ip.rs::tests::enforces_blacklist_and_whitelist", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "function", + "line": 379, + "path": "backend-services/utils/ip_rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/key_util.py::module:key_util", + "notes": "Rust supports JWT_KEYS list/wrapper/single-object forms, HS256 and RS256, inline and file-backed RSA verification/signing keys, active signing selection, explicit kid verification including inactive rotation keys, single-key no-kid fallback, legacy-key fallback, and JWT_SECRET_KEY compatibility. Python's five-minute process cache and development import-time DEFAULT_DEV_KEY snapshot are not reproduced.", + "rust_symbols": [ + "gateway-rs/src/policy/auth.rs::select_configured_key", + "gateway-rs/src/routes/platform.rs::sign_token" + ], + "rust_tests": [ + "gateway-rs/src/policy/auth.rs::tests::configured_verification_key_selection_matches_legacy_kid_rules", + "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/key_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/key_util.py::class:KeyInfo", + "notes": "Rust supports JWT_KEYS list/wrapper/single-object forms, HS256 and RS256, inline and file-backed RSA verification/signing keys, active signing selection, explicit kid verification including inactive rotation keys, single-key no-kid fallback, legacy-key fallback, and JWT_SECRET_KEY compatibility. Python's five-minute process cache and development import-time DEFAULT_DEV_KEY snapshot are not reproduced.", + "rust_symbols": [ + "gateway-rs/src/policy/auth.rs::select_configured_key", + "gateway-rs/src/routes/platform.rs::sign_token" + ], + "rust_tests": [ + "gateway-rs/src/policy/auth.rs::tests::configured_verification_key_selection_matches_legacy_kid_rules", + "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python" + ], + "source": { + "kind": "class", + "line": 19, + "path": "backend-services/utils/key_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/key_util.py::field:KeyInfo.kid", + "notes": "Rust supports JWT_KEYS list/wrapper/single-object forms, HS256 and RS256, inline and file-backed RSA verification/signing keys, active signing selection, explicit kid verification including inactive rotation keys, single-key no-kid fallback, legacy-key fallback, and JWT_SECRET_KEY compatibility. Python's five-minute process cache and development import-time DEFAULT_DEV_KEY snapshot are not reproduced.", + "rust_symbols": [ + "gateway-rs/src/policy/auth.rs::select_configured_key", + "gateway-rs/src/routes/platform.rs::sign_token" + ], + "rust_tests": [ + "gateway-rs/src/policy/auth.rs::tests::configured_verification_key_selection_matches_legacy_kid_rules", + "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python" + ], + "source": { + "kind": "field", + "line": 20, + "path": "backend-services/utils/key_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/key_util.py::field:KeyInfo.algorithm", + "notes": "Rust supports JWT_KEYS list/wrapper/single-object forms, HS256 and RS256, inline and file-backed RSA verification/signing keys, active signing selection, explicit kid verification including inactive rotation keys, single-key no-kid fallback, legacy-key fallback, and JWT_SECRET_KEY compatibility. Python's five-minute process cache and development import-time DEFAULT_DEV_KEY snapshot are not reproduced.", + "rust_symbols": [ + "gateway-rs/src/policy/auth.rs::select_configured_key", + "gateway-rs/src/routes/platform.rs::sign_token" + ], + "rust_tests": [ + "gateway-rs/src/policy/auth.rs::tests::configured_verification_key_selection_matches_legacy_kid_rules", + "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python" + ], + "source": { + "kind": "field", + "line": 21, + "path": "backend-services/utils/key_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/key_util.py::field:KeyInfo.signing_key", + "notes": "Rust supports JWT_KEYS list/wrapper/single-object forms, HS256 and RS256, inline and file-backed RSA verification/signing keys, active signing selection, explicit kid verification including inactive rotation keys, single-key no-kid fallback, legacy-key fallback, and JWT_SECRET_KEY compatibility. Python's five-minute process cache and development import-time DEFAULT_DEV_KEY snapshot are not reproduced.", + "rust_symbols": [ + "gateway-rs/src/policy/auth.rs::select_configured_key", + "gateway-rs/src/routes/platform.rs::sign_token" + ], + "rust_tests": [ + "gateway-rs/src/policy/auth.rs::tests::configured_verification_key_selection_matches_legacy_kid_rules", + "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python" + ], + "source": { + "kind": "field", + "line": 22, + "path": "backend-services/utils/key_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/key_util.py::field:KeyInfo.verification_key", + "notes": "Rust supports JWT_KEYS list/wrapper/single-object forms, HS256 and RS256, inline and file-backed RSA verification/signing keys, active signing selection, explicit kid verification including inactive rotation keys, single-key no-kid fallback, legacy-key fallback, and JWT_SECRET_KEY compatibility. Python's five-minute process cache and development import-time DEFAULT_DEV_KEY snapshot are not reproduced.", + "rust_symbols": [ + "gateway-rs/src/policy/auth.rs::select_configured_key", + "gateway-rs/src/routes/platform.rs::sign_token" + ], + "rust_tests": [ + "gateway-rs/src/policy/auth.rs::tests::configured_verification_key_selection_matches_legacy_kid_rules", + "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python" + ], + "source": { + "kind": "field", + "line": 23, + "path": "backend-services/utils/key_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/key_util.py::field:KeyInfo.active", + "notes": "Rust supports JWT_KEYS list/wrapper/single-object forms, HS256 and RS256, inline and file-backed RSA verification/signing keys, active signing selection, explicit kid verification including inactive rotation keys, single-key no-kid fallback, legacy-key fallback, and JWT_SECRET_KEY compatibility. Python's five-minute process cache and development import-time DEFAULT_DEV_KEY snapshot are not reproduced.", + "rust_symbols": [ + "gateway-rs/src/policy/auth.rs::select_configured_key", + "gateway-rs/src/routes/platform.rs::sign_token" + ], + "rust_tests": [ + "gateway-rs/src/policy/auth.rs::tests::configured_verification_key_selection_matches_legacy_kid_rules", + "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python" + ], + "source": { + "kind": "field", + "line": 24, + "path": "backend-services/utils/key_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/key_util.py::function:load_keys", + "notes": "Rust supports JWT_KEYS list/wrapper/single-object forms, HS256 and RS256, inline and file-backed RSA verification/signing keys, active signing selection, explicit kid verification including inactive rotation keys, single-key no-kid fallback, legacy-key fallback, and JWT_SECRET_KEY compatibility. Python's five-minute process cache and development import-time DEFAULT_DEV_KEY snapshot are not reproduced.", + "rust_symbols": [ + "gateway-rs/src/policy/auth.rs::select_configured_key", + "gateway-rs/src/routes/platform.rs::sign_token" + ], + "rust_tests": [ + "gateway-rs/src/policy/auth.rs::tests::configured_verification_key_selection_matches_legacy_kid_rules", + "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python" + ], + "source": { + "kind": "function", + "line": 41, + "path": "backend-services/utils/key_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/key_util.py::function:get_signing_key", + "notes": "Rust supports JWT_KEYS list/wrapper/single-object forms, HS256 and RS256, inline and file-backed RSA verification/signing keys, active signing selection, explicit kid verification including inactive rotation keys, single-key no-kid fallback, legacy-key fallback, and JWT_SECRET_KEY compatibility. Python's five-minute process cache and development import-time DEFAULT_DEV_KEY snapshot are not reproduced.", + "rust_symbols": [ + "gateway-rs/src/policy/auth.rs::select_configured_key", + "gateway-rs/src/routes/platform.rs::sign_token" + ], + "rust_tests": [ + "gateway-rs/src/policy/auth.rs::tests::configured_verification_key_selection_matches_legacy_kid_rules", + "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python" + ], + "source": { + "kind": "function", + "line": 139, + "path": "backend-services/utils/key_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/key_util.py::function:get_verification_key", + "notes": "Rust supports JWT_KEYS list/wrapper/single-object forms, HS256 and RS256, inline and file-backed RSA verification/signing keys, active signing selection, explicit kid verification including inactive rotation keys, single-key no-kid fallback, legacy-key fallback, and JWT_SECRET_KEY compatibility. Python's five-minute process cache and development import-time DEFAULT_DEV_KEY snapshot are not reproduced.", + "rust_symbols": [ + "gateway-rs/src/policy/auth.rs::select_configured_key", + "gateway-rs/src/routes/platform.rs::sign_token" + ], + "rust_tests": [ + "gateway-rs/src/policy/auth.rs::tests::configured_verification_key_selection_matches_legacy_kid_rules", + "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python" + ], + "source": { + "kind": "function", + "line": 165, + "path": "backend-services/utils/key_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/limit_throttle_util.py::module:limit_throttle_util", + "notes": "Rust preserves duration aliases/defaults, expiring shared counters, user rate-limit boundaries, throttle activation/count/queue/excess rules, dynamic wait scaling, IP bucketing, retry headers/body, disable flag, and cache reset. Python's process-local fallback after Redis errors and test-runtime minimum-sleep branches are intentionally absent from production-native enforcement.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs::duration_to_seconds", + "gateway-rs/src/policy/evaluator.rs::evaluate_request", + "gateway-rs/src/policy/throttle.rs::enforce_throttle", + "gateway-rs/src/routes/platform.rs::ip_rate_limit" + ], + "rust_tests": [ + "gateway-rs/src/policy/throttle.rs::tests::python_test_throttle_dynamic_wait_uses_fractional_seconds", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/limit_throttle_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/limit_throttle_util.py::class:InMemoryWindowCounter", + "notes": "Rust preserves duration aliases/defaults, expiring shared counters, user rate-limit boundaries, throttle activation/count/queue/excess rules, dynamic wait scaling, IP bucketing, retry headers/body, disable flag, and cache reset. Python's process-local fallback after Redis errors and test-runtime minimum-sleep branches are intentionally absent from production-native enforcement.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs::duration_to_seconds", + "gateway-rs/src/policy/evaluator.rs::evaluate_request", + "gateway-rs/src/policy/throttle.rs::enforce_throttle", + "gateway-rs/src/routes/platform.rs::ip_rate_limit" + ], + "rust_tests": [ + "gateway-rs/src/policy/throttle.rs::tests::python_test_throttle_dynamic_wait_uses_fractional_seconds", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "class", + "line": 17, + "path": "backend-services/utils/limit_throttle_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/limit_throttle_util.py::method:InMemoryWindowCounter.__init__", + "notes": "Rust preserves duration aliases/defaults, expiring shared counters, user rate-limit boundaries, throttle activation/count/queue/excess rules, dynamic wait scaling, IP bucketing, retry headers/body, disable flag, and cache reset. Python's process-local fallback after Redis errors and test-runtime minimum-sleep branches are intentionally absent from production-native enforcement.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs::duration_to_seconds", + "gateway-rs/src/policy/evaluator.rs::evaluate_request", + "gateway-rs/src/policy/throttle.rs::enforce_throttle", + "gateway-rs/src/routes/platform.rs::ip_rate_limit" + ], + "rust_tests": [ + "gateway-rs/src/policy/throttle.rs::tests::python_test_throttle_dynamic_wait_uses_fractional_seconds", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "method", + "line": 41, + "path": "backend-services/utils/limit_throttle_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/limit_throttle_util.py::async_method:InMemoryWindowCounter.incr", + "notes": "Rust preserves duration aliases/defaults, expiring shared counters, user rate-limit boundaries, throttle activation/count/queue/excess rules, dynamic wait scaling, IP bucketing, retry headers/body, disable flag, and cache reset. Python's process-local fallback after Redis errors and test-runtime minimum-sleep branches are intentionally absent from production-native enforcement.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs::duration_to_seconds", + "gateway-rs/src/policy/evaluator.rs::evaluate_request", + "gateway-rs/src/policy/throttle.rs::enforce_throttle", + "gateway-rs/src/routes/platform.rs::ip_rate_limit" + ], + "rust_tests": [ + "gateway-rs/src/policy/throttle.rs::tests::python_test_throttle_dynamic_wait_uses_fractional_seconds", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "async_method", + "line": 45, + "path": "backend-services/utils/limit_throttle_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/limit_throttle_util.py::async_method:InMemoryWindowCounter.expire", + "notes": "Rust preserves duration aliases/defaults, expiring shared counters, user rate-limit boundaries, throttle activation/count/queue/excess rules, dynamic wait scaling, IP bucketing, retry headers/body, disable flag, and cache reset. Python's process-local fallback after Redis errors and test-runtime minimum-sleep branches are intentionally absent from production-native enforcement.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs::duration_to_seconds", + "gateway-rs/src/policy/evaluator.rs::evaluate_request", + "gateway-rs/src/policy/throttle.rs::enforce_throttle", + "gateway-rs/src/routes/platform.rs::ip_rate_limit" + ], + "rust_tests": [ + "gateway-rs/src/policy/throttle.rs::tests::python_test_throttle_dynamic_wait_uses_fractional_seconds", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "async_method", + "line": 56, + "path": "backend-services/utils/limit_throttle_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/limit_throttle_util.py::function:duration_to_seconds", + "notes": "Rust preserves duration aliases/defaults, expiring shared counters, user rate-limit boundaries, throttle activation/count/queue/excess rules, dynamic wait scaling, IP bucketing, retry headers/body, disable flag, and cache reset. Python's process-local fallback after Redis errors and test-runtime minimum-sleep branches are intentionally absent from production-native enforcement.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs::duration_to_seconds", + "gateway-rs/src/policy/evaluator.rs::evaluate_request", + "gateway-rs/src/policy/throttle.rs::enforce_throttle", + "gateway-rs/src/routes/platform.rs::ip_rate_limit" + ], + "rust_tests": [ + "gateway-rs/src/policy/throttle.rs::tests::python_test_throttle_dynamic_wait_uses_fractional_seconds", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "function", + "line": 68, + "path": "backend-services/utils/limit_throttle_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/limit_throttle_util.py::async_function:limit_and_throttle", + "notes": "Rust preserves duration aliases/defaults, expiring shared counters, user rate-limit boundaries, throttle activation/count/queue/excess rules, dynamic wait scaling, IP bucketing, retry headers/body, disable flag, and cache reset. Python's process-local fallback after Redis errors and test-runtime minimum-sleep branches are intentionally absent from production-native enforcement.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs::duration_to_seconds", + "gateway-rs/src/policy/evaluator.rs::evaluate_request", + "gateway-rs/src/policy/throttle.rs::enforce_throttle", + "gateway-rs/src/routes/platform.rs::ip_rate_limit" + ], + "rust_tests": [ + "gateway-rs/src/policy/throttle.rs::tests::python_test_throttle_dynamic_wait_uses_fractional_seconds", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "async_function", + "line": 85, + "path": "backend-services/utils/limit_throttle_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/limit_throttle_util.py::function:reset_counters", + "notes": "Rust preserves duration aliases/defaults, expiring shared counters, user rate-limit boundaries, throttle activation/count/queue/excess rules, dynamic wait scaling, IP bucketing, retry headers/body, disable flag, and cache reset. Python's process-local fallback after Redis errors and test-runtime minimum-sleep branches are intentionally absent from production-native enforcement.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs::duration_to_seconds", + "gateway-rs/src/policy/evaluator.rs::evaluate_request", + "gateway-rs/src/policy/throttle.rs::enforce_throttle", + "gateway-rs/src/routes/platform.rs::ip_rate_limit" + ], + "rust_tests": [ + "gateway-rs/src/policy/throttle.rs::tests::python_test_throttle_dynamic_wait_uses_fractional_seconds", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "function", + "line": 213, + "path": "backend-services/utils/limit_throttle_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/limit_throttle_util.py::async_function:limit_by_ip", + "notes": "Rust preserves duration aliases/defaults, expiring shared counters, user rate-limit boundaries, throttle activation/count/queue/excess rules, dynamic wait scaling, IP bucketing, retry headers/body, disable flag, and cache reset. Python's process-local fallback after Redis errors and test-runtime minimum-sleep branches are intentionally absent from production-native enforcement.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs::duration_to_seconds", + "gateway-rs/src/policy/evaluator.rs::evaluate_request", + "gateway-rs/src/policy/throttle.rs::enforce_throttle", + "gateway-rs/src/routes/platform.rs::ip_rate_limit" + ], + "rust_tests": [ + "gateway-rs/src/policy/throttle.rs::tests::python_test_throttle_dynamic_wait_uses_fractional_seconds", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "async_function", + "line": 229, + "path": "backend-services/utils/limit_throttle_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/memory_dump_util.py::module:memory_dump_util", + "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore now decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy. Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model.", + "rust_symbols": [ + "gateway-rs/src/storage/snapshot.rs::dump", + "gateway-rs/src/storage/snapshot.rs::restore", + "gateway-rs/src/storage/snapshot.rs::restore_latest", + "gateway-rs/src/storage/snapshot.rs::restore_python_json_values", + "gateway-rs/src/storage/snapshot.rs::reconcile_bootstrap_admin" + ], + "rust_tests": [ + "gateway-rs/src/storage/snapshot.rs::tests::decrypts_a_dump_created_by_the_python_backend", + "gateway-rs/src/storage/snapshot.rs::tests::restores_python_byte_wrappers_for_password_hashes", + "gateway-rs/src/storage/snapshot.rs::tests::failed_restore_is_atomic_and_exact_file_restore_succeeds" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/memory_dump_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/memory_dump_util.py::function:_normalize_dump_path", + "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore now decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy. Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model.", + "rust_symbols": [ + "gateway-rs/src/storage/snapshot.rs::dump", + "gateway-rs/src/storage/snapshot.rs::restore", + "gateway-rs/src/storage/snapshot.rs::restore_latest", + "gateway-rs/src/storage/snapshot.rs::restore_python_json_values", + "gateway-rs/src/storage/snapshot.rs::reconcile_bootstrap_admin" + ], + "rust_tests": [ + "gateway-rs/src/storage/snapshot.rs::tests::decrypts_a_dump_created_by_the_python_backend", + "gateway-rs/src/storage/snapshot.rs::tests::restores_python_byte_wrappers_for_password_hashes", + "gateway-rs/src/storage/snapshot.rs::tests::failed_restore_is_atomic_and_exact_file_restore_succeeds" + ], + "source": { + "kind": "function", + "line": 20, + "path": "backend-services/utils/memory_dump_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/memory_dump_util.py::function:_derive_key", + "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore now decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy. Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model.", + "rust_symbols": [ + "gateway-rs/src/storage/snapshot.rs::dump", + "gateway-rs/src/storage/snapshot.rs::restore", + "gateway-rs/src/storage/snapshot.rs::restore_latest", + "gateway-rs/src/storage/snapshot.rs::restore_python_json_values", + "gateway-rs/src/storage/snapshot.rs::reconcile_bootstrap_admin" + ], + "rust_tests": [ + "gateway-rs/src/storage/snapshot.rs::tests::decrypts_a_dump_created_by_the_python_backend", + "gateway-rs/src/storage/snapshot.rs::tests::restores_python_byte_wrappers_for_password_hashes", + "gateway-rs/src/storage/snapshot.rs::tests::failed_restore_is_atomic_and_exact_file_restore_succeeds" + ], + "source": { + "kind": "function", + "line": 41, + "path": "backend-services/utils/memory_dump_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/memory_dump_util.py::function:_encrypt_blob", + "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore now decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy. Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model.", + "rust_symbols": [ + "gateway-rs/src/storage/snapshot.rs::dump", + "gateway-rs/src/storage/snapshot.rs::restore", + "gateway-rs/src/storage/snapshot.rs::restore_latest", + "gateway-rs/src/storage/snapshot.rs::restore_python_json_values", + "gateway-rs/src/storage/snapshot.rs::reconcile_bootstrap_admin" + ], + "rust_tests": [ + "gateway-rs/src/storage/snapshot.rs::tests::decrypts_a_dump_created_by_the_python_backend", + "gateway-rs/src/storage/snapshot.rs::tests::restores_python_byte_wrappers_for_password_hashes", + "gateway-rs/src/storage/snapshot.rs::tests::failed_restore_is_atomic_and_exact_file_restore_succeeds" + ], + "source": { + "kind": "function", + "line": 46, + "path": "backend-services/utils/memory_dump_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/memory_dump_util.py::function:_decrypt_blob", + "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore now decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy. Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model.", + "rust_symbols": [ + "gateway-rs/src/storage/snapshot.rs::dump", + "gateway-rs/src/storage/snapshot.rs::restore", + "gateway-rs/src/storage/snapshot.rs::restore_latest", + "gateway-rs/src/storage/snapshot.rs::restore_python_json_values", + "gateway-rs/src/storage/snapshot.rs::reconcile_bootstrap_admin" + ], + "rust_tests": [ + "gateway-rs/src/storage/snapshot.rs::tests::decrypts_a_dump_created_by_the_python_backend", + "gateway-rs/src/storage/snapshot.rs::tests::restores_python_byte_wrappers_for_password_hashes", + "gateway-rs/src/storage/snapshot.rs::tests::failed_restore_is_atomic_and_exact_file_restore_succeeds" + ], + "source": { + "kind": "function", + "line": 58, + "path": "backend-services/utils/memory_dump_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/memory_dump_util.py::function:_split_dir_and_stem", + "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore now decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy. Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model.", + "rust_symbols": [ + "gateway-rs/src/storage/snapshot.rs::dump", + "gateway-rs/src/storage/snapshot.rs::restore", + "gateway-rs/src/storage/snapshot.rs::restore_latest", + "gateway-rs/src/storage/snapshot.rs::restore_python_json_values", + "gateway-rs/src/storage/snapshot.rs::reconcile_bootstrap_admin" + ], + "rust_tests": [ + "gateway-rs/src/storage/snapshot.rs::tests::decrypts_a_dump_created_by_the_python_backend", + "gateway-rs/src/storage/snapshot.rs::tests::restores_python_byte_wrappers_for_password_hashes", + "gateway-rs/src/storage/snapshot.rs::tests::failed_restore_is_atomic_and_exact_file_restore_succeeds" + ], + "source": { + "kind": "function", + "line": 73, + "path": "backend-services/utils/memory_dump_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/memory_dump_util.py::function:_to_jsonable", + "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore now decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy. Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model.", + "rust_symbols": [ + "gateway-rs/src/storage/snapshot.rs::dump", + "gateway-rs/src/storage/snapshot.rs::restore", + "gateway-rs/src/storage/snapshot.rs::restore_latest", + "gateway-rs/src/storage/snapshot.rs::restore_python_json_values", + "gateway-rs/src/storage/snapshot.rs::reconcile_bootstrap_admin" + ], + "rust_tests": [ + "gateway-rs/src/storage/snapshot.rs::tests::decrypts_a_dump_created_by_the_python_backend", + "gateway-rs/src/storage/snapshot.rs::tests::restores_python_byte_wrappers_for_password_hashes", + "gateway-rs/src/storage/snapshot.rs::tests::failed_restore_is_atomic_and_exact_file_restore_succeeds" + ], + "source": { + "kind": "function", + "line": 106, + "path": "backend-services/utils/memory_dump_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/memory_dump_util.py::function:_json_default", + "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore now decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy. Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model.", + "rust_symbols": [ + "gateway-rs/src/storage/snapshot.rs::dump", + "gateway-rs/src/storage/snapshot.rs::restore", + "gateway-rs/src/storage/snapshot.rs::restore_latest", + "gateway-rs/src/storage/snapshot.rs::restore_python_json_values", + "gateway-rs/src/storage/snapshot.rs::reconcile_bootstrap_admin" + ], + "rust_tests": [ + "gateway-rs/src/storage/snapshot.rs::tests::decrypts_a_dump_created_by_the_python_backend", + "gateway-rs/src/storage/snapshot.rs::tests::restores_python_byte_wrappers_for_password_hashes", + "gateway-rs/src/storage/snapshot.rs::tests::failed_restore_is_atomic_and_exact_file_restore_succeeds" + ], + "source": { + "kind": "function", + "line": 143, + "path": "backend-services/utils/memory_dump_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/memory_dump_util.py::function:_from_jsonable", + "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore now decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy. Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model.", + "rust_symbols": [ + "gateway-rs/src/storage/snapshot.rs::dump", + "gateway-rs/src/storage/snapshot.rs::restore", + "gateway-rs/src/storage/snapshot.rs::restore_latest", + "gateway-rs/src/storage/snapshot.rs::restore_python_json_values", + "gateway-rs/src/storage/snapshot.rs::reconcile_bootstrap_admin" + ], + "rust_tests": [ + "gateway-rs/src/storage/snapshot.rs::tests::decrypts_a_dump_created_by_the_python_backend", + "gateway-rs/src/storage/snapshot.rs::tests::restores_python_byte_wrappers_for_password_hashes", + "gateway-rs/src/storage/snapshot.rs::tests::failed_restore_is_atomic_and_exact_file_restore_succeeds" + ], + "source": { + "kind": "function", + "line": 152, + "path": "backend-services/utils/memory_dump_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/memory_dump_util.py::function:_sanitize_for_dump", + "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore now decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy. Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model.", + "rust_symbols": [ + "gateway-rs/src/storage/snapshot.rs::dump", + "gateway-rs/src/storage/snapshot.rs::restore", + "gateway-rs/src/storage/snapshot.rs::restore_latest", + "gateway-rs/src/storage/snapshot.rs::restore_python_json_values", + "gateway-rs/src/storage/snapshot.rs::reconcile_bootstrap_admin" + ], + "rust_tests": [ + "gateway-rs/src/storage/snapshot.rs::tests::decrypts_a_dump_created_by_the_python_backend", + "gateway-rs/src/storage/snapshot.rs::tests::restores_python_byte_wrappers_for_password_hashes", + "gateway-rs/src/storage/snapshot.rs::tests::failed_restore_is_atomic_and_exact_file_restore_succeeds" + ], + "source": { + "kind": "function", + "line": 176, + "path": "backend-services/utils/memory_dump_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/memory_dump_util.py::function:_sanitize_for_dump.should_redact", + "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore now decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy. Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model.", + "rust_symbols": [ + "gateway-rs/src/storage/snapshot.rs::dump", + "gateway-rs/src/storage/snapshot.rs::restore", + "gateway-rs/src/storage/snapshot.rs::restore_latest", + "gateway-rs/src/storage/snapshot.rs::restore_python_json_values", + "gateway-rs/src/storage/snapshot.rs::reconcile_bootstrap_admin" + ], + "rust_tests": [ + "gateway-rs/src/storage/snapshot.rs::tests::decrypts_a_dump_created_by_the_python_backend", + "gateway-rs/src/storage/snapshot.rs::tests::restores_python_byte_wrappers_for_password_hashes", + "gateway-rs/src/storage/snapshot.rs::tests::failed_restore_is_atomic_and_exact_file_restore_succeeds" + ], + "source": { + "kind": "function", + "line": 204, + "path": "backend-services/utils/memory_dump_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/memory_dump_util.py::function:_sanitize_for_dump.redact_value", + "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore now decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy. Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model.", + "rust_symbols": [ + "gateway-rs/src/storage/snapshot.rs::dump", + "gateway-rs/src/storage/snapshot.rs::restore", + "gateway-rs/src/storage/snapshot.rs::restore_latest", + "gateway-rs/src/storage/snapshot.rs::restore_python_json_values", + "gateway-rs/src/storage/snapshot.rs::reconcile_bootstrap_admin" + ], + "rust_tests": [ + "gateway-rs/src/storage/snapshot.rs::tests::decrypts_a_dump_created_by_the_python_backend", + "gateway-rs/src/storage/snapshot.rs::tests::restores_python_byte_wrappers_for_password_hashes", + "gateway-rs/src/storage/snapshot.rs::tests::failed_restore_is_atomic_and_exact_file_restore_succeeds" + ], + "source": { + "kind": "function", + "line": 210, + "path": "backend-services/utils/memory_dump_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/memory_dump_util.py::function:dump_memory_to_file", + "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore now decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy. Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model.", + "rust_symbols": [ + "gateway-rs/src/storage/snapshot.rs::dump", + "gateway-rs/src/storage/snapshot.rs::restore", + "gateway-rs/src/storage/snapshot.rs::restore_latest", + "gateway-rs/src/storage/snapshot.rs::restore_python_json_values", + "gateway-rs/src/storage/snapshot.rs::reconcile_bootstrap_admin" + ], + "rust_tests": [ + "gateway-rs/src/storage/snapshot.rs::tests::decrypts_a_dump_created_by_the_python_backend", + "gateway-rs/src/storage/snapshot.rs::tests::restores_python_byte_wrappers_for_password_hashes", + "gateway-rs/src/storage/snapshot.rs::tests::failed_restore_is_atomic_and_exact_file_restore_succeeds" + ], + "source": { + "kind": "function", + "line": 228, + "path": "backend-services/utils/memory_dump_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/memory_dump_util.py::function:restore_memory_from_file", + "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore now decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy. Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model.", + "rust_symbols": [ + "gateway-rs/src/storage/snapshot.rs::dump", + "gateway-rs/src/storage/snapshot.rs::restore", + "gateway-rs/src/storage/snapshot.rs::restore_latest", + "gateway-rs/src/storage/snapshot.rs::restore_python_json_values", + "gateway-rs/src/storage/snapshot.rs::reconcile_bootstrap_admin" + ], + "rust_tests": [ + "gateway-rs/src/storage/snapshot.rs::tests::decrypts_a_dump_created_by_the_python_backend", + "gateway-rs/src/storage/snapshot.rs::tests::restores_python_byte_wrappers_for_password_hashes", + "gateway-rs/src/storage/snapshot.rs::tests::failed_restore_is_atomic_and_exact_file_restore_succeeds" + ], + "source": { + "kind": "function", + "line": 255, + "path": "backend-services/utils/memory_dump_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/memory_dump_util.py::function:find_latest_dump_path", + "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore now decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy. Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model.", + "rust_symbols": [ + "gateway-rs/src/storage/snapshot.rs::dump", + "gateway-rs/src/storage/snapshot.rs::restore", + "gateway-rs/src/storage/snapshot.rs::restore_latest", + "gateway-rs/src/storage/snapshot.rs::restore_python_json_values", + "gateway-rs/src/storage/snapshot.rs::reconcile_bootstrap_admin" + ], + "rust_tests": [ + "gateway-rs/src/storage/snapshot.rs::tests::decrypts_a_dump_created_by_the_python_backend", + "gateway-rs/src/storage/snapshot.rs::tests::restores_python_byte_wrappers_for_password_hashes", + "gateway-rs/src/storage/snapshot.rs::tests::failed_restore_is_atomic_and_exact_file_restore_succeeds" + ], + "source": { + "kind": "function", + "line": 295, + "path": "backend-services/utils/memory_dump_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/memory_dump_util.py::function:find_latest_dump_path.newest_bin_in_dir", + "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore now decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy. Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model.", + "rust_symbols": [ + "gateway-rs/src/storage/snapshot.rs::dump", + "gateway-rs/src/storage/snapshot.rs::restore", + "gateway-rs/src/storage/snapshot.rs::restore_latest", + "gateway-rs/src/storage/snapshot.rs::restore_python_json_values", + "gateway-rs/src/storage/snapshot.rs::reconcile_bootstrap_admin" + ], + "rust_tests": [ + "gateway-rs/src/storage/snapshot.rs::tests::decrypts_a_dump_created_by_the_python_backend", + "gateway-rs/src/storage/snapshot.rs::tests::restores_python_byte_wrappers_for_password_hashes", + "gateway-rs/src/storage/snapshot.rs::tests::failed_restore_is_atomic_and_exact_file_restore_succeeds" + ], + "source": { + "kind": "function", + "line": 303, + "path": "backend-services/utils/memory_dump_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/memory_log.py::module:memory_log", + "notes": "Rust now records every formatted structured event into a thread-safe 50,000-line ring buffer, returns copied snapshots, stores compatible time/name/level/message JSON records, and merges recent memory records into native log queries/exports.", + "rust_symbols": [ + "gateway-rs/src/observability/logging.rs::memory_log_snapshot", + "gateway-rs/src/observability/logging.rs::RedactingJsonEvent.format_event", + "gateway-rs/src/routes/platform.rs::read_log_records" + ], + "rust_tests": [ + "gateway-rs/src/observability/logging.rs::tests::json_sink_redacts_free_form_messages_and_sensitive_fields", + "gateway-rs/tests/security_settings_parity.rs::live_logging_endpoints_match_python" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/memory_log.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/memory_log.py::class:_MemoryLogStore", + "notes": "Rust now records every formatted structured event into a thread-safe 50,000-line ring buffer, returns copied snapshots, stores compatible time/name/level/message JSON records, and merges recent memory records into native log queries/exports.", + "rust_symbols": [ + "gateway-rs/src/observability/logging.rs::memory_log_snapshot", + "gateway-rs/src/observability/logging.rs::RedactingJsonEvent.format_event", + "gateway-rs/src/routes/platform.rs::read_log_records" + ], + "rust_tests": [ + "gateway-rs/src/observability/logging.rs::tests::json_sink_redacts_free_form_messages_and_sensitive_fields", + "gateway-rs/tests/security_settings_parity.rs::live_logging_endpoints_match_python" + ], + "source": { + "kind": "class", + "line": 20, + "path": "backend-services/utils/memory_log.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/memory_log.py::method:_MemoryLogStore.__init__", + "notes": "Rust now records every formatted structured event into a thread-safe 50,000-line ring buffer, returns copied snapshots, stores compatible time/name/level/message JSON records, and merges recent memory records into native log queries/exports.", + "rust_symbols": [ + "gateway-rs/src/observability/logging.rs::memory_log_snapshot", + "gateway-rs/src/observability/logging.rs::RedactingJsonEvent.format_event", + "gateway-rs/src/routes/platform.rs::read_log_records" + ], + "rust_tests": [ + "gateway-rs/src/observability/logging.rs::tests::json_sink_redacts_free_form_messages_and_sensitive_fields", + "gateway-rs/tests/security_settings_parity.rs::live_logging_endpoints_match_python" + ], + "source": { + "kind": "method", + "line": 21, + "path": "backend-services/utils/memory_log.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/memory_log.py::method:_MemoryLogStore.add", + "notes": "Rust now records every formatted structured event into a thread-safe 50,000-line ring buffer, returns copied snapshots, stores compatible time/name/level/message JSON records, and merges recent memory records into native log queries/exports.", + "rust_symbols": [ + "gateway-rs/src/observability/logging.rs::memory_log_snapshot", + "gateway-rs/src/observability/logging.rs::RedactingJsonEvent.format_event", + "gateway-rs/src/routes/platform.rs::read_log_records" + ], + "rust_tests": [ + "gateway-rs/src/observability/logging.rs::tests::json_sink_redacts_free_form_messages_and_sensitive_fields", + "gateway-rs/tests/security_settings_parity.rs::live_logging_endpoints_match_python" + ], + "source": { + "kind": "method", + "line": 25, + "path": "backend-services/utils/memory_log.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/memory_log.py::method:_MemoryLogStore.snapshot", + "notes": "Rust now records every formatted structured event into a thread-safe 50,000-line ring buffer, returns copied snapshots, stores compatible time/name/level/message JSON records, and merges recent memory records into native log queries/exports.", + "rust_symbols": [ + "gateway-rs/src/observability/logging.rs::memory_log_snapshot", + "gateway-rs/src/observability/logging.rs::RedactingJsonEvent.format_event", + "gateway-rs/src/routes/platform.rs::read_log_records" + ], + "rust_tests": [ + "gateway-rs/src/observability/logging.rs::tests::json_sink_redacts_free_form_messages_and_sensitive_fields", + "gateway-rs/tests/security_settings_parity.rs::live_logging_endpoints_match_python" + ], + "source": { + "kind": "method", + "line": 29, + "path": "backend-services/utils/memory_log.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/memory_log.py::function:memory_log_snapshot", + "notes": "Rust now records every formatted structured event into a thread-safe 50,000-line ring buffer, returns copied snapshots, stores compatible time/name/level/message JSON records, and merges recent memory records into native log queries/exports.", + "rust_symbols": [ + "gateway-rs/src/observability/logging.rs::memory_log_snapshot", + "gateway-rs/src/observability/logging.rs::RedactingJsonEvent.format_event", + "gateway-rs/src/routes/platform.rs::read_log_records" + ], + "rust_tests": [ + "gateway-rs/src/observability/logging.rs::tests::json_sink_redacts_free_form_messages_and_sensitive_fields", + "gateway-rs/tests/security_settings_parity.rs::live_logging_endpoints_match_python" + ], + "source": { + "kind": "function", + "line": 38, + "path": "backend-services/utils/memory_log.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/memory_log.py::class:MemoryLogHandler", + "notes": "Rust now records every formatted structured event into a thread-safe 50,000-line ring buffer, returns copied snapshots, stores compatible time/name/level/message JSON records, and merges recent memory records into native log queries/exports.", + "rust_symbols": [ + "gateway-rs/src/observability/logging.rs::memory_log_snapshot", + "gateway-rs/src/observability/logging.rs::RedactingJsonEvent.format_event", + "gateway-rs/src/routes/platform.rs::read_log_records" + ], + "rust_tests": [ + "gateway-rs/src/observability/logging.rs::tests::json_sink_redacts_free_form_messages_and_sensitive_fields", + "gateway-rs/tests/security_settings_parity.rs::live_logging_endpoints_match_python" + ], + "source": { + "kind": "class", + "line": 42, + "path": "backend-services/utils/memory_log.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/memory_log.py::method:MemoryLogHandler.__init__", + "notes": "Rust now records every formatted structured event into a thread-safe 50,000-line ring buffer, returns copied snapshots, stores compatible time/name/level/message JSON records, and merges recent memory records into native log queries/exports.", + "rust_symbols": [ + "gateway-rs/src/observability/logging.rs::memory_log_snapshot", + "gateway-rs/src/observability/logging.rs::RedactingJsonEvent.format_event", + "gateway-rs/src/routes/platform.rs::read_log_records" + ], + "rust_tests": [ + "gateway-rs/src/observability/logging.rs::tests::json_sink_redacts_free_form_messages_and_sensitive_fields", + "gateway-rs/tests/security_settings_parity.rs::live_logging_endpoints_match_python" + ], + "source": { + "kind": "method", + "line": 49, + "path": "backend-services/utils/memory_log.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/memory_log.py::method:MemoryLogHandler.emit", + "notes": "Rust now records every formatted structured event into a thread-safe 50,000-line ring buffer, returns copied snapshots, stores compatible time/name/level/message JSON records, and merges recent memory records into native log queries/exports.", + "rust_symbols": [ + "gateway-rs/src/observability/logging.rs::memory_log_snapshot", + "gateway-rs/src/observability/logging.rs::RedactingJsonEvent.format_event", + "gateway-rs/src/routes/platform.rs::read_log_records" + ], + "rust_tests": [ + "gateway-rs/src/observability/logging.rs::tests::json_sink_redacts_free_form_messages_and_sensitive_fields", + "gateway-rs/tests/security_settings_parity.rs::live_logging_endpoints_match_python" + ], + "source": { + "kind": "method", + "line": 52, + "path": "backend-services/utils/memory_log.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/metrics_util.py::module:metrics_util", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/routes/platform.rs::monitor_metrics" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_accepts_python_range_parameters_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/metrics_util.py" + }, + "status": "partial" + }, + { + "decorators": [ + "dataclass" + ], + "domain": "utils", + "id": "backend-services/utils/metrics_util.py::class:MinuteBucket", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/routes/platform.rs::monitor_metrics" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_accepts_python_range_parameters_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity" + ], + "source": { + "kind": "class", + "line": 16, + "path": "backend-services/utils/metrics_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/metrics_util.py::field:MinuteBucket.start_ts", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/routes/platform.rs::monitor_metrics" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_accepts_python_range_parameters_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity" + ], + "source": { + "kind": "field", + "line": 17, + "path": "backend-services/utils/metrics_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/metrics_util.py::field:MinuteBucket.count", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/routes/platform.rs::monitor_metrics" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_accepts_python_range_parameters_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity" + ], + "source": { + "kind": "field", + "line": 18, + "path": "backend-services/utils/metrics_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/metrics_util.py::field:MinuteBucket.test_count", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/routes/platform.rs::monitor_metrics" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_accepts_python_range_parameters_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity" + ], + "source": { + "kind": "field", + "line": 19, + "path": "backend-services/utils/metrics_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/metrics_util.py::field:MinuteBucket.error_count", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/routes/platform.rs::monitor_metrics" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_accepts_python_range_parameters_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity" + ], + "source": { + "kind": "field", + "line": 20, + "path": "backend-services/utils/metrics_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/metrics_util.py::field:MinuteBucket.total_ms", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/routes/platform.rs::monitor_metrics" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_accepts_python_range_parameters_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity" + ], + "source": { + "kind": "field", + "line": 21, + "path": "backend-services/utils/metrics_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/metrics_util.py::field:MinuteBucket.bytes_in", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/routes/platform.rs::monitor_metrics" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_accepts_python_range_parameters_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity" + ], + "source": { + "kind": "field", + "line": 22, + "path": "backend-services/utils/metrics_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/metrics_util.py::field:MinuteBucket.bytes_out", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/routes/platform.rs::monitor_metrics" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_accepts_python_range_parameters_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity" + ], + "source": { + "kind": "field", + "line": 23, + "path": "backend-services/utils/metrics_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/metrics_util.py::field:MinuteBucket.upstream_timeouts", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/routes/platform.rs::monitor_metrics" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_accepts_python_range_parameters_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity" + ], + "source": { + "kind": "field", + "line": 24, + "path": "backend-services/utils/metrics_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/metrics_util.py::field:MinuteBucket.retries", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/routes/platform.rs::monitor_metrics" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_accepts_python_range_parameters_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity" + ], + "source": { + "kind": "field", + "line": 25, + "path": "backend-services/utils/metrics_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/metrics_util.py::field:MinuteBucket.status_counts", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/routes/platform.rs::monitor_metrics" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_accepts_python_range_parameters_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity" + ], + "source": { + "kind": "field", + "line": 27, + "path": "backend-services/utils/metrics_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/metrics_util.py::field:MinuteBucket.api_counts", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/routes/platform.rs::monitor_metrics" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_accepts_python_range_parameters_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity" + ], + "source": { + "kind": "field", + "line": 28, + "path": "backend-services/utils/metrics_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/metrics_util.py::field:MinuteBucket.api_error_counts", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/routes/platform.rs::monitor_metrics" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_accepts_python_range_parameters_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity" + ], + "source": { + "kind": "field", + "line": 29, + "path": "backend-services/utils/metrics_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/metrics_util.py::field:MinuteBucket.user_counts", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/routes/platform.rs::monitor_metrics" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_accepts_python_range_parameters_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity" + ], + "source": { + "kind": "field", + "line": 30, + "path": "backend-services/utils/metrics_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/metrics_util.py::field:MinuteBucket.latencies", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/routes/platform.rs::monitor_metrics" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_accepts_python_range_parameters_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity" + ], + "source": { + "kind": "field", + "line": 31, + "path": "backend-services/utils/metrics_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/metrics_util.py::method:MinuteBucket.add", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/routes/platform.rs::monitor_metrics" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_accepts_python_range_parameters_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity" + ], + "source": { + "kind": "method", + "line": 33, + "path": "backend-services/utils/metrics_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/metrics_util.py::method:MinuteBucket.to_dict", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/routes/platform.rs::monitor_metrics" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_accepts_python_range_parameters_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity" + ], + "source": { + "kind": "method", + "line": 85, + "path": "backend-services/utils/metrics_util.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "utils", + "id": "backend-services/utils/metrics_util.py::method:MinuteBucket.from_dict", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/routes/platform.rs::monitor_metrics" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_accepts_python_range_parameters_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity" + ], + "source": { + "kind": "method", + "line": 103, + "path": "backend-services/utils/metrics_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/metrics_util.py::class:MetricsStore", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/routes/platform.rs::monitor_metrics" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_accepts_python_range_parameters_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity" + ], + "source": { + "kind": "class", + "line": 125, + "path": "backend-services/utils/metrics_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/metrics_util.py::method:MetricsStore.__init__", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/routes/platform.rs::monitor_metrics" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_accepts_python_range_parameters_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity" + ], + "source": { + "kind": "method", + "line": 126, + "path": "backend-services/utils/metrics_util.py" + }, + "status": "partial" + }, + { + "decorators": [ + "staticmethod" + ], + "domain": "utils", + "id": "backend-services/utils/metrics_util.py::method:MetricsStore._minute_floor", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/routes/platform.rs::monitor_metrics" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_accepts_python_range_parameters_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity" + ], + "source": { + "kind": "method", + "line": 141, + "path": "backend-services/utils/metrics_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/metrics_util.py::method:MetricsStore._ensure_bucket", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/routes/platform.rs::monitor_metrics" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_accepts_python_range_parameters_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity" + ], + "source": { + "kind": "method", + "line": 144, + "path": "backend-services/utils/metrics_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/metrics_util.py::method:MetricsStore.record", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/routes/platform.rs::monitor_metrics" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_accepts_python_range_parameters_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity" + ], + "source": { + "kind": "method", + "line": 155, + "path": "backend-services/utils/metrics_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/metrics_util.py::method:MetricsStore.record_retry", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/routes/platform.rs::monitor_metrics" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_accepts_python_range_parameters_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity" + ], + "source": { + "kind": "method", + "line": 192, + "path": "backend-services/utils/metrics_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/metrics_util.py::method:MetricsStore.record_upstream_timeout", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/routes/platform.rs::monitor_metrics" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_accepts_python_range_parameters_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity" + ], + "source": { + "kind": "method", + "line": 202, + "path": "backend-services/utils/metrics_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/metrics_util.py::method:MetricsStore.snapshot", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/routes/platform.rs::monitor_metrics" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_accepts_python_range_parameters_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity" + ], + "source": { + "kind": "method", + "line": 212, + "path": "backend-services/utils/metrics_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/metrics_util.py::method:MetricsStore.to_dict", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/routes/platform.rs::monitor_metrics" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_accepts_python_range_parameters_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity" + ], + "source": { + "kind": "method", + "line": 349, + "path": "backend-services/utils/metrics_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/metrics_util.py::method:MetricsStore.load_dict", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/routes/platform.rs::monitor_metrics" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_accepts_python_range_parameters_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity" + ], + "source": { + "kind": "method", + "line": 362, + "path": "backend-services/utils/metrics_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/metrics_util.py::method:MetricsStore.save_to_file", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/routes/platform.rs::monitor_metrics" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_accepts_python_range_parameters_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity" + ], + "source": { + "kind": "method", + "line": 383, + "path": "backend-services/utils/metrics_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/metrics_util.py::method:MetricsStore.load_from_file", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/routes/platform.rs::monitor_metrics" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_accepts_python_range_parameters_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity" + ], + "source": { + "kind": "method", + "line": 396, + "path": "backend-services/utils/metrics_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/paging_util.py::module:paging_util", + "notes": "Rust now preserves the MAX_PAGE_SIZE default, blank/invalid fallback, minimum-one coercion, one-based validation, and exact bound messages at management list boundaries. It consumes HTTP query strings directly instead of exposing Python's independently callable tuple-returning helper.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::configured_max_page_size", + "gateway-rs/src/routes/platform.rs::validate_pagination" + ], + "rust_tests": [ + "gateway-rs/src/routes/platform.rs::tests::pagination_is_one_based_and_capped" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/paging_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/paging_util.py::function:max_page_size", + "notes": "Rust now preserves the MAX_PAGE_SIZE default, blank/invalid fallback, minimum-one coercion, one-based validation, and exact bound messages at management list boundaries. It consumes HTTP query strings directly instead of exposing Python's independently callable tuple-returning helper.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::configured_max_page_size", + "gateway-rs/src/routes/platform.rs::validate_pagination" + ], + "rust_tests": [ + "gateway-rs/src/routes/platform.rs::tests::pagination_is_one_based_and_capped" + ], + "source": { + "kind": "function", + "line": 6, + "path": "backend-services/utils/paging_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/paging_util.py::function:validate_page_params", + "notes": "Rust now preserves the MAX_PAGE_SIZE default, blank/invalid fallback, minimum-one coercion, one-based validation, and exact bound messages at management list boundaries. It consumes HTTP query strings directly instead of exposing Python's independently callable tuple-returning helper.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::configured_max_page_size", + "gateway-rs/src/routes/platform.rs::validate_pagination" + ], + "rust_tests": [ + "gateway-rs/src/routes/platform.rs::tests::pagination_is_one_based_and_capped" + ], + "source": { + "kind": "function", + "line": 16, + "path": "backend-services/utils/paging_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/password_util.py::module:password_util", + "notes": "Rust uses bcrypt for hash/verify and now counts Unicode characters while accepting Unicode uppercase, lowercase, and numeric characters under the pinned password policy. Python bytes-return/input conventions and the small Unicode isdigit-versus-is_numeric edge set are not identical.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::secure_password", + "gateway-rs/src/storage/runtime.rs::SharedStorage.connect" + ], + "rust_tests": [ + "gateway-rs/src/routes/platform.rs::tests::enforces_the_python_password_policy", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/password_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/password_util.py::function:hash_password", + "notes": "Rust uses bcrypt for hash/verify and now counts Unicode characters while accepting Unicode uppercase, lowercase, and numeric characters under the pinned password policy. Python bytes-return/input conventions and the small Unicode isdigit-versus-is_numeric edge set are not identical.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::secure_password", + "gateway-rs/src/storage/runtime.rs::SharedStorage.connect" + ], + "rust_tests": [ + "gateway-rs/src/routes/platform.rs::tests::enforces_the_python_password_policy", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials" + ], + "source": { + "kind": "function", + "line": 10, + "path": "backend-services/utils/password_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/password_util.py::function:verify_password", + "notes": "Rust uses bcrypt for hash/verify and now counts Unicode characters while accepting Unicode uppercase, lowercase, and numeric characters under the pinned password policy. Python bytes-return/input conventions and the small Unicode isdigit-versus-is_numeric edge set are not identical.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::secure_password", + "gateway-rs/src/storage/runtime.rs::SharedStorage.connect" + ], + "rust_tests": [ + "gateway-rs/src/routes/platform.rs::tests::enforces_the_python_password_policy", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials" + ], + "source": { + "kind": "function", + "line": 15, + "path": "backend-services/utils/password_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/password_util.py::function:is_secure_password", + "notes": "Rust uses bcrypt for hash/verify and now counts Unicode characters while accepting Unicode uppercase, lowercase, and numeric characters under the pinned password policy. Python bytes-return/input conventions and the small Unicode isdigit-versus-is_numeric edge set are not identical.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::secure_password", + "gateway-rs/src/storage/runtime.rs::SharedStorage.connect" + ], + "rust_tests": [ + "gateway-rs/src/routes/platform.rs::tests::enforces_the_python_password_policy", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials" + ], + "source": { + "kind": "function", + "line": 20, + "path": "backend-services/utils/password_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/prometheus_metrics.py::module:prometheus_metrics", + "notes": "Rust preserves enable/disable behavior, the exact histogram buckets and names, nonnegative duration observations, status labels, retry/timeout counters, and Prometheus text rendering; native output also exposes the additive active-request gauge.", + "rust_symbols": [ + "gateway-rs/src/observability/metrics.rs::observe_request", + "gateway-rs/src/observability/metrics.rs::render", + "gateway-rs/src/routes/metrics.rs::metrics" + ], + "rust_tests": [ + "gateway-rs/src/observability/metrics.rs::tests::renders_python_compatible_metric_names", + "gateway-rs/tests/platform_native.rs::prometheus_metrics_exposition_counters_allowlist_and_token_match_python" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/prometheus_metrics.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/prometheus_metrics.py::class:_NoopMetric", + "notes": "Rust preserves enable/disable behavior, the exact histogram buckets and names, nonnegative duration observations, status labels, retry/timeout counters, and Prometheus text rendering; native output also exposes the additive active-request gauge.", + "rust_symbols": [ + "gateway-rs/src/observability/metrics.rs::observe_request", + "gateway-rs/src/observability/metrics.rs::render", + "gateway-rs/src/routes/metrics.rs::metrics" + ], + "rust_tests": [ + "gateway-rs/src/observability/metrics.rs::tests::renders_python_compatible_metric_names", + "gateway-rs/tests/platform_native.rs::prometheus_metrics_exposition_counters_allowlist_and_token_match_python" + ], + "source": { + "kind": "class", + "line": 5, + "path": "backend-services/utils/prometheus_metrics.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/prometheus_metrics.py::method:_NoopMetric.labels", + "notes": "Rust preserves enable/disable behavior, the exact histogram buckets and names, nonnegative duration observations, status labels, retry/timeout counters, and Prometheus text rendering; native output also exposes the additive active-request gauge.", + "rust_symbols": [ + "gateway-rs/src/observability/metrics.rs::observe_request", + "gateway-rs/src/observability/metrics.rs::render", + "gateway-rs/src/routes/metrics.rs::metrics" + ], + "rust_tests": [ + "gateway-rs/src/observability/metrics.rs::tests::renders_python_compatible_metric_names", + "gateway-rs/tests/platform_native.rs::prometheus_metrics_exposition_counters_allowlist_and_token_match_python" + ], + "source": { + "kind": "method", + "line": 6, + "path": "backend-services/utils/prometheus_metrics.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/prometheus_metrics.py::method:_NoopMetric.inc", + "notes": "Rust preserves enable/disable behavior, the exact histogram buckets and names, nonnegative duration observations, status labels, retry/timeout counters, and Prometheus text rendering; native output also exposes the additive active-request gauge.", + "rust_symbols": [ + "gateway-rs/src/observability/metrics.rs::observe_request", + "gateway-rs/src/observability/metrics.rs::render", + "gateway-rs/src/routes/metrics.rs::metrics" + ], + "rust_tests": [ + "gateway-rs/src/observability/metrics.rs::tests::renders_python_compatible_metric_names", + "gateway-rs/tests/platform_native.rs::prometheus_metrics_exposition_counters_allowlist_and_token_match_python" + ], + "source": { + "kind": "method", + "line": 9, + "path": "backend-services/utils/prometheus_metrics.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/prometheus_metrics.py::method:_NoopMetric.observe", + "notes": "Rust preserves enable/disable behavior, the exact histogram buckets and names, nonnegative duration observations, status labels, retry/timeout counters, and Prometheus text rendering; native output also exposes the additive active-request gauge.", + "rust_symbols": [ + "gateway-rs/src/observability/metrics.rs::observe_request", + "gateway-rs/src/observability/metrics.rs::render", + "gateway-rs/src/routes/metrics.rs::metrics" + ], + "rust_tests": [ + "gateway-rs/src/observability/metrics.rs::tests::renders_python_compatible_metric_names", + "gateway-rs/tests/platform_native.rs::prometheus_metrics_exposition_counters_allowlist_and_token_match_python" + ], + "source": { + "kind": "method", + "line": 12, + "path": "backend-services/utils/prometheus_metrics.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/prometheus_metrics.py::function:generate_latest", + "notes": "Rust preserves enable/disable behavior, the exact histogram buckets and names, nonnegative duration observations, status labels, retry/timeout counters, and Prometheus text rendering; native output also exposes the additive active-request gauge.", + "rust_symbols": [ + "gateway-rs/src/observability/metrics.rs::observe_request", + "gateway-rs/src/observability/metrics.rs::render", + "gateway-rs/src/routes/metrics.rs::metrics" + ], + "rust_tests": [ + "gateway-rs/src/observability/metrics.rs::tests::renders_python_compatible_metric_names", + "gateway-rs/tests/platform_native.rs::prometheus_metrics_exposition_counters_allowlist_and_token_match_python" + ], + "source": { + "kind": "function", + "line": 24, + "path": "backend-services/utils/prometheus_metrics.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/prometheus_metrics.py::function:observe_request", + "notes": "Rust preserves enable/disable behavior, the exact histogram buckets and names, nonnegative duration observations, status labels, retry/timeout counters, and Prometheus text rendering; native output also exposes the additive active-request gauge.", + "rust_symbols": [ + "gateway-rs/src/observability/metrics.rs::observe_request", + "gateway-rs/src/observability/metrics.rs::render", + "gateway-rs/src/routes/metrics.rs::metrics" + ], + "rust_tests": [ + "gateway-rs/src/observability/metrics.rs::tests::renders_python_compatible_metric_names", + "gateway-rs/tests/platform_native.rs::prometheus_metrics_exposition_counters_allowlist_and_token_match_python" + ], + "source": { + "kind": "function", + "line": 63, + "path": "backend-services/utils/prometheus_metrics.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/prometheus_metrics.py::function:record_retry", + "notes": "Rust preserves enable/disable behavior, the exact histogram buckets and names, nonnegative duration observations, status labels, retry/timeout counters, and Prometheus text rendering; native output also exposes the additive active-request gauge.", + "rust_symbols": [ + "gateway-rs/src/observability/metrics.rs::observe_request", + "gateway-rs/src/observability/metrics.rs::render", + "gateway-rs/src/routes/metrics.rs::metrics" + ], + "rust_tests": [ + "gateway-rs/src/observability/metrics.rs::tests::renders_python_compatible_metric_names", + "gateway-rs/tests/platform_native.rs::prometheus_metrics_exposition_counters_allowlist_and_token_match_python" + ], + "source": { + "kind": "function", + "line": 73, + "path": "backend-services/utils/prometheus_metrics.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/prometheus_metrics.py::function:record_upstream_timeout", + "notes": "Rust preserves enable/disable behavior, the exact histogram buckets and names, nonnegative duration observations, status labels, retry/timeout counters, and Prometheus text rendering; native output also exposes the additive active-request gauge.", + "rust_symbols": [ + "gateway-rs/src/observability/metrics.rs::observe_request", + "gateway-rs/src/observability/metrics.rs::render", + "gateway-rs/src/routes/metrics.rs::metrics" + ], + "rust_tests": [ + "gateway-rs/src/observability/metrics.rs::tests::renders_python_compatible_metric_names", + "gateway-rs/tests/platform_native.rs::prometheus_metrics_exposition_counters_allowlist_and_token_match_python" + ], + "source": { + "kind": "function", + "line": 82, + "path": "backend-services/utils/prometheus_metrics.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/prometheus_metrics.py::function:render_latest", + "notes": "Rust preserves enable/disable behavior, the exact histogram buckets and names, nonnegative duration observations, status labels, retry/timeout counters, and Prometheus text rendering; native output also exposes the additive active-request gauge.", + "rust_symbols": [ + "gateway-rs/src/observability/metrics.rs::observe_request", + "gateway-rs/src/observability/metrics.rs::render", + "gateway-rs/src/routes/metrics.rs::metrics" + ], + "rust_tests": [ + "gateway-rs/src/observability/metrics.rs::tests::renders_python_compatible_metric_names", + "gateway-rs/tests/platform_native.rs::prometheus_metrics_exposition_counters_allowlist_and_token_match_python" + ], + "source": { + "kind": "function", + "line": 91, + "path": "backend-services/utils/prometheus_metrics.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/quota_tracker.py::module:quota_tracker", + "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior. Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers; the pinned helper itself inconsistently mixes string keys and Redis hashes, and no production Python caller uses those paths.", + "rust_symbols": [ + "gateway-rs/src/policy/quota.rs::quota_usage_status", + "gateway-rs/src/policy/quota.rs::increment_quota_by", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period" + ], + "rust_tests": [ + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/quota.rs::tests::quota_increment_is_atomic_and_scoped_to_its_period", + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/quota_tracker.py" + }, + "status": "partial" + }, + { + "decorators": [ + "dataclass" + ], + "domain": "utils", + "id": "backend-services/utils/quota_tracker.py::class:QuotaCheckResult", + "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior. Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers; the pinned helper itself inconsistently mixes string keys and Redis hashes, and no production Python caller uses those paths.", + "rust_symbols": [ + "gateway-rs/src/policy/quota.rs::quota_usage_status", + "gateway-rs/src/policy/quota.rs::increment_quota_by", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period" + ], + "rust_tests": [ + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/quota.rs::tests::quota_increment_is_atomic_and_scoped_to_its_period", + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "class", + "line": 19, + "path": "backend-services/utils/quota_tracker.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/quota_tracker.py::field:QuotaCheckResult.allowed", + "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior. Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers; the pinned helper itself inconsistently mixes string keys and Redis hashes, and no production Python caller uses those paths.", + "rust_symbols": [ + "gateway-rs/src/policy/quota.rs::quota_usage_status", + "gateway-rs/src/policy/quota.rs::increment_quota_by", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period" + ], + "rust_tests": [ + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/quota.rs::tests::quota_increment_is_atomic_and_scoped_to_its_period", + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "field", + "line": 22, + "path": "backend-services/utils/quota_tracker.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/quota_tracker.py::field:QuotaCheckResult.current_usage", + "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior. Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers; the pinned helper itself inconsistently mixes string keys and Redis hashes, and no production Python caller uses those paths.", + "rust_symbols": [ + "gateway-rs/src/policy/quota.rs::quota_usage_status", + "gateway-rs/src/policy/quota.rs::increment_quota_by", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period" + ], + "rust_tests": [ + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/quota.rs::tests::quota_increment_is_atomic_and_scoped_to_its_period", + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "field", + "line": 23, + "path": "backend-services/utils/quota_tracker.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/quota_tracker.py::field:QuotaCheckResult.limit", + "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior. Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers; the pinned helper itself inconsistently mixes string keys and Redis hashes, and no production Python caller uses those paths.", + "rust_symbols": [ + "gateway-rs/src/policy/quota.rs::quota_usage_status", + "gateway-rs/src/policy/quota.rs::increment_quota_by", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period" + ], + "rust_tests": [ + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/quota.rs::tests::quota_increment_is_atomic_and_scoped_to_its_period", + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "field", + "line": 24, + "path": "backend-services/utils/quota_tracker.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/quota_tracker.py::field:QuotaCheckResult.remaining", + "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior. Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers; the pinned helper itself inconsistently mixes string keys and Redis hashes, and no production Python caller uses those paths.", + "rust_symbols": [ + "gateway-rs/src/policy/quota.rs::quota_usage_status", + "gateway-rs/src/policy/quota.rs::increment_quota_by", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period" + ], + "rust_tests": [ + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/quota.rs::tests::quota_increment_is_atomic_and_scoped_to_its_period", + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "field", + "line": 25, + "path": "backend-services/utils/quota_tracker.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/quota_tracker.py::field:QuotaCheckResult.reset_at", + "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior. Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers; the pinned helper itself inconsistently mixes string keys and Redis hashes, and no production Python caller uses those paths.", + "rust_symbols": [ + "gateway-rs/src/policy/quota.rs::quota_usage_status", + "gateway-rs/src/policy/quota.rs::increment_quota_by", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period" + ], + "rust_tests": [ + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/quota.rs::tests::quota_increment_is_atomic_and_scoped_to_its_period", + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "field", + "line": 26, + "path": "backend-services/utils/quota_tracker.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/quota_tracker.py::field:QuotaCheckResult.percentage_used", + "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior. Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers; the pinned helper itself inconsistently mixes string keys and Redis hashes, and no production Python caller uses those paths.", + "rust_symbols": [ + "gateway-rs/src/policy/quota.rs::quota_usage_status", + "gateway-rs/src/policy/quota.rs::increment_quota_by", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period" + ], + "rust_tests": [ + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/quota.rs::tests::quota_increment_is_atomic_and_scoped_to_its_period", + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "field", + "line": 27, + "path": "backend-services/utils/quota_tracker.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/quota_tracker.py::field:QuotaCheckResult.is_warning", + "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior. Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers; the pinned helper itself inconsistently mixes string keys and Redis hashes, and no production Python caller uses those paths.", + "rust_symbols": [ + "gateway-rs/src/policy/quota.rs::quota_usage_status", + "gateway-rs/src/policy/quota.rs::increment_quota_by", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period" + ], + "rust_tests": [ + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/quota.rs::tests::quota_increment_is_atomic_and_scoped_to_its_period", + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "field", + "line": 28, + "path": "backend-services/utils/quota_tracker.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/quota_tracker.py::field:QuotaCheckResult.is_critical", + "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior. Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers; the pinned helper itself inconsistently mixes string keys and Redis hashes, and no production Python caller uses those paths.", + "rust_symbols": [ + "gateway-rs/src/policy/quota.rs::quota_usage_status", + "gateway-rs/src/policy/quota.rs::increment_quota_by", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period" + ], + "rust_tests": [ + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/quota.rs::tests::quota_increment_is_atomic_and_scoped_to_its_period", + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "field", + "line": 29, + "path": "backend-services/utils/quota_tracker.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/quota_tracker.py::class:QuotaTracker", + "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior. Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers; the pinned helper itself inconsistently mixes string keys and Redis hashes, and no production Python caller uses those paths.", + "rust_symbols": [ + "gateway-rs/src/policy/quota.rs::quota_usage_status", + "gateway-rs/src/policy/quota.rs::increment_quota_by", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period" + ], + "rust_tests": [ + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/quota.rs::tests::quota_increment_is_atomic_and_scoped_to_its_period", + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "class", + "line": 32, + "path": "backend-services/utils/quota_tracker.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/quota_tracker.py::method:QuotaTracker.__init__", + "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior. Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers; the pinned helper itself inconsistently mixes string keys and Redis hashes, and no production Python caller uses those paths.", + "rust_symbols": [ + "gateway-rs/src/policy/quota.rs::quota_usage_status", + "gateway-rs/src/policy/quota.rs::increment_quota_by", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period" + ], + "rust_tests": [ + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/quota.rs::tests::quota_increment_is_atomic_and_scoped_to_its_period", + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "method", + "line": 44, + "path": "backend-services/utils/quota_tracker.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/quota_tracker.py::method:QuotaTracker.check_quota", + "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior. Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers; the pinned helper itself inconsistently mixes string keys and Redis hashes, and no production Python caller uses those paths.", + "rust_symbols": [ + "gateway-rs/src/policy/quota.rs::quota_usage_status", + "gateway-rs/src/policy/quota.rs::increment_quota_by", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period" + ], + "rust_tests": [ + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/quota.rs::tests::quota_increment_is_atomic_and_scoped_to_its_period", + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "method", + "line": 53, + "path": "backend-services/utils/quota_tracker.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/quota_tracker.py::method:QuotaTracker.increment_quota", + "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior. Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers; the pinned helper itself inconsistently mixes string keys and Redis hashes, and no production Python caller uses those paths.", + "rust_symbols": [ + "gateway-rs/src/policy/quota.rs::quota_usage_status", + "gateway-rs/src/policy/quota.rs::increment_quota_by", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period" + ], + "rust_tests": [ + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/quota.rs::tests::quota_increment_is_atomic_and_scoped_to_its_period", + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "method", + "line": 146, + "path": "backend-services/utils/quota_tracker.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/quota_tracker.py::method:QuotaTracker.get_quota_usage", + "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior. Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers; the pinned helper itself inconsistently mixes string keys and Redis hashes, and no production Python caller uses those paths.", + "rust_symbols": [ + "gateway-rs/src/policy/quota.rs::quota_usage_status", + "gateway-rs/src/policy/quota.rs::increment_quota_by", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period" + ], + "rust_tests": [ + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/quota.rs::tests::quota_increment_is_atomic_and_scoped_to_its_period", + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "method", + "line": 182, + "path": "backend-services/utils/quota_tracker.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/quota_tracker.py::method:QuotaTracker.reset_quota", + "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior. Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers; the pinned helper itself inconsistently mixes string keys and Redis hashes, and no production Python caller uses those paths.", + "rust_symbols": [ + "gateway-rs/src/policy/quota.rs::quota_usage_status", + "gateway-rs/src/policy/quota.rs::increment_quota_by", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period" + ], + "rust_tests": [ + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/quota.rs::tests::quota_increment_is_atomic_and_scoped_to_its_period", + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "method", + "line": 233, + "path": "backend-services/utils/quota_tracker.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/quota_tracker.py::method:QuotaTracker.get_all_quotas", + "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior. Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers; the pinned helper itself inconsistently mixes string keys and Redis hashes, and no production Python caller uses those paths.", + "rust_symbols": [ + "gateway-rs/src/policy/quota.rs::quota_usage_status", + "gateway-rs/src/policy/quota.rs::increment_quota_by", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period" + ], + "rust_tests": [ + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/quota.rs::tests::quota_increment_is_atomic_and_scoped_to_its_period", + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "method", + "line": 258, + "path": "backend-services/utils/quota_tracker.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/quota_tracker.py::method:QuotaTracker.check_and_increment", + "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior. Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers; the pinned helper itself inconsistently mixes string keys and Redis hashes, and no production Python caller uses those paths.", + "rust_symbols": [ + "gateway-rs/src/policy/quota.rs::quota_usage_status", + "gateway-rs/src/policy/quota.rs::increment_quota_by", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period" + ], + "rust_tests": [ + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/quota.rs::tests::quota_increment_is_atomic_and_scoped_to_its_period", + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "method", + "line": 277, + "path": "backend-services/utils/quota_tracker.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/quota_tracker.py::method:QuotaTracker._get_period_key", + "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior. Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers; the pinned helper itself inconsistently mixes string keys and Redis hashes, and no production Python caller uses those paths.", + "rust_symbols": [ + "gateway-rs/src/policy/quota.rs::quota_usage_status", + "gateway-rs/src/policy/quota.rs::increment_quota_by", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period" + ], + "rust_tests": [ + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/quota.rs::tests::quota_increment_is_atomic_and_scoped_to_its_period", + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "method", + "line": 315, + "path": "backend-services/utils/quota_tracker.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/quota_tracker.py::method:QuotaTracker._get_next_reset", + "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior. Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers; the pinned helper itself inconsistently mixes string keys and Redis hashes, and no production Python caller uses those paths.", + "rust_symbols": [ + "gateway-rs/src/policy/quota.rs::quota_usage_status", + "gateway-rs/src/policy/quota.rs::increment_quota_by", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period" + ], + "rust_tests": [ + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/quota.rs::tests::quota_increment_is_atomic_and_scoped_to_its_period", + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "method", + "line": 334, + "path": "backend-services/utils/quota_tracker.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/quota_tracker.py::method:QuotaTracker._initialize_quota", + "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior. Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers; the pinned helper itself inconsistently mixes string keys and Redis hashes, and no production Python caller uses those paths.", + "rust_symbols": [ + "gateway-rs/src/policy/quota.rs::quota_usage_status", + "gateway-rs/src/policy/quota.rs::increment_quota_by", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period" + ], + "rust_tests": [ + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/quota.rs::tests::quota_increment_is_atomic_and_scoped_to_its_period", + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "method", + "line": 359, + "path": "backend-services/utils/quota_tracker.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/quota_tracker.py::method:QuotaTracker.get_quota_history", + "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior. Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers; the pinned helper itself inconsistently mixes string keys and Redis hashes, and no production Python caller uses those paths.", + "rust_symbols": [ + "gateway-rs/src/policy/quota.rs::quota_usage_status", + "gateway-rs/src/policy/quota.rs::increment_quota_by", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period" + ], + "rust_tests": [ + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/quota.rs::tests::quota_increment_is_atomic_and_scoped_to_its_period", + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "method", + "line": 377, + "path": "backend-services/utils/quota_tracker.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/quota_tracker.py::function:get_quota_tracker", + "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior. Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers; the pinned helper itself inconsistently mixes string keys and Redis hashes, and no production Python caller uses those paths.", + "rust_symbols": [ + "gateway-rs/src/policy/quota.rs::quota_usage_status", + "gateway-rs/src/policy/quota.rs::increment_quota_by", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period" + ], + "rust_tests": [ + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/quota.rs::tests::quota_increment_is_atomic_and_scoped_to_its_period", + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "source": { + "kind": "function", + "line": 399, + "path": "backend-services/utils/quota_tracker.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limit_simulator.py::module:rate_limit_simulator", + "notes": "Rust now provides the standalone offline simulator: uniform, burst, spike, gradual, and random traffic generation; Python's inclusive sliding-window limit and burst accounting; per-second peaks and aggregate statistics; rule comparisons; change previews; burst-effectiveness sweeps; reports and recommendations; named scenarios; and quick simulation. Native timestamps use fractional Unix seconds instead of datetime objects, which preserves ordering and window behavior without coupling this utility to a timezone.", + "rust_symbols": [ + "gateway-rs/src/policy/simulator.rs::generate_requests", + "gateway-rs/src/policy/simulator.rs::simulate_rule", + "gateway-rs/src/policy/simulator.rs::preview_rule_change", + "gateway-rs/src/policy/simulator.rs::test_burst_effectiveness", + "gateway-rs/src/policy/simulator.rs::generate_report", + "gateway-rs/src/policy/simulator.rs::run_scenario", + "gateway-rs/src/policy/simulator.rs::quick_simulate" + ], + "rust_tests": [ + "gateway-rs/src/policy/simulator.rs::tests::generates_python_traffic_patterns", + "gateway-rs/src/policy/simulator.rs::tests::simulates_limit_and_burst_like_python", + "gateway-rs/src/policy/simulator.rs::tests::comparison_and_scenario_helpers_preserve_python_shapes" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/rate_limit_simulator.py" + }, + "status": "translated" + }, + { + "decorators": [ + "dataclass" + ], + "domain": "utils", + "id": "backend-services/utils/rate_limit_simulator.py::class:SimulationRequest", + "notes": "Rust now provides the standalone offline simulator: uniform, burst, spike, gradual, and random traffic generation; Python's inclusive sliding-window limit and burst accounting; per-second peaks and aggregate statistics; rule comparisons; change previews; burst-effectiveness sweeps; reports and recommendations; named scenarios; and quick simulation. Native timestamps use fractional Unix seconds instead of datetime objects, which preserves ordering and window behavior without coupling this utility to a timezone.", + "rust_symbols": [ + "gateway-rs/src/policy/simulator.rs::generate_requests", + "gateway-rs/src/policy/simulator.rs::simulate_rule", + "gateway-rs/src/policy/simulator.rs::preview_rule_change", + "gateway-rs/src/policy/simulator.rs::test_burst_effectiveness", + "gateway-rs/src/policy/simulator.rs::generate_report", + "gateway-rs/src/policy/simulator.rs::run_scenario", + "gateway-rs/src/policy/simulator.rs::quick_simulate" + ], + "rust_tests": [ + "gateway-rs/src/policy/simulator.rs::tests::generates_python_traffic_patterns", + "gateway-rs/src/policy/simulator.rs::tests::simulates_limit_and_burst_like_python", + "gateway-rs/src/policy/simulator.rs::tests::comparison_and_scenario_helpers_preserve_python_shapes" + ], + "source": { + "kind": "class", + "line": 20, + "path": "backend-services/utils/rate_limit_simulator.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limit_simulator.py::field:SimulationRequest.timestamp", + "notes": "Rust now provides the standalone offline simulator: uniform, burst, spike, gradual, and random traffic generation; Python's inclusive sliding-window limit and burst accounting; per-second peaks and aggregate statistics; rule comparisons; change previews; burst-effectiveness sweeps; reports and recommendations; named scenarios; and quick simulation. Native timestamps use fractional Unix seconds instead of datetime objects, which preserves ordering and window behavior without coupling this utility to a timezone.", + "rust_symbols": [ + "gateway-rs/src/policy/simulator.rs::generate_requests", + "gateway-rs/src/policy/simulator.rs::simulate_rule", + "gateway-rs/src/policy/simulator.rs::preview_rule_change", + "gateway-rs/src/policy/simulator.rs::test_burst_effectiveness", + "gateway-rs/src/policy/simulator.rs::generate_report", + "gateway-rs/src/policy/simulator.rs::run_scenario", + "gateway-rs/src/policy/simulator.rs::quick_simulate" + ], + "rust_tests": [ + "gateway-rs/src/policy/simulator.rs::tests::generates_python_traffic_patterns", + "gateway-rs/src/policy/simulator.rs::tests::simulates_limit_and_burst_like_python", + "gateway-rs/src/policy/simulator.rs::tests::comparison_and_scenario_helpers_preserve_python_shapes" + ], + "source": { + "kind": "field", + "line": 23, + "path": "backend-services/utils/rate_limit_simulator.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limit_simulator.py::field:SimulationRequest.user_id", + "notes": "Rust now provides the standalone offline simulator: uniform, burst, spike, gradual, and random traffic generation; Python's inclusive sliding-window limit and burst accounting; per-second peaks and aggregate statistics; rule comparisons; change previews; burst-effectiveness sweeps; reports and recommendations; named scenarios; and quick simulation. Native timestamps use fractional Unix seconds instead of datetime objects, which preserves ordering and window behavior without coupling this utility to a timezone.", + "rust_symbols": [ + "gateway-rs/src/policy/simulator.rs::generate_requests", + "gateway-rs/src/policy/simulator.rs::simulate_rule", + "gateway-rs/src/policy/simulator.rs::preview_rule_change", + "gateway-rs/src/policy/simulator.rs::test_burst_effectiveness", + "gateway-rs/src/policy/simulator.rs::generate_report", + "gateway-rs/src/policy/simulator.rs::run_scenario", + "gateway-rs/src/policy/simulator.rs::quick_simulate" + ], + "rust_tests": [ + "gateway-rs/src/policy/simulator.rs::tests::generates_python_traffic_patterns", + "gateway-rs/src/policy/simulator.rs::tests::simulates_limit_and_burst_like_python", + "gateway-rs/src/policy/simulator.rs::tests::comparison_and_scenario_helpers_preserve_python_shapes" + ], + "source": { + "kind": "field", + "line": 24, + "path": "backend-services/utils/rate_limit_simulator.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limit_simulator.py::field:SimulationRequest.endpoint", + "notes": "Rust now provides the standalone offline simulator: uniform, burst, spike, gradual, and random traffic generation; Python's inclusive sliding-window limit and burst accounting; per-second peaks and aggregate statistics; rule comparisons; change previews; burst-effectiveness sweeps; reports and recommendations; named scenarios; and quick simulation. Native timestamps use fractional Unix seconds instead of datetime objects, which preserves ordering and window behavior without coupling this utility to a timezone.", + "rust_symbols": [ + "gateway-rs/src/policy/simulator.rs::generate_requests", + "gateway-rs/src/policy/simulator.rs::simulate_rule", + "gateway-rs/src/policy/simulator.rs::preview_rule_change", + "gateway-rs/src/policy/simulator.rs::test_burst_effectiveness", + "gateway-rs/src/policy/simulator.rs::generate_report", + "gateway-rs/src/policy/simulator.rs::run_scenario", + "gateway-rs/src/policy/simulator.rs::quick_simulate" + ], + "rust_tests": [ + "gateway-rs/src/policy/simulator.rs::tests::generates_python_traffic_patterns", + "gateway-rs/src/policy/simulator.rs::tests::simulates_limit_and_burst_like_python", + "gateway-rs/src/policy/simulator.rs::tests::comparison_and_scenario_helpers_preserve_python_shapes" + ], + "source": { + "kind": "field", + "line": 25, + "path": "backend-services/utils/rate_limit_simulator.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limit_simulator.py::field:SimulationRequest.ip", + "notes": "Rust now provides the standalone offline simulator: uniform, burst, spike, gradual, and random traffic generation; Python's inclusive sliding-window limit and burst accounting; per-second peaks and aggregate statistics; rule comparisons; change previews; burst-effectiveness sweeps; reports and recommendations; named scenarios; and quick simulation. Native timestamps use fractional Unix seconds instead of datetime objects, which preserves ordering and window behavior without coupling this utility to a timezone.", + "rust_symbols": [ + "gateway-rs/src/policy/simulator.rs::generate_requests", + "gateway-rs/src/policy/simulator.rs::simulate_rule", + "gateway-rs/src/policy/simulator.rs::preview_rule_change", + "gateway-rs/src/policy/simulator.rs::test_burst_effectiveness", + "gateway-rs/src/policy/simulator.rs::generate_report", + "gateway-rs/src/policy/simulator.rs::run_scenario", + "gateway-rs/src/policy/simulator.rs::quick_simulate" + ], + "rust_tests": [ + "gateway-rs/src/policy/simulator.rs::tests::generates_python_traffic_patterns", + "gateway-rs/src/policy/simulator.rs::tests::simulates_limit_and_burst_like_python", + "gateway-rs/src/policy/simulator.rs::tests::comparison_and_scenario_helpers_preserve_python_shapes" + ], + "source": { + "kind": "field", + "line": 26, + "path": "backend-services/utils/rate_limit_simulator.py" + }, + "status": "translated" + }, + { + "decorators": [ + "dataclass" + ], + "domain": "utils", + "id": "backend-services/utils/rate_limit_simulator.py::class:SimulationResult", + "notes": "Rust now provides the standalone offline simulator: uniform, burst, spike, gradual, and random traffic generation; Python's inclusive sliding-window limit and burst accounting; per-second peaks and aggregate statistics; rule comparisons; change previews; burst-effectiveness sweeps; reports and recommendations; named scenarios; and quick simulation. Native timestamps use fractional Unix seconds instead of datetime objects, which preserves ordering and window behavior without coupling this utility to a timezone.", + "rust_symbols": [ + "gateway-rs/src/policy/simulator.rs::generate_requests", + "gateway-rs/src/policy/simulator.rs::simulate_rule", + "gateway-rs/src/policy/simulator.rs::preview_rule_change", + "gateway-rs/src/policy/simulator.rs::test_burst_effectiveness", + "gateway-rs/src/policy/simulator.rs::generate_report", + "gateway-rs/src/policy/simulator.rs::run_scenario", + "gateway-rs/src/policy/simulator.rs::quick_simulate" + ], + "rust_tests": [ + "gateway-rs/src/policy/simulator.rs::tests::generates_python_traffic_patterns", + "gateway-rs/src/policy/simulator.rs::tests::simulates_limit_and_burst_like_python", + "gateway-rs/src/policy/simulator.rs::tests::comparison_and_scenario_helpers_preserve_python_shapes" + ], + "source": { + "kind": "class", + "line": 30, + "path": "backend-services/utils/rate_limit_simulator.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limit_simulator.py::field:SimulationResult.total_requests", + "notes": "Rust now provides the standalone offline simulator: uniform, burst, spike, gradual, and random traffic generation; Python's inclusive sliding-window limit and burst accounting; per-second peaks and aggregate statistics; rule comparisons; change previews; burst-effectiveness sweeps; reports and recommendations; named scenarios; and quick simulation. Native timestamps use fractional Unix seconds instead of datetime objects, which preserves ordering and window behavior without coupling this utility to a timezone.", + "rust_symbols": [ + "gateway-rs/src/policy/simulator.rs::generate_requests", + "gateway-rs/src/policy/simulator.rs::simulate_rule", + "gateway-rs/src/policy/simulator.rs::preview_rule_change", + "gateway-rs/src/policy/simulator.rs::test_burst_effectiveness", + "gateway-rs/src/policy/simulator.rs::generate_report", + "gateway-rs/src/policy/simulator.rs::run_scenario", + "gateway-rs/src/policy/simulator.rs::quick_simulate" + ], + "rust_tests": [ + "gateway-rs/src/policy/simulator.rs::tests::generates_python_traffic_patterns", + "gateway-rs/src/policy/simulator.rs::tests::simulates_limit_and_burst_like_python", + "gateway-rs/src/policy/simulator.rs::tests::comparison_and_scenario_helpers_preserve_python_shapes" + ], + "source": { + "kind": "field", + "line": 33, + "path": "backend-services/utils/rate_limit_simulator.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limit_simulator.py::field:SimulationResult.allowed_requests", + "notes": "Rust now provides the standalone offline simulator: uniform, burst, spike, gradual, and random traffic generation; Python's inclusive sliding-window limit and burst accounting; per-second peaks and aggregate statistics; rule comparisons; change previews; burst-effectiveness sweeps; reports and recommendations; named scenarios; and quick simulation. Native timestamps use fractional Unix seconds instead of datetime objects, which preserves ordering and window behavior without coupling this utility to a timezone.", + "rust_symbols": [ + "gateway-rs/src/policy/simulator.rs::generate_requests", + "gateway-rs/src/policy/simulator.rs::simulate_rule", + "gateway-rs/src/policy/simulator.rs::preview_rule_change", + "gateway-rs/src/policy/simulator.rs::test_burst_effectiveness", + "gateway-rs/src/policy/simulator.rs::generate_report", + "gateway-rs/src/policy/simulator.rs::run_scenario", + "gateway-rs/src/policy/simulator.rs::quick_simulate" + ], + "rust_tests": [ + "gateway-rs/src/policy/simulator.rs::tests::generates_python_traffic_patterns", + "gateway-rs/src/policy/simulator.rs::tests::simulates_limit_and_burst_like_python", + "gateway-rs/src/policy/simulator.rs::tests::comparison_and_scenario_helpers_preserve_python_shapes" + ], + "source": { + "kind": "field", + "line": 34, + "path": "backend-services/utils/rate_limit_simulator.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limit_simulator.py::field:SimulationResult.blocked_requests", + "notes": "Rust now provides the standalone offline simulator: uniform, burst, spike, gradual, and random traffic generation; Python's inclusive sliding-window limit and burst accounting; per-second peaks and aggregate statistics; rule comparisons; change previews; burst-effectiveness sweeps; reports and recommendations; named scenarios; and quick simulation. Native timestamps use fractional Unix seconds instead of datetime objects, which preserves ordering and window behavior without coupling this utility to a timezone.", + "rust_symbols": [ + "gateway-rs/src/policy/simulator.rs::generate_requests", + "gateway-rs/src/policy/simulator.rs::simulate_rule", + "gateway-rs/src/policy/simulator.rs::preview_rule_change", + "gateway-rs/src/policy/simulator.rs::test_burst_effectiveness", + "gateway-rs/src/policy/simulator.rs::generate_report", + "gateway-rs/src/policy/simulator.rs::run_scenario", + "gateway-rs/src/policy/simulator.rs::quick_simulate" + ], + "rust_tests": [ + "gateway-rs/src/policy/simulator.rs::tests::generates_python_traffic_patterns", + "gateway-rs/src/policy/simulator.rs::tests::simulates_limit_and_burst_like_python", + "gateway-rs/src/policy/simulator.rs::tests::comparison_and_scenario_helpers_preserve_python_shapes" + ], + "source": { + "kind": "field", + "line": 35, + "path": "backend-services/utils/rate_limit_simulator.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limit_simulator.py::field:SimulationResult.burst_used_count", + "notes": "Rust now provides the standalone offline simulator: uniform, burst, spike, gradual, and random traffic generation; Python's inclusive sliding-window limit and burst accounting; per-second peaks and aggregate statistics; rule comparisons; change previews; burst-effectiveness sweeps; reports and recommendations; named scenarios; and quick simulation. Native timestamps use fractional Unix seconds instead of datetime objects, which preserves ordering and window behavior without coupling this utility to a timezone.", + "rust_symbols": [ + "gateway-rs/src/policy/simulator.rs::generate_requests", + "gateway-rs/src/policy/simulator.rs::simulate_rule", + "gateway-rs/src/policy/simulator.rs::preview_rule_change", + "gateway-rs/src/policy/simulator.rs::test_burst_effectiveness", + "gateway-rs/src/policy/simulator.rs::generate_report", + "gateway-rs/src/policy/simulator.rs::run_scenario", + "gateway-rs/src/policy/simulator.rs::quick_simulate" + ], + "rust_tests": [ + "gateway-rs/src/policy/simulator.rs::tests::generates_python_traffic_patterns", + "gateway-rs/src/policy/simulator.rs::tests::simulates_limit_and_burst_like_python", + "gateway-rs/src/policy/simulator.rs::tests::comparison_and_scenario_helpers_preserve_python_shapes" + ], + "source": { + "kind": "field", + "line": 36, + "path": "backend-services/utils/rate_limit_simulator.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limit_simulator.py::field:SimulationResult.success_rate", + "notes": "Rust now provides the standalone offline simulator: uniform, burst, spike, gradual, and random traffic generation; Python's inclusive sliding-window limit and burst accounting; per-second peaks and aggregate statistics; rule comparisons; change previews; burst-effectiveness sweeps; reports and recommendations; named scenarios; and quick simulation. Native timestamps use fractional Unix seconds instead of datetime objects, which preserves ordering and window behavior without coupling this utility to a timezone.", + "rust_symbols": [ + "gateway-rs/src/policy/simulator.rs::generate_requests", + "gateway-rs/src/policy/simulator.rs::simulate_rule", + "gateway-rs/src/policy/simulator.rs::preview_rule_change", + "gateway-rs/src/policy/simulator.rs::test_burst_effectiveness", + "gateway-rs/src/policy/simulator.rs::generate_report", + "gateway-rs/src/policy/simulator.rs::run_scenario", + "gateway-rs/src/policy/simulator.rs::quick_simulate" + ], + "rust_tests": [ + "gateway-rs/src/policy/simulator.rs::tests::generates_python_traffic_patterns", + "gateway-rs/src/policy/simulator.rs::tests::simulates_limit_and_burst_like_python", + "gateway-rs/src/policy/simulator.rs::tests::comparison_and_scenario_helpers_preserve_python_shapes" + ], + "source": { + "kind": "field", + "line": 37, + "path": "backend-services/utils/rate_limit_simulator.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limit_simulator.py::field:SimulationResult.average_remaining", + "notes": "Rust now provides the standalone offline simulator: uniform, burst, spike, gradual, and random traffic generation; Python's inclusive sliding-window limit and burst accounting; per-second peaks and aggregate statistics; rule comparisons; change previews; burst-effectiveness sweeps; reports and recommendations; named scenarios; and quick simulation. Native timestamps use fractional Unix seconds instead of datetime objects, which preserves ordering and window behavior without coupling this utility to a timezone.", + "rust_symbols": [ + "gateway-rs/src/policy/simulator.rs::generate_requests", + "gateway-rs/src/policy/simulator.rs::simulate_rule", + "gateway-rs/src/policy/simulator.rs::preview_rule_change", + "gateway-rs/src/policy/simulator.rs::test_burst_effectiveness", + "gateway-rs/src/policy/simulator.rs::generate_report", + "gateway-rs/src/policy/simulator.rs::run_scenario", + "gateway-rs/src/policy/simulator.rs::quick_simulate" + ], + "rust_tests": [ + "gateway-rs/src/policy/simulator.rs::tests::generates_python_traffic_patterns", + "gateway-rs/src/policy/simulator.rs::tests::simulates_limit_and_burst_like_python", + "gateway-rs/src/policy/simulator.rs::tests::comparison_and_scenario_helpers_preserve_python_shapes" + ], + "source": { + "kind": "field", + "line": 38, + "path": "backend-services/utils/rate_limit_simulator.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limit_simulator.py::field:SimulationResult.peak_usage", + "notes": "Rust now provides the standalone offline simulator: uniform, burst, spike, gradual, and random traffic generation; Python's inclusive sliding-window limit and burst accounting; per-second peaks and aggregate statistics; rule comparisons; change previews; burst-effectiveness sweeps; reports and recommendations; named scenarios; and quick simulation. Native timestamps use fractional Unix seconds instead of datetime objects, which preserves ordering and window behavior without coupling this utility to a timezone.", + "rust_symbols": [ + "gateway-rs/src/policy/simulator.rs::generate_requests", + "gateway-rs/src/policy/simulator.rs::simulate_rule", + "gateway-rs/src/policy/simulator.rs::preview_rule_change", + "gateway-rs/src/policy/simulator.rs::test_burst_effectiveness", + "gateway-rs/src/policy/simulator.rs::generate_report", + "gateway-rs/src/policy/simulator.rs::run_scenario", + "gateway-rs/src/policy/simulator.rs::quick_simulate" + ], + "rust_tests": [ + "gateway-rs/src/policy/simulator.rs::tests::generates_python_traffic_patterns", + "gateway-rs/src/policy/simulator.rs::tests::simulates_limit_and_burst_like_python", + "gateway-rs/src/policy/simulator.rs::tests::comparison_and_scenario_helpers_preserve_python_shapes" + ], + "source": { + "kind": "field", + "line": 39, + "path": "backend-services/utils/rate_limit_simulator.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limit_simulator.py::field:SimulationResult.requests_by_second", + "notes": "Rust now provides the standalone offline simulator: uniform, burst, spike, gradual, and random traffic generation; Python's inclusive sliding-window limit and burst accounting; per-second peaks and aggregate statistics; rule comparisons; change previews; burst-effectiveness sweeps; reports and recommendations; named scenarios; and quick simulation. Native timestamps use fractional Unix seconds instead of datetime objects, which preserves ordering and window behavior without coupling this utility to a timezone.", + "rust_symbols": [ + "gateway-rs/src/policy/simulator.rs::generate_requests", + "gateway-rs/src/policy/simulator.rs::simulate_rule", + "gateway-rs/src/policy/simulator.rs::preview_rule_change", + "gateway-rs/src/policy/simulator.rs::test_burst_effectiveness", + "gateway-rs/src/policy/simulator.rs::generate_report", + "gateway-rs/src/policy/simulator.rs::run_scenario", + "gateway-rs/src/policy/simulator.rs::quick_simulate" + ], + "rust_tests": [ + "gateway-rs/src/policy/simulator.rs::tests::generates_python_traffic_patterns", + "gateway-rs/src/policy/simulator.rs::tests::simulates_limit_and_burst_like_python", + "gateway-rs/src/policy/simulator.rs::tests::comparison_and_scenario_helpers_preserve_python_shapes" + ], + "source": { + "kind": "field", + "line": 40, + "path": "backend-services/utils/rate_limit_simulator.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limit_simulator.py::class:RateLimitSimulator", + "notes": "Rust now provides the standalone offline simulator: uniform, burst, spike, gradual, and random traffic generation; Python's inclusive sliding-window limit and burst accounting; per-second peaks and aggregate statistics; rule comparisons; change previews; burst-effectiveness sweeps; reports and recommendations; named scenarios; and quick simulation. Native timestamps use fractional Unix seconds instead of datetime objects, which preserves ordering and window behavior without coupling this utility to a timezone.", + "rust_symbols": [ + "gateway-rs/src/policy/simulator.rs::generate_requests", + "gateway-rs/src/policy/simulator.rs::simulate_rule", + "gateway-rs/src/policy/simulator.rs::preview_rule_change", + "gateway-rs/src/policy/simulator.rs::test_burst_effectiveness", + "gateway-rs/src/policy/simulator.rs::generate_report", + "gateway-rs/src/policy/simulator.rs::run_scenario", + "gateway-rs/src/policy/simulator.rs::quick_simulate" + ], + "rust_tests": [ + "gateway-rs/src/policy/simulator.rs::tests::generates_python_traffic_patterns", + "gateway-rs/src/policy/simulator.rs::tests::simulates_limit_and_burst_like_python", + "gateway-rs/src/policy/simulator.rs::tests::comparison_and_scenario_helpers_preserve_python_shapes" + ], + "source": { + "kind": "class", + "line": 43, + "path": "backend-services/utils/rate_limit_simulator.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limit_simulator.py::method:RateLimitSimulator.__init__", + "notes": "Rust now provides the standalone offline simulator: uniform, burst, spike, gradual, and random traffic generation; Python's inclusive sliding-window limit and burst accounting; per-second peaks and aggregate statistics; rule comparisons; change previews; burst-effectiveness sweeps; reports and recommendations; named scenarios; and quick simulation. Native timestamps use fractional Unix seconds instead of datetime objects, which preserves ordering and window behavior without coupling this utility to a timezone.", + "rust_symbols": [ + "gateway-rs/src/policy/simulator.rs::generate_requests", + "gateway-rs/src/policy/simulator.rs::simulate_rule", + "gateway-rs/src/policy/simulator.rs::preview_rule_change", + "gateway-rs/src/policy/simulator.rs::test_burst_effectiveness", + "gateway-rs/src/policy/simulator.rs::generate_report", + "gateway-rs/src/policy/simulator.rs::run_scenario", + "gateway-rs/src/policy/simulator.rs::quick_simulate" + ], + "rust_tests": [ + "gateway-rs/src/policy/simulator.rs::tests::generates_python_traffic_patterns", + "gateway-rs/src/policy/simulator.rs::tests::simulates_limit_and_burst_like_python", + "gateway-rs/src/policy/simulator.rs::tests::comparison_and_scenario_helpers_preserve_python_shapes" + ], + "source": { + "kind": "method", + "line": 48, + "path": "backend-services/utils/rate_limit_simulator.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limit_simulator.py::method:RateLimitSimulator.generate_requests", + "notes": "Rust now provides the standalone offline simulator: uniform, burst, spike, gradual, and random traffic generation; Python's inclusive sliding-window limit and burst accounting; per-second peaks and aggregate statistics; rule comparisons; change previews; burst-effectiveness sweeps; reports and recommendations; named scenarios; and quick simulation. Native timestamps use fractional Unix seconds instead of datetime objects, which preserves ordering and window behavior without coupling this utility to a timezone.", + "rust_symbols": [ + "gateway-rs/src/policy/simulator.rs::generate_requests", + "gateway-rs/src/policy/simulator.rs::simulate_rule", + "gateway-rs/src/policy/simulator.rs::preview_rule_change", + "gateway-rs/src/policy/simulator.rs::test_burst_effectiveness", + "gateway-rs/src/policy/simulator.rs::generate_report", + "gateway-rs/src/policy/simulator.rs::run_scenario", + "gateway-rs/src/policy/simulator.rs::quick_simulate" + ], + "rust_tests": [ + "gateway-rs/src/policy/simulator.rs::tests::generates_python_traffic_patterns", + "gateway-rs/src/policy/simulator.rs::tests::simulates_limit_and_burst_like_python", + "gateway-rs/src/policy/simulator.rs::tests::comparison_and_scenario_helpers_preserve_python_shapes" + ], + "source": { + "kind": "method", + "line": 52, + "path": "backend-services/utils/rate_limit_simulator.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limit_simulator.py::method:RateLimitSimulator.simulate_rule", + "notes": "Rust now provides the standalone offline simulator: uniform, burst, spike, gradual, and random traffic generation; Python's inclusive sliding-window limit and burst accounting; per-second peaks and aggregate statistics; rule comparisons; change previews; burst-effectiveness sweeps; reports and recommendations; named scenarios; and quick simulation. Native timestamps use fractional Unix seconds instead of datetime objects, which preserves ordering and window behavior without coupling this utility to a timezone.", + "rust_symbols": [ + "gateway-rs/src/policy/simulator.rs::generate_requests", + "gateway-rs/src/policy/simulator.rs::simulate_rule", + "gateway-rs/src/policy/simulator.rs::preview_rule_change", + "gateway-rs/src/policy/simulator.rs::test_burst_effectiveness", + "gateway-rs/src/policy/simulator.rs::generate_report", + "gateway-rs/src/policy/simulator.rs::run_scenario", + "gateway-rs/src/policy/simulator.rs::quick_simulate" + ], + "rust_tests": [ + "gateway-rs/src/policy/simulator.rs::tests::generates_python_traffic_patterns", + "gateway-rs/src/policy/simulator.rs::tests::simulates_limit_and_burst_like_python", + "gateway-rs/src/policy/simulator.rs::tests::comparison_and_scenario_helpers_preserve_python_shapes" + ], + "source": { + "kind": "method", + "line": 147, + "path": "backend-services/utils/rate_limit_simulator.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limit_simulator.py::method:RateLimitSimulator._get_window_seconds", + "notes": "Rust now provides the standalone offline simulator: uniform, burst, spike, gradual, and random traffic generation; Python's inclusive sliding-window limit and burst accounting; per-second peaks and aggregate statistics; rule comparisons; change previews; burst-effectiveness sweeps; reports and recommendations; named scenarios; and quick simulation. Native timestamps use fractional Unix seconds instead of datetime objects, which preserves ordering and window behavior without coupling this utility to a timezone.", + "rust_symbols": [ + "gateway-rs/src/policy/simulator.rs::generate_requests", + "gateway-rs/src/policy/simulator.rs::simulate_rule", + "gateway-rs/src/policy/simulator.rs::preview_rule_change", + "gateway-rs/src/policy/simulator.rs::test_burst_effectiveness", + "gateway-rs/src/policy/simulator.rs::generate_report", + "gateway-rs/src/policy/simulator.rs::run_scenario", + "gateway-rs/src/policy/simulator.rs::quick_simulate" + ], + "rust_tests": [ + "gateway-rs/src/policy/simulator.rs::tests::generates_python_traffic_patterns", + "gateway-rs/src/policy/simulator.rs::tests::simulates_limit_and_burst_like_python", + "gateway-rs/src/policy/simulator.rs::tests::comparison_and_scenario_helpers_preserve_python_shapes" + ], + "source": { + "kind": "method", + "line": 217, + "path": "backend-services/utils/rate_limit_simulator.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limit_simulator.py::method:RateLimitSimulator.compare_rules", + "notes": "Rust now provides the standalone offline simulator: uniform, burst, spike, gradual, and random traffic generation; Python's inclusive sliding-window limit and burst accounting; per-second peaks and aggregate statistics; rule comparisons; change previews; burst-effectiveness sweeps; reports and recommendations; named scenarios; and quick simulation. Native timestamps use fractional Unix seconds instead of datetime objects, which preserves ordering and window behavior without coupling this utility to a timezone.", + "rust_symbols": [ + "gateway-rs/src/policy/simulator.rs::generate_requests", + "gateway-rs/src/policy/simulator.rs::simulate_rule", + "gateway-rs/src/policy/simulator.rs::preview_rule_change", + "gateway-rs/src/policy/simulator.rs::test_burst_effectiveness", + "gateway-rs/src/policy/simulator.rs::generate_report", + "gateway-rs/src/policy/simulator.rs::run_scenario", + "gateway-rs/src/policy/simulator.rs::quick_simulate" + ], + "rust_tests": [ + "gateway-rs/src/policy/simulator.rs::tests::generates_python_traffic_patterns", + "gateway-rs/src/policy/simulator.rs::tests::simulates_limit_and_burst_like_python", + "gateway-rs/src/policy/simulator.rs::tests::comparison_and_scenario_helpers_preserve_python_shapes" + ], + "source": { + "kind": "method", + "line": 228, + "path": "backend-services/utils/rate_limit_simulator.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limit_simulator.py::method:RateLimitSimulator.preview_rule_change", + "notes": "Rust now provides the standalone offline simulator: uniform, burst, spike, gradual, and random traffic generation; Python's inclusive sliding-window limit and burst accounting; per-second peaks and aggregate statistics; rule comparisons; change previews; burst-effectiveness sweeps; reports and recommendations; named scenarios; and quick simulation. Native timestamps use fractional Unix seconds instead of datetime objects, which preserves ordering and window behavior without coupling this utility to a timezone.", + "rust_symbols": [ + "gateway-rs/src/policy/simulator.rs::generate_requests", + "gateway-rs/src/policy/simulator.rs::simulate_rule", + "gateway-rs/src/policy/simulator.rs::preview_rule_change", + "gateway-rs/src/policy/simulator.rs::test_burst_effectiveness", + "gateway-rs/src/policy/simulator.rs::generate_report", + "gateway-rs/src/policy/simulator.rs::run_scenario", + "gateway-rs/src/policy/simulator.rs::quick_simulate" + ], + "rust_tests": [ + "gateway-rs/src/policy/simulator.rs::tests::generates_python_traffic_patterns", + "gateway-rs/src/policy/simulator.rs::tests::simulates_limit_and_burst_like_python", + "gateway-rs/src/policy/simulator.rs::tests::comparison_and_scenario_helpers_preserve_python_shapes" + ], + "source": { + "kind": "method", + "line": 249, + "path": "backend-services/utils/rate_limit_simulator.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limit_simulator.py::method:RateLimitSimulator.test_burst_effectiveness", + "notes": "Rust now provides the standalone offline simulator: uniform, burst, spike, gradual, and random traffic generation; Python's inclusive sliding-window limit and burst accounting; per-second peaks and aggregate statistics; rule comparisons; change previews; burst-effectiveness sweeps; reports and recommendations; named scenarios; and quick simulation. Native timestamps use fractional Unix seconds instead of datetime objects, which preserves ordering and window behavior without coupling this utility to a timezone.", + "rust_symbols": [ + "gateway-rs/src/policy/simulator.rs::generate_requests", + "gateway-rs/src/policy/simulator.rs::simulate_rule", + "gateway-rs/src/policy/simulator.rs::preview_rule_change", + "gateway-rs/src/policy/simulator.rs::test_burst_effectiveness", + "gateway-rs/src/policy/simulator.rs::generate_report", + "gateway-rs/src/policy/simulator.rs::run_scenario", + "gateway-rs/src/policy/simulator.rs::quick_simulate" + ], + "rust_tests": [ + "gateway-rs/src/policy/simulator.rs::tests::generates_python_traffic_patterns", + "gateway-rs/src/policy/simulator.rs::tests::simulates_limit_and_burst_like_python", + "gateway-rs/src/policy/simulator.rs::tests::comparison_and_scenario_helpers_preserve_python_shapes" + ], + "source": { + "kind": "method", + "line": 281, + "path": "backend-services/utils/rate_limit_simulator.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limit_simulator.py::method:RateLimitSimulator.generate_report", + "notes": "Rust now provides the standalone offline simulator: uniform, burst, spike, gradual, and random traffic generation; Python's inclusive sliding-window limit and burst accounting; per-second peaks and aggregate statistics; rule comparisons; change previews; burst-effectiveness sweeps; reports and recommendations; named scenarios; and quick simulation. Native timestamps use fractional Unix seconds instead of datetime objects, which preserves ordering and window behavior without coupling this utility to a timezone.", + "rust_symbols": [ + "gateway-rs/src/policy/simulator.rs::generate_requests", + "gateway-rs/src/policy/simulator.rs::simulate_rule", + "gateway-rs/src/policy/simulator.rs::preview_rule_change", + "gateway-rs/src/policy/simulator.rs::test_burst_effectiveness", + "gateway-rs/src/policy/simulator.rs::generate_report", + "gateway-rs/src/policy/simulator.rs::run_scenario", + "gateway-rs/src/policy/simulator.rs::quick_simulate" + ], + "rust_tests": [ + "gateway-rs/src/policy/simulator.rs::tests::generates_python_traffic_patterns", + "gateway-rs/src/policy/simulator.rs::tests::simulates_limit_and_burst_like_python", + "gateway-rs/src/policy/simulator.rs::tests::comparison_and_scenario_helpers_preserve_python_shapes" + ], + "source": { + "kind": "method", + "line": 318, + "path": "backend-services/utils/rate_limit_simulator.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limit_simulator.py::method:RateLimitSimulator.run_scenario", + "notes": "Rust now provides the standalone offline simulator: uniform, burst, spike, gradual, and random traffic generation; Python's inclusive sliding-window limit and burst accounting; per-second peaks and aggregate statistics; rule comparisons; change previews; burst-effectiveness sweeps; reports and recommendations; named scenarios; and quick simulation. Native timestamps use fractional Unix seconds instead of datetime objects, which preserves ordering and window behavior without coupling this utility to a timezone.", + "rust_symbols": [ + "gateway-rs/src/policy/simulator.rs::generate_requests", + "gateway-rs/src/policy/simulator.rs::simulate_rule", + "gateway-rs/src/policy/simulator.rs::preview_rule_change", + "gateway-rs/src/policy/simulator.rs::test_burst_effectiveness", + "gateway-rs/src/policy/simulator.rs::generate_report", + "gateway-rs/src/policy/simulator.rs::run_scenario", + "gateway-rs/src/policy/simulator.rs::quick_simulate" + ], + "rust_tests": [ + "gateway-rs/src/policy/simulator.rs::tests::generates_python_traffic_patterns", + "gateway-rs/src/policy/simulator.rs::tests::simulates_limit_and_burst_like_python", + "gateway-rs/src/policy/simulator.rs::tests::comparison_and_scenario_helpers_preserve_python_shapes" + ], + "source": { + "kind": "method", + "line": 368, + "path": "backend-services/utils/rate_limit_simulator.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limit_simulator.py::function:quick_simulate", + "notes": "Rust now provides the standalone offline simulator: uniform, burst, spike, gradual, and random traffic generation; Python's inclusive sliding-window limit and burst accounting; per-second peaks and aggregate statistics; rule comparisons; change previews; burst-effectiveness sweeps; reports and recommendations; named scenarios; and quick simulation. Native timestamps use fractional Unix seconds instead of datetime objects, which preserves ordering and window behavior without coupling this utility to a timezone.", + "rust_symbols": [ + "gateway-rs/src/policy/simulator.rs::generate_requests", + "gateway-rs/src/policy/simulator.rs::simulate_rule", + "gateway-rs/src/policy/simulator.rs::preview_rule_change", + "gateway-rs/src/policy/simulator.rs::test_burst_effectiveness", + "gateway-rs/src/policy/simulator.rs::generate_report", + "gateway-rs/src/policy/simulator.rs::run_scenario", + "gateway-rs/src/policy/simulator.rs::quick_simulate" + ], + "rust_tests": [ + "gateway-rs/src/policy/simulator.rs::tests::generates_python_traffic_patterns", + "gateway-rs/src/policy/simulator.rs::tests::simulates_limit_and_burst_like_python", + "gateway-rs/src/policy/simulator.rs::tests::comparison_and_scenario_helpers_preserve_python_shapes" + ], + "source": { + "kind": "function", + "line": 411, + "path": "backend-services/utils/rate_limit_simulator.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limiter.py::module:rate_limiter", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::WindowCounter", + "gateway-rs/src/storage/cache.rs::TokenBucketCounter", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/policy/tier.rs::enforce", + "gateway-rs/src/storage/runtime.rs::SharedStorage.check_tier_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests", + "gateway-rs/src/policy/tier.rs::tests", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [ + "dataclass" + ], + "domain": "utils", + "id": "backend-services/utils/rate_limiter.py::class:RateLimitResult", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::WindowCounter", + "gateway-rs/src/storage/cache.rs::TokenBucketCounter", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/policy/tier.rs::enforce", + "gateway-rs/src/storage/runtime.rs::SharedStorage.check_tier_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests", + "gateway-rs/src/policy/tier.rs::tests", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "class", + "line": 26, + "path": "backend-services/utils/rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limiter.py::field:RateLimitResult.allowed", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::WindowCounter", + "gateway-rs/src/storage/cache.rs::TokenBucketCounter", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/policy/tier.rs::enforce", + "gateway-rs/src/storage/runtime.rs::SharedStorage.check_tier_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests", + "gateway-rs/src/policy/tier.rs::tests", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "field", + "line": 29, + "path": "backend-services/utils/rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limiter.py::field:RateLimitResult.limit", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::WindowCounter", + "gateway-rs/src/storage/cache.rs::TokenBucketCounter", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/policy/tier.rs::enforce", + "gateway-rs/src/storage/runtime.rs::SharedStorage.check_tier_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests", + "gateway-rs/src/policy/tier.rs::tests", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "field", + "line": 30, + "path": "backend-services/utils/rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limiter.py::field:RateLimitResult.remaining", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::WindowCounter", + "gateway-rs/src/storage/cache.rs::TokenBucketCounter", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/policy/tier.rs::enforce", + "gateway-rs/src/storage/runtime.rs::SharedStorage.check_tier_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests", + "gateway-rs/src/policy/tier.rs::tests", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "field", + "line": 31, + "path": "backend-services/utils/rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limiter.py::field:RateLimitResult.reset_at", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::WindowCounter", + "gateway-rs/src/storage/cache.rs::TokenBucketCounter", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/policy/tier.rs::enforce", + "gateway-rs/src/storage/runtime.rs::SharedStorage.check_tier_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests", + "gateway-rs/src/policy/tier.rs::tests", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "field", + "line": 32, + "path": "backend-services/utils/rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limiter.py::field:RateLimitResult.retry_after", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::WindowCounter", + "gateway-rs/src/storage/cache.rs::TokenBucketCounter", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/policy/tier.rs::enforce", + "gateway-rs/src/storage/runtime.rs::SharedStorage.check_tier_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests", + "gateway-rs/src/policy/tier.rs::tests", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "field", + "line": 33, + "path": "backend-services/utils/rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limiter.py::field:RateLimitResult.burst_remaining", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::WindowCounter", + "gateway-rs/src/storage/cache.rs::TokenBucketCounter", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/policy/tier.rs::enforce", + "gateway-rs/src/storage/runtime.rs::SharedStorage.check_tier_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests", + "gateway-rs/src/policy/tier.rs::tests", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "field", + "line": 34, + "path": "backend-services/utils/rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limiter.py::method:RateLimitResult.to_info", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::WindowCounter", + "gateway-rs/src/storage/cache.rs::TokenBucketCounter", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/policy/tier.rs::enforce", + "gateway-rs/src/storage/runtime.rs::SharedStorage.check_tier_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests", + "gateway-rs/src/policy/tier.rs::tests", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "method", + "line": 36, + "path": "backend-services/utils/rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limiter.py::class:InMemoryRateLimitStorage", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::WindowCounter", + "gateway-rs/src/storage/cache.rs::TokenBucketCounter", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/policy/tier.rs::enforce", + "gateway-rs/src/storage/runtime.rs::SharedStorage.check_tier_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests", + "gateway-rs/src/policy/tier.rs::tests", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "class", + "line": 47, + "path": "backend-services/utils/rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limiter.py::method:InMemoryRateLimitStorage.__init__", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::WindowCounter", + "gateway-rs/src/storage/cache.rs::TokenBucketCounter", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/policy/tier.rs::enforce", + "gateway-rs/src/storage/runtime.rs::SharedStorage.check_tier_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests", + "gateway-rs/src/policy/tier.rs::tests", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "method", + "line": 53, + "path": "backend-services/utils/rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limiter.py::method:InMemoryRateLimitStorage._cleanup", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::WindowCounter", + "gateway-rs/src/storage/cache.rs::TokenBucketCounter", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/policy/tier.rs::enforce", + "gateway-rs/src/storage/runtime.rs::SharedStorage.check_tier_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests", + "gateway-rs/src/policy/tier.rs::tests", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "method", + "line": 59, + "path": "backend-services/utils/rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limiter.py::method:InMemoryRateLimitStorage.get", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::WindowCounter", + "gateway-rs/src/storage/cache.rs::TokenBucketCounter", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/policy/tier.rs::enforce", + "gateway-rs/src/storage/runtime.rs::SharedStorage.check_tier_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests", + "gateway-rs/src/policy/tier.rs::tests", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "method", + "line": 66, + "path": "backend-services/utils/rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limiter.py::method:InMemoryRateLimitStorage.set", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::WindowCounter", + "gateway-rs/src/storage/cache.rs::TokenBucketCounter", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/policy/tier.rs::enforce", + "gateway-rs/src/storage/runtime.rs::SharedStorage.check_tier_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests", + "gateway-rs/src/policy/tier.rs::tests", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "method", + "line": 74, + "path": "backend-services/utils/rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limiter.py::method:InMemoryRateLimitStorage.incr", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::WindowCounter", + "gateway-rs/src/storage/cache.rs::TokenBucketCounter", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/policy/tier.rs::enforce", + "gateway-rs/src/storage/runtime.rs::SharedStorage.check_tier_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests", + "gateway-rs/src/policy/tier.rs::tests", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "method", + "line": 81, + "path": "backend-services/utils/rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limiter.py::method:InMemoryRateLimitStorage.expire", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::WindowCounter", + "gateway-rs/src/storage/cache.rs::TokenBucketCounter", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/policy/tier.rs::enforce", + "gateway-rs/src/storage/runtime.rs::SharedStorage.check_tier_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests", + "gateway-rs/src/policy/tier.rs::tests", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "method", + "line": 88, + "path": "backend-services/utils/rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limiter.py::method:InMemoryRateLimitStorage.delete", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::WindowCounter", + "gateway-rs/src/storage/cache.rs::TokenBucketCounter", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/policy/tier.rs::enforce", + "gateway-rs/src/storage/runtime.rs::SharedStorage.check_tier_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests", + "gateway-rs/src/policy/tier.rs::tests", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "method", + "line": 93, + "path": "backend-services/utils/rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limiter.py::method:InMemoryRateLimitStorage.hmget", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::WindowCounter", + "gateway-rs/src/storage/cache.rs::TokenBucketCounter", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/policy/tier.rs::enforce", + "gateway-rs/src/storage/runtime.rs::SharedStorage.check_tier_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests", + "gateway-rs/src/policy/tier.rs::tests", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "method", + "line": 104, + "path": "backend-services/utils/rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limiter.py::method:InMemoryRateLimitStorage.hmset", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::WindowCounter", + "gateway-rs/src/storage/cache.rs::TokenBucketCounter", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/policy/tier.rs::enforce", + "gateway-rs/src/storage/runtime.rs::SharedStorage.check_tier_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests", + "gateway-rs/src/policy/tier.rs::tests", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "method", + "line": 112, + "path": "backend-services/utils/rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limiter.py::method:InMemoryRateLimitStorage.hset", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::WindowCounter", + "gateway-rs/src/storage/cache.rs::TokenBucketCounter", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/policy/tier.rs::enforce", + "gateway-rs/src/storage/runtime.rs::SharedStorage.check_tier_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests", + "gateway-rs/src/policy/tier.rs::tests", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "method", + "line": 122, + "path": "backend-services/utils/rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limiter.py::method:InMemoryRateLimitStorage.flushall", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::WindowCounter", + "gateway-rs/src/storage/cache.rs::TokenBucketCounter", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/policy/tier.rs::enforce", + "gateway-rs/src/storage/runtime.rs::SharedStorage.check_tier_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests", + "gateway-rs/src/policy/tier.rs::tests", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "method", + "line": 127, + "path": "backend-services/utils/rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limiter.py::class:RateLimiter", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::WindowCounter", + "gateway-rs/src/storage/cache.rs::TokenBucketCounter", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/policy/tier.rs::enforce", + "gateway-rs/src/storage/runtime.rs::SharedStorage.check_tier_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests", + "gateway-rs/src/policy/tier.rs::tests", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "class", + "line": 133, + "path": "backend-services/utils/rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limiter.py::method:RateLimiter.__init__", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::WindowCounter", + "gateway-rs/src/storage/cache.rs::TokenBucketCounter", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/policy/tier.rs::enforce", + "gateway-rs/src/storage/runtime.rs::SharedStorage.check_tier_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests", + "gateway-rs/src/policy/tier.rs::tests", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "method", + "line": 144, + "path": "backend-services/utils/rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limiter.py::method:RateLimiter.check_rate_limit", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::WindowCounter", + "gateway-rs/src/storage/cache.rs::TokenBucketCounter", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/policy/tier.rs::enforce", + "gateway-rs/src/storage/runtime.rs::SharedStorage.check_tier_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests", + "gateway-rs/src/policy/tier.rs::tests", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "method", + "line": 175, + "path": "backend-services/utils/rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limiter.py::method:RateLimiter._check_sliding_window", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::WindowCounter", + "gateway-rs/src/storage/cache.rs::TokenBucketCounter", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/policy/tier.rs::enforce", + "gateway-rs/src/storage/runtime.rs::SharedStorage.check_tier_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests", + "gateway-rs/src/policy/tier.rs::tests", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "method", + "line": 198, + "path": "backend-services/utils/rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limiter.py::method:RateLimiter.check_token_bucket", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::WindowCounter", + "gateway-rs/src/storage/cache.rs::TokenBucketCounter", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/policy/tier.rs::enforce", + "gateway-rs/src/storage/runtime.rs::SharedStorage.check_tier_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests", + "gateway-rs/src/policy/tier.rs::tests", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "method", + "line": 274, + "path": "backend-services/utils/rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limiter.py::method:RateLimiter.check_hybrid", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::WindowCounter", + "gateway-rs/src/storage/cache.rs::TokenBucketCounter", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/policy/tier.rs::enforce", + "gateway-rs/src/storage/runtime.rs::SharedStorage.check_tier_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests", + "gateway-rs/src/policy/tier.rs::tests", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "method", + "line": 357, + "path": "backend-services/utils/rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limiter.py::method:RateLimiter._use_burst_tokens", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::WindowCounter", + "gateway-rs/src/storage/cache.rs::TokenBucketCounter", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/policy/tier.rs::enforce", + "gateway-rs/src/storage/runtime.rs::SharedStorage.check_tier_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests", + "gateway-rs/src/policy/tier.rs::tests", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "method", + "line": 391, + "path": "backend-services/utils/rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limiter.py::method:RateLimiter.reset_limit", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::WindowCounter", + "gateway-rs/src/storage/cache.rs::TokenBucketCounter", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/policy/tier.rs::enforce", + "gateway-rs/src/storage/runtime.rs::SharedStorage.check_tier_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests", + "gateway-rs/src/policy/tier.rs::tests", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "method", + "line": 453, + "path": "backend-services/utils/rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limiter.py::method:RateLimiter.get_current_usage", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::WindowCounter", + "gateway-rs/src/storage/cache.rs::TokenBucketCounter", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/policy/tier.rs::enforce", + "gateway-rs/src/storage/runtime.rs::SharedStorage.check_tier_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests", + "gateway-rs/src/policy/tier.rs::tests", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "method", + "line": 487, + "path": "backend-services/utils/rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limiter.py::method:RateLimiter.reset_all", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::WindowCounter", + "gateway-rs/src/storage/cache.rs::TokenBucketCounter", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/policy/tier.rs::enforce", + "gateway-rs/src/storage/runtime.rs::SharedStorage.check_tier_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests", + "gateway-rs/src/policy/tier.rs::tests", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "method", + "line": 530, + "path": "backend-services/utils/rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/rate_limiter.py::function:get_rate_limiter", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::WindowCounter", + "gateway-rs/src/storage/cache.rs::TokenBucketCounter", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/policy/tier.rs::enforce", + "gateway-rs/src/storage/runtime.rs::SharedStorage.check_tier_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests", + "gateway-rs/src/policy/tier.rs::tests", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "source": { + "kind": "function", + "line": 547, + "path": "backend-services/utils/rate_limiter.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/redis_client.py::module:redis_client", + "notes": "Approved language/runtime replacement: the Python file is a redis-py connection-pool facade over generic Redis commands. Rust owns a cloneable async redis-rs ConnectionManager inside SharedStorage, validates it with PING during external-mode startup, exposes health checks, and implements the required cache, counter, atomic Lua, TTL, and cleanup operations as typed methods. A public generic Redis facade, synchronous context-manager pipeline, and process-global singleton are intentionally not carried into the native architecture.", + "rationale": "Python-specific synchronous redis-py adapter and singleton lifecycle are obsolete in the async native storage runtime; required Redis behavior is implemented through typed SharedStorage operations.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window", + "gateway-rs/src/storage/runtime.rs::SharedStorage.redis_healthy" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/redis_client.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/redis_client.py::class:RedisClient", + "notes": "Approved language/runtime replacement: the Python file is a redis-py connection-pool facade over generic Redis commands. Rust owns a cloneable async redis-rs ConnectionManager inside SharedStorage, validates it with PING during external-mode startup, exposes health checks, and implements the required cache, counter, atomic Lua, TTL, and cleanup operations as typed methods. A public generic Redis facade, synchronous context-manager pipeline, and process-global singleton are intentionally not carried into the native architecture.", + "rationale": "Python-specific synchronous redis-py adapter and singleton lifecycle are obsolete in the async native storage runtime; required Redis behavior is implemented through typed SharedStorage operations.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window", + "gateway-rs/src/storage/runtime.rs::SharedStorage.redis_healthy" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "class", + "line": 17, + "path": "backend-services/utils/redis_client.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/redis_client.py::method:RedisClient.__init__", + "notes": "Approved language/runtime replacement: the Python file is a redis-py connection-pool facade over generic Redis commands. Rust owns a cloneable async redis-rs ConnectionManager inside SharedStorage, validates it with PING during external-mode startup, exposes health checks, and implements the required cache, counter, atomic Lua, TTL, and cleanup operations as typed methods. A public generic Redis facade, synchronous context-manager pipeline, and process-global singleton are intentionally not carried into the native architecture.", + "rationale": "Python-specific synchronous redis-py adapter and singleton lifecycle are obsolete in the async native storage runtime; required Redis behavior is implemented through typed SharedStorage operations.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window", + "gateway-rs/src/storage/runtime.rs::SharedStorage.redis_healthy" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 28, + "path": "backend-services/utils/redis_client.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/redis_client.py::method:RedisClient._test_connection", + "notes": "Approved language/runtime replacement: the Python file is a redis-py connection-pool facade over generic Redis commands. Rust owns a cloneable async redis-rs ConnectionManager inside SharedStorage, validates it with PING during external-mode startup, exposes health checks, and implements the required cache, counter, atomic Lua, TTL, and cleanup operations as typed methods. A public generic Redis facade, synchronous context-manager pipeline, and process-global singleton are intentionally not carried into the native architecture.", + "rationale": "Python-specific synchronous redis-py adapter and singleton lifecycle are obsolete in the async native storage runtime; required Redis behavior is implemented through typed SharedStorage operations.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window", + "gateway-rs/src/storage/runtime.rs::SharedStorage.redis_healthy" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 75, + "path": "backend-services/utils/redis_client.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/redis_client.py::method:RedisClient.get", + "notes": "Approved language/runtime replacement: the Python file is a redis-py connection-pool facade over generic Redis commands. Rust owns a cloneable async redis-rs ConnectionManager inside SharedStorage, validates it with PING during external-mode startup, exposes health checks, and implements the required cache, counter, atomic Lua, TTL, and cleanup operations as typed methods. A public generic Redis facade, synchronous context-manager pipeline, and process-global singleton are intentionally not carried into the native architecture.", + "rationale": "Python-specific synchronous redis-py adapter and singleton lifecycle are obsolete in the async native storage runtime; required Redis behavior is implemented through typed SharedStorage operations.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window", + "gateway-rs/src/storage/runtime.rs::SharedStorage.redis_healthy" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 88, + "path": "backend-services/utils/redis_client.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/redis_client.py::method:RedisClient.set", + "notes": "Approved language/runtime replacement: the Python file is a redis-py connection-pool facade over generic Redis commands. Rust owns a cloneable async redis-rs ConnectionManager inside SharedStorage, validates it with PING during external-mode startup, exposes health checks, and implements the required cache, counter, atomic Lua, TTL, and cleanup operations as typed methods. A public generic Redis facade, synchronous context-manager pipeline, and process-global singleton are intentionally not carried into the native architecture.", + "rationale": "Python-specific synchronous redis-py adapter and singleton lifecycle are obsolete in the async native storage runtime; required Redis behavior is implemented through typed SharedStorage operations.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window", + "gateway-rs/src/storage/runtime.rs::SharedStorage.redis_healthy" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 104, + "path": "backend-services/utils/redis_client.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/redis_client.py::method:RedisClient.incr", + "notes": "Approved language/runtime replacement: the Python file is a redis-py connection-pool facade over generic Redis commands. Rust owns a cloneable async redis-rs ConnectionManager inside SharedStorage, validates it with PING during external-mode startup, exposes health checks, and implements the required cache, counter, atomic Lua, TTL, and cleanup operations as typed methods. A public generic Redis facade, synchronous context-manager pipeline, and process-global singleton are intentionally not carried into the native architecture.", + "rationale": "Python-specific synchronous redis-py adapter and singleton lifecycle are obsolete in the async native storage runtime; required Redis behavior is implemented through typed SharedStorage operations.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window", + "gateway-rs/src/storage/runtime.rs::SharedStorage.redis_healthy" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 134, + "path": "backend-services/utils/redis_client.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/redis_client.py::method:RedisClient.decr", + "notes": "Approved language/runtime replacement: the Python file is a redis-py connection-pool facade over generic Redis commands. Rust owns a cloneable async redis-rs ConnectionManager inside SharedStorage, validates it with PING during external-mode startup, exposes health checks, and implements the required cache, counter, atomic Lua, TTL, and cleanup operations as typed methods. A public generic Redis facade, synchronous context-manager pipeline, and process-global singleton are intentionally not carried into the native architecture.", + "rationale": "Python-specific synchronous redis-py adapter and singleton lifecycle are obsolete in the async native storage runtime; required Redis behavior is implemented through typed SharedStorage operations.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window", + "gateway-rs/src/storage/runtime.rs::SharedStorage.redis_healthy" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 151, + "path": "backend-services/utils/redis_client.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/redis_client.py::method:RedisClient.expire", + "notes": "Approved language/runtime replacement: the Python file is a redis-py connection-pool facade over generic Redis commands. Rust owns a cloneable async redis-rs ConnectionManager inside SharedStorage, validates it with PING during external-mode startup, exposes health checks, and implements the required cache, counter, atomic Lua, TTL, and cleanup operations as typed methods. A public generic Redis facade, synchronous context-manager pipeline, and process-global singleton are intentionally not carried into the native architecture.", + "rationale": "Python-specific synchronous redis-py adapter and singleton lifecycle are obsolete in the async native storage runtime; required Redis behavior is implemented through typed SharedStorage operations.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window", + "gateway-rs/src/storage/runtime.rs::SharedStorage.redis_healthy" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 168, + "path": "backend-services/utils/redis_client.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/redis_client.py::method:RedisClient.ttl", + "notes": "Approved language/runtime replacement: the Python file is a redis-py connection-pool facade over generic Redis commands. Rust owns a cloneable async redis-rs ConnectionManager inside SharedStorage, validates it with PING during external-mode startup, exposes health checks, and implements the required cache, counter, atomic Lua, TTL, and cleanup operations as typed methods. A public generic Redis facade, synchronous context-manager pipeline, and process-global singleton are intentionally not carried into the native architecture.", + "rationale": "Python-specific synchronous redis-py adapter and singleton lifecycle are obsolete in the async native storage runtime; required Redis behavior is implemented through typed SharedStorage operations.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window", + "gateway-rs/src/storage/runtime.rs::SharedStorage.redis_healthy" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 185, + "path": "backend-services/utils/redis_client.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/redis_client.py::method:RedisClient.delete", + "notes": "Approved language/runtime replacement: the Python file is a redis-py connection-pool facade over generic Redis commands. Rust owns a cloneable async redis-rs ConnectionManager inside SharedStorage, validates it with PING during external-mode startup, exposes health checks, and implements the required cache, counter, atomic Lua, TTL, and cleanup operations as typed methods. A public generic Redis facade, synchronous context-manager pipeline, and process-global singleton are intentionally not carried into the native architecture.", + "rationale": "Python-specific synchronous redis-py adapter and singleton lifecycle are obsolete in the async native storage runtime; required Redis behavior is implemented through typed SharedStorage operations.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window", + "gateway-rs/src/storage/runtime.rs::SharedStorage.redis_healthy" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 201, + "path": "backend-services/utils/redis_client.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/redis_client.py::method:RedisClient.exists", + "notes": "Approved language/runtime replacement: the Python file is a redis-py connection-pool facade over generic Redis commands. Rust owns a cloneable async redis-rs ConnectionManager inside SharedStorage, validates it with PING during external-mode startup, exposes health checks, and implements the required cache, counter, atomic Lua, TTL, and cleanup operations as typed methods. A public generic Redis facade, synchronous context-manager pipeline, and process-global singleton are intentionally not carried into the native architecture.", + "rationale": "Python-specific synchronous redis-py adapter and singleton lifecycle are obsolete in the async native storage runtime; required Redis behavior is implemented through typed SharedStorage operations.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window", + "gateway-rs/src/storage/runtime.rs::SharedStorage.redis_healthy" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 217, + "path": "backend-services/utils/redis_client.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/redis_client.py::method:RedisClient.hget", + "notes": "Approved language/runtime replacement: the Python file is a redis-py connection-pool facade over generic Redis commands. Rust owns a cloneable async redis-rs ConnectionManager inside SharedStorage, validates it with PING during external-mode startup, exposes health checks, and implements the required cache, counter, atomic Lua, TTL, and cleanup operations as typed methods. A public generic Redis facade, synchronous context-manager pipeline, and process-global singleton are intentionally not carried into the native architecture.", + "rationale": "Python-specific synchronous redis-py adapter and singleton lifecycle are obsolete in the async native storage runtime; required Redis behavior is implemented through typed SharedStorage operations.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window", + "gateway-rs/src/storage/runtime.rs::SharedStorage.redis_healthy" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 233, + "path": "backend-services/utils/redis_client.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/redis_client.py::method:RedisClient.hset", + "notes": "Approved language/runtime replacement: the Python file is a redis-py connection-pool facade over generic Redis commands. Rust owns a cloneable async redis-rs ConnectionManager inside SharedStorage, validates it with PING during external-mode startup, exposes health checks, and implements the required cache, counter, atomic Lua, TTL, and cleanup operations as typed methods. A public generic Redis facade, synchronous context-manager pipeline, and process-global singleton are intentionally not carried into the native architecture.", + "rationale": "Python-specific synchronous redis-py adapter and singleton lifecycle are obsolete in the async native storage runtime; required Redis behavior is implemented through typed SharedStorage operations.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window", + "gateway-rs/src/storage/runtime.rs::SharedStorage.redis_healthy" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 250, + "path": "backend-services/utils/redis_client.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/redis_client.py::method:RedisClient.hmget", + "notes": "Approved language/runtime replacement: the Python file is a redis-py connection-pool facade over generic Redis commands. Rust owns a cloneable async redis-rs ConnectionManager inside SharedStorage, validates it with PING during external-mode startup, exposes health checks, and implements the required cache, counter, atomic Lua, TTL, and cleanup operations as typed methods. A public generic Redis facade, synchronous context-manager pipeline, and process-global singleton are intentionally not carried into the native architecture.", + "rationale": "Python-specific synchronous redis-py adapter and singleton lifecycle are obsolete in the async native storage runtime; required Redis behavior is implemented through typed SharedStorage operations.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window", + "gateway-rs/src/storage/runtime.rs::SharedStorage.redis_healthy" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 269, + "path": "backend-services/utils/redis_client.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/redis_client.py::method:RedisClient.hmset", + "notes": "Approved language/runtime replacement: the Python file is a redis-py connection-pool facade over generic Redis commands. Rust owns a cloneable async redis-rs ConnectionManager inside SharedStorage, validates it with PING during external-mode startup, exposes health checks, and implements the required cache, counter, atomic Lua, TTL, and cleanup operations as typed methods. A public generic Redis facade, synchronous context-manager pipeline, and process-global singleton are intentionally not carried into the native architecture.", + "rationale": "Python-specific synchronous redis-py adapter and singleton lifecycle are obsolete in the async native storage runtime; required Redis behavior is implemented through typed SharedStorage operations.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window", + "gateway-rs/src/storage/runtime.rs::SharedStorage.redis_healthy" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 286, + "path": "backend-services/utils/redis_client.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [ + "contextmanager" + ], + "domain": "utils", + "id": "backend-services/utils/redis_client.py::method:RedisClient.pipeline", + "notes": "Approved language/runtime replacement: the Python file is a redis-py connection-pool facade over generic Redis commands. Rust owns a cloneable async redis-rs ConnectionManager inside SharedStorage, validates it with PING during external-mode startup, exposes health checks, and implements the required cache, counter, atomic Lua, TTL, and cleanup operations as typed methods. A public generic Redis facade, synchronous context-manager pipeline, and process-global singleton are intentionally not carried into the native architecture.", + "rationale": "Python-specific synchronous redis-py adapter and singleton lifecycle are obsolete in the async native storage runtime; required Redis behavior is implemented through typed SharedStorage operations.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window", + "gateway-rs/src/storage/runtime.rs::SharedStorage.redis_healthy" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 305, + "path": "backend-services/utils/redis_client.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/redis_client.py::method:RedisClient.zadd", + "notes": "Approved language/runtime replacement: the Python file is a redis-py connection-pool facade over generic Redis commands. Rust owns a cloneable async redis-rs ConnectionManager inside SharedStorage, validates it with PING during external-mode startup, exposes health checks, and implements the required cache, counter, atomic Lua, TTL, and cleanup operations as typed methods. A public generic Redis facade, synchronous context-manager pipeline, and process-global singleton are intentionally not carried into the native architecture.", + "rationale": "Python-specific synchronous redis-py adapter and singleton lifecycle are obsolete in the async native storage runtime; required Redis behavior is implemented through typed SharedStorage operations.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window", + "gateway-rs/src/storage/runtime.rs::SharedStorage.redis_healthy" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 330, + "path": "backend-services/utils/redis_client.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/redis_client.py::method:RedisClient.zremrangebyscore", + "notes": "Approved language/runtime replacement: the Python file is a redis-py connection-pool facade over generic Redis commands. Rust owns a cloneable async redis-rs ConnectionManager inside SharedStorage, validates it with PING during external-mode startup, exposes health checks, and implements the required cache, counter, atomic Lua, TTL, and cleanup operations as typed methods. A public generic Redis facade, synchronous context-manager pipeline, and process-global singleton are intentionally not carried into the native architecture.", + "rationale": "Python-specific synchronous redis-py adapter and singleton lifecycle are obsolete in the async native storage runtime; required Redis behavior is implemented through typed SharedStorage operations.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window", + "gateway-rs/src/storage/runtime.rs::SharedStorage.redis_healthy" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 347, + "path": "backend-services/utils/redis_client.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/redis_client.py::method:RedisClient.zcount", + "notes": "Approved language/runtime replacement: the Python file is a redis-py connection-pool facade over generic Redis commands. Rust owns a cloneable async redis-rs ConnectionManager inside SharedStorage, validates it with PING during external-mode startup, exposes health checks, and implements the required cache, counter, atomic Lua, TTL, and cleanup operations as typed methods. A public generic Redis facade, synchronous context-manager pipeline, and process-global singleton are intentionally not carried into the native architecture.", + "rationale": "Python-specific synchronous redis-py adapter and singleton lifecycle are obsolete in the async native storage runtime; required Redis behavior is implemented through typed SharedStorage operations.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window", + "gateway-rs/src/storage/runtime.rs::SharedStorage.redis_healthy" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 365, + "path": "backend-services/utils/redis_client.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/redis_client.py::method:RedisClient.close", + "notes": "Approved language/runtime replacement: the Python file is a redis-py connection-pool facade over generic Redis commands. Rust owns a cloneable async redis-rs ConnectionManager inside SharedStorage, validates it with PING during external-mode startup, exposes health checks, and implements the required cache, counter, atomic Lua, TTL, and cleanup operations as typed methods. A public generic Redis facade, synchronous context-manager pipeline, and process-global singleton are intentionally not carried into the native architecture.", + "rationale": "Python-specific synchronous redis-py adapter and singleton lifecycle are obsolete in the async native storage runtime; required Redis behavior is implemented through typed SharedStorage operations.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window", + "gateway-rs/src/storage/runtime.rs::SharedStorage.redis_healthy" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "method", + "line": 383, + "path": "backend-services/utils/redis_client.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/redis_client.py::function:get_redis_client", + "notes": "Approved language/runtime replacement: the Python file is a redis-py connection-pool facade over generic Redis commands. Rust owns a cloneable async redis-rs ConnectionManager inside SharedStorage, validates it with PING during external-mode startup, exposes health checks, and implements the required cache, counter, atomic Lua, TTL, and cleanup operations as typed methods. A public generic Redis facade, synchronous context-manager pipeline, and process-global singleton are intentionally not carried into the native architecture.", + "rationale": "Python-specific synchronous redis-py adapter and singleton lifecycle are obsolete in the async native storage runtime; required Redis behavior is implemented through typed SharedStorage operations.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window", + "gateway-rs/src/storage/runtime.rs::SharedStorage.redis_healthy" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "function", + "line": 396, + "path": "backend-services/utils/redis_client.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/redis_client.py::function:close_redis_client", + "notes": "Approved language/runtime replacement: the Python file is a redis-py connection-pool facade over generic Redis commands. Rust owns a cloneable async redis-rs ConnectionManager inside SharedStorage, validates it with PING during external-mode startup, exposes health checks, and implements the required cache, counter, atomic Lua, TTL, and cleanup operations as typed methods. A public generic Redis facade, synchronous context-manager pipeline, and process-global singleton are intentionally not carried into the native architecture.", + "rationale": "Python-specific synchronous redis-py adapter and singleton lifecycle are obsolete in the async native storage runtime; required Redis behavior is implemented through typed SharedStorage operations.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window", + "gateway-rs/src/storage/runtime.rs::SharedStorage.redis_healthy" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "source": { + "kind": "function", + "line": 419, + "path": "backend-services/utils/redis_client.py" + }, + "status": "approved_obsolete" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/response_util.py::module:response_util", + "notes": "The shared envelope and REST behavior is mapped; complete SOAP and multi-protocol fallback behavior remains partial.", + "rust_symbols": [ + "gateway-rs/src/middleware/response_compat.rs" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::strict_envelope_preserves_legacy_status_tokens_and_probe_shape" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/response_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/response_util.py::function:_normalize_headers", + "notes": "Rust emits both request_id and x-request-id and preserves caller-provided IDs through platform and gateway responses.", + "rust_symbols": [ + "gateway-rs/src/middleware/request_id.rs::request_id" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::request_id_is_forwarded_to_authenticated_rest_upstream_and_response", + "gateway-rs/tests/platform_native.rs::platform_security_headers_csp_hsts_and_request_ids_match_python" + ], + "source": { + "kind": "function", + "line": 11, + "path": "backend-services/utils/response_util.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/response_util.py::function:_envelope", + "notes": "The Rust response middleware adds the original status_code to strict JSON envelopes.", + "rust_symbols": [ + "gateway-rs/src/middleware/response_compat.rs::response_compat" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::strict_envelope_preserves_legacy_status_tokens_and_probe_shape", + "gateway-rs/tests/platform_native.rs::rest_strict_response_envelope_wraps_proxy_message_like_python", + "gateway-rs/tests/platform_native.rs::graphql_strict_response_envelope_wraps_proxy_data_like_python" + ], + "source": { + "kind": "function", + "line": 26, + "path": "backend-services/utils/response_util.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/response_util.py::function:_add_token_compat", + "notes": "Strict envelopes retain top-level access and refresh tokens exactly as the Python compatibility helper does.", + "rust_symbols": [ + "gateway-rs/src/middleware/response_compat.rs::response_compat" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::strict_envelope_preserves_legacy_status_tokens_and_probe_shape" + ], + "source": { + "kind": "function", + "line": 30, + "path": "backend-services/utils/response_util.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/response_util.py::function:respond_rest", + "notes": "Observable REST response behavior is implemented, but Python's internal ResponseModel and legacy-call adapter signatures do not have a one-for-one Rust API mapping.", + "rust_symbols": [ + "gateway-rs/src/middleware/response_compat.rs::response_compat", + "gateway-rs/src/routes/platform.rs" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::strict_envelope_preserves_legacy_status_tokens_and_probe_shape" + ], + "source": { + "kind": "function", + "line": 40, + "path": "backend-services/utils/response_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/response_util.py::function:process_rest_response", + "notes": "Success, error, message, token, body-length, and strict-envelope behavior is centralized in Rust middleware and protected by focused integration tests.", + "rust_symbols": [ + "gateway-rs/src/middleware/response_compat.rs::response_compat" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::strict_envelope_preserves_legacy_status_tokens_and_probe_shape", + "gateway-rs/tests/platform_native.rs::rest_strict_response_envelope_wraps_proxy_message_like_python" + ], + "source": { + "kind": "function", + "line": 77, + "path": "backend-services/utils/response_util.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/response_util.py::function:process_soap_response", + "notes": "Rust preserves SOAP media types and maps common upstream failures, but Python's complete synthetic 201/error/fallback response matrix lacks a focused Rust equivalent test.", + "rust_symbols": [ + "gateway-rs/src/routes/soap.rs::soap_gateway", + "gateway-rs/src/protocol/soap.rs" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::soap_upstream_not_found_maps_to_python_404", + "gateway-rs/tests/live_tests_parity.rs::soap_content_types_and_retry_real_upstream_parity" + ], + "source": { + "kind": "function", + "line": 150, + "path": "backend-services/utils/response_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/response_util.py::function:process_response", + "notes": "Rust has protocol-specific REST, GraphQL, SOAP, and gRPC response paths, but the complete fallback and exception matrix is not yet mapped assertion by assertion.", + "rust_symbols": [ + "gateway-rs/src/middleware/response_compat.rs::response_compat", + "gateway-rs/src/routes/rest.rs", + "gateway-rs/src/routes/graphql.rs", + "gateway-rs/src/routes/soap.rs", + "gateway-rs/src/routes/grpc.rs" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rest_strict_response_envelope_wraps_proxy_message_like_python", + "gateway-rs/tests/platform_native.rs::graphql_strict_response_envelope_wraps_proxy_data_like_python", + "gateway-rs/tests/live_tests_parity.rs::soap_content_types_and_retry_real_upstream_parity", + "gateway-rs/tests/live_tests_parity.rs::grpc_gateway_maps_upstream_statuses_parity" + ], + "source": { + "kind": "function", + "line": 182, + "path": "backend-services/utils/response_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/role_util.py::module:role_util", + "notes": "Rust strips storage IDs, recognizes platform_admin plus legacy admin names, resolves admin users, and performs role permission checks for every pinned action. Typed storage failures return false directly, so Python's intermediate cache warming and validate_platform_role 404-to-500 exception quirk are not reproduced everywhere.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::has_permission", + "gateway-rs/src/routes/platform.rs::is_admin_user", + "gateway-rs/src/routes/platform.rs::is_admin_role", + "gateway-rs/src/policy/roles.rs::is_admin_user" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::role_route_permissions_visibility_and_admin_codes_match_python", + "gateway-rs/tests/roles_groups_parity.rs::non_admin_managers_cannot_discover_or_manage_bootstrap_admin" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/role_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/role_util.py::function:_strip_id", + "notes": "Rust strips storage IDs, recognizes platform_admin plus legacy admin names, resolves admin users, and performs role permission checks for every pinned action. Typed storage failures return false directly, so Python's intermediate cache warming and validate_platform_role 404-to-500 exception quirk are not reproduced everywhere.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::has_permission", + "gateway-rs/src/routes/platform.rs::is_admin_user", + "gateway-rs/src/routes/platform.rs::is_admin_role", + "gateway-rs/src/policy/roles.rs::is_admin_user" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::role_route_permissions_visibility_and_admin_codes_match_python", + "gateway-rs/tests/roles_groups_parity.rs::non_admin_managers_cannot_discover_or_manage_bootstrap_admin" + ], + "source": { + "kind": "function", + "line": 17, + "path": "backend-services/utils/role_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/role_util.py::async_function:is_admin_role", + "notes": "Rust strips storage IDs, recognizes platform_admin plus legacy admin names, resolves admin users, and performs role permission checks for every pinned action. Typed storage failures return false directly, so Python's intermediate cache warming and validate_platform_role 404-to-500 exception quirk are not reproduced everywhere.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::has_permission", + "gateway-rs/src/routes/platform.rs::is_admin_user", + "gateway-rs/src/routes/platform.rs::is_admin_role", + "gateway-rs/src/policy/roles.rs::is_admin_user" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::role_route_permissions_visibility_and_admin_codes_match_python", + "gateway-rs/tests/roles_groups_parity.rs::non_admin_managers_cannot_discover_or_manage_bootstrap_admin" + ], + "source": { + "kind": "async_function", + "line": 26, + "path": "backend-services/utils/role_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/role_util.py::async_function:is_admin_user", + "notes": "Rust strips storage IDs, recognizes platform_admin plus legacy admin names, resolves admin users, and performs role permission checks for every pinned action. Typed storage failures return false directly, so Python's intermediate cache warming and validate_platform_role 404-to-500 exception quirk are not reproduced everywhere.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::has_permission", + "gateway-rs/src/routes/platform.rs::is_admin_user", + "gateway-rs/src/routes/platform.rs::is_admin_role", + "gateway-rs/src/policy/roles.rs::is_admin_user" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::role_route_permissions_visibility_and_admin_codes_match_python", + "gateway-rs/tests/roles_groups_parity.rs::non_admin_managers_cannot_discover_or_manage_bootstrap_admin" + ], + "source": { + "kind": "async_function", + "line": 50, + "path": "backend-services/utils/role_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/role_util.py::async_function:is_platform_admin_role", + "notes": "Rust strips storage IDs, recognizes platform_admin plus legacy admin names, resolves admin users, and performs role permission checks for every pinned action. Typed storage failures return false directly, so Python's intermediate cache warming and validate_platform_role 404-to-500 exception quirk are not reproduced everywhere.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::has_permission", + "gateway-rs/src/routes/platform.rs::is_admin_user", + "gateway-rs/src/routes/platform.rs::is_admin_role", + "gateway-rs/src/policy/roles.rs::is_admin_user" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::role_route_permissions_visibility_and_admin_codes_match_python", + "gateway-rs/tests/roles_groups_parity.rs::non_admin_managers_cannot_discover_or_manage_bootstrap_admin" + ], + "source": { + "kind": "async_function", + "line": 66, + "path": "backend-services/utils/role_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/role_util.py::async_function:is_platform_admin_user", + "notes": "Rust strips storage IDs, recognizes platform_admin plus legacy admin names, resolves admin users, and performs role permission checks for every pinned action. Typed storage failures return false directly, so Python's intermediate cache warming and validate_platform_role 404-to-500 exception quirk are not reproduced everywhere.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::has_permission", + "gateway-rs/src/routes/platform.rs::is_admin_user", + "gateway-rs/src/routes/platform.rs::is_admin_role", + "gateway-rs/src/policy/roles.rs::is_admin_user" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::role_route_permissions_visibility_and_admin_codes_match_python", + "gateway-rs/tests/roles_groups_parity.rs::non_admin_managers_cannot_discover_or_manage_bootstrap_admin" + ], + "source": { + "kind": "async_function", + "line": 70, + "path": "backend-services/utils/role_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/role_util.py::async_function:validate_platform_role", + "notes": "Rust strips storage IDs, recognizes platform_admin plus legacy admin names, resolves admin users, and performs role permission checks for every pinned action. Typed storage failures return false directly, so Python's intermediate cache warming and validate_platform_role 404-to-500 exception quirk are not reproduced everywhere.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::has_permission", + "gateway-rs/src/routes/platform.rs::is_admin_user", + "gateway-rs/src/routes/platform.rs::is_admin_role", + "gateway-rs/src/policy/roles.rs::is_admin_user" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::role_route_permissions_visibility_and_admin_codes_match_python", + "gateway-rs/tests/roles_groups_parity.rs::non_admin_managers_cannot_discover_or_manage_bootstrap_admin" + ], + "source": { + "kind": "async_function", + "line": 74, + "path": "backend-services/utils/role_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/role_util.py::async_function:platform_role_required_bool", + "notes": "Rust strips storage IDs, recognizes platform_admin plus legacy admin names, resolves admin users, and performs role permission checks for every pinned action. Typed storage failures return false directly, so Python's intermediate cache warming and validate_platform_role 404-to-500 exception quirk are not reproduced everywhere.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::has_permission", + "gateway-rs/src/routes/platform.rs::is_admin_user", + "gateway-rs/src/routes/platform.rs::is_admin_role", + "gateway-rs/src/policy/roles.rs::is_admin_user" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::role_route_permissions_visibility_and_admin_codes_match_python", + "gateway-rs/tests/roles_groups_parity.rs::non_admin_managers_cannot_discover_or_manage_bootstrap_admin" + ], + "source": { + "kind": "async_function", + "line": 125, + "path": "backend-services/utils/role_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/routing_util.py::module:routing_util", + "notes": "Rust preserves client-routing over endpoint over API precedence, per-key round robin, endpoint client_uri lookup, and shared cache indices. Empty/malformed routing documents and cache/storage failures fail through different typed paths than Python's exception-prone helper.", + "rust_symbols": [ + "gateway-rs/src/gateway/routing.rs::select_upstream", + "gateway-rs/src/policy/evaluator.rs::evaluate_request" + ], + "rust_tests": [ + "gateway-rs/src/gateway/routing.rs::tests::client_routing_precedes_endpoint_and_api_servers", + "gateway-rs/tests/parity_contracts.rs::rust_matches_checked_in_wire_contracts" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/routing_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/routing_util.py::async_function:get_client_routing", + "notes": "Rust preserves client-routing over endpoint over API precedence, per-key round robin, endpoint client_uri lookup, and shared cache indices. Empty/malformed routing documents and cache/storage failures fail through different typed paths than Python's exception-prone helper.", + "rust_symbols": [ + "gateway-rs/src/gateway/routing.rs::select_upstream", + "gateway-rs/src/policy/evaluator.rs::evaluate_request" + ], + "rust_tests": [ + "gateway-rs/src/gateway/routing.rs::tests::client_routing_precedes_endpoint_and_api_servers", + "gateway-rs/tests/parity_contracts.rs::rust_matches_checked_in_wire_contracts" + ], + "source": { + "kind": "async_function", + "line": 11, + "path": "backend-services/utils/routing_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/routing_util.py::async_function:get_routing_info", + "notes": "Rust preserves client-routing over endpoint over API precedence, per-key round robin, endpoint client_uri lookup, and shared cache indices. Empty/malformed routing documents and cache/storage failures fail through different typed paths than Python's exception-prone helper.", + "rust_symbols": [ + "gateway-rs/src/gateway/routing.rs::select_upstream", + "gateway-rs/src/policy/evaluator.rs::evaluate_request" + ], + "rust_tests": [ + "gateway-rs/src/gateway/routing.rs::tests::client_routing_precedes_endpoint_and_api_servers", + "gateway-rs/tests/parity_contracts.rs::rust_matches_checked_in_wire_contracts" + ], + "source": { + "kind": "async_function", + "line": 35, + "path": "backend-services/utils/routing_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/routing_util.py::async_function:pick_upstream_server", + "notes": "Rust preserves client-routing over endpoint over API precedence, per-key round robin, endpoint client_uri lookup, and shared cache indices. Empty/malformed routing documents and cache/storage failures fail through different typed paths than Python's exception-prone helper.", + "rust_symbols": [ + "gateway-rs/src/gateway/routing.rs::select_upstream", + "gateway-rs/src/policy/evaluator.rs::evaluate_request" + ], + "rust_tests": [ + "gateway-rs/src/gateway/routing.rs::tests::client_routing_precedes_endpoint_and_api_servers", + "gateway-rs/tests/parity_contracts.rs::rust_matches_checked_in_wire_contracts" + ], + "source": { + "kind": "async_function", + "line": 56, + "path": "backend-services/utils/routing_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/sanitize_util.py::module:sanitize_util", + "notes": "Rust implements the pinned HTML escaping/tag stripping, whitespace and NUL normalization, character-count truncation, dangerous URL-scheme rejection, control-character removal, and ASCII username/API-name allowlists as typed utilities.", + "rust_symbols": [ + "gateway-rs/src/validation/sanitize.rs::sanitize_html", + "gateway-rs/src/validation/sanitize.rs::sanitize_input", + "gateway-rs/src/validation/sanitize.rs::sanitize_url", + "gateway-rs/src/validation/sanitize.rs::strip_control_characters", + "gateway-rs/src/validation/sanitize.rs::sanitize_username", + "gateway-rs/src/validation/sanitize.rs::sanitize_api_name" + ], + "rust_tests": [ + "gateway-rs/src/validation/sanitize.rs::tests::sanitizers_match_python_examples_and_character_limits" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/sanitize_util.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/sanitize_util.py::function:sanitize_html", + "notes": "Rust implements the pinned HTML escaping/tag stripping, whitespace and NUL normalization, character-count truncation, dangerous URL-scheme rejection, control-character removal, and ASCII username/API-name allowlists as typed utilities.", + "rust_symbols": [ + "gateway-rs/src/validation/sanitize.rs::sanitize_html", + "gateway-rs/src/validation/sanitize.rs::sanitize_input", + "gateway-rs/src/validation/sanitize.rs::sanitize_url", + "gateway-rs/src/validation/sanitize.rs::strip_control_characters", + "gateway-rs/src/validation/sanitize.rs::sanitize_username", + "gateway-rs/src/validation/sanitize.rs::sanitize_api_name" + ], + "rust_tests": [ + "gateway-rs/src/validation/sanitize.rs::tests::sanitizers_match_python_examples_and_character_limits" + ], + "source": { + "kind": "function", + "line": 11, + "path": "backend-services/utils/sanitize_util.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/sanitize_util.py::function:sanitize_input", + "notes": "Rust implements the pinned HTML escaping/tag stripping, whitespace and NUL normalization, character-count truncation, dangerous URL-scheme rejection, control-character removal, and ASCII username/API-name allowlists as typed utilities.", + "rust_symbols": [ + "gateway-rs/src/validation/sanitize.rs::sanitize_html", + "gateway-rs/src/validation/sanitize.rs::sanitize_input", + "gateway-rs/src/validation/sanitize.rs::sanitize_url", + "gateway-rs/src/validation/sanitize.rs::strip_control_characters", + "gateway-rs/src/validation/sanitize.rs::sanitize_username", + "gateway-rs/src/validation/sanitize.rs::sanitize_api_name" + ], + "rust_tests": [ + "gateway-rs/src/validation/sanitize.rs::tests::sanitizers_match_python_examples_and_character_limits" + ], + "source": { + "kind": "function", + "line": 24, + "path": "backend-services/utils/sanitize_util.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/sanitize_util.py::function:sanitize_url", + "notes": "Rust implements the pinned HTML escaping/tag stripping, whitespace and NUL normalization, character-count truncation, dangerous URL-scheme rejection, control-character removal, and ASCII username/API-name allowlists as typed utilities.", + "rust_symbols": [ + "gateway-rs/src/validation/sanitize.rs::sanitize_html", + "gateway-rs/src/validation/sanitize.rs::sanitize_input", + "gateway-rs/src/validation/sanitize.rs::sanitize_url", + "gateway-rs/src/validation/sanitize.rs::strip_control_characters", + "gateway-rs/src/validation/sanitize.rs::sanitize_username", + "gateway-rs/src/validation/sanitize.rs::sanitize_api_name" + ], + "rust_tests": [ + "gateway-rs/src/validation/sanitize.rs::tests::sanitizers_match_python_examples_and_character_limits" + ], + "source": { + "kind": "function", + "line": 38, + "path": "backend-services/utils/sanitize_util.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/sanitize_util.py::function:strip_control_characters", + "notes": "Rust implements the pinned HTML escaping/tag stripping, whitespace and NUL normalization, character-count truncation, dangerous URL-scheme rejection, control-character removal, and ASCII username/API-name allowlists as typed utilities.", + "rust_symbols": [ + "gateway-rs/src/validation/sanitize.rs::sanitize_html", + "gateway-rs/src/validation/sanitize.rs::sanitize_input", + "gateway-rs/src/validation/sanitize.rs::sanitize_url", + "gateway-rs/src/validation/sanitize.rs::strip_control_characters", + "gateway-rs/src/validation/sanitize.rs::sanitize_username", + "gateway-rs/src/validation/sanitize.rs::sanitize_api_name" + ], + "rust_tests": [ + "gateway-rs/src/validation/sanitize.rs::tests::sanitizers_match_python_examples_and_character_limits" + ], + "source": { + "kind": "function", + "line": 53, + "path": "backend-services/utils/sanitize_util.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/sanitize_util.py::function:sanitize_username", + "notes": "Rust implements the pinned HTML escaping/tag stripping, whitespace and NUL normalization, character-count truncation, dangerous URL-scheme rejection, control-character removal, and ASCII username/API-name allowlists as typed utilities.", + "rust_symbols": [ + "gateway-rs/src/validation/sanitize.rs::sanitize_html", + "gateway-rs/src/validation/sanitize.rs::sanitize_input", + "gateway-rs/src/validation/sanitize.rs::sanitize_url", + "gateway-rs/src/validation/sanitize.rs::strip_control_characters", + "gateway-rs/src/validation/sanitize.rs::sanitize_username", + "gateway-rs/src/validation/sanitize.rs::sanitize_api_name" + ], + "rust_tests": [ + "gateway-rs/src/validation/sanitize.rs::tests::sanitizers_match_python_examples_and_character_limits" + ], + "source": { + "kind": "function", + "line": 62, + "path": "backend-services/utils/sanitize_util.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/sanitize_util.py::function:sanitize_api_name", + "notes": "Rust implements the pinned HTML escaping/tag stripping, whitespace and NUL normalization, character-count truncation, dangerous URL-scheme rejection, control-character removal, and ASCII username/API-name allowlists as typed utilities.", + "rust_symbols": [ + "gateway-rs/src/validation/sanitize.rs::sanitize_html", + "gateway-rs/src/validation/sanitize.rs::sanitize_input", + "gateway-rs/src/validation/sanitize.rs::sanitize_url", + "gateway-rs/src/validation/sanitize.rs::strip_control_characters", + "gateway-rs/src/validation/sanitize.rs::sanitize_username", + "gateway-rs/src/validation/sanitize.rs::sanitize_api_name" + ], + "rust_tests": [ + "gateway-rs/src/validation/sanitize.rs::tests::sanitizers_match_python_examples_and_character_limits" + ], + "source": { + "kind": "function", + "line": 73, + "path": "backend-services/utils/sanitize_util.py" + }, + "status": "translated" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/security_settings_util.py::module:security_settings_util", + "notes": "Rust preserves environment/default merging, database-over-file precedence, memory-mode file restore, initial persistence, partial settings updates, cached runtime propagation, configurable autosave cadence, and settings-file mirroring. The native worker reacts to settings changes without task restart, uses atomic owner-only file writes, and honors enable_auto_save; pinned Python's loop inadvertently dumps whenever memory mode and frequency are set even when enable_auto_save is false.", + "rust_symbols": [ + "gateway-rs/src/storage/security_settings.rs", + "gateway-rs/src/state.rs::MemoryAutosaveConfig", + "gateway-rs/src/storage/snapshot.rs::spawn_autosave", + "gateway-rs/src/routes/platform.rs::upsert_security_settings" + ], + "rust_tests": [ + "gateway-rs/src/storage/security_settings.rs::tests", + "gateway-rs/tests/security_settings_parity.rs" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/security_settings_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/security_settings_util.py::function:_normalize_path", + "notes": "Rust preserves environment/default merging, database-over-file precedence, memory-mode file restore, initial persistence, partial settings updates, cached runtime propagation, configurable autosave cadence, and settings-file mirroring. The native worker reacts to settings changes without task restart, uses atomic owner-only file writes, and honors enable_auto_save; pinned Python's loop inadvertently dumps whenever memory mode and frequency are set even when enable_auto_save is false.", + "rust_symbols": [ + "gateway-rs/src/storage/security_settings.rs", + "gateway-rs/src/state.rs::MemoryAutosaveConfig", + "gateway-rs/src/storage/snapshot.rs::spawn_autosave", + "gateway-rs/src/routes/platform.rs::upsert_security_settings" + ], + "rust_tests": [ + "gateway-rs/src/storage/security_settings.rs::tests", + "gateway-rs/tests/security_settings_parity.rs" + ], + "source": { + "kind": "function", + "line": 23, + "path": "backend-services/utils/security_settings_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/security_settings_util.py::function:_env_bool", + "notes": "Rust preserves environment/default merging, database-over-file precedence, memory-mode file restore, initial persistence, partial settings updates, cached runtime propagation, configurable autosave cadence, and settings-file mirroring. The native worker reacts to settings changes without task restart, uses atomic owner-only file writes, and honors enable_auto_save; pinned Python's loop inadvertently dumps whenever memory mode and frequency are set even when enable_auto_save is false.", + "rust_symbols": [ + "gateway-rs/src/storage/security_settings.rs", + "gateway-rs/src/state.rs::MemoryAutosaveConfig", + "gateway-rs/src/storage/snapshot.rs::spawn_autosave", + "gateway-rs/src/routes/platform.rs::upsert_security_settings" + ], + "rust_tests": [ + "gateway-rs/src/storage/security_settings.rs::tests", + "gateway-rs/tests/security_settings_parity.rs" + ], + "source": { + "kind": "function", + "line": 37, + "path": "backend-services/utils/security_settings_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/security_settings_util.py::function:_env_int", + "notes": "Rust preserves environment/default merging, database-over-file precedence, memory-mode file restore, initial persistence, partial settings updates, cached runtime propagation, configurable autosave cadence, and settings-file mirroring. The native worker reacts to settings changes without task restart, uses atomic owner-only file writes, and honors enable_auto_save; pinned Python's loop inadvertently dumps whenever memory mode and frequency are set even when enable_auto_save is false.", + "rust_symbols": [ + "gateway-rs/src/storage/security_settings.rs", + "gateway-rs/src/state.rs::MemoryAutosaveConfig", + "gateway-rs/src/storage/snapshot.rs::spawn_autosave", + "gateway-rs/src/routes/platform.rs::upsert_security_settings" + ], + "rust_tests": [ + "gateway-rs/src/storage/security_settings.rs::tests", + "gateway-rs/tests/security_settings_parity.rs" + ], + "source": { + "kind": "function", + "line": 47, + "path": "backend-services/utils/security_settings_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/security_settings_util.py::function:_get_collection", + "notes": "Rust preserves environment/default merging, database-over-file precedence, memory-mode file restore, initial persistence, partial settings updates, cached runtime propagation, configurable autosave cadence, and settings-file mirroring. The native worker reacts to settings changes without task restart, uses atomic owner-only file writes, and honors enable_auto_save; pinned Python's loop inadvertently dumps whenever memory mode and frequency are set even when enable_auto_save is false.", + "rust_symbols": [ + "gateway-rs/src/storage/security_settings.rs", + "gateway-rs/src/state.rs::MemoryAutosaveConfig", + "gateway-rs/src/storage/snapshot.rs::spawn_autosave", + "gateway-rs/src/routes/platform.rs::upsert_security_settings" + ], + "rust_tests": [ + "gateway-rs/src/storage/security_settings.rs::tests", + "gateway-rs/tests/security_settings_parity.rs" + ], + "source": { + "kind": "function", + "line": 77, + "path": "backend-services/utils/security_settings_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/security_settings_util.py::function:_merge_settings", + "notes": "Rust preserves environment/default merging, database-over-file precedence, memory-mode file restore, initial persistence, partial settings updates, cached runtime propagation, configurable autosave cadence, and settings-file mirroring. The native worker reacts to settings changes without task restart, uses atomic owner-only file writes, and honors enable_auto_save; pinned Python's loop inadvertently dumps whenever memory mode and frequency are set even when enable_auto_save is false.", + "rust_symbols": [ + "gateway-rs/src/storage/security_settings.rs", + "gateway-rs/src/state.rs::MemoryAutosaveConfig", + "gateway-rs/src/storage/snapshot.rs::spawn_autosave", + "gateway-rs/src/routes/platform.rs::upsert_security_settings" + ], + "rust_tests": [ + "gateway-rs/src/storage/security_settings.rs::tests", + "gateway-rs/tests/security_settings_parity.rs" + ], + "source": { + "kind": "function", + "line": 81, + "path": "backend-services/utils/security_settings_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/security_settings_util.py::function:get_cached_settings", + "notes": "Rust preserves environment/default merging, database-over-file precedence, memory-mode file restore, initial persistence, partial settings updates, cached runtime propagation, configurable autosave cadence, and settings-file mirroring. The native worker reacts to settings changes without task restart, uses atomic owner-only file writes, and honors enable_auto_save; pinned Python's loop inadvertently dumps whenever memory mode and frequency are set even when enable_auto_save is false.", + "rust_symbols": [ + "gateway-rs/src/storage/security_settings.rs", + "gateway-rs/src/state.rs::MemoryAutosaveConfig", + "gateway-rs/src/storage/snapshot.rs::spawn_autosave", + "gateway-rs/src/routes/platform.rs::upsert_security_settings" + ], + "rust_tests": [ + "gateway-rs/src/storage/security_settings.rs::tests", + "gateway-rs/tests/security_settings_parity.rs" + ], + "source": { + "kind": "function", + "line": 88, + "path": "backend-services/utils/security_settings_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/security_settings_util.py::function:_load_from_file", + "notes": "Rust preserves environment/default merging, database-over-file precedence, memory-mode file restore, initial persistence, partial settings updates, cached runtime propagation, configurable autosave cadence, and settings-file mirroring. The native worker reacts to settings changes without task restart, uses atomic owner-only file writes, and honors enable_auto_save; pinned Python's loop inadvertently dumps whenever memory mode and frequency are set even when enable_auto_save is false.", + "rust_symbols": [ + "gateway-rs/src/storage/security_settings.rs", + "gateway-rs/src/state.rs::MemoryAutosaveConfig", + "gateway-rs/src/storage/snapshot.rs::spawn_autosave", + "gateway-rs/src/routes/platform.rs::upsert_security_settings" + ], + "rust_tests": [ + "gateway-rs/src/storage/security_settings.rs::tests", + "gateway-rs/tests/security_settings_parity.rs" + ], + "source": { + "kind": "function", + "line": 95, + "path": "backend-services/utils/security_settings_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/security_settings_util.py::function:_save_to_file", + "notes": "Rust preserves environment/default merging, database-over-file precedence, memory-mode file restore, initial persistence, partial settings updates, cached runtime propagation, configurable autosave cadence, and settings-file mirroring. The native worker reacts to settings changes without task restart, uses atomic owner-only file writes, and honors enable_auto_save; pinned Python's loop inadvertently dumps whenever memory mode and frequency are set even when enable_auto_save is false.", + "rust_symbols": [ + "gateway-rs/src/storage/security_settings.rs", + "gateway-rs/src/state.rs::MemoryAutosaveConfig", + "gateway-rs/src/storage/snapshot.rs::spawn_autosave", + "gateway-rs/src/routes/platform.rs::upsert_security_settings" + ], + "rust_tests": [ + "gateway-rs/src/storage/security_settings.rs::tests", + "gateway-rs/tests/security_settings_parity.rs" + ], + "source": { + "kind": "function", + "line": 114, + "path": "backend-services/utils/security_settings_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/security_settings_util.py::async_function:load_settings", + "notes": "Rust preserves environment/default merging, database-over-file precedence, memory-mode file restore, initial persistence, partial settings updates, cached runtime propagation, configurable autosave cadence, and settings-file mirroring. The native worker reacts to settings changes without task restart, uses atomic owner-only file writes, and honors enable_auto_save; pinned Python's loop inadvertently dumps whenever memory mode and frequency are set even when enable_auto_save is false.", + "rust_symbols": [ + "gateway-rs/src/storage/security_settings.rs", + "gateway-rs/src/state.rs::MemoryAutosaveConfig", + "gateway-rs/src/storage/snapshot.rs::spawn_autosave", + "gateway-rs/src/routes/platform.rs::upsert_security_settings" + ], + "rust_tests": [ + "gateway-rs/src/storage/security_settings.rs::tests", + "gateway-rs/tests/security_settings_parity.rs" + ], + "source": { + "kind": "async_function", + "line": 125, + "path": "backend-services/utils/security_settings_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/security_settings_util.py::async_function:save_settings", + "notes": "Rust preserves environment/default merging, database-over-file precedence, memory-mode file restore, initial persistence, partial settings updates, cached runtime propagation, configurable autosave cadence, and settings-file mirroring. The native worker reacts to settings changes without task restart, uses atomic owner-only file writes, and honors enable_auto_save; pinned Python's loop inadvertently dumps whenever memory mode and frequency are set even when enable_auto_save is false.", + "rust_symbols": [ + "gateway-rs/src/storage/security_settings.rs", + "gateway-rs/src/state.rs::MemoryAutosaveConfig", + "gateway-rs/src/storage/snapshot.rs::spawn_autosave", + "gateway-rs/src/routes/platform.rs::upsert_security_settings" + ], + "rust_tests": [ + "gateway-rs/src/storage/security_settings.rs::tests", + "gateway-rs/tests/security_settings_parity.rs" + ], + "source": { + "kind": "async_function", + "line": 157, + "path": "backend-services/utils/security_settings_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/security_settings_util.py::async_function:_auto_save_loop", + "notes": "Rust preserves environment/default merging, database-over-file precedence, memory-mode file restore, initial persistence, partial settings updates, cached runtime propagation, configurable autosave cadence, and settings-file mirroring. The native worker reacts to settings changes without task restart, uses atomic owner-only file writes, and honors enable_auto_save; pinned Python's loop inadvertently dumps whenever memory mode and frequency are set even when enable_auto_save is false.", + "rust_symbols": [ + "gateway-rs/src/storage/security_settings.rs", + "gateway-rs/src/state.rs::MemoryAutosaveConfig", + "gateway-rs/src/storage/snapshot.rs::spawn_autosave", + "gateway-rs/src/routes/platform.rs::upsert_security_settings" + ], + "rust_tests": [ + "gateway-rs/src/storage/security_settings.rs::tests", + "gateway-rs/tests/security_settings_parity.rs" + ], + "source": { + "kind": "async_function", + "line": 176, + "path": "backend-services/utils/security_settings_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/security_settings_util.py::async_function:start_auto_save_task", + "notes": "Rust preserves environment/default merging, database-over-file precedence, memory-mode file restore, initial persistence, partial settings updates, cached runtime propagation, configurable autosave cadence, and settings-file mirroring. The native worker reacts to settings changes without task restart, uses atomic owner-only file writes, and honors enable_auto_save; pinned Python's loop inadvertently dumps whenever memory mode and frequency are set even when enable_auto_save is false.", + "rust_symbols": [ + "gateway-rs/src/storage/security_settings.rs", + "gateway-rs/src/state.rs::MemoryAutosaveConfig", + "gateway-rs/src/storage/snapshot.rs::spawn_autosave", + "gateway-rs/src/routes/platform.rs::upsert_security_settings" + ], + "rust_tests": [ + "gateway-rs/src/storage/security_settings.rs::tests", + "gateway-rs/tests/security_settings_parity.rs" + ], + "source": { + "kind": "async_function", + "line": 197, + "path": "backend-services/utils/security_settings_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/security_settings_util.py::async_function:stop_auto_save_task", + "notes": "Rust preserves environment/default merging, database-over-file precedence, memory-mode file restore, initial persistence, partial settings updates, cached runtime propagation, configurable autosave cadence, and settings-file mirroring. The native worker reacts to settings changes without task restart, uses atomic owner-only file writes, and honors enable_auto_save; pinned Python's loop inadvertently dumps whenever memory mode and frequency are set even when enable_auto_save is false.", + "rust_symbols": [ + "gateway-rs/src/storage/security_settings.rs", + "gateway-rs/src/state.rs::MemoryAutosaveConfig", + "gateway-rs/src/storage/snapshot.rs::spawn_autosave", + "gateway-rs/src/routes/platform.rs::upsert_security_settings" + ], + "rust_tests": [ + "gateway-rs/src/storage/security_settings.rs::tests", + "gateway-rs/tests/security_settings_parity.rs" + ], + "source": { + "kind": "async_function", + "line": 206, + "path": "backend-services/utils/security_settings_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/security_settings_util.py::async_function:restart_auto_save_task", + "notes": "Rust preserves environment/default merging, database-over-file precedence, memory-mode file restore, initial persistence, partial settings updates, cached runtime propagation, configurable autosave cadence, and settings-file mirroring. The native worker reacts to settings changes without task restart, uses atomic owner-only file writes, and honors enable_auto_save; pinned Python's loop inadvertently dumps whenever memory mode and frequency are set even when enable_auto_save is false.", + "rust_symbols": [ + "gateway-rs/src/storage/security_settings.rs", + "gateway-rs/src/state.rs::MemoryAutosaveConfig", + "gateway-rs/src/storage/snapshot.rs::spawn_autosave", + "gateway-rs/src/routes/platform.rs::upsert_security_settings" + ], + "rust_tests": [ + "gateway-rs/src/storage/security_settings.rs::tests", + "gateway-rs/tests/security_settings_parity.rs" + ], + "source": { + "kind": "async_function", + "line": 219, + "path": "backend-services/utils/security_settings_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/shared_metrics_util.py::module:shared_metrics_util", + "notes": "Rust records the same Redis minute-bucket fields and native monitor responses merge in-process gateway counters. Cross-process Redis bucket merging into monitor snapshots, including Python's exact day grouping, top-list merge, unique-user overcount, and fail-open scan behavior, is not yet implemented.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.record_gateway_metric", + "gateway-rs/src/routes/platform.rs::monitor_metrics" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/shared_metrics_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/shared_metrics_util.py::function:merge_rust_gateway_metrics", + "notes": "Rust records the same Redis minute-bucket fields and native monitor responses merge in-process gateway counters. Cross-process Redis bucket merging into monitor snapshots, including Python's exact day grouping, top-list merge, unique-user overcount, and fail-open scan behavior, is not yet implemented.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.record_gateway_metric", + "gateway-rs/src/routes/platform.rs::monitor_metrics" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity" + ], + "source": { + "kind": "function", + "line": 11, + "path": "backend-services/utils/shared_metrics_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/subscription_util.py::module:subscription_util", + "notes": "Rust enforces the same authentication, admin bypass default, protocol API/version resolution, 403 detail, and subscription-list membership. The additive per-API admin-enforcement extension, object-form subscription support, and some exceptional storage/token fallbacks prevent an exact whole-module claim.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::evaluate_request", + "gateway-rs/src/policy/subscription.rs::enforce_subscription" + ], + "rust_tests": [ + "gateway-rs/src/policy/subscription.rs::tests::admin_bypasses_subscription_unless_enforced", + "gateway-rs/src/policy/subscription.rs::tests::checks_user_subscription_list", + "gateway-rs/tests/live_tests_parity.rs::grpc_gateway_maps_upstream_statuses_parity" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/subscription_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/subscription_util.py::async_function:subscription_required", + "notes": "Rust enforces the same authentication, admin bypass default, protocol API/version resolution, 403 detail, and subscription-list membership. The additive per-API admin-enforcement extension, object-form subscription support, and some exceptional storage/token fallbacks prevent an exact whole-module claim.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::evaluate_request", + "gateway-rs/src/policy/subscription.rs::enforce_subscription" + ], + "rust_tests": [ + "gateway-rs/src/policy/subscription.rs::tests::admin_bypasses_subscription_unless_enforced", + "gateway-rs/src/policy/subscription.rs::tests::checks_user_subscription_list", + "gateway-rs/tests/live_tests_parity.rs::grpc_gateway_maps_upstream_statuses_parity" + ], + "source": { + "kind": "async_function", + "line": 22, + "path": "backend-services/utils/subscription_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/transform_util.py::module:transform_util", + "notes": "Rust preserves request/response header, JSON body, array JSONPath, query, wrap/remove/rename/set, and status transformations in the native proxy. Scalar header/query additions now use Python-compatible True/False/None spelling and status maps accept numeric strings. The unused Python TransformError and validate_transform_config helpers have no direct native call equivalents, and invalid HTTP header material is skipped at the typed HeaderMap boundary.", + "rust_symbols": [ + "gateway-rs/src/gateway/transforms.rs::transform_request", + "gateway-rs/src/gateway/transforms.rs::transform_response", + "gateway-rs/src/gateway/transforms.rs::set_path", + "gateway-rs/src/gateway/transforms.rs::take_path" + ], + "rust_tests": [ + "gateway-rs/src/gateway/transforms.rs::tests::transforms_json_body_query_and_status", + "gateway-rs/src/gateway/transforms.rs::tests::transforms_array_paths_like_the_python_gateway" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/transform_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/transform_util.py::class:TransformError", + "notes": "Rust preserves request/response header, JSON body, array JSONPath, query, wrap/remove/rename/set, and status transformations in the native proxy. Scalar header/query additions now use Python-compatible True/False/None spelling and status maps accept numeric strings. The unused Python TransformError and validate_transform_config helpers have no direct native call equivalents, and invalid HTTP header material is skipped at the typed HeaderMap boundary.", + "rust_symbols": [ + "gateway-rs/src/gateway/transforms.rs::transform_request", + "gateway-rs/src/gateway/transforms.rs::transform_response", + "gateway-rs/src/gateway/transforms.rs::set_path", + "gateway-rs/src/gateway/transforms.rs::take_path" + ], + "rust_tests": [ + "gateway-rs/src/gateway/transforms.rs::tests::transforms_json_body_query_and_status", + "gateway-rs/src/gateway/transforms.rs::tests::transforms_array_paths_like_the_python_gateway" + ], + "source": { + "kind": "class", + "line": 16, + "path": "backend-services/utils/transform_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/transform_util.py::method:TransformError.__init__", + "notes": "Rust preserves request/response header, JSON body, array JSONPath, query, wrap/remove/rename/set, and status transformations in the native proxy. Scalar header/query additions now use Python-compatible True/False/None spelling and status maps accept numeric strings. The unused Python TransformError and validate_transform_config helpers have no direct native call equivalents, and invalid HTTP header material is skipped at the typed HeaderMap boundary.", + "rust_symbols": [ + "gateway-rs/src/gateway/transforms.rs::transform_request", + "gateway-rs/src/gateway/transforms.rs::transform_response", + "gateway-rs/src/gateway/transforms.rs::set_path", + "gateway-rs/src/gateway/transforms.rs::take_path" + ], + "rust_tests": [ + "gateway-rs/src/gateway/transforms.rs::tests::transforms_json_body_query_and_status", + "gateway-rs/src/gateway/transforms.rs::tests::transforms_array_paths_like_the_python_gateway" + ], + "source": { + "kind": "method", + "line": 19, + "path": "backend-services/utils/transform_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/transform_util.py::function:_get_jsonpath_value", + "notes": "Rust preserves request/response header, JSON body, array JSONPath, query, wrap/remove/rename/set, and status transformations in the native proxy. Scalar header/query additions now use Python-compatible True/False/None spelling and status maps accept numeric strings. The unused Python TransformError and validate_transform_config helpers have no direct native call equivalents, and invalid HTTP header material is skipped at the typed HeaderMap boundary.", + "rust_symbols": [ + "gateway-rs/src/gateway/transforms.rs::transform_request", + "gateway-rs/src/gateway/transforms.rs::transform_response", + "gateway-rs/src/gateway/transforms.rs::set_path", + "gateway-rs/src/gateway/transforms.rs::take_path" + ], + "rust_tests": [ + "gateway-rs/src/gateway/transforms.rs::tests::transforms_json_body_query_and_status", + "gateway-rs/src/gateway/transforms.rs::tests::transforms_array_paths_like_the_python_gateway" + ], + "source": { + "kind": "function", + "line": 25, + "path": "backend-services/utils/transform_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/transform_util.py::function:_set_jsonpath_value", + "notes": "Rust preserves request/response header, JSON body, array JSONPath, query, wrap/remove/rename/set, and status transformations in the native proxy. Scalar header/query additions now use Python-compatible True/False/None spelling and status maps accept numeric strings. The unused Python TransformError and validate_transform_config helpers have no direct native call equivalents, and invalid HTTP header material is skipped at the typed HeaderMap boundary.", + "rust_symbols": [ + "gateway-rs/src/gateway/transforms.rs::transform_request", + "gateway-rs/src/gateway/transforms.rs::transform_response", + "gateway-rs/src/gateway/transforms.rs::set_path", + "gateway-rs/src/gateway/transforms.rs::take_path" + ], + "rust_tests": [ + "gateway-rs/src/gateway/transforms.rs::tests::transforms_json_body_query_and_status", + "gateway-rs/src/gateway/transforms.rs::tests::transforms_array_paths_like_the_python_gateway" + ], + "source": { + "kind": "function", + "line": 76, + "path": "backend-services/utils/transform_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/transform_util.py::function:_delete_jsonpath", + "notes": "Rust preserves request/response header, JSON body, array JSONPath, query, wrap/remove/rename/set, and status transformations in the native proxy. Scalar header/query additions now use Python-compatible True/False/None spelling and status maps accept numeric strings. The unused Python TransformError and validate_transform_config helpers have no direct native call equivalents, and invalid HTTP header material is skipped at the typed HeaderMap boundary.", + "rust_symbols": [ + "gateway-rs/src/gateway/transforms.rs::transform_request", + "gateway-rs/src/gateway/transforms.rs::transform_response", + "gateway-rs/src/gateway/transforms.rs::set_path", + "gateway-rs/src/gateway/transforms.rs::take_path" + ], + "rust_tests": [ + "gateway-rs/src/gateway/transforms.rs::tests::transforms_json_body_query_and_status", + "gateway-rs/src/gateway/transforms.rs::tests::transforms_array_paths_like_the_python_gateway" + ], + "source": { + "kind": "function", + "line": 143, + "path": "backend-services/utils/transform_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/transform_util.py::function:transform_headers", + "notes": "Rust preserves request/response header, JSON body, array JSONPath, query, wrap/remove/rename/set, and status transformations in the native proxy. Scalar header/query additions now use Python-compatible True/False/None spelling and status maps accept numeric strings. The unused Python TransformError and validate_transform_config helpers have no direct native call equivalents, and invalid HTTP header material is skipped at the typed HeaderMap boundary.", + "rust_symbols": [ + "gateway-rs/src/gateway/transforms.rs::transform_request", + "gateway-rs/src/gateway/transforms.rs::transform_response", + "gateway-rs/src/gateway/transforms.rs::set_path", + "gateway-rs/src/gateway/transforms.rs::take_path" + ], + "rust_tests": [ + "gateway-rs/src/gateway/transforms.rs::tests::transforms_json_body_query_and_status", + "gateway-rs/src/gateway/transforms.rs::tests::transforms_array_paths_like_the_python_gateway" + ], + "source": { + "kind": "function", + "line": 198, + "path": "backend-services/utils/transform_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/transform_util.py::function:transform_body", + "notes": "Rust preserves request/response header, JSON body, array JSONPath, query, wrap/remove/rename/set, and status transformations in the native proxy. Scalar header/query additions now use Python-compatible True/False/None spelling and status maps accept numeric strings. The unused Python TransformError and validate_transform_config helpers have no direct native call equivalents, and invalid HTTP header material is skipped at the typed HeaderMap boundary.", + "rust_symbols": [ + "gateway-rs/src/gateway/transforms.rs::transform_request", + "gateway-rs/src/gateway/transforms.rs::transform_response", + "gateway-rs/src/gateway/transforms.rs::set_path", + "gateway-rs/src/gateway/transforms.rs::take_path" + ], + "rust_tests": [ + "gateway-rs/src/gateway/transforms.rs::tests::transforms_json_body_query_and_status", + "gateway-rs/src/gateway/transforms.rs::tests::transforms_array_paths_like_the_python_gateway" + ], + "source": { + "kind": "function", + "line": 248, + "path": "backend-services/utils/transform_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/transform_util.py::function:transform_query_params", + "notes": "Rust preserves request/response header, JSON body, array JSONPath, query, wrap/remove/rename/set, and status transformations in the native proxy. Scalar header/query additions now use Python-compatible True/False/None spelling and status maps accept numeric strings. The unused Python TransformError and validate_transform_config helpers have no direct native call equivalents, and invalid HTTP header material is skipped at the typed HeaderMap boundary.", + "rust_symbols": [ + "gateway-rs/src/gateway/transforms.rs::transform_request", + "gateway-rs/src/gateway/transforms.rs::transform_response", + "gateway-rs/src/gateway/transforms.rs::set_path", + "gateway-rs/src/gateway/transforms.rs::take_path" + ], + "rust_tests": [ + "gateway-rs/src/gateway/transforms.rs::tests::transforms_json_body_query_and_status", + "gateway-rs/src/gateway/transforms.rs::tests::transforms_array_paths_like_the_python_gateway" + ], + "source": { + "kind": "function", + "line": 315, + "path": "backend-services/utils/transform_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/transform_util.py::function:map_status_code", + "notes": "Rust preserves request/response header, JSON body, array JSONPath, query, wrap/remove/rename/set, and status transformations in the native proxy. Scalar header/query additions now use Python-compatible True/False/None spelling and status maps accept numeric strings. The unused Python TransformError and validate_transform_config helpers have no direct native call equivalents, and invalid HTTP header material is skipped at the typed HeaderMap boundary.", + "rust_symbols": [ + "gateway-rs/src/gateway/transforms.rs::transform_request", + "gateway-rs/src/gateway/transforms.rs::transform_response", + "gateway-rs/src/gateway/transforms.rs::set_path", + "gateway-rs/src/gateway/transforms.rs::take_path" + ], + "rust_tests": [ + "gateway-rs/src/gateway/transforms.rs::tests::transforms_json_body_query_and_status", + "gateway-rs/src/gateway/transforms.rs::tests::transforms_array_paths_like_the_python_gateway" + ], + "source": { + "kind": "function", + "line": 360, + "path": "backend-services/utils/transform_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/transform_util.py::async_function:apply_request_transforms", + "notes": "Rust preserves request/response header, JSON body, array JSONPath, query, wrap/remove/rename/set, and status transformations in the native proxy. Scalar header/query additions now use Python-compatible True/False/None spelling and status maps accept numeric strings. The unused Python TransformError and validate_transform_config helpers have no direct native call equivalents, and invalid HTTP header material is skipped at the typed HeaderMap boundary.", + "rust_symbols": [ + "gateway-rs/src/gateway/transforms.rs::transform_request", + "gateway-rs/src/gateway/transforms.rs::transform_response", + "gateway-rs/src/gateway/transforms.rs::set_path", + "gateway-rs/src/gateway/transforms.rs::take_path" + ], + "rust_tests": [ + "gateway-rs/src/gateway/transforms.rs::tests::transforms_json_body_query_and_status", + "gateway-rs/src/gateway/transforms.rs::tests::transforms_array_paths_like_the_python_gateway" + ], + "source": { + "kind": "async_function", + "line": 395, + "path": "backend-services/utils/transform_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/transform_util.py::async_function:apply_response_transforms", + "notes": "Rust preserves request/response header, JSON body, array JSONPath, query, wrap/remove/rename/set, and status transformations in the native proxy. Scalar header/query additions now use Python-compatible True/False/None spelling and status maps accept numeric strings. The unused Python TransformError and validate_transform_config helpers have no direct native call equivalents, and invalid HTTP header material is skipped at the typed HeaderMap boundary.", + "rust_symbols": [ + "gateway-rs/src/gateway/transforms.rs::transform_request", + "gateway-rs/src/gateway/transforms.rs::transform_response", + "gateway-rs/src/gateway/transforms.rs::set_path", + "gateway-rs/src/gateway/transforms.rs::take_path" + ], + "rust_tests": [ + "gateway-rs/src/gateway/transforms.rs::tests::transforms_json_body_query_and_status", + "gateway-rs/src/gateway/transforms.rs::tests::transforms_array_paths_like_the_python_gateway" + ], + "source": { + "kind": "async_function", + "line": 429, + "path": "backend-services/utils/transform_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/transform_util.py::function:validate_transform_config", + "notes": "Rust preserves request/response header, JSON body, array JSONPath, query, wrap/remove/rename/set, and status transformations in the native proxy. Scalar header/query additions now use Python-compatible True/False/None spelling and status maps accept numeric strings. The unused Python TransformError and validate_transform_config helpers have no direct native call equivalents, and invalid HTTP header material is skipped at the typed HeaderMap boundary.", + "rust_symbols": [ + "gateway-rs/src/gateway/transforms.rs::transform_request", + "gateway-rs/src/gateway/transforms.rs::transform_response", + "gateway-rs/src/gateway/transforms.rs::set_path", + "gateway-rs/src/gateway/transforms.rs::take_path" + ], + "rust_tests": [ + "gateway-rs/src/gateway/transforms.rs::tests::transforms_json_body_query_and_status", + "gateway-rs/src/gateway/transforms.rs::tests::transforms_array_paths_like_the_python_gateway" + ], + "source": { + "kind": "function", + "line": 463, + "path": "backend-services/utils/transform_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/validation_util.py::module:validation_util", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "rust_symbols": [ + "gateway-rs/src/validation/json.rs::validate_json_with_registry", + "gateway-rs/src/validation/json.rs::ValidatorRegistry", + "gateway-rs/src/validation/xml.rs::soap_body_object", + "gateway-rs/src/routes/rest.rs::validate_protocol_request_with_registry", + "gateway-rs/src/routes/rest.rs::graphql_validation_schema" + ], + "rust_tests": [ + "gateway-rs/src/validation/json.rs::tests::preserves_python_validation_messages_and_coercion_edges", + "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", + "gateway-rs/src/validation/xml.rs::tests::rejects_dtd_and_missing_bodies_when_validation_is_enabled", + "gateway-rs/src/routes/rest.rs::tests::scopes_graphql_validation_to_the_named_operation" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/validation_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/validation_util.py::class:ValidationError", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "rust_symbols": [ + "gateway-rs/src/validation/json.rs::validate_json_with_registry", + "gateway-rs/src/validation/json.rs::ValidatorRegistry", + "gateway-rs/src/validation/xml.rs::soap_body_object", + "gateway-rs/src/routes/rest.rs::validate_protocol_request_with_registry", + "gateway-rs/src/routes/rest.rs::graphql_validation_schema" + ], + "rust_tests": [ + "gateway-rs/src/validation/json.rs::tests::preserves_python_validation_messages_and_coercion_edges", + "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", + "gateway-rs/src/validation/xml.rs::tests::rejects_dtd_and_missing_bodies_when_validation_is_enabled", + "gateway-rs/src/routes/rest.rs::tests::scopes_graphql_validation_to_the_named_operation" + ], + "source": { + "kind": "class", + "line": 33, + "path": "backend-services/utils/validation_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/validation_util.py::method:ValidationError.__init__", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "rust_symbols": [ + "gateway-rs/src/validation/json.rs::validate_json_with_registry", + "gateway-rs/src/validation/json.rs::ValidatorRegistry", + "gateway-rs/src/validation/xml.rs::soap_body_object", + "gateway-rs/src/routes/rest.rs::validate_protocol_request_with_registry", + "gateway-rs/src/routes/rest.rs::graphql_validation_schema" + ], + "rust_tests": [ + "gateway-rs/src/validation/json.rs::tests::preserves_python_validation_messages_and_coercion_edges", + "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", + "gateway-rs/src/validation/xml.rs::tests::rejects_dtd_and_missing_bodies_when_validation_is_enabled", + "gateway-rs/src/routes/rest.rs::tests::scopes_graphql_validation_to_the_named_operation" + ], + "source": { + "kind": "method", + "line": 34, + "path": "backend-services/utils/validation_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/validation_util.py::class:ValidationUtil", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "rust_symbols": [ + "gateway-rs/src/validation/json.rs::validate_json_with_registry", + "gateway-rs/src/validation/json.rs::ValidatorRegistry", + "gateway-rs/src/validation/xml.rs::soap_body_object", + "gateway-rs/src/routes/rest.rs::validate_protocol_request_with_registry", + "gateway-rs/src/routes/rest.rs::graphql_validation_schema" + ], + "rust_tests": [ + "gateway-rs/src/validation/json.rs::tests::preserves_python_validation_messages_and_coercion_edges", + "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", + "gateway-rs/src/validation/xml.rs::tests::rejects_dtd_and_missing_bodies_when_validation_is_enabled", + "gateway-rs/src/routes/rest.rs::tests::scopes_graphql_validation_to_the_named_operation" + ], + "source": { + "kind": "class", + "line": 40, + "path": "backend-services/utils/validation_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/validation_util.py::method:ValidationUtil.__init__", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "rust_symbols": [ + "gateway-rs/src/validation/json.rs::validate_json_with_registry", + "gateway-rs/src/validation/json.rs::ValidatorRegistry", + "gateway-rs/src/validation/xml.rs::soap_body_object", + "gateway-rs/src/routes/rest.rs::validate_protocol_request_with_registry", + "gateway-rs/src/routes/rest.rs::graphql_validation_schema" + ], + "rust_tests": [ + "gateway-rs/src/validation/json.rs::tests::preserves_python_validation_messages_and_coercion_edges", + "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", + "gateway-rs/src/validation/xml.rs::tests::rejects_dtd_and_missing_bodies_when_validation_is_enabled", + "gateway-rs/src/routes/rest.rs::tests::scopes_graphql_validation_to_the_named_operation" + ], + "source": { + "kind": "method", + "line": 41, + "path": "backend-services/utils/validation_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/validation_util.py::method:ValidationUtil._reject_unsafe_xml", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "rust_symbols": [ + "gateway-rs/src/validation/json.rs::validate_json_with_registry", + "gateway-rs/src/validation/json.rs::ValidatorRegistry", + "gateway-rs/src/validation/xml.rs::soap_body_object", + "gateway-rs/src/routes/rest.rs::validate_protocol_request_with_registry", + "gateway-rs/src/routes/rest.rs::graphql_validation_schema" + ], + "rust_tests": [ + "gateway-rs/src/validation/json.rs::tests::preserves_python_validation_messages_and_coercion_edges", + "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", + "gateway-rs/src/validation/xml.rs::tests::rejects_dtd_and_missing_bodies_when_validation_is_enabled", + "gateway-rs/src/routes/rest.rs::tests::scopes_graphql_validation_to_the_named_operation" + ], + "source": { + "kind": "method", + "line": 59, + "path": "backend-services/utils/validation_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/validation_util.py::method:ValidationUtil.register_custom_validator", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "rust_symbols": [ + "gateway-rs/src/validation/json.rs::validate_json_with_registry", + "gateway-rs/src/validation/json.rs::ValidatorRegistry", + "gateway-rs/src/validation/xml.rs::soap_body_object", + "gateway-rs/src/routes/rest.rs::validate_protocol_request_with_registry", + "gateway-rs/src/routes/rest.rs::graphql_validation_schema" + ], + "rust_tests": [ + "gateway-rs/src/validation/json.rs::tests::preserves_python_validation_messages_and_coercion_edges", + "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", + "gateway-rs/src/validation/xml.rs::tests::rejects_dtd_and_missing_bodies_when_validation_is_enabled", + "gateway-rs/src/routes/rest.rs::tests::scopes_graphql_validation_to_the_named_operation" + ], + "source": { + "kind": "method", + "line": 71, + "path": "backend-services/utils/validation_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/validation_util.py::async_method:ValidationUtil.get_validation_schema", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "rust_symbols": [ + "gateway-rs/src/validation/json.rs::validate_json_with_registry", + "gateway-rs/src/validation/json.rs::ValidatorRegistry", + "gateway-rs/src/validation/xml.rs::soap_body_object", + "gateway-rs/src/routes/rest.rs::validate_protocol_request_with_registry", + "gateway-rs/src/routes/rest.rs::graphql_validation_schema" + ], + "rust_tests": [ + "gateway-rs/src/validation/json.rs::tests::preserves_python_validation_messages_and_coercion_edges", + "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", + "gateway-rs/src/validation/xml.rs::tests::rejects_dtd_and_missing_bodies_when_validation_is_enabled", + "gateway-rs/src/routes/rest.rs::tests::scopes_graphql_validation_to_the_named_operation" + ], + "source": { + "kind": "async_method", + "line": 76, + "path": "backend-services/utils/validation_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/validation_util.py::method:ValidationUtil._validate_schema_paths", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "rust_symbols": [ + "gateway-rs/src/validation/json.rs::validate_json_with_registry", + "gateway-rs/src/validation/json.rs::ValidatorRegistry", + "gateway-rs/src/validation/xml.rs::soap_body_object", + "gateway-rs/src/routes/rest.rs::validate_protocol_request_with_registry", + "gateway-rs/src/routes/rest.rs::graphql_validation_schema" + ], + "rust_tests": [ + "gateway-rs/src/validation/json.rs::tests::preserves_python_validation_messages_and_coercion_edges", + "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", + "gateway-rs/src/validation/xml.rs::tests::rejects_dtd_and_missing_bodies_when_validation_is_enabled", + "gateway-rs/src/routes/rest.rs::tests::scopes_graphql_validation_to_the_named_operation" + ], + "source": { + "kind": "method", + "line": 115, + "path": "backend-services/utils/validation_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/validation_util.py::method:ValidationUtil._is_valid_field_path", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "rust_symbols": [ + "gateway-rs/src/validation/json.rs::validate_json_with_registry", + "gateway-rs/src/validation/json.rs::ValidatorRegistry", + "gateway-rs/src/validation/xml.rs::soap_body_object", + "gateway-rs/src/routes/rest.rs::validate_protocol_request_with_registry", + "gateway-rs/src/routes/rest.rs::graphql_validation_schema" + ], + "rust_tests": [ + "gateway-rs/src/validation/json.rs::tests::preserves_python_validation_messages_and_coercion_edges", + "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", + "gateway-rs/src/validation/xml.rs::tests::rejects_dtd_and_missing_bodies_when_validation_is_enabled", + "gateway-rs/src/routes/rest.rs::tests::scopes_graphql_validation_to_the_named_operation" + ], + "source": { + "kind": "method", + "line": 125, + "path": "backend-services/utils/validation_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/validation_util.py::method:ValidationUtil._validate_string", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "rust_symbols": [ + "gateway-rs/src/validation/json.rs::validate_json_with_registry", + "gateway-rs/src/validation/json.rs::ValidatorRegistry", + "gateway-rs/src/validation/xml.rs::soap_body_object", + "gateway-rs/src/routes/rest.rs::validate_protocol_request_with_registry", + "gateway-rs/src/routes/rest.rs::graphql_validation_schema" + ], + "rust_tests": [ + "gateway-rs/src/validation/json.rs::tests::preserves_python_validation_messages_and_coercion_edges", + "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", + "gateway-rs/src/validation/xml.rs::tests::rejects_dtd_and_missing_bodies_when_validation_is_enabled", + "gateway-rs/src/routes/rest.rs::tests::scopes_graphql_validation_to_the_named_operation" + ], + "source": { + "kind": "method", + "line": 136, + "path": "backend-services/utils/validation_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/validation_util.py::method:ValidationUtil._validate_number", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "rust_symbols": [ + "gateway-rs/src/validation/json.rs::validate_json_with_registry", + "gateway-rs/src/validation/json.rs::ValidatorRegistry", + "gateway-rs/src/validation/xml.rs::soap_body_object", + "gateway-rs/src/routes/rest.rs::validate_protocol_request_with_registry", + "gateway-rs/src/routes/rest.rs::graphql_validation_schema" + ], + "rust_tests": [ + "gateway-rs/src/validation/json.rs::tests::preserves_python_validation_messages_and_coercion_edges", + "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", + "gateway-rs/src/validation/xml.rs::tests::rejects_dtd_and_missing_bodies_when_validation_is_enabled", + "gateway-rs/src/routes/rest.rs::tests::scopes_graphql_validation_to_the_named_operation" + ], + "source": { + "kind": "method", + "line": 148, + "path": "backend-services/utils/validation_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/validation_util.py::method:ValidationUtil._validate_boolean", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "rust_symbols": [ + "gateway-rs/src/validation/json.rs::validate_json_with_registry", + "gateway-rs/src/validation/json.rs::ValidatorRegistry", + "gateway-rs/src/validation/xml.rs::soap_body_object", + "gateway-rs/src/routes/rest.rs::validate_protocol_request_with_registry", + "gateway-rs/src/routes/rest.rs::graphql_validation_schema" + ], + "rust_tests": [ + "gateway-rs/src/validation/json.rs::tests::preserves_python_validation_messages_and_coercion_edges", + "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", + "gateway-rs/src/validation/xml.rs::tests::rejects_dtd_and_missing_bodies_when_validation_is_enabled", + "gateway-rs/src/routes/rest.rs::tests::scopes_graphql_validation_to_the_named_operation" + ], + "source": { + "kind": "method", + "line": 156, + "path": "backend-services/utils/validation_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/validation_util.py::method:ValidationUtil._validate_array", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "rust_symbols": [ + "gateway-rs/src/validation/json.rs::validate_json_with_registry", + "gateway-rs/src/validation/json.rs::ValidatorRegistry", + "gateway-rs/src/validation/xml.rs::soap_body_object", + "gateway-rs/src/routes/rest.rs::validate_protocol_request_with_registry", + "gateway-rs/src/routes/rest.rs::graphql_validation_schema" + ], + "rust_tests": [ + "gateway-rs/src/validation/json.rs::tests::preserves_python_validation_messages_and_coercion_edges", + "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", + "gateway-rs/src/validation/xml.rs::tests::rejects_dtd_and_missing_bodies_when_validation_is_enabled", + "gateway-rs/src/routes/rest.rs::tests::scopes_graphql_validation_to_the_named_operation" + ], + "source": { + "kind": "method", + "line": 160, + "path": "backend-services/utils/validation_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/validation_util.py::method:ValidationUtil._validate_object", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "rust_symbols": [ + "gateway-rs/src/validation/json.rs::validate_json_with_registry", + "gateway-rs/src/validation/json.rs::ValidatorRegistry", + "gateway-rs/src/validation/xml.rs::soap_body_object", + "gateway-rs/src/routes/rest.rs::validate_protocol_request_with_registry", + "gateway-rs/src/routes/rest.rs::graphql_validation_schema" + ], + "rust_tests": [ + "gateway-rs/src/validation/json.rs::tests::preserves_python_validation_messages_and_coercion_edges", + "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", + "gateway-rs/src/validation/xml.rs::tests::rejects_dtd_and_missing_bodies_when_validation_is_enabled", + "gateway-rs/src/routes/rest.rs::tests::scopes_graphql_validation_to_the_named_operation" + ], + "source": { + "kind": "method", + "line": 171, + "path": "backend-services/utils/validation_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/validation_util.py::method:ValidationUtil._validate_value", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "rust_symbols": [ + "gateway-rs/src/validation/json.rs::validate_json_with_registry", + "gateway-rs/src/validation/json.rs::ValidatorRegistry", + "gateway-rs/src/validation/xml.rs::soap_body_object", + "gateway-rs/src/routes/rest.rs::validate_protocol_request_with_registry", + "gateway-rs/src/routes/rest.rs::graphql_validation_schema" + ], + "rust_tests": [ + "gateway-rs/src/validation/json.rs::tests::preserves_python_validation_messages_and_coercion_edges", + "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", + "gateway-rs/src/validation/xml.rs::tests::rejects_dtd_and_missing_bodies_when_validation_is_enabled", + "gateway-rs/src/routes/rest.rs::tests::scopes_graphql_validation_to_the_named_operation" + ], + "source": { + "kind": "method", + "line": 183, + "path": "backend-services/utils/validation_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/validation_util.py::method:ValidationUtil._validate_email", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "rust_symbols": [ + "gateway-rs/src/validation/json.rs::validate_json_with_registry", + "gateway-rs/src/validation/json.rs::ValidatorRegistry", + "gateway-rs/src/validation/xml.rs::soap_body_object", + "gateway-rs/src/routes/rest.rs::validate_protocol_request_with_registry", + "gateway-rs/src/routes/rest.rs::graphql_validation_schema" + ], + "rust_tests": [ + "gateway-rs/src/validation/json.rs::tests::preserves_python_validation_messages_and_coercion_edges", + "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", + "gateway-rs/src/validation/xml.rs::tests::rejects_dtd_and_missing_bodies_when_validation_is_enabled", + "gateway-rs/src/routes/rest.rs::tests::scopes_graphql_validation_to_the_named_operation" + ], + "source": { + "kind": "method", + "line": 198, + "path": "backend-services/utils/validation_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/validation_util.py::method:ValidationUtil._validate_url", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "rust_symbols": [ + "gateway-rs/src/validation/json.rs::validate_json_with_registry", + "gateway-rs/src/validation/json.rs::ValidatorRegistry", + "gateway-rs/src/validation/xml.rs::soap_body_object", + "gateway-rs/src/routes/rest.rs::validate_protocol_request_with_registry", + "gateway-rs/src/routes/rest.rs::graphql_validation_schema" + ], + "rust_tests": [ + "gateway-rs/src/validation/json.rs::tests::preserves_python_validation_messages_and_coercion_edges", + "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", + "gateway-rs/src/validation/xml.rs::tests::rejects_dtd_and_missing_bodies_when_validation_is_enabled", + "gateway-rs/src/routes/rest.rs::tests::scopes_graphql_validation_to_the_named_operation" + ], + "source": { + "kind": "method", + "line": 203, + "path": "backend-services/utils/validation_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/validation_util.py::method:ValidationUtil._validate_date", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "rust_symbols": [ + "gateway-rs/src/validation/json.rs::validate_json_with_registry", + "gateway-rs/src/validation/json.rs::ValidatorRegistry", + "gateway-rs/src/validation/xml.rs::soap_body_object", + "gateway-rs/src/routes/rest.rs::validate_protocol_request_with_registry", + "gateway-rs/src/routes/rest.rs::graphql_validation_schema" + ], + "rust_tests": [ + "gateway-rs/src/validation/json.rs::tests::preserves_python_validation_messages_and_coercion_edges", + "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", + "gateway-rs/src/validation/xml.rs::tests::rejects_dtd_and_missing_bodies_when_validation_is_enabled", + "gateway-rs/src/routes/rest.rs::tests::scopes_graphql_validation_to_the_named_operation" + ], + "source": { + "kind": "method", + "line": 211, + "path": "backend-services/utils/validation_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/validation_util.py::method:ValidationUtil._validate_datetime", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "rust_symbols": [ + "gateway-rs/src/validation/json.rs::validate_json_with_registry", + "gateway-rs/src/validation/json.rs::ValidatorRegistry", + "gateway-rs/src/validation/xml.rs::soap_body_object", + "gateway-rs/src/routes/rest.rs::validate_protocol_request_with_registry", + "gateway-rs/src/routes/rest.rs::graphql_validation_schema" + ], + "rust_tests": [ + "gateway-rs/src/validation/json.rs::tests::preserves_python_validation_messages_and_coercion_edges", + "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", + "gateway-rs/src/validation/xml.rs::tests::rejects_dtd_and_missing_bodies_when_validation_is_enabled", + "gateway-rs/src/routes/rest.rs::tests::scopes_graphql_validation_to_the_named_operation" + ], + "source": { + "kind": "method", + "line": 217, + "path": "backend-services/utils/validation_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/validation_util.py::method:ValidationUtil._validate_uuid", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "rust_symbols": [ + "gateway-rs/src/validation/json.rs::validate_json_with_registry", + "gateway-rs/src/validation/json.rs::ValidatorRegistry", + "gateway-rs/src/validation/xml.rs::soap_body_object", + "gateway-rs/src/routes/rest.rs::validate_protocol_request_with_registry", + "gateway-rs/src/routes/rest.rs::graphql_validation_schema" + ], + "rust_tests": [ + "gateway-rs/src/validation/json.rs::tests::preserves_python_validation_messages_and_coercion_edges", + "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", + "gateway-rs/src/validation/xml.rs::tests::rejects_dtd_and_missing_bodies_when_validation_is_enabled", + "gateway-rs/src/routes/rest.rs::tests::scopes_graphql_validation_to_the_named_operation" + ], + "source": { + "kind": "method", + "line": 223, + "path": "backend-services/utils/validation_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/validation_util.py::async_method:ValidationUtil.validate_rest_request", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "rust_symbols": [ + "gateway-rs/src/validation/json.rs::validate_json_with_registry", + "gateway-rs/src/validation/json.rs::ValidatorRegistry", + "gateway-rs/src/validation/xml.rs::soap_body_object", + "gateway-rs/src/routes/rest.rs::validate_protocol_request_with_registry", + "gateway-rs/src/routes/rest.rs::graphql_validation_schema" + ], + "rust_tests": [ + "gateway-rs/src/validation/json.rs::tests::preserves_python_validation_messages_and_coercion_edges", + "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", + "gateway-rs/src/validation/xml.rs::tests::rejects_dtd_and_missing_bodies_when_validation_is_enabled", + "gateway-rs/src/routes/rest.rs::tests::scopes_graphql_validation_to_the_named_operation" + ], + "source": { + "kind": "async_method", + "line": 229, + "path": "backend-services/utils/validation_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/validation_util.py::async_method:ValidationUtil.validate_soap_request", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "rust_symbols": [ + "gateway-rs/src/validation/json.rs::validate_json_with_registry", + "gateway-rs/src/validation/json.rs::ValidatorRegistry", + "gateway-rs/src/validation/xml.rs::soap_body_object", + "gateway-rs/src/routes/rest.rs::validate_protocol_request_with_registry", + "gateway-rs/src/routes/rest.rs::graphql_validation_schema" + ], + "rust_tests": [ + "gateway-rs/src/validation/json.rs::tests::preserves_python_validation_messages_and_coercion_edges", + "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", + "gateway-rs/src/validation/xml.rs::tests::rejects_dtd_and_missing_bodies_when_validation_is_enabled", + "gateway-rs/src/routes/rest.rs::tests::scopes_graphql_validation_to_the_named_operation" + ], + "source": { + "kind": "async_method", + "line": 245, + "path": "backend-services/utils/validation_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/validation_util.py::async_method:ValidationUtil.validate_grpc_request", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "rust_symbols": [ + "gateway-rs/src/validation/json.rs::validate_json_with_registry", + "gateway-rs/src/validation/json.rs::ValidatorRegistry", + "gateway-rs/src/validation/xml.rs::soap_body_object", + "gateway-rs/src/routes/rest.rs::validate_protocol_request_with_registry", + "gateway-rs/src/routes/rest.rs::graphql_validation_schema" + ], + "rust_tests": [ + "gateway-rs/src/validation/json.rs::tests::preserves_python_validation_messages_and_coercion_edges", + "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", + "gateway-rs/src/validation/xml.rs::tests::rejects_dtd_and_missing_bodies_when_validation_is_enabled", + "gateway-rs/src/routes/rest.rs::tests::scopes_graphql_validation_to_the_named_operation" + ], + "source": { + "kind": "async_method", + "line": 265, + "path": "backend-services/utils/validation_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/validation_util.py::async_method:ValidationUtil.validate_graphql_request", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "rust_symbols": [ + "gateway-rs/src/validation/json.rs::validate_json_with_registry", + "gateway-rs/src/validation/json.rs::ValidatorRegistry", + "gateway-rs/src/validation/xml.rs::soap_body_object", + "gateway-rs/src/routes/rest.rs::validate_protocol_request_with_registry", + "gateway-rs/src/routes/rest.rs::graphql_validation_schema" + ], + "rust_tests": [ + "gateway-rs/src/validation/json.rs::tests::preserves_python_validation_messages_and_coercion_edges", + "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", + "gateway-rs/src/validation/xml.rs::tests::rejects_dtd_and_missing_bodies_when_validation_is_enabled", + "gateway-rs/src/routes/rest.rs::tests::scopes_graphql_validation_to_the_named_operation" + ], + "source": { + "kind": "async_method", + "line": 277, + "path": "backend-services/utils/validation_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/validation_util.py::method:ValidationUtil._extract_operation_name", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "rust_symbols": [ + "gateway-rs/src/validation/json.rs::validate_json_with_registry", + "gateway-rs/src/validation/json.rs::ValidatorRegistry", + "gateway-rs/src/validation/xml.rs::soap_body_object", + "gateway-rs/src/routes/rest.rs::validate_protocol_request_with_registry", + "gateway-rs/src/routes/rest.rs::graphql_validation_schema" + ], + "rust_tests": [ + "gateway-rs/src/validation/json.rs::tests::preserves_python_validation_messages_and_coercion_edges", + "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", + "gateway-rs/src/validation/xml.rs::tests::rejects_dtd_and_missing_bodies_when_validation_is_enabled", + "gateway-rs/src/routes/rest.rs::tests::scopes_graphql_validation_to_the_named_operation" + ], + "source": { + "kind": "method", + "line": 301, + "path": "backend-services/utils/validation_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/validation_util.py::method:ValidationUtil._get_nested_value", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "rust_symbols": [ + "gateway-rs/src/validation/json.rs::validate_json_with_registry", + "gateway-rs/src/validation/json.rs::ValidatorRegistry", + "gateway-rs/src/validation/xml.rs::soap_body_object", + "gateway-rs/src/routes/rest.rs::validate_protocol_request_with_registry", + "gateway-rs/src/routes/rest.rs::graphql_validation_schema" + ], + "rust_tests": [ + "gateway-rs/src/validation/json.rs::tests::preserves_python_validation_messages_and_coercion_edges", + "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", + "gateway-rs/src/validation/xml.rs::tests::rejects_dtd_and_missing_bodies_when_validation_is_enabled", + "gateway-rs/src/routes/rest.rs::tests::scopes_graphql_validation_to_the_named_operation" + ], + "source": { + "kind": "method", + "line": 305, + "path": "backend-services/utils/validation_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/validation_util.py::method:ValidationUtil._strip_ns", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "rust_symbols": [ + "gateway-rs/src/validation/json.rs::validate_json_with_registry", + "gateway-rs/src/validation/json.rs::ValidatorRegistry", + "gateway-rs/src/validation/xml.rs::soap_body_object", + "gateway-rs/src/routes/rest.rs::validate_protocol_request_with_registry", + "gateway-rs/src/routes/rest.rs::graphql_validation_schema" + ], + "rust_tests": [ + "gateway-rs/src/validation/json.rs::tests::preserves_python_validation_messages_and_coercion_edges", + "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", + "gateway-rs/src/validation/xml.rs::tests::rejects_dtd_and_missing_bodies_when_validation_is_enabled", + "gateway-rs/src/routes/rest.rs::tests::scopes_graphql_validation_to_the_named_operation" + ], + "source": { + "kind": "method", + "line": 325, + "path": "backend-services/utils/validation_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/validation_util.py::method:ValidationUtil._xml_to_dict", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "rust_symbols": [ + "gateway-rs/src/validation/json.rs::validate_json_with_registry", + "gateway-rs/src/validation/json.rs::ValidatorRegistry", + "gateway-rs/src/validation/xml.rs::soap_body_object", + "gateway-rs/src/routes/rest.rs::validate_protocol_request_with_registry", + "gateway-rs/src/routes/rest.rs::graphql_validation_schema" + ], + "rust_tests": [ + "gateway-rs/src/validation/json.rs::tests::preserves_python_validation_messages_and_coercion_edges", + "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", + "gateway-rs/src/validation/xml.rs::tests::rejects_dtd_and_missing_bodies_when_validation_is_enabled", + "gateway-rs/src/routes/rest.rs::tests::scopes_graphql_validation_to_the_named_operation" + ], + "source": { + "kind": "method", + "line": 330, + "path": "backend-services/utils/validation_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/validation_util.py::method:ValidationUtil._protobuf_to_dict", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "rust_symbols": [ + "gateway-rs/src/validation/json.rs::validate_json_with_registry", + "gateway-rs/src/validation/json.rs::ValidatorRegistry", + "gateway-rs/src/validation/xml.rs::soap_body_object", + "gateway-rs/src/routes/rest.rs::validate_protocol_request_with_registry", + "gateway-rs/src/routes/rest.rs::graphql_validation_schema" + ], + "rust_tests": [ + "gateway-rs/src/validation/json.rs::tests::preserves_python_validation_messages_and_coercion_edges", + "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", + "gateway-rs/src/validation/xml.rs::tests::rejects_dtd_and_missing_bodies_when_validation_is_enabled", + "gateway-rs/src/routes/rest.rs::tests::scopes_graphql_validation_to_the_named_operation" + ], + "source": { + "kind": "method", + "line": 340, + "path": "backend-services/utils/validation_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/vault_encryption_util.py::module:vault_encryption_util", + "notes": "Rust derives the same PBKDF2-SHA256 Fernet key from email, username, and VAULT_KEY, emits v1: ciphertext, accepts prefixed or legacy unprefixed ciphertext, decrypts values, and reports configuration state. Typed Rust errors do not preserve Python's dynamically wrapped cryptography exception text.", + "rust_symbols": [ + "gateway-rs/src/storage/vault.rs::encrypt", + "gateway-rs/src/storage/vault.rs::decrypt", + "gateway-rs/src/storage/vault.rs::is_configured" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::vault_lifecycle_encrypts_at_rest_and_never_returns_the_secret" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/vault_encryption_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/vault_encryption_util.py::function:_derive_key_from_components", + "notes": "Rust derives the same PBKDF2-SHA256 Fernet key from email, username, and VAULT_KEY, emits v1: ciphertext, accepts prefixed or legacy unprefixed ciphertext, decrypts values, and reports configuration state. Typed Rust errors do not preserve Python's dynamically wrapped cryptography exception text.", + "rust_symbols": [ + "gateway-rs/src/storage/vault.rs::encrypt", + "gateway-rs/src/storage/vault.rs::decrypt", + "gateway-rs/src/storage/vault.rs::is_configured" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::vault_lifecycle_encrypts_at_rest_and_never_returns_the_secret" + ], + "source": { + "kind": "function", + "line": 20, + "path": "backend-services/utils/vault_encryption_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/vault_encryption_util.py::function:encrypt_vault_value", + "notes": "Rust derives the same PBKDF2-SHA256 Fernet key from email, username, and VAULT_KEY, emits v1: ciphertext, accepts prefixed or legacy unprefixed ciphertext, decrypts values, and reports configuration state. Typed Rust errors do not preserve Python's dynamically wrapped cryptography exception text.", + "rust_symbols": [ + "gateway-rs/src/storage/vault.rs::encrypt", + "gateway-rs/src/storage/vault.rs::decrypt", + "gateway-rs/src/storage/vault.rs::is_configured" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::vault_lifecycle_encrypts_at_rest_and_never_returns_the_secret" + ], + "source": { + "kind": "function", + "line": 52, + "path": "backend-services/utils/vault_encryption_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/vault_encryption_util.py::function:decrypt_vault_value", + "notes": "Rust derives the same PBKDF2-SHA256 Fernet key from email, username, and VAULT_KEY, emits v1: ciphertext, accepts prefixed or legacy unprefixed ciphertext, decrypts values, and reports configuration state. Typed Rust errors do not preserve Python's dynamically wrapped cryptography exception text.", + "rust_symbols": [ + "gateway-rs/src/storage/vault.rs::encrypt", + "gateway-rs/src/storage/vault.rs::decrypt", + "gateway-rs/src/storage/vault.rs::is_configured" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::vault_lifecycle_encrypts_at_rest_and_never_returns_the_secret" + ], + "source": { + "kind": "function", + "line": 90, + "path": "backend-services/utils/vault_encryption_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/vault_encryption_util.py::function:is_vault_configured", + "notes": "Rust derives the same PBKDF2-SHA256 Fernet key from email, username, and VAULT_KEY, emits v1: ciphertext, accepts prefixed or legacy unprefixed ciphertext, decrypts values, and reports configuration state. Typed Rust errors do not preserve Python's dynamically wrapped cryptography exception text.", + "rust_symbols": [ + "gateway-rs/src/storage/vault.rs::encrypt", + "gateway-rs/src/storage/vault.rs::decrypt", + "gateway-rs/src/storage/vault.rs::is_configured" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::vault_lifecycle_encrypts_at_rest_and_never_returns_the_secret" + ], + "source": { + "kind": "function", + "line": 132, + "path": "backend-services/utils/vault_encryption_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/wsdl_util.py::module:wsdl_util", + "notes": "Rust provides XXE/DTD-safe WSDL parsing and validation, service/namespace/operation/action/endpoint extraction, SOAP 1.1/1.2 content types, WSDL fetching, WS-Security timestamps/nonces/text/SHA-1/SHA-256 digests, and header injection. XML serialization whitespace/prefix choices and exact fetch/parser exception strings are not byte-identical.", + "rust_symbols": [ + "gateway-rs/src/routes/discovery.rs::parse_wsdl", + "gateway-rs/src/protocol/soap.rs::prepare_request", + "gateway-rs/src/routes/platform.rs::api_discovery_routes" + ], + "rust_tests": [ + "gateway-rs/src/routes/discovery.rs::tests::parses_wsdl_operations_and_rejects_doctypes", + "gateway-rs/tests/platform_native.rs::memory_mode_parses_and_imports_wsdl_without_an_external_service", + "gateway-rs/tests/live_tests_parity.rs::soap_content_types_and_retry_real_upstream_parity" + ], + "source": { + "kind": "module", + "line": 1, + "path": "backend-services/utils/wsdl_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/wsdl_util.py::function:_safe_parse_xml", + "notes": "Rust provides XXE/DTD-safe WSDL parsing and validation, service/namespace/operation/action/endpoint extraction, SOAP 1.1/1.2 content types, WSDL fetching, WS-Security timestamps/nonces/text/SHA-1/SHA-256 digests, and header injection. XML serialization whitespace/prefix choices and exact fetch/parser exception strings are not byte-identical.", + "rust_symbols": [ + "gateway-rs/src/routes/discovery.rs::parse_wsdl", + "gateway-rs/src/protocol/soap.rs::prepare_request", + "gateway-rs/src/routes/platform.rs::api_discovery_routes" + ], + "rust_tests": [ + "gateway-rs/src/routes/discovery.rs::tests::parses_wsdl_operations_and_rejects_doctypes", + "gateway-rs/tests/platform_native.rs::memory_mode_parses_and_imports_wsdl_without_an_external_service", + "gateway-rs/tests/live_tests_parity.rs::soap_content_types_and_retry_real_upstream_parity" + ], + "source": { + "kind": "function", + "line": 35, + "path": "backend-services/utils/wsdl_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/wsdl_util.py::function:detect_soap_version", + "notes": "Rust provides XXE/DTD-safe WSDL parsing and validation, service/namespace/operation/action/endpoint extraction, SOAP 1.1/1.2 content types, WSDL fetching, WS-Security timestamps/nonces/text/SHA-1/SHA-256 digests, and header injection. XML serialization whitespace/prefix choices and exact fetch/parser exception strings are not byte-identical.", + "rust_symbols": [ + "gateway-rs/src/routes/discovery.rs::parse_wsdl", + "gateway-rs/src/protocol/soap.rs::prepare_request", + "gateway-rs/src/routes/platform.rs::api_discovery_routes" + ], + "rust_tests": [ + "gateway-rs/src/routes/discovery.rs::tests::parses_wsdl_operations_and_rejects_doctypes", + "gateway-rs/tests/platform_native.rs::memory_mode_parses_and_imports_wsdl_without_an_external_service", + "gateway-rs/tests/live_tests_parity.rs::soap_content_types_and_retry_real_upstream_parity" + ], + "source": { + "kind": "function", + "line": 57, + "path": "backend-services/utils/wsdl_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/wsdl_util.py::function:get_content_type_for_version", + "notes": "Rust provides XXE/DTD-safe WSDL parsing and validation, service/namespace/operation/action/endpoint extraction, SOAP 1.1/1.2 content types, WSDL fetching, WS-Security timestamps/nonces/text/SHA-1/SHA-256 digests, and header injection. XML serialization whitespace/prefix choices and exact fetch/parser exception strings are not byte-identical.", + "rust_symbols": [ + "gateway-rs/src/routes/discovery.rs::parse_wsdl", + "gateway-rs/src/protocol/soap.rs::prepare_request", + "gateway-rs/src/routes/platform.rs::api_discovery_routes" + ], + "rust_tests": [ + "gateway-rs/src/routes/discovery.rs::tests::parses_wsdl_operations_and_rejects_doctypes", + "gateway-rs/tests/platform_native.rs::memory_mode_parses_and_imports_wsdl_without_an_external_service", + "gateway-rs/tests/live_tests_parity.rs::soap_content_types_and_retry_real_upstream_parity" + ], + "source": { + "kind": "function", + "line": 79, + "path": "backend-services/utils/wsdl_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/wsdl_util.py::async_function:fetch_wsdl", + "notes": "Rust provides XXE/DTD-safe WSDL parsing and validation, service/namespace/operation/action/endpoint extraction, SOAP 1.1/1.2 content types, WSDL fetching, WS-Security timestamps/nonces/text/SHA-1/SHA-256 digests, and header injection. XML serialization whitespace/prefix choices and exact fetch/parser exception strings are not byte-identical.", + "rust_symbols": [ + "gateway-rs/src/routes/discovery.rs::parse_wsdl", + "gateway-rs/src/protocol/soap.rs::prepare_request", + "gateway-rs/src/routes/platform.rs::api_discovery_routes" + ], + "rust_tests": [ + "gateway-rs/src/routes/discovery.rs::tests::parses_wsdl_operations_and_rejects_doctypes", + "gateway-rs/tests/platform_native.rs::memory_mode_parses_and_imports_wsdl_without_an_external_service", + "gateway-rs/tests/live_tests_parity.rs::soap_content_types_and_retry_real_upstream_parity" + ], + "source": { + "kind": "async_function", + "line": 98, + "path": "backend-services/utils/wsdl_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/wsdl_util.py::function:parse_wsdl", + "notes": "Rust provides XXE/DTD-safe WSDL parsing and validation, service/namespace/operation/action/endpoint extraction, SOAP 1.1/1.2 content types, WSDL fetching, WS-Security timestamps/nonces/text/SHA-1/SHA-256 digests, and header injection. XML serialization whitespace/prefix choices and exact fetch/parser exception strings are not byte-identical.", + "rust_symbols": [ + "gateway-rs/src/routes/discovery.rs::parse_wsdl", + "gateway-rs/src/protocol/soap.rs::prepare_request", + "gateway-rs/src/routes/platform.rs::api_discovery_routes" + ], + "rust_tests": [ + "gateway-rs/src/routes/discovery.rs::tests::parses_wsdl_operations_and_rejects_doctypes", + "gateway-rs/tests/platform_native.rs::memory_mode_parses_and_imports_wsdl_without_an_external_service", + "gateway-rs/tests/live_tests_parity.rs::soap_content_types_and_retry_real_upstream_parity" + ], + "source": { + "kind": "function", + "line": 121, + "path": "backend-services/utils/wsdl_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/wsdl_util.py::function:create_ws_security_header", + "notes": "Rust provides XXE/DTD-safe WSDL parsing and validation, service/namespace/operation/action/endpoint extraction, SOAP 1.1/1.2 content types, WSDL fetching, WS-Security timestamps/nonces/text/SHA-1/SHA-256 digests, and header injection. XML serialization whitespace/prefix choices and exact fetch/parser exception strings are not byte-identical.", + "rust_symbols": [ + "gateway-rs/src/routes/discovery.rs::parse_wsdl", + "gateway-rs/src/protocol/soap.rs::prepare_request", + "gateway-rs/src/routes/platform.rs::api_discovery_routes" + ], + "rust_tests": [ + "gateway-rs/src/routes/discovery.rs::tests::parses_wsdl_operations_and_rejects_doctypes", + "gateway-rs/tests/platform_native.rs::memory_mode_parses_and_imports_wsdl_without_an_external_service", + "gateway-rs/tests/live_tests_parity.rs::soap_content_types_and_retry_real_upstream_parity" + ], + "source": { + "kind": "function", + "line": 236, + "path": "backend-services/utils/wsdl_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/wsdl_util.py::function:inject_ws_security", + "notes": "Rust provides XXE/DTD-safe WSDL parsing and validation, service/namespace/operation/action/endpoint extraction, SOAP 1.1/1.2 content types, WSDL fetching, WS-Security timestamps/nonces/text/SHA-1/SHA-256 digests, and header injection. XML serialization whitespace/prefix choices and exact fetch/parser exception strings are not byte-identical.", + "rust_symbols": [ + "gateway-rs/src/routes/discovery.rs::parse_wsdl", + "gateway-rs/src/protocol/soap.rs::prepare_request", + "gateway-rs/src/routes/platform.rs::api_discovery_routes" + ], + "rust_tests": [ + "gateway-rs/src/routes/discovery.rs::tests::parses_wsdl_operations_and_rejects_doctypes", + "gateway-rs/tests/platform_native.rs::memory_mode_parses_and_imports_wsdl_without_an_external_service", + "gateway-rs/tests/live_tests_parity.rs::soap_content_types_and_retry_real_upstream_parity" + ], + "source": { + "kind": "function", + "line": 322, + "path": "backend-services/utils/wsdl_util.py" + }, + "status": "partial" + }, + { + "decorators": [], + "domain": "utils", + "id": "backend-services/utils/wsdl_util.py::function:validate_wsdl_content", + "notes": "Rust provides XXE/DTD-safe WSDL parsing and validation, service/namespace/operation/action/endpoint extraction, SOAP 1.1/1.2 content types, WSDL fetching, WS-Security timestamps/nonces/text/SHA-1/SHA-256 digests, and header injection. XML serialization whitespace/prefix choices and exact fetch/parser exception strings are not byte-identical.", + "rust_symbols": [ + "gateway-rs/src/routes/discovery.rs::parse_wsdl", + "gateway-rs/src/protocol/soap.rs::prepare_request", + "gateway-rs/src/routes/platform.rs::api_discovery_routes" + ], + "rust_tests": [ + "gateway-rs/src/routes/discovery.rs::tests::parses_wsdl_operations_and_rejects_doctypes", + "gateway-rs/tests/platform_native.rs::memory_mode_parses_and_imports_wsdl_without_an_external_service", + "gateway-rs/tests/live_tests_parity.rs::soap_content_types_and_retry_real_upstream_parity" + ], + "source": { + "kind": "function", + "line": 366, + "path": "backend-services/utils/wsdl_util.py" + }, + "status": "partial" + } + ], + "generation": { + "command": "python3 scripts/generate_source_coverage_ledger.py --write", + "status_values": [ + "approved_changed", + "approved_obsolete", + "missing", + "partial", + "translated", + "unreviewed" + ] + }, + "reference": { + "commit": "10699820f50abe3940134536a98c955deab6959f", + "git_ref": "python-parity-reference" + }, + "schema_version": 1, + "summary": { + "domain_status_counts": { + "application": { + "approved_obsolete": 2, + "partial": 29, + "translated": 23 + }, + "middleware": { + "partial": 39, + "translated": 7 + }, + "models": { + "approved_obsolete": 94, + "partial": 262, + "translated": 337 + }, + "routes": { + "approved_changed": 4, + "partial": 355, + "translated": 54 + }, + "services": { + "partial": 104, + "translated": 82 + }, + "utils": { + "approved_obsolete": 65, + "partial": 554, + "translated": 289 + } + }, + "kind_counts": { + "async_function": 294, + "async_method": 164, + "class": 192, + "field": 929, + "function": 222, + "method": 354, + "module": 145 + }, + "reviewed_percent": 100.0, + "reviewed_source_units": 2300, + "status_counts": { + "approved_changed": 4, + "approved_obsolete": 161, + "partial": 1343, + "translated": 792 + }, + "total_source_units": 2300 + } +} diff --git a/parity/source_coverage_overrides.json b/parity/source_coverage_overrides.json new file mode 100644 index 00000000..4f8ec107 --- /dev/null +++ b/parity/source_coverage_overrides.json @@ -0,0 +1,2420 @@ +{ + "entries": { + "backend-services/doorman.py::function:_migrate_generated_directory": { + "notes": "Rust owns the root-level generated/ directory directly and does not use backend-services/generated as its canonical destination.", + "rationale": "Python-only directory-layout migration is obsolete after removal of the Python backend runtime.", + "rust_symbols": [], "rust_tests": [], "status": "approved_obsolete" + }, + "backend-services/doorman.py::async_function:validate_database_connections": { + "notes": "Rust establishes and validates configured shared storage before binding its listener.", + "rust_symbols": ["gateway-rs/src/storage/runtime.rs::SharedStorage.connect", "gateway-rs/src/main.rs::main"], + "rust_tests": ["gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart"], + "status": "translated" + }, + "backend-services/doorman.py::function:validate_token_revocation_config": { + "notes": "Rust fails configuration when memory storage is combined with multiple workers and validates JWT storage requirements before startup.", + "rust_symbols": ["gateway-rs/src/config.rs::validate_runtime_environment"], + "rust_tests": ["gateway-rs/src/config.rs::tests::memory_mode_rejects_multiple_workers"], + "status": "translated" + }, + "backend-services/doorman.py::function:_generate_unique_id": { + "notes": "The pinned Python operation IDs are served unchanged from the frozen platform OpenAPI document.", + "rust_symbols": ["gateway-rs/src/routes/platform.rs::platform_openapi"], + "rust_tests": ["gateway-rs/tests/openapi_parity.rs::pinned_openapi_operation_ids_are_stable_and_lowercase"], + "status": "translated" + }, + "backend-services/doorman.py::async_function:forwarded_proto_middleware": { + "notes": "The Rust router does not issue FastAPI scheme-derived trailing-slash redirects, so mutating the ASGI request scheme has no Rust runtime role.", + "rationale": "Framework-specific redirect workaround made obsolete by Axum routing.", + "rust_symbols": [], "rust_tests": [], "status": "approved_obsolete" + }, + "backend-services/doorman.py::function:_platform_cors_config": { + "notes": "Rust preserves the environment-derived origin, method, header, credential, and strict-mode defaults.", + "rust_symbols": ["gateway-rs/src/middleware/platform_cors.rs"], + "rust_tests": ["gateway-rs/src/middleware/platform_cors.rs::tests::platform_cors_wildcard_origin_with_credentials_non_strict_echoes_origin"], + "status": "translated" + }, + "backend-services/doorman.py::async_function:platform_cors": { + "notes": "Rust preserves platform preflight and actual-response CORS behavior, including strict wildcard handling and Vary replacement.", + "rust_symbols": ["gateway-rs/src/middleware/platform_cors.rs::platform_cors"], + "rust_tests": ["gateway-rs/src/middleware/platform_cors.rs::tests::platform_cors_actual_response_sets_vary_origin", "gateway-rs/tests/live_tests_parity.rs::live_platform_cors_default_preflight_parity"], + "status": "translated" + }, + "backend-services/doorman.py::function:_get_max_body_size": { + "notes": "Rust reads the same global and protocol-specific body-limit environment variables with the Python default.", + "rust_symbols": ["gateway-rs/src/middleware/body_limit.rs::BodyLimits.from_env"], + "rust_tests": ["gateway-rs/tests/runtime.rs::protocol_body_limits_match_python"], + "status": "translated" + }, + "backend-services/doorman.py::class:LimitedStreamReader": { + "notes": "Axum's bounded body collection enforces the accumulated streaming limit without an ASGI receive wrapper.", + "rust_symbols": ["gateway-rs/src/routes/platform.rs::platform_dispatch"], + "rust_tests": ["gateway-rs/tests/platform_native.rs::platform_body_limit_uses_runtime_environment"], + "status": "translated" + }, + "backend-services/doorman.py::method:LimitedStreamReader.__init__": { + "notes": "The bound is carried directly into Axum body collection.", + "rust_symbols": ["gateway-rs/src/middleware/body_limit.rs::BodyLimits"], + "rust_tests": ["gateway-rs/tests/runtime.rs::protocol_body_limits_match_python"], + "status": "translated" + }, + "backend-services/doorman.py::async_method:LimitedStreamReader.__call__": { + "notes": "Axum's bounded body collector rejects cumulative streamed bytes above the selected limit.", + "rust_symbols": ["gateway-rs/src/routes/platform.rs::platform_dispatch"], + "rust_tests": ["gateway-rs/tests/platform_native.rs::platform_body_limit_uses_runtime_environment"], + "status": "translated" + }, + "backend-services/doorman.py::async_function:body_size_limit": { + "notes": "Rust preserves global/protocol limits, exclusions, monitor/security bypasses, and 413 behavior for collected request bodies.", + "rust_symbols": ["gateway-rs/src/middleware/body_limit.rs::BodyLimits", "gateway-rs/src/routes/platform.rs::platform_dispatch"], + "rust_tests": ["gateway-rs/tests/platform_native.rs::platform_body_limit_uses_runtime_environment", "gateway-rs/tests/runtime.rs::protocol_body_limits_match_python"], + "status": "translated" + }, + "backend-services/doorman.py::async_function:policy_revision_middleware": { + "notes": "Rust bumps shared policy revision atomically in every successful storage mutation rather than in an HTTP after-hook.", + "rust_symbols": ["gateway-rs/src/storage/runtime.rs::SharedStorage.bump_policy_revision"], + "rust_tests": ["gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart"], + "status": "translated" + }, + "backend-services/doorman.py::async_function:request_id_middleware": { + "notes": "Rust accepts the same request-id headers, generates UUIDs, propagates x-request-id internally, and emits both response header spellings.", + "rust_symbols": ["gateway-rs/src/middleware/request_id.rs::request_id"], + "rust_tests": ["gateway-rs/tests/platform_native.rs::platform_security_headers_csp_hsts_and_request_ids_match_python", "gateway-rs/tests/live_tests_parity.rs::request_id_is_forwarded_to_authenticated_rest_upstream_and_response"], + "status": "translated" + }, + "backend-services/doorman.py::async_function:security_headers": { + "notes": "Rust matches default security headers, docs CSP/frame behavior, custom CSP, and HTTPS-only HSTS.", + "rust_symbols": ["gateway-rs/src/middleware/security_headers.rs::security_headers"], + "rust_tests": ["gateway-rs/tests/platform_native.rs::platform_security_headers_csp_hsts_and_request_ids_match_python"], + "status": "translated" + }, + "backend-services/doorman.py::class:Settings": { + "notes": "Rust loads and validates the equivalent storage and JWT settings before startup, with additional v2 production hardening.", + "rust_symbols": ["gateway-rs/src/config.rs::Config", "gateway-rs/src/config.rs::SharedStorageConfig"], + "rust_tests": ["gateway-rs/src/config.rs::tests::memory_mode_rejects_multiple_workers"], + "status": "translated" + }, + "backend-services/doorman.py::async_function:automatic_purger": { + "notes": "Rust runs an interval-based revocation purge after initial restored-state cleanup.", + "rust_symbols": ["gateway-rs/src/main.rs::spawn_revocation_purger", "gateway-rs/src/main.rs::run_revocation_purge"], + "rust_tests": ["gateway-rs/tests/common/mod.rs::shared_storage_revocation_lifecycle"], + "status": "translated" + }, + "backend-services/doorman.py::async_function:internal_server_error_handler": { + "notes": "Rust's panic catcher emits the pinned 500 ISE001 JSON envelope for unhandled request panics.", + "rust_symbols": ["gateway-rs/src/app.rs::handle_panic"], + "rust_tests": ["gateway-rs/src/app.rs::tests::panic_handler_matches_python_internal_error_envelope"], + "status": "translated" + }, + "backend-services/doorman.py::async_function:validation_exception_handler": { + "notes": "Rust typed request boundaries emit the pinned 422 VAL001 envelope before route logic.", + "rust_symbols": ["gateway-rs/src/routes/platform.rs::validation_errors"], + "rust_tests": ["gateway-rs/tests/platform_native.rs::malformed_typed_control_plane_json_validates_before_auth"], + "status": "translated" + }, + "backend-services/doorman.py::function:start": { + "notes": "The Rust start subcommand preserves the pinned detached child launch, null standard streams, process-group ownership on Unix, already-running PID-file check, PID creation, and success logging. PID_FILE is honored in addition to the legacy doorman.pid default.", + "rust_symbols": ["gateway-rs/src/main.rs::start_process"], + "rust_tests": ["gateway-rs/src/main.rs::tests::pid_files_require_a_positive_integer"], + "status": "translated" + }, + "backend-services/doorman.py::function:stop": { + "notes": "The Rust stop subcommand preserves the absent-PID no-op, positive PID parsing, Unix process-group SIGTERM with a 15-second wait, Windows taskkill behavior, and PID-file removal.", + "rust_symbols": ["gateway-rs/src/main.rs::stop_process", "gateway-rs/src/main.rs::stop_unix_process_group"], + "rust_tests": ["gateway-rs/src/main.rs::tests::pid_files_require_a_positive_integer"], + "status": "translated" + }, + "backend-services/doorman.py::function:restart": { + "notes": "The Rust restart subcommand performs the pinned stop, one-second delay, and detached start sequence. The management restart helper now recognizes the same PID_FILE override as the CLI.", + "rust_symbols": ["gateway-rs/src/main.rs::main", "gateway-rs/src/routes/platform.rs::schedule_restart"], + "rust_tests": ["gateway-rs/src/main.rs::tests::pid_files_require_a_positive_integer"], + "status": "translated" + }, + "backend-services/doorman.py::function:run": { + "notes": "The Rust executable validates configuration, binds HOST/PORT, serves the full router, and drains on shutdown signals.", + "rust_symbols": ["gateway-rs/src/main.rs::main"], + "rust_tests": ["gateway-rs/tests/process_lifecycle.rs::sigterm_drains_active_request_before_final_snapshot_and_restart"], + "status": "translated" + }, + "backend-services/doorman.py::function:main": { + "notes": "The Rust executable is the direct foreground server entrypoint.", + "rust_symbols": ["gateway-rs/src/main.rs::main"], + "rust_tests": ["gateway-rs/tests/live_tcp_port_3001.rs::rust_binary_serves_live_tcp_port"], + "status": "translated" + }, + "backend-services/doorman.py::function:seed_command": { + "notes": "The Rust seed subcommand preserves all seven pinned CLI options and defaults, help, configuration/storage initialization, progress summary, failure exit, success message, and count result while delegating fixture generation to the native demo_seed module.", + "rust_symbols": ["gateway-rs/src/main.rs::seed_command", "gateway-rs/src/main.rs::parse_seed_options", "gateway-rs/src/demo_seed.rs::run_seed"], + "rust_tests": ["gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults", "gateway-rs/src/demo_seed.rs::tests::defaults_match_the_python_seed_command"], + "status": "translated" + }, + "backend-services/models/create_api_model.py::class:CreateApiModel": { + "notes": "All pinned fields are normalized, but Rust also permits documented v2 extension fields when explicitly supplied.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "status": "partial" + }, + "backend-services/models/create_api_model.py::class:CreateApiModel.Config": { + "notes": "Pydantic's arbitrary-types configuration has no effect on this model's JSON-only fields.", + "rationale": "Python framework configuration is unnecessary in the typed Rust/serde implementation.", + "rust_symbols": [], + "rust_tests": [], + "status": "approved_obsolete" + }, + "backend-services/models/create_api_model.py::field:CreateApiModel.Config.arbitrary_types_allowed": { + "notes": "Every accepted field is a JSON scalar, list, or object and does not require arbitrary Python types.", + "rationale": "Python framework flag with no observable contract for this model.", + "rust_symbols": [], + "rust_tests": [], + "status": "approved_obsolete" + }, + "backend-services/models/create_api_model.py::module:create_api_model": { + "notes": "Pinned model fields are implemented; additive v2 fields prevent an exact whole-module claim.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "status": "partial" + }, + "backend-services/models/create_endpoint_model.py::class:CreateEndpointModel.Config": { + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in the Rust implementation.", + "rust_symbols": [], + "rust_tests": [], + "status": "approved_obsolete" + }, + "backend-services/models/create_endpoint_model.py::field:CreateEndpointModel.Config.arbitrary_types_allowed": { + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Python framework flag with no observable contract for this model.", + "rust_symbols": [], + "rust_tests": [], + "status": "approved_obsolete" + }, + "backend-services/models/create_endpoint_validation_model.py::class:CreateEndpointValidationModel.Config": { + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], "rust_tests": [], "status": "approved_obsolete" + }, + "backend-services/models/create_endpoint_validation_model.py::field:CreateEndpointValidationModel.Config.arbitrary_types_allowed": { + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Python framework flag with no observable contract for this model.", + "rust_symbols": [], "rust_tests": [], "status": "approved_obsolete" + }, + "backend-services/models/create_group_model.py::class:CreateGroupModel.Config": { + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], "rust_tests": [], "status": "approved_obsolete" + }, + "backend-services/models/create_group_model.py::field:CreateGroupModel.Config.arbitrary_types_allowed": { + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Python framework flag with no observable contract for this model.", + "rust_symbols": [], "rust_tests": [], "status": "approved_obsolete" + }, + "backend-services/models/create_role_model.py::class:CreateRoleModel.Config": { + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], "rust_tests": [], "status": "approved_obsolete" + }, + "backend-services/models/create_role_model.py::field:CreateRoleModel.Config.arbitrary_types_allowed": { + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Python framework flag with no observable contract for this model.", + "rust_symbols": [], "rust_tests": [], "status": "approved_obsolete" + }, + "backend-services/models/create_routing_model.py::class:CreateRoutingModel.Config": { + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], "rust_tests": [], "status": "approved_obsolete" + }, + "backend-services/models/create_routing_model.py::field:CreateRoutingModel.Config.arbitrary_types_allowed": { + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Python framework flag with no observable contract for this model.", + "rust_symbols": [], "rust_tests": [], "status": "approved_obsolete" + }, + "backend-services/models/request_model.py::class:RequestModel": { + "notes": "The class is declared but never imported or instantiated by pinned production code.", + "rationale": "Unused Python request container with no runtime contract to preserve.", + "rust_symbols": [], + "rust_tests": [], + "status": "approved_obsolete" + }, + "backend-services/models/create_vault_entry_model.py::class:CreateVaultEntryModel.Config": { + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], "rust_tests": [], "status": "approved_obsolete" + }, + "backend-services/models/create_vault_entry_model.py::field:CreateVaultEntryModel.Config.arbitrary_types_allowed": { + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], "rust_tests": [], "status": "approved_obsolete" + }, + "backend-services/models/credit_model.py::class:CreditTierModel.Config": { + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], "rust_tests": [], "status": "approved_obsolete" + }, + "backend-services/models/credit_model.py::field:CreditTierModel.Config.arbitrary_types_allowed": { + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], "rust_tests": [], "status": "approved_obsolete" + }, + "backend-services/models/credit_model.py::class:CreditModel.Config": { + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], "rust_tests": [], "status": "approved_obsolete" + }, + "backend-services/models/credit_model.py::field:CreditModel.Config.arbitrary_types_allowed": { + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], "rust_tests": [], "status": "approved_obsolete" + }, + "backend-services/models/credit_model.py::field:CreditModel.api_key_rotation_expires": { + "notes": "Rust accepts and persists scalar string representations, but exact Pydantic datetime parsing and normalization is not yet implemented.", + "rust_symbols": ["gateway-rs/src/routes/platform.rs::normalize_credit_model"], + "rust_tests": ["gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision"], + "status": "partial" + }, + "backend-services/models/credit_model.py::class:CreditModel": { + "notes": "All fields except exact api_key_rotation_expires datetime parsing are translated.", + "rust_symbols": ["gateway-rs/src/routes/platform.rs::normalize_credit_model"], + "rust_tests": ["gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision"], + "status": "partial" + }, + "backend-services/models/credit_model.py::module:credit_model": { + "notes": "CreditTierModel and the remaining CreditModel fields are translated; exact Pydantic datetime parsing remains open.", + "rust_symbols": ["gateway-rs/src/routes/platform.rs::normalize_credit_model"], + "rust_tests": ["gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision"], + "status": "partial" + }, + "backend-services/models/update_password_model.py::class:UpdatePasswordModel.Config": { + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], "rust_tests": [], "status": "approved_obsolete" + }, + "backend-services/models/update_password_model.py::field:UpdatePasswordModel.Config.arbitrary_types_allowed": { + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], "rust_tests": [], "status": "approved_obsolete" + }, + "backend-services/models/update_vault_entry_model.py::class:UpdateVaultEntryModel.Config": { + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], "rust_tests": [], "status": "approved_obsolete" + }, + "backend-services/models/update_vault_entry_model.py::field:UpdateVaultEntryModel.Config.arbitrary_types_allowed": { + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], "rust_tests": [], "status": "approved_obsolete" + }, + "backend-services/models/create_user_model.py::class:CreateUserModel.Config": { + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], "rust_tests": [], "status": "approved_obsolete" + }, + "backend-services/models/create_user_model.py::field:CreateUserModel.Config.arbitrary_types_allowed": { + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], "rust_tests": [], "status": "approved_obsolete" + }, + "backend-services/models/update_user_model.py::class:UpdateUserModel.Config": { + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], "rust_tests": [], "status": "approved_obsolete" + }, + "backend-services/models/update_user_model.py::field:UpdateUserModel.Config.arbitrary_types_allowed": { + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], "rust_tests": [], "status": "approved_obsolete" + }, + "backend-services/models/user_credits_model.py::class:UserCreditInformationModel.Config": { + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], "rust_tests": [], "status": "approved_obsolete" + }, + "backend-services/models/user_credits_model.py::field:UserCreditInformationModel.Config.arbitrary_types_allowed": { + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], "rust_tests": [], "status": "approved_obsolete" + }, + "backend-services/models/user_credits_model.py::class:UserCreditModel.Config": { + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], "rust_tests": [], "status": "approved_obsolete" + }, + "backend-services/models/user_credits_model.py::field:UserCreditModel.Config.arbitrary_types_allowed": { + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], "rust_tests": [], "status": "approved_obsolete" + }, + "backend-services/models/request_model.py::field:RequestModel.body": { + "notes": "The containing RequestModel is unused by pinned production code.", + "rationale": "Field of an unused Python-only request container.", + "rust_symbols": [], + "rust_tests": [], + "status": "approved_obsolete" + }, + "backend-services/models/request_model.py::field:RequestModel.headers": { + "notes": "The containing RequestModel is unused by pinned production code.", + "rationale": "Field of an unused Python-only request container.", + "rust_symbols": [], + "rust_tests": [], + "status": "approved_obsolete" + }, + "backend-services/models/request_model.py::field:RequestModel.identity": { + "notes": "The containing RequestModel is unused by pinned production code.", + "rationale": "Field of an unused Python-only request container.", + "rust_symbols": [], + "rust_tests": [], + "status": "approved_obsolete" + }, + "backend-services/models/request_model.py::field:RequestModel.method": { + "notes": "The containing RequestModel is unused by pinned production code.", + "rationale": "Field of an unused Python-only request container.", + "rust_symbols": [], + "rust_tests": [], + "status": "approved_obsolete" + }, + "backend-services/models/request_model.py::field:RequestModel.path": { + "notes": "The containing RequestModel is unused by pinned production code.", + "rationale": "Field of an unused Python-only request container.", + "rust_symbols": [], + "rust_tests": [], + "status": "approved_obsolete" + }, + "backend-services/models/request_model.py::field:RequestModel.query_params": { + "notes": "The containing RequestModel is unused by pinned production code.", + "rationale": "Field of an unused Python-only request container.", + "rust_symbols": [], + "rust_tests": [], + "status": "approved_obsolete" + }, + "backend-services/models/request_model.py::module:request_model": { + "notes": "No pinned production module imports RequestModel.", + "rationale": "Unused Python model module with no runtime contract to preserve.", + "rust_symbols": [], + "rust_tests": [], + "status": "approved_obsolete" + }, + "backend-services/models/response_model.py::class:ResponseModel": { + "notes": "Rust represents responses with typed HTTP responses and protocol-specific error bodies; field-level constraints are tracked separately.", + "rust_symbols": [ + "gateway-rs/src/middleware/response_compat.rs::response_compat", + "gateway-rs/src/policy/mod.rs::PolicyErrorBody" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::strict_envelope_preserves_legacy_status_tokens_and_probe_shape" + ], + "status": "partial" + }, + "backend-services/models/response_model.py::field:ResponseModel.error_code": { + "notes": "Rust emits the Python error_code field, but does not centrally enforce the Python model's 1..255 internal string constraint.", + "rust_symbols": [ + "gateway-rs/src/policy/mod.rs::PolicyErrorBody.error_code" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::strict_envelope_preserves_legacy_status_tokens_and_probe_shape" + ], + "status": "partial" + }, + "backend-services/models/response_model.py::field:ResponseModel.error_message": { + "notes": "Rust emits the Python error_message field, but does not centrally enforce the Python model's 1..255 internal string constraint.", + "rust_symbols": [ + "gateway-rs/src/policy/mod.rs::PolicyErrorBody.error_message" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::strict_envelope_preserves_legacy_status_tokens_and_probe_shape" + ], + "status": "partial" + }, + "backend-services/models/response_model.py::field:ResponseModel.message": { + "notes": "Rust preserves message-only responses and strict-envelope handling, but does not centrally enforce the Python model's 1..255 internal string constraint.", + "rust_symbols": [ + "gateway-rs/src/middleware/response_compat.rs::MessageEnvelope" + ], + "rust_tests": [ + "gateway-rs/src/middleware/response_compat.rs::tests::only_plain_message_payloads_use_message_envelope" + ], + "status": "partial" + }, + "backend-services/models/response_model.py::field:ResponseModel.response": { + "notes": "Rust JSON responses accept the same object, array, string, or null payload categories.", + "rust_symbols": [ + "gateway-rs/src/middleware/response_compat.rs::response_compat" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rest_strict_response_envelope_wraps_proxy_message_like_python", + "gateway-rs/tests/platform_native.rs::graphql_strict_response_envelope_wraps_proxy_data_like_python" + ], + "status": "translated" + }, + "backend-services/models/response_model.py::field:ResponseModel.response_headers": { + "notes": "Rust response builders and request-ID middleware preserve compatible response headers.", + "rust_symbols": [ + "gateway-rs/src/middleware/request_id.rs::request_id" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::platform_security_headers_csp_hsts_and_request_ids_match_python", + "gateway-rs/tests/live_tests_parity.rs::request_id_is_forwarded_to_authenticated_rest_upstream_and_response" + ], + "status": "translated" + }, + "backend-services/models/response_model.py::field:ResponseModel.status_code": { + "notes": "Rust HTTP responses and strict envelopes preserve both transport and original status semantics.", + "rust_symbols": [ + "gateway-rs/src/middleware/response_compat.rs::response_compat" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::strict_envelope_preserves_legacy_status_tokens_and_probe_shape" + ], + "status": "translated" + }, + "backend-services/models/response_model.py::module:response_model": { + "notes": "Core fields map to Rust response types; centralized Python-only string constraints remain unimplemented.", + "rust_symbols": [ + "gateway-rs/src/middleware/response_compat.rs", + "gateway-rs/src/policy/mod.rs::PolicyErrorBody" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::strict_envelope_preserves_legacy_status_tokens_and_probe_shape" + ], + "status": "partial" + }, + "backend-services/models/endpoint_validation_model_response.py::class:EndpointValidationModelResponse.Config": { + "notes": "The model contains only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], "rust_tests": [], "status": "approved_obsolete" + }, + "backend-services/models/endpoint_validation_model_response.py::field:EndpointValidationModelResponse.Config.arbitrary_types_allowed": { + "notes": "The model contains only JSON-compatible values.", + "rationale": "Python framework flag with no observable contract for this model.", + "rust_symbols": [], "rust_tests": [], "status": "approved_obsolete" + }, + "backend-services/models/subscribe_model.py::class:SubscribeModel.Config": { + "notes": "The model accepts only JSON-compatible scalar values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in the Rust implementation.", + "rust_symbols": [], + "rust_tests": [], + "status": "approved_obsolete" + }, + "backend-services/models/subscribe_model.py::field:SubscribeModel.Config.arbitrary_types_allowed": { + "notes": "The model accepts only JSON-compatible scalar values.", + "rationale": "Python framework flag with no observable contract for this model.", + "rust_symbols": [], + "rust_tests": [], + "status": "approved_obsolete" + }, + "backend-services/models/update_api_model.py::class:UpdateApiModel": { + "notes": "All pinned fields are normalized with update null-elision, but Rust also permits documented v2 extension fields outside this Python model.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "status": "partial" + }, + "backend-services/models/update_api_model.py::class:UpdateApiModel.Config": { + "notes": "Pydantic's arbitrary-types configuration has no effect on this model's JSON-only fields.", + "rationale": "Python framework configuration is unnecessary in the typed Rust/serde implementation.", + "rust_symbols": [], + "rust_tests": [], + "status": "approved_obsolete" + }, + "backend-services/models/update_api_model.py::field:UpdateApiModel.Config.arbitrary_types_allowed": { + "notes": "Every accepted field is a JSON scalar, list, or object and does not require arbitrary Python types.", + "rationale": "Python framework flag with no observable contract for this model.", + "rust_symbols": [], + "rust_tests": [], + "status": "approved_obsolete" + }, + "backend-services/models/update_api_model.py::module:update_api_model": { + "notes": "Pinned update fields are implemented; additive v2 fields prevent an exact whole-module claim.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "status": "partial" + }, + "backend-services/models/update_endpoint_model.py::class:UpdateEndpointModel.Config": { + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in the Rust implementation.", + "rust_symbols": [], + "rust_tests": [], + "status": "approved_obsolete" + }, + "backend-services/models/update_endpoint_model.py::field:UpdateEndpointModel.Config.arbitrary_types_allowed": { + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Python framework flag with no observable contract for this model.", + "rust_symbols": [], + "rust_tests": [], + "status": "approved_obsolete" + }, + "backend-services/models/update_endpoint_validation_model.py::class:UpdateEndpointValidationModel.Config": { + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], "rust_tests": [], "status": "approved_obsolete" + }, + "backend-services/models/update_endpoint_validation_model.py::field:UpdateEndpointValidationModel.Config.arbitrary_types_allowed": { + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Python framework flag with no observable contract for this model.", + "rust_symbols": [], "rust_tests": [], "status": "approved_obsolete" + }, + "backend-services/models/update_group_model.py::class:UpdateGroupModel.Config": { + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], "rust_tests": [], "status": "approved_obsolete" + }, + "backend-services/models/update_group_model.py::field:UpdateGroupModel.Config.arbitrary_types_allowed": { + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Python framework flag with no observable contract for this model.", + "rust_symbols": [], "rust_tests": [], "status": "approved_obsolete" + }, + "backend-services/models/update_role_model.py::class:UpdateRoleModel.Config": { + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], "rust_tests": [], "status": "approved_obsolete" + }, + "backend-services/models/update_role_model.py::field:UpdateRoleModel.Config.arbitrary_types_allowed": { + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Python framework flag with no observable contract for this model.", + "rust_symbols": [], "rust_tests": [], "status": "approved_obsolete" + }, + "backend-services/models/update_routing_model.py::class:UpdateRoutingModel.Config": { + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Pydantic arbitrary-types configuration has no observable effect in Rust.", + "rust_symbols": [], "rust_tests": [], "status": "approved_obsolete" + }, + "backend-services/models/update_routing_model.py::field:UpdateRoutingModel.Config.arbitrary_types_allowed": { + "notes": "The model accepts only JSON-compatible values.", + "rationale": "Python framework flag with no observable contract for this model.", + "rust_symbols": [], "rust_tests": [], "status": "approved_obsolete" + }, + "backend-services/utils/correlation_util.py::async_function:run_async_with_correlation": { + "notes": "The helper is not referenced by pinned production code; Rust async tasks pass request context explicitly.", + "rationale": "Unused Python convenience wrapper with no externally observable contract.", + "rust_symbols": [], + "rust_tests": [], + "status": "approved_obsolete" + }, + "backend-services/utils/correlation_util.py::async_function:run_with_correlation": { + "notes": "The helper is not referenced by pinned production code; Rust futures carry request state explicitly.", + "rationale": "Unused Python contextvars convenience wrapper with no externally observable contract.", + "rust_symbols": [], + "rust_tests": [], + "status": "approved_obsolete" + }, + "backend-services/utils/correlation_util.py::class:CorrelationContext": { + "notes": "No pinned production caller constructs this context manager.", + "rationale": "Unused Python context-manager abstraction; request scoping is native middleware state in Rust.", + "rust_symbols": [], + "rust_tests": [], + "status": "approved_obsolete" + }, + "backend-services/utils/correlation_util.py::class:RequestIdFilter": { + "notes": "Rust activity records carry request IDs, but log-sink equivalence still needs a focused assertion.", + "rust_symbols": [ + "gateway-rs/src/middleware/activity.rs::activity", + "gateway-rs/src/middleware/request_id.rs::RequestId" + ], + "rust_tests": [], + "status": "partial" + }, + "backend-services/utils/correlation_util.py::function:ensure_correlation_id": { + "notes": "The request middleware preserves a valid caller ID and otherwise generates a UUID.", + "rust_symbols": [ + "gateway-rs/src/middleware/request_id.rs::request_id" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::request_id_is_forwarded_to_authenticated_rest_upstream_and_response", + "gateway-rs/tests/platform_native.rs::platform_security_headers_csp_hsts_and_request_ids_match_python" + ], + "status": "translated" + }, + "backend-services/utils/correlation_util.py::function:get_correlation_id": { + "notes": "Axum request extensions replace contextvars for request-scoped lookup.", + "rust_symbols": [ + "gateway-rs/src/middleware/request_id.rs::RequestId" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::request_id_is_forwarded_to_authenticated_rest_upstream_and_response" + ], + "status": "translated" + }, + "backend-services/utils/correlation_util.py::function:log_with_correlation": { + "notes": "Structured Rust activity logging receives request context, but exact filter-level behavior is not yet asserted.", + "rust_symbols": [ + "gateway-rs/src/middleware/activity.rs::activity" + ], + "rust_tests": [], + "status": "partial" + }, + "backend-services/utils/correlation_util.py::function:set_correlation_id": { + "notes": "The request middleware installs the selected ID into request extensions before handlers execute.", + "rust_symbols": [ + "gateway-rs/src/middleware/request_id.rs::request_id" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::request_id_is_forwarded_to_authenticated_rest_upstream_and_response", + "gateway-rs/tests/platform_native.rs::platform_security_headers_csp_hsts_and_request_ids_match_python" + ], + "status": "translated" + }, + "backend-services/utils/correlation_util.py::method:CorrelationContext.__enter__": { + "notes": "No pinned production caller enters this context manager.", + "rationale": "Unused Python context-manager method with no externally observable contract.", + "rust_symbols": [], + "rust_tests": [], + "status": "approved_obsolete" + }, + "backend-services/utils/correlation_util.py::method:CorrelationContext.__exit__": { + "notes": "No pinned production caller exits this context manager.", + "rationale": "Unused Python context-manager method with no externally observable contract.", + "rust_symbols": [], + "rust_tests": [], + "status": "approved_obsolete" + }, + "backend-services/utils/correlation_util.py::method:CorrelationContext.__init__": { + "notes": "No pinned production caller constructs this context manager.", + "rationale": "Unused Python context-manager initializer with no externally observable contract.", + "rust_symbols": [], + "rust_tests": [], + "status": "approved_obsolete" + }, + "backend-services/utils/correlation_util.py::method:RequestIdFilter.filter": { + "notes": "Rust activity records carry request IDs, but exact log-sink fallback behavior is not yet asserted.", + "rust_symbols": [ + "gateway-rs/src/middleware/activity.rs::activity" + ], + "rust_tests": [], + "status": "partial" + }, + "backend-services/utils/correlation_util.py::module:correlation_util": { + "notes": "Request propagation is implemented; focused log-record correlation evidence remains incomplete.", + "rust_symbols": [ + "gateway-rs/src/middleware/request_id.rs", + "gateway-rs/src/middleware/activity.rs" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::request_id_is_forwarded_to_authenticated_rest_upstream_and_response" + ], + "status": "partial" + }, + "backend-services/utils/response_util.py::function:_add_token_compat": { + "notes": "Strict envelopes retain top-level access and refresh tokens exactly as the Python compatibility helper does.", + "rust_symbols": [ + "gateway-rs/src/middleware/response_compat.rs::response_compat" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::strict_envelope_preserves_legacy_status_tokens_and_probe_shape" + ], + "status": "translated" + }, + "backend-services/utils/response_util.py::function:_envelope": { + "notes": "The Rust response middleware adds the original status_code to strict JSON envelopes.", + "rust_symbols": [ + "gateway-rs/src/middleware/response_compat.rs::response_compat" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::strict_envelope_preserves_legacy_status_tokens_and_probe_shape", + "gateway-rs/tests/platform_native.rs::rest_strict_response_envelope_wraps_proxy_message_like_python", + "gateway-rs/tests/platform_native.rs::graphql_strict_response_envelope_wraps_proxy_data_like_python" + ], + "status": "translated" + }, + "backend-services/utils/response_util.py::function:_normalize_headers": { + "notes": "Rust emits both request_id and x-request-id and preserves caller-provided IDs through platform and gateway responses.", + "rust_symbols": [ + "gateway-rs/src/middleware/request_id.rs::request_id" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::request_id_is_forwarded_to_authenticated_rest_upstream_and_response", + "gateway-rs/tests/platform_native.rs::platform_security_headers_csp_hsts_and_request_ids_match_python" + ], + "status": "translated" + }, + "backend-services/utils/response_util.py::function:process_response": { + "notes": "Rust has protocol-specific REST, GraphQL, SOAP, and gRPC response paths, but the complete fallback and exception matrix is not yet mapped assertion by assertion.", + "rust_symbols": [ + "gateway-rs/src/middleware/response_compat.rs::response_compat", + "gateway-rs/src/routes/rest.rs", + "gateway-rs/src/routes/graphql.rs", + "gateway-rs/src/routes/soap.rs", + "gateway-rs/src/routes/grpc.rs" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rest_strict_response_envelope_wraps_proxy_message_like_python", + "gateway-rs/tests/platform_native.rs::graphql_strict_response_envelope_wraps_proxy_data_like_python", + "gateway-rs/tests/live_tests_parity.rs::soap_content_types_and_retry_real_upstream_parity", + "gateway-rs/tests/live_tests_parity.rs::grpc_gateway_maps_upstream_statuses_parity" + ], + "status": "partial" + }, + "backend-services/utils/response_util.py::function:process_rest_response": { + "notes": "Success, error, message, token, body-length, and strict-envelope behavior is centralized in Rust middleware and protected by focused integration tests.", + "rust_symbols": [ + "gateway-rs/src/middleware/response_compat.rs::response_compat" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::strict_envelope_preserves_legacy_status_tokens_and_probe_shape", + "gateway-rs/tests/platform_native.rs::rest_strict_response_envelope_wraps_proxy_message_like_python" + ], + "status": "translated" + }, + "backend-services/utils/response_util.py::function:process_soap_response": { + "notes": "Rust preserves SOAP media types and maps common upstream failures, but Python's complete synthetic 201/error/fallback response matrix lacks a focused Rust equivalent test.", + "rust_symbols": [ + "gateway-rs/src/routes/soap.rs::soap_gateway", + "gateway-rs/src/protocol/soap.rs" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::soap_upstream_not_found_maps_to_python_404", + "gateway-rs/tests/live_tests_parity.rs::soap_content_types_and_retry_real_upstream_parity" + ], + "status": "partial" + }, + "backend-services/utils/response_util.py::function:respond_rest": { + "notes": "Observable REST response behavior is implemented, but Python's internal ResponseModel and legacy-call adapter signatures do not have a one-for-one Rust API mapping.", + "rust_symbols": [ + "gateway-rs/src/middleware/response_compat.rs::response_compat", + "gateway-rs/src/routes/platform.rs" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::strict_envelope_preserves_legacy_status_tokens_and_probe_shape" + ], + "status": "partial" + }, + "backend-services/utils/response_util.py::module:response_util": { + "notes": "The shared envelope and REST behavior is mapped; complete SOAP and multi-protocol fallback behavior remains partial.", + "rust_symbols": [ + "gateway-rs/src/middleware/response_compat.rs" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::strict_envelope_preserves_legacy_status_tokens_and_probe_shape" + ], + "status": "partial" + } + }, + "file_defaults": { + "backend-services/routes/group_routes.py": { + "notes": "Rust preserves group CRUD, model validation, permissions, duplicate/not-found behavior, pagination, and response bodies.", + "rust_symbols": ["gateway-rs/src/routes/platform.rs::entity_routes"], + "rust_tests": ["gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates", "gateway-rs/tests/roles_groups_parity.rs"], + "status": "translated" + }, + "backend-services/routes/logging_routes.py": { + "notes": "Rust preserves authenticated log querying, file listing, statistics, filtered/redacted export, and downloads over native structured log files.", + "rust_symbols": ["gateway-rs/src/routes/platform.rs::logging_routes"], + "rust_tests": ["gateway-rs/tests/security_settings_parity.rs::live_logging_endpoints_match_python", "gateway-rs/tests/security_settings_parity.rs::log_export_filters_records_and_redacts_nested_credentials"], + "status": "translated" + }, + "backend-services/routes/metrics_routes.py": { + "notes": "Rust preserves the Prometheus endpoint, enable flag, IP allowlist, bearer/query token extraction, authorization, and exposition counters.", + "rust_symbols": ["gateway-rs/src/routes/metrics.rs::metrics"], + "rust_tests": ["gateway-rs/tests/platform_native.rs::prometheus_metrics_exposition_counters_allowlist_and_token_match_python"], + "status": "translated" + }, + "backend-services/routes/routing_routes.py": { + "notes": "Rust preserves routing CRUD, generated client keys, validation, permission/error behavior, pagination, and server-index update exclusion.", + "rust_symbols": ["gateway-rs/src/routes/platform.rs::entity_routes"], + "rust_tests": ["gateway-rs/tests/platform_native.rs::routing_models_match_pydantic_generation_coercion_and_update_exclusion", "gateway-rs/tests/roles_groups_parity.rs"], + "status": "translated" + }, + "backend-services/routes/subscription_routes.py": { + "notes": "Rust preserves subscribe/unsubscribe, current/admin list access, available-API filtering, model coercion, permissions, and pinned errors.", + "rust_symbols": ["gateway-rs/src/routes/platform.rs::subscription_routes"], + "rust_tests": ["gateway-rs/tests/live_tests_parity.rs::live_test_21_subscription_list_unsubscribe_parity", "gateway-rs/tests/platform_native.rs::subscription_model_coerces_python_scalars_and_ignores_unknown_fields"], + "status": "translated" + }, + "backend-services/routes/vault_routes.py": { + "notes": "Rust preserves authenticated vault CRUD, validation, encryption-at-rest, duplicate/not-found errors, description-only updates, secret suppression, and the pinned empty read-body quirk.", + "rust_symbols": ["gateway-rs/src/routes/platform.rs::vault_routes", "gateway-rs/src/storage/vault.rs"], + "rust_tests": ["gateway-rs/tests/platform_native.rs::vault_lifecycle_encrypts_at_rest_and_never_returns_the_secret"], + "status": "translated" + }, + "backend-services/routes/dashboard_routes.py": { + "notes": "Rust returns the pinned dashboard totals, monthly usage, active users, popular APIs, and response shape from native storage and analytics.", + "rust_symbols": ["gateway-rs/src/routes/platform.rs::dashboard"], + "rust_tests": ["gateway-rs/tests/live_tests_parity.rs::monitor_dashboard_liveness_readiness_and_metrics_parity"], + "status": "translated" + }, + "backend-services/routes/demo_routes.py": { + "notes": "Rust preserves admin-only demo seeding and error envelopes but currently seeds only three API/endpoint examples; Python supports configurable bulk users, APIs, endpoints, groups, protos, logs, and deterministic seeds.", + "rust_symbols": ["gateway-rs/src/routes/platform.rs::demo_seed"], + "rust_tests": ["gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract"], + "status": "partial" + }, + "backend-services/routes/grpc_routes.py": { + "notes": "Rust provides authenticated descriptor-backed service discovery and the native gRPC-Web proxy with policy, CORS, unary, and streaming behavior.", + "rust_symbols": ["gateway-rs/src/routes/platform.rs::api_discovery_routes", "gateway-rs/src/routes/grpc_web.rs::grpc_web_policy_then_execute"], + "rust_tests": ["gateway-rs/tests/live_tests_parity.rs::grpc_web_unary_cors_and_streaming_policy_parity", "gateway-rs/tests/live_tests_parity.rs::live_test_60_grpc_gateway_basic_flow_parity"], + "status": "translated" + }, + "backend-services/routes/config_hot_reload_routes.py": { + "notes": "Rust intentionally returns useful current/reload/key data and applies supported gateway settings; Python's ResponseModel silently discarded the undeclared data field and emitted empty success bodies.", + "rationale": "v2 fixes the pinned hot-reload response bug and explicitly distinguishes live-applied keys from restart-required settings.", + "rust_symbols": ["gateway-rs/src/routes/platform.rs::config_current", "gateway-rs/src/hot_reload.rs::HotReloadConfig"], + "rust_tests": ["gateway-rs/tests/platform_native.rs::config_reload_routes_preserve_legacy_values_metadata_and_permissions"], + "status": "approved_changed" + }, + "backend-services/routes/graphql_routes.py": { + "notes": "Rust preserves authenticated schema fetch/cache/refresh and type listing with pinned permission and error behavior.", + "rust_symbols": ["gateway-rs/src/routes/platform.rs::api_discovery_routes"], + "rust_tests": ["gateway-rs/tests/platform_native.rs::discovery_document_reads_fetch_once_and_reuse_the_python_cache_contract"], + "status": "translated" + }, + "backend-services/routes/security_routes.py": { + "notes": "Rust preserves settings read/update validation, permission checks, persistence/runtime publication, redaction, and controlled restart scheduling.", + "rust_symbols": ["gateway-rs/src/routes/platform.rs::get_security_settings", "gateway-rs/src/routes/platform.rs::upsert_security_settings", "gateway-rs/src/routes/platform.rs::schedule_restart"], + "rust_tests": ["gateway-rs/tests/security_settings_parity.rs::live_security_settings_get_put_matches_python", "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract"], + "status": "translated" + }, + "backend-services/routes/wsdl_routes.py": { + "notes": "Rust preserves authenticated WSDL fetch/cache/refresh/import and raw parse behavior with native XML processing and pinned errors.", + "rust_symbols": ["gateway-rs/src/routes/platform.rs::api_discovery_routes", "gateway-rs/src/routes/platform.rs::parse_wsdl_document"], + "rust_tests": ["gateway-rs/tests/platform_native.rs::discovery_document_reads_fetch_once_and_reuse_the_python_cache_contract", "gateway-rs/tests/platform_native.rs::memory_mode_parses_and_imports_wsdl_without_an_external_service"], + "status": "translated" + }, + "backend-services/middleware/analytics_middleware.py": { + "notes": "Rust records gateway timing, status, byte counts, API/user/endpoint identity, persistence buckets, and aggregate counters. Some Python-only percentile/sample details remain covered by the partial analytics model mapping.", + "rust_symbols": ["gateway-rs/src/middleware/activity.rs::track_active_requests", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request"], + "rust_tests": ["gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts"], + "status": "partial" + }, + "backend-services/middleware/latency_injection_middleware.py": { + "notes": "Rust now honors ENABLE_LATENCY_INJECTION and X-Doorman-Latency globally with trimming, invalid-value elision, nonnegative clamping, and the 5000ms cap; Python's arbitrary-size and Unicode integer spellings remain an extreme parsing edge.", + "rust_symbols": ["gateway-rs/src/middleware/chaos.rs::latency_injection"], + "rust_tests": ["gateway-rs/src/middleware/chaos.rs::tests::legacy_header_latency_matches_python_bounds_and_parsing"], + "status": "partial" + }, + "backend-services/middleware/logging_middleware.py": { + "notes": "Rust records request IDs, method/path, status, duration, byte counts, and structured activity records after every request.", + "rust_symbols": ["gateway-rs/src/middleware/activity.rs::track_active_requests", "gateway-rs/src/middleware/request_id.rs::request_id"], + "rust_tests": ["gateway-rs/tests/platform_native.rs::rust_gateway_activity_json_has_queryable_python_log_fields", "gateway-rs/tests/security_settings_parity.rs::unknown_path_404_is_written_to_the_gateway_activity_log"], + "status": "translated" + }, + "backend-services/middleware/rate_limit_middleware.py": { + "notes": "Rust implements user/API/endpoint policy selection, fixed/sliding/token/hybrid counters, quotas, response failures, and headers, but the Python middleware's helper surface has not yet been mapped method-by-method.", + "rust_symbols": ["gateway-rs/src/policy/evaluator.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs"], + "rust_tests": ["gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker"], + "status": "partial" + }, + "backend-services/middleware/security_audit_middleware.py": { + "notes": "Rust emits payload-free named management audits and security failure activity records, but Python's audit of every platform read has not been reproduced one-for-one.", + "rust_symbols": ["gateway-rs/src/middleware/activity.rs::track_active_requests", "gateway-rs/src/observability/audit.rs", "gateway-rs/src/routes/platform.rs::audit_management_request"], + "rust_tests": ["gateway-rs/tests/platform_native.rs::platform_mutations_emit_payload_free_audit_events", "gateway-rs/tests/platform_native.rs::global_ip_denial_emits_the_python_audit_action"], + "status": "partial" + }, + "backend-services/middleware/tier_rate_limit_middleware.py": { + "notes": "Rust resolves tier assignments and overrides and enforces tier rate/quota limits, but the Python middleware helper surface has not yet been mapped method-by-method.", + "rust_symbols": ["gateway-rs/src/policy/evaluator.rs", "gateway-rs/src/policy/tier.rs"], + "rust_tests": ["gateway-rs/tests/live_tests_parity.rs::live_test_34_tier_rate_limiting_strict_local_parity", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers"], + "status": "partial" + }, + "backend-services/middleware/websocket_reject_middleware.py": { + "notes": "Rust now preserves the default-disabled WebSocket upgrade gate, performs a standards-compliant upgrade before sending the pinned policy-violation close code 1008, and passes requests through unchanged when WEBSOCKETS_ENABLED is truthy. Non-upgrade HTTP requests are never intercepted.", + "rust_symbols": [ + "gateway-rs/src/config.rs::Config.websockets_enabled", + "gateway-rs/src/middleware/websocket_reject.rs::reject_disabled_websockets" + ], + "rust_tests": [ + "gateway-rs/src/middleware/websocket_reject.rs::tests::recognizes_websocket_upgrade_headers_case_insensitively", + "gateway-rs/tests/platform_native.rs::graphql_websocket_upgrade_has_no_route_like_python" + ], + "status": "translated" + }, + "backend-services/doorman.py": { + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "rust_symbols": ["gateway-rs/src/main.rs", "gateway-rs/src/app.rs", "gateway-rs/src/config.rs"], + "rust_tests": ["gateway-rs/tests/process_lifecycle.rs", "gateway-rs/tests/platform_native.rs::platform_security_headers_csp_hsts_and_request_ids_match_python"], + "status": "partial" + }, + "backend-services/models/analytics_models.py": { + "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", + "gateway-rs/src/routes/platform.rs::analytics_overview" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" + ], + "status": "partial" + }, + "backend-services/models/api_model_response.py": { + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": ["gateway-rs/src/routes/platform.rs::platform_openapi"], + "rust_tests": ["gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface"], + "status": "translated" + }, + "backend-services/models/create_user_model.py": { + "notes": "Rust matches required fields, defaults and null materialization, scalar/list coercion, Unicode character bounds, numeric and boolean constraints, dictionary handling, and ignored unknown fields.", + "rust_symbols": ["gateway-rs/src/routes/platform.rs::normalize_create_user_model"], + "rust_tests": ["gateway-rs/tests/platform_native.rs::user_create_matches_pydantic_bounds_and_scalar_coercion"], + "status": "translated" + }, + "backend-services/models/credit_model.py": { + "notes": "Rust matches required nested fields, defaults and null materialization, Pydantic scalar/integer coercion, Unicode character bounds, list minimums, and ignored unknown fields.", + "rust_symbols": ["gateway-rs/src/routes/platform.rs::normalize_credit_model"], + "rust_tests": ["gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision"], + "status": "translated" + }, + "backend-services/models/endpoint_model_response.py": { + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": ["gateway-rs/src/routes/platform.rs::platform_openapi"], + "rust_tests": ["gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface"], + "status": "translated" + }, + "backend-services/models/group_model_response.py": { + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": ["gateway-rs/src/routes/platform.rs::platform_openapi"], + "rust_tests": ["gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface"], + "status": "translated" + }, + "backend-services/models/create_api_model.py": { + "notes": "The shared Rust create normalizer contains the pinned field, Pydantic coercion category, defaults, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "status": "translated" + }, + "backend-services/models/create_endpoint_model.py": { + "notes": "Rust matches required fields, scalar/list coercion, character-count limits, optional identifier behavior, defaults, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_endpoint_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::endpoint_models_match_pydantic_coercion_bounds_and_null_elision" + ], + "status": "translated" + }, + "backend-services/models/create_endpoint_validation_model.py": { + "notes": "Rust now validates and normalizes the required outer fields and recursive schema before authorization; extreme Pydantic numeric-union coercion remains unproven.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_endpoint_validation_model", + "gateway-rs/src/routes/platform.rs::normalize_validation_schema_model" + ], + "rust_tests": ["gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts"], + "status": "partial" + }, + "backend-services/models/create_group_model.py": { + "notes": "Rust matches required/default fields, scalar/list coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": ["gateway-rs/src/routes/platform.rs::normalize_group_model"], + "rust_tests": ["gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates"], + "status": "translated" + }, + "backend-services/models/create_role_model.py": { + "notes": "Rust matches role defaults, boolean coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": ["gateway-rs/src/routes/platform.rs::normalize_role_model"], + "rust_tests": ["gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates"], + "status": "translated" + }, + "backend-services/models/create_routing_model.py": { + "notes": "Rust matches required/default fields, list/scalar/integer coercion, character-count bounds, and minimum server count.", + "rust_symbols": ["gateway-rs/src/routes/platform.rs::normalize_routing_model"], + "rust_tests": ["gateway-rs/tests/platform_native.rs::routing_models_match_pydantic_generation_coercion_and_update_exclusion"], + "status": "translated" + }, + "backend-services/models/delete_successfully.py": { + "notes": "ResponseMessage is never imported or referenced by pinned production code.", + "rationale": "Unused Python response-model wrapper with no runtime behavior to translate.", + "rust_symbols": [], + "rust_tests": [], + "status": "approved_obsolete" + }, + "backend-services/models/endpoint_validation_model_response.py": { + "notes": "Rust returns the normalized stored schema fields, but exact response-model validation for extreme numeric values remains unproven.", + "rust_symbols": ["gateway-rs/src/routes/platform.rs::endpoint_routes"], + "rust_tests": ["gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts"], + "status": "partial" + }, + "backend-services/models/field_validation_model.py": { + "notes": "Rust implements required/type, min/max, pattern, enum, format, custom-validator, nested-schema, and array-item behavior; extreme Pydantic numeric-union coercion remains unproven.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_field_validation_model", + "gateway-rs/src/validation/json.rs::validate_json_with_registry" + ], + "rust_tests": [ + "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" + ], + "status": "partial" + }, + "backend-services/models/subscribe_model.py": { + "notes": "Rust matches required fields, Python scalar-to-string coercion, character-count bounds, unknown-field handling, and validation-before-authentication ordering.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_subscription_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::incomplete_subscription_payload_uses_python_validation_envelope_before_auth", + "gateway-rs/tests/platform_native.rs::subscription_model_coerces_python_scalars_and_ignores_unknown_fields" + ], + "status": "translated" + }, + "backend-services/models/update_api_model.py": { + "notes": "The shared Rust update normalizer contains the pinned field, Pydantic coercion category, null-elision, and field constraints.", + "rust_symbols": [ + "gateway-rs/src/platform_contract.rs::normalize_update_api", + "gateway-rs/src/platform_contract.rs::normalize_api_fields" + ], + "rust_tests": [ + "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", + "gateway-rs/src/platform_contract.rs::tests::validation_uses_fastapi_pydantic_error_shape", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" + ], + "status": "translated" + }, + "backend-services/models/update_endpoint_model.py": { + "notes": "Rust matches optional fields, scalar/list coercion, character-count limits, update null-elision, and ignored unknown fields.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_endpoint_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::endpoint_models_match_pydantic_coercion_bounds_and_null_elision" + ], + "status": "translated" + }, + "backend-services/models/update_endpoint_validation_model.py": { + "notes": "Rust validates required update fields and recursively normalizes schemas; extreme Pydantic numeric-union coercion remains unproven.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_endpoint_validation_model", + "gateway-rs/src/routes/platform.rs::normalize_validation_schema_model" + ], + "rust_tests": ["gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts"], + "status": "partial" + }, + "backend-services/models/update_group_model.py": { + "notes": "Rust matches optional fields, null-elision, scalar/list coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": ["gateway-rs/src/routes/platform.rs::normalize_group_model"], + "rust_tests": ["gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates"], + "status": "translated" + }, + "backend-services/models/update_role_model.py": { + "notes": "Rust matches optional fields, null-elision, boolean coercion, character-count bounds, and ignored unknown fields.", + "rust_symbols": ["gateway-rs/src/routes/platform.rs::normalize_role_model"], + "rust_tests": ["gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates"], + "status": "translated" + }, + "backend-services/models/update_routing_model.py": { + "notes": "Rust matches optional fields, null-elision, excluded server_index behavior, list/scalar coercion, and character-count bounds.", + "rust_symbols": ["gateway-rs/src/routes/platform.rs::normalize_routing_model"], + "rust_tests": ["gateway-rs/tests/platform_native.rs::routing_models_match_pydantic_generation_coercion_and_update_exclusion"], + "status": "translated" + }, + "backend-services/models/update_user_model.py": { + "notes": "Rust matches optional fields, null-elision used by the Python service, scalar/list coercion, Unicode character bounds, numeric and boolean constraints, dictionary handling, and ignored unknown fields.", + "rust_symbols": ["gateway-rs/src/routes/platform.rs::normalize_update_user_model"], + "rust_tests": ["gateway-rs/tests/platform_native.rs::user_update_matches_pydantic_null_coercion_and_unknown_field_rules"], + "status": "translated" + }, + "backend-services/models/user_model_response.py": { + "notes": "The class is imported by user_routes.py but never referenced by a response_model declaration, annotation, constructor, or runtime check.", + "rationale": "Unused Python response schema with no observable runtime contract to preserve.", + "rust_symbols": [], + "rust_tests": [], + "status": "approved_obsolete" + }, + "backend-services/models/user_credits_model.py": { + "notes": "Rust matches required nested fields, defaults and null materialization, Pydantic scalar coercion, Unicode character bounds, ignored unknown fields, and the service's path/body username mismatch error.", + "rust_symbols": ["gateway-rs/src/routes/platform.rs::normalize_user_credit_model", "gateway-rs/src/routes/platform.rs::credit_routes"], + "rust_tests": ["gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision"], + "status": "translated" + }, + "backend-services/models/update_password_model.py": { + "notes": "Rust matches the required field, Pydantic scalar-to-string coercion, Unicode character bounds, ignored unknown fields, and validation-before-authentication ordering.", + "rust_symbols": ["gateway-rs/src/routes/platform.rs::normalize_update_password_model"], + "rust_tests": ["gateway-rs/tests/platform_native.rs::update_password_model_validates_before_auth_and_matches_pydantic_bounds"], + "status": "translated" + }, + "backend-services/models/role_model_response.py": { + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": ["gateway-rs/src/routes/platform.rs::platform_openapi"], + "rust_tests": ["gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface"], + "status": "translated" + }, + "backend-services/models/routing_model_response.py": { + "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering and server_index exclusion; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", + "rust_symbols": ["gateway-rs/src/routes/platform.rs::platform_openapi"], + "rust_tests": ["gateway-rs/tests/openapi_parity.rs::openapi_matches_the_pinned_python_surface"], + "status": "translated" + }, + "backend-services/models/rate_limit_models.py": { + "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs", + "gateway-rs/src/policy/quota.rs", + "gateway-rs/src/policy/tier.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" + ], + "status": "partial" + }, + "backend-services/models/security_settings_model.py": { + "notes": "Rust matches all optional fields, null elision, Pydantic v1 scalar/list coercion, the 60-second lower bound, ignored unknown fields, and declaration-ordered validation errors.", + "rust_symbols": ["gateway-rs/src/routes/platform.rs::normalize_security_settings"], + "rust_tests": [ + "gateway-rs/src/routes/platform.rs::tests::security_settings_scalar_coercion_matches_python_model", + "gateway-rs/src/routes/platform.rs::tests::security_settings_list_coercion_and_indexed_errors_match_python", + "gateway-rs/src/routes/platform.rs::tests::security_settings_dump_path_coercion_matches_python_model", + "gateway-rs/src/routes/platform.rs::tests::security_settings_scalar_errors_follow_python_declaration_order" + ], + "status": "translated" + }, + "backend-services/models/create_vault_entry_model.py": { + "notes": "Rust matches required and optional fields, scalar-to-string coercion, Unicode character bounds, ignored unknown fields, and secret handling.", + "rust_symbols": ["gateway-rs/src/routes/platform.rs::vault_routes"], + "rust_tests": ["gateway-rs/tests/platform_native.rs::vault_lifecycle_encrypts_at_rest_and_never_returns_the_secret"], + "status": "translated" + }, + "backend-services/models/update_vault_entry_model.py": { + "notes": "Rust matches the optional nullable description, scalar-to-string coercion, Unicode character bound, and ignored unknown fields.", + "rust_symbols": ["gateway-rs/src/routes/platform.rs::vault_routes"], + "rust_tests": ["gateway-rs/tests/platform_native.rs::vault_lifecycle_encrypts_at_rest_and_never_returns_the_secret"], + "status": "translated" + }, + "backend-services/models/vault_entry_model_response.py": { + "notes": "The response model is declared but never imported or used by pinned production code; vault routes use ResponseModel instead.", + "rationale": "Unused Python response schema with no runtime contract to preserve.", + "rust_symbols": [], + "rust_tests": [], + "status": "approved_obsolete" + }, + "backend-services/models/validation_schema_model.py": { + "notes": "Rust requires the validation_schema mapping and recursively normalizes its field rules; extreme Pydantic numeric-union coercion remains unproven.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::normalize_validation_schema_model", + "gateway-rs/src/validation/json.rs::validate_json_with_registry" + ], + "rust_tests": [ + "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" + ], + "status": "partial" + }, + "backend-services/routes/authorization_routes.py": { + "notes": "Every route is mapped to native Rust. Login, registration, refresh-token claims/cookies, authentication-failure envelopes, and cookie deletion still have documented observable differences, so the module is not yet fully translated.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::login", + "gateway-rs/src/routes/platform.rs::register", + "gateway-rs/src/routes/platform.rs::authorization_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python", + "gateway-rs/tests/platform_native.rs::authorization_refresh_and_invalidate_match_python", + "gateway-rs/tests/platform_native.rs::authorization_admin_lifecycle_and_revoke_match_python" + ], + "status": "partial" + }, + "backend-services/routes/user_routes.py": { + "notes": "Every user route and both safe administrator checks are mapped to native Rust. Rust now matches public authenticated listing with administrator filtering, core CRUD permission ordering, bootstrap-admin protections, route-specific USR codes/messages, model validation, and role-change subscription pruning. Exact self-service restricted-field text and some auth/storage exceptional envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::user_routes", + "gateway-rs/src/routes/platform.rs::user_by", + "gateway-rs/src/routes/platform.rs::create_user" + ], + "rust_tests": [ + "gateway-rs/tests/user_lifecycle_parity.rs::self_service_updates_cannot_escalate_privileges", + "gateway-rs/tests/user_lifecycle_parity.rs::python_test_user_me_and_crud", + "gateway-rs/tests/user_lifecycle_parity.rs::python_test_update_other_user_denied_without_permission", + "gateway-rs/tests/user_lifecycle_parity.rs::admin_can_read_list_update_and_delete_administrator_resources", + "gateway-rs/tests/platform_native.rs::user_role_change_prunes_subscriptions_with_python_iteration_behavior" + ], + "status": "partial" + }, + "backend-services/routes/api_routes.py": { + "notes": "All API CRUD/list routes are implemented natively. Rust matches the pinned create/update-only manage_apis boundary (authenticated reads, listing, and deletion remain available without that permission), model validation, duplicate responses, pagination, immutable identity fields, public-credit exclusion, CRUD bodies, and missing-item status. The proto-upload-before-create path intentionally persists descriptor metadata differently and some auth/storage exceptional envelopes remain incomplete.", + "rust_symbols": ["gateway-rs/src/routes/platform.rs::api_routes"], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::least_privilege_role_cannot_create_apis_or_read_logs", + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts", + "gateway-rs/tests/platform_native.rs::python_api_and_endpoint_crud_lookup_and_missing_contracts" + ], + "status": "partial" + }, + "backend-services/routes/endpoint_routes.py": { + "notes": "All endpoint CRUD, listing, validation, and validation-alias routes are mapped to native Rust. Core endpoints match typed-model validation, create/update/delete permissions and route-specific denial codes, authenticated reads/listing, missing-item/list errors, immutable identity checks, duplicate/client-URI checks, and CRUD responses. Endpoint-validation service error semantics and a few exceptional storage envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::endpoint_routes", + "gateway-rs/src/routes/platform.rs::document_by_method" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::least_privilege_role_cannot_create_apis_or_read_logs", + "gateway-rs/tests/platform_native.rs::endpoint_models_match_pydantic_coercion_bounds_and_null_elision", + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" + ], + "status": "partial" + }, + "backend-services/routes/monitor_routes.py": { + "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness now matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. Metrics aggregation and report sections are present, but exact range/group/sort aggregation, Python date parsing, log-backed report reconstruction, daily bandwidth rows, and dynamic filenames remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::readiness", + "gateway-rs/src/routes/platform.rs::monitor_metrics", + "gateway-rs/src/routes/platform.rs::monitor_report" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::monitor_dashboard_liveness_readiness_and_metrics_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_report_returns_python_compatible_csv_sections", + "gateway-rs/tests/platform_native.rs::readiness_degrades_when_an_active_grpc_api_lacks_a_descriptor", + "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health" + ], + "status": "partial" + }, + "backend-services/routes/gateway_routes.py": { + "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively. The monolithic Python gateway implementation is distributed across Rust protocol/policy modules, and every exceptional fallback and duplicate legacy gRPC definition has not yet been mapped statement-for-statement.", + "rust_symbols": [ + "gateway-rs/src/routes/operations.rs", + "gateway-rs/src/routes/rest.rs", + "gateway-rs/src/routes/soap.rs", + "gateway-rs/src/routes/graphql.rs", + "gateway-rs/src/routes/grpc.rs" + ], + "rust_tests": [ + "gateway-rs/tests/runtime.rs::rust_health_matches_public_contract", + "gateway-rs/tests/runtime.rs::rust_serves_status_unauthorized_from_rust", + "gateway-rs/tests/runtime.rs::rust_handles_cache_delete_locally", + "gateway-rs/tests/runtime.rs::rest_head_uses_a_registered_get_endpoint_like_python", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "status": "partial" + }, + "backend-services/routes/config_routes.py": { + "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are implemented natively. Rust now matches granular export/import permission codes, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, malformed-entry handling, snapshots, and the pinned rollback error/success envelopes. Storage transactions are intentionally stronger than Python's sequential writes, and exact datetime representation plus every partial-write failure mode are not 1:1.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::config_export", + "gateway-rs/src/routes/platform.rs::config_import", + "gateway-rs/src/routes/platform.rs::config_rollback", + "gateway-rs/src/storage/runtime.rs::SharedStorage.import_configuration_atomically" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_config_export_sections_and_import_variants", + "gateway-rs/tests/platform_native.rs::python_config_permissions_granular_export_and_gateway_import_contracts", + "gateway-rs/tests/platform_native.rs::config_export_missing_named_resources_return_python_404", + "gateway-rs/tests/platform_native.rs::config_rollback_preserves_python_permission_and_missing_snapshot_quirks", + "gateway-rs/tests/platform_native.rs::python_config_import_ignores_malformed_entries", + "gateway-rs/tests/platform_native.rs::memory_mode_login_crud_import_and_rollback_are_native" + ], + "status": "partial" + }, + "backend-services/routes/credit_routes.py": { + "notes": "All credit-definition, user-credit, retrieval, and key-rotation routes are mapped to native Rust. Definition management now matches manage_credits gates, masked response fields, default paginated list shape, CRD021 misses, typed models, CRUD errors, and user-credit retrieval permissions. Exact query pagination/search, the Python path-username shadowing bug, encrypted key rotation/creation semantics, and some database-specific error envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::credit_routes", + "gateway-rs/src/routes/platform.rs::normalize_credit_model", + "gateway-rs/src/routes/platform.rs::normalize_user_credit_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_credit_definition_masks_secret_key_material", + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision", + "gateway-rs/tests/platform_native.rs::limited_role_cannot_manage_monitor_credits_caches_or_endpoint_validation" + ], + "status": "partial" + }, + "backend-services/routes/proto_routes.py": { + "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust now matches operation-specific AUTH001/API008 permission errors, case-insensitive filename extension handling, Python's ignored client filename, retrieval message/API002 miss, update message, nullable descriptor deletion, and delete-always-success behavior. Filesystem archive/package-init helpers are obsolete in the native runtime, while exact compiler diagnostics and every validation error string remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::proto_routes", + "gateway-rs/src/routes/platform.rs::compile_proto", + "gateway-rs/src/routes/platform.rs::backfill_grpc_descriptors" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract", + "gateway-rs/tests/platform_native.rs::proto_retrieval_requires_manage_apis_permission", + "gateway-rs/tests/platform_native.rs::descriptor_backfill_compiles_active_grpc_apis_missing_descriptors" + ], + "status": "partial" + }, + "backend-services/routes/tools_routes.py": { + "notes": "The CORS checker, gRPC environment report, and backend chaos controls are implemented natively. Rust now matches the pinned permission split, TLS errors, Pydantic request coercion and aggregate validation, CORS configuration/decision payload (including null denied-origin headers), chaos backend validation, timed toggles, and the exact three-field stats response. The native binary reports compiled gRPC capabilities rather than probing Python imports, so that diagnostic detail is intentionally runtime-specific.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::cors_check_config_from", + "gateway-rs/src/routes/platform.rs::cors_check", + "gateway-rs/src/routes/platform.rs::normalize_cors_check", + "gateway-rs/src/routes/platform.rs::normalize_chaos_toggle" + ], + "rust_tests": [ + "gateway-rs/src/routes/platform.rs::tests::tools_cors_checker_matches_pinned_python_matrix", + "gateway-rs/tests/platform_native.rs::tools_permissions_and_required_models_match_python", + "gateway-rs/tests/python_parity_suite.rs::parity_test_developer_tools_chaos_and_simulator", + "gateway-rs/tests/security_settings_parity.rs::live_tools_cors_check_matches_python" + ], + "status": "partial" + }, + "backend-services/routes/openapi_routes.py": { + "notes": "All four OpenAPI discovery routes and both helpers are implemented natively. Rust now matches manage_apis/manage_endpoints boundaries, route-specific errors and messages, ordered multi-server fetching, parsed endpoint shape, cached reads, refresh summary responses, fetch-on-import behavior, duplicate skipping, description truncation, and parse previews. Rust persists fetched specs with the API record instead of using Python's process-local one-hour cache, and exact malformed nested-spec exceptions/storage failure envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::openapi_discovery_route", + "gateway-rs/src/routes/platform.rs::fetch_openapi_spec", + "gateway-rs/src/routes/discovery.rs::parse_openapi", + "gateway-rs/src/routes/discovery.rs::openapi_endpoints" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::discovery_permissions_and_missing_document_contracts_match_python", + "gateway-rs/tests/platform_native.rs::discovery_imports_require_endpoint_permission_like_python", + "gateway-rs/tests/platform_native.rs::discovery_document_reads_fetch_once_and_reuse_the_python_cache_contract" + ], + "status": "partial" + }, + "backend-services/routes/memory_routes.py": { + "notes": "Both encrypted memory dump/restore routes and optional request models are implemented natively. Rust matches manage_security gates and SEC codes, memory-mode and key checks, Pydantic path validation/coercion, encrypted round trips, response nesting, missing-file handling, and generic failure envelopes. Rust deliberately restricts snapshot paths to the configured dump directory rather than accepting arbitrary filesystem paths, so path-policy behavior is not 1:1.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::memory_dump", + "gateway-rs/src/routes/platform.rs::memory_restore", + "gateway-rs/src/routes/platform.rs::memory_request_path", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/tests/memory_routes_parity.rs::python_memory_route_contracts_in_isolated_processes" + ], + "status": "partial" + }, + "backend-services/routes/role_routes.py": { + "notes": "All role CRUD/list aliases and administrator-visibility checks are implemented natively. Rust now matches authenticated permission-free reads, operation-specific ROLE009/010/011 denials, ROLE013-016 administrator protections, legacy platform_admin detection, service ROLE001/004/005 errors, sorted pagination metadata, non-admin filtering, Pydantic model normalization, and CRUD responses. Exact malformed integer query validation and exceptional cache/database failure envelopes remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::entity_routes", + "gateway-rs/src/routes/platform.rs::normalize_role_model", + "gateway-rs/src/routes/platform.rs::is_admin_role", + "gateway-rs/src/routes/platform.rs::is_admin_user" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::role_route_permissions_visibility_and_admin_codes_match_python", + "gateway-rs/tests/roles_groups_parity.rs::non_admin_managers_cannot_discover_or_manage_bootstrap_admin", + "gateway-rs/tests/roles_groups_parity.rs::missing_group_and_role_contracts_match_python_service_codes", + "gateway-rs/tests/roles_groups_parity.rs::python_test_roles_and_groups_crud" + ], + "status": "partial" + }, + "backend-services/routes/analytics_routes.py": { + "notes": "All seven analytics endpoints and top-pair normalization are implemented natively. Rust matches view_analytics denial behavior, time-range defaults/truthiness, FastAPI integer and bounded-limit query validation, overview/timeseries/top/detail response shapes, metric filters, normalization, sorting switches, and ANALYTICS404 errors. Native aggregate counters are not yet fully time-range scoped, endpoint latency/percentiles are placeholders, and Python's exact granularity rebucketing and snapshot percentile calculations remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::analytics_overview", + "gateway-rs/src/routes/platform.rs::analytics_timeseries", + "gateway-rs/src/routes/platform.rs::analytics_top", + "gateway-rs/src/routes/platform.rs::analytics_detail", + "gateway-rs/src/routes/platform.rs::analytics_query_error" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", + "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract" + ], + "status": "partial" + }, + "backend-services/routes/quota_routes.py": { + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::quota_routes", + "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", + "gateway-rs/src/routes/platform.rs::quota_values", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period", + "gateway-rs/src/routes/platform.rs::quota_tier_info" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "status": "partial" + }, + "backend-services/routes/rate_limit_rule_routes.py": { + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", + "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_integer", + "gateway-rs/src/routes/platform.rs::rate_rule_response" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" + ], + "status": "partial" + }, + "backend-services/routes/tier_routes.py": { + "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::tier_limits_response", + "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_public_and_protected_route_boundaries_match_python", + "gateway-rs/tests/platform_native.rs::tier_crud_returns_normalized_python_tier_contracts", + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" + ], + "status": "partial" + }, + "backend-services/utils/email_util.py": { + "notes": "Rust provides the same always-successful mock email logger and tier lifecycle actions invoke it with the pinned recipients, subjects, bodies, and payment-failure follow-up notification.", + "rust_symbols": [ + "gateway-rs/src/observability/email.rs::send_email", + "gateway-rs/src/routes/platform.rs::send_tier_notification" + ], + "rust_tests": [ + "gateway-rs/src/observability/email.rs::tests::mock_email_always_succeeds", + "gateway-rs/tests/platform_native.rs::tier_actions_create_python_style_assignment_records" + ], + "status": "translated" + }, + "backend-services/utils/group_util.py": { + "notes": "Rust resolves the authenticated user and API before enforcing the same non-empty group intersection and 401 detail across REST, SOAP, GraphQL, and gRPC. The monolithic evaluator replaces Python's path parsing/cache lookup, but exact malformed-path and missing-user exception fallbacks are not fully identical.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::evaluate_request", + "gateway-rs/src/policy/groups.rs::enforce_group_access" + ], + "rust_tests": [ + "gateway-rs/src/policy/groups.rs::tests::requires_group_intersection_for_legacy_contract" + ], + "status": "partial" + }, + "backend-services/utils/shared_metrics_util.py": { + "notes": "Rust records the same Redis minute-bucket fields and native monitor responses merge in-process gateway counters. Cross-process Redis bucket merging into monitor snapshots, including Python's exact day grouping, top-list merge, unique-user overcount, and fail-open scan behavior, is not yet implemented.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.record_gateway_metric", + "gateway-rs/src/routes/platform.rs::monitor_metrics" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity" + ], + "status": "partial" + }, + "backend-services/utils/subscription_util.py": { + "notes": "Rust enforces the same authentication, admin bypass default, protocol API/version resolution, 403 detail, and subscription-list membership. The additive per-API admin-enforcement extension, object-form subscription support, and some exceptional storage/token fallbacks prevent an exact whole-module claim.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::evaluate_request", + "gateway-rs/src/policy/subscription.rs::enforce_subscription" + ], + "rust_tests": [ + "gateway-rs/src/policy/subscription.rs::tests::admin_bypasses_subscription_unless_enforced", + "gateway-rs/src/policy/subscription.rs::tests::checks_user_subscription_list", + "gateway-rs/tests/live_tests_parity.rs::grpc_gateway_maps_upstream_statuses_parity" + ], + "status": "partial" + }, + "backend-services/utils/error_util.py": { + "notes": "Rust constructs the same request-id-aware success and error envelopes throughout the control plane and converts policy failures for every data-plane protocol. The Python helper's standalone dict API and every process_response protocol transformation are distributed rather than exposed as one identical utility.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::success", + "gateway-rs/src/routes/platform.rs::error", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/tests/runtime.rs::rust_rejects_unported_health_methods_in_rust" + ], + "status": "partial" + }, + "backend-services/utils/paging_util.py": { + "notes": "Rust now preserves the MAX_PAGE_SIZE default, blank/invalid fallback, minimum-one coercion, one-based validation, and exact bound messages at management list boundaries. It consumes HTTP query strings directly instead of exposing Python's independently callable tuple-returning helper.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::configured_max_page_size", + "gateway-rs/src/routes/platform.rs::validate_pagination" + ], + "rust_tests": [ + "gateway-rs/src/routes/platform.rs::tests::pagination_is_one_based_and_capped" + ], + "status": "partial" + }, + "backend-services/utils/api_resolution_util.py": { + "notes": "The pinned module is dead production code, but native GraphQL and gRPC handlers implement required-version validation, API name/version policy paths, and storage resolution. Exact behavior for direct calls with nested or empty arbitrary path strings is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/routes/graphql.rs::graphql_policy_then_execute", + "gateway-rs/src/routes/grpc.rs::grpc_policy_then_execute", + "gateway-rs/src/policy/evaluator.rs::evaluate_request" + ], + "rust_tests": [ + "gateway-rs/src/routes/grpc.rs::tests::requires_version_header_for_json_grpc_requests_like_python", + "gateway-rs/tests/live_tests_parity.rs::live_test_66_graphql_missing_version_header_parity" + ], + "status": "partial" + }, + "backend-services/utils/api_util.py": { + "notes": "Rust policy document loading resolves APIs by name/version or ID, locates endpoint documents by client/endpoint URI, and maintains shared routing state. Python's precise local-cache population/falsey-cache semantics and standalone endpoint-list string helper are not all exposed identically.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.load_policy_documents", + "gateway-rs/src/policy/evaluator.rs::evaluate_request" + ], + "rust_tests": [ + "gateway-rs/tests/runtime.rs::rest_head_uses_a_registered_get_endpoint_like_python" + ], + "status": "partial" + }, + "backend-services/utils/credit_util.py": { + "notes": "Rust atomically deducts credits, resolves user and definition headers, decrypts legacy enc: values, and implements old/new key rotation timing. Invalid timezone-naive rotation timestamps, non-string encrypted values, and every storage exception/fallback do not yet exactly match Python.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.deduct_credit", + "gateway-rs/src/policy/credits.rs::credit_header_values", + "gateway-rs/src/policy/credits.rs::evaluate_credits" + ], + "rust_tests": [ + "gateway-rs/src/policy/credits.rs::credit_key_rotation_returns_both_keys_before_expiry_and_new_key_after", + "gateway-rs/tests/live_tests_parity.rs::live_test_30_rest_gateway_basic_crud_and_subscription_parity" + ], + "status": "partial" + }, + "backend-services/utils/encryption_util.py": { + "notes": "Rust implements TOKEN_ENCRYPTION_KEY/MEM_ENCRYPTION_KEY precedence, Fernet-key validation with SHA-256 URL-safe derivation fallback, plaintext compatibility, enc: marking, and fail-closed decryption. Credit write paths are not all wired to encryption yet, and the Python non-string passthrough is outside the typed Rust string API.", + "rust_symbols": [ + "gateway-rs/src/storage/field_encryption.rs::encrypt_value", + "gateway-rs/src/storage/field_encryption.rs::decrypt_value" + ], + "rust_tests": [ + "gateway-rs/src/storage/field_encryption.rs::tests::plaintext_values_pass_through_without_an_encryption_marker" + ], + "status": "partial" + }, + "backend-services/utils/password_util.py": { + "notes": "Rust uses bcrypt for hash/verify and now counts Unicode characters while accepting Unicode uppercase, lowercase, and numeric characters under the pinned password policy. Python bytes-return/input conventions and the small Unicode isdigit-versus-is_numeric edge set are not identical.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::secure_password", + "gateway-rs/src/storage/runtime.rs::SharedStorage.connect" + ], + "rust_tests": [ + "gateway-rs/src/routes/platform.rs::tests::enforces_the_python_password_policy", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials" + ], + "status": "partial" + }, + "backend-services/utils/routing_util.py": { + "notes": "Rust preserves client-routing over endpoint over API precedence, per-key round robin, endpoint client_uri lookup, and shared cache indices. Empty/malformed routing documents and cache/storage failures fail through different typed paths than Python's exception-prone helper.", + "rust_symbols": [ + "gateway-rs/src/gateway/routing.rs::select_upstream", + "gateway-rs/src/policy/evaluator.rs::evaluate_request" + ], + "rust_tests": [ + "gateway-rs/src/gateway/routing.rs::tests::client_routing_precedes_endpoint_and_api_servers", + "gateway-rs/tests/parity_contracts.rs::rust_matches_checked_in_wire_contracts" + ], + "status": "partial" + }, + "backend-services/utils/audit_util.py": { + "notes": "Rust emits structured management and IP audit events and now matches Python's recursive sensitive-key exception rules plus JWT, authorization, API-key, hex, and private-key value redaction. Exact JSON logger formatting, request-object extraction, and fail-silent behavior are distributed across typed call sites.", + "rust_symbols": [ + "gateway-rs/src/observability/audit.rs::redact_record", + "gateway-rs/src/observability/audit.rs::management_mutation", + "gateway-rs/src/observability/audit.rs::global_ip_deny" + ], + "rust_tests": [ + "gateway-rs/src/observability/audit.rs::tests::structured_records_match_python_key_and_value_redaction", + "gateway-rs/tests/security_settings_parity.rs::log_export_filters_records_and_redacts_nested_credentials" + ], + "status": "partial" + }, + "backend-services/utils/cache_manager_util.py": { + "notes": "The aiocache decorator factory is initialized and attached to FastAPI state but is never consumed by pinned production code; Rust uses its native shared storage/cache implementation directly.", + "rationale": "Unused FastAPI/aiocache framework adapter made obsolete with removal of the Python application runtime.", + "rust_symbols": [], + "rust_tests": [], + "status": "approved_obsolete" + }, + "backend-services/utils/gateway_utils.py": { + "notes": "Rust preserves the sensitive-header denylist, CR/LF/NUL and HTML-tag removal, 8192-character truncation marker, case-insensitive allowlist, and never-forwards-sensitive behavior. Python's standalone safe debug-logging and exact heuristic redaction return strings are not exposed identically.", + "rust_symbols": [ + "gateway-rs/src/gateway/headers.rs::SENSITIVE_HEADERS", + "gateway-rs/src/routes/rest.rs::sanitize_forwarded_header_value" + ], + "rust_tests": [ + "gateway-rs/src/routes/rest.rs::tests::sanitizes_and_bounds_forwarded_header_values_like_python", + "gateway-rs/src/routes/rest.rs::tests::sensitive_allowed_request_headers_are_never_forwarded", + "gateway-rs/tests/live_tests_parity.rs::rest_request_and_response_header_allowlists_real_upstream_parity" + ], + "status": "partial" + }, + "backend-services/utils/vault_encryption_util.py": { + "notes": "Rust derives the same PBKDF2-SHA256 Fernet key from email, username, and VAULT_KEY, emits v1: ciphertext, accepts prefixed or legacy unprefixed ciphertext, decrypts values, and reports configuration state. Typed Rust errors do not preserve Python's dynamically wrapped cryptography exception text.", + "rust_symbols": [ + "gateway-rs/src/storage/vault.rs::encrypt", + "gateway-rs/src/storage/vault.rs::decrypt", + "gateway-rs/src/storage/vault.rs::is_configured" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::vault_lifecycle_encrypts_at_rest_and_never_returns_the_secret" + ], + "status": "partial" + }, + "backend-services/services/subscription_service.py": { + "notes": "Rust preserves API existence checks, subscription retrieval including the empty-list special case, subscribe/unsubscribe mutation, cache-backed shared state, request-id errors, messages, and SUB003-SUB006 contracts through native routes.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::subscription_routes" + ], + "rust_tests": [ + "gateway-rs/tests/live_tests_parity.rs::live_test_21_subscription_list_unsubscribe_parity", + "gateway-rs/tests/platform_native.rs::subscription_model_coerces_python_scalars_and_ignores_unknown_fields" + ], + "status": "translated" + }, + "backend-services/utils/grpc_util.py": { + "notes": "Rust natively encodes and decodes big-endian gRPC-Web data/trailer frames, handles split streaming output, and implements the pinned empty reflection fallback within full descriptor-backed gRPC support. The standalone Python parser's incomplete-buffer discard and duplicate default/custom trailer-line quirks are not reproduced byte-for-byte.", + "rust_symbols": [ + "gateway-rs/src/protocol/grpc.rs::decode_web_data_frame", + "gateway-rs/src/protocol/grpc.rs::web_data_frame", + "gateway-rs/src/protocol/grpc.rs::web_trailer_frame" + ], + "rust_tests": [ + "gateway-rs/src/protocol/grpc.rs::tests::grpc_web_frames_round_trip_and_emit_trailers", + "gateway-rs/tests/live_tests_parity.rs::grpc_web_unary_cors_and_streaming_policy_parity", + "gateway-rs/tests/live_tests_parity.rs::live_test_grpc_reflection_no_proto_parity" + ], + "status": "partial" + }, + "backend-services/utils/health_check_util.py": { + "notes": "Rust checks configured Mongo/Redis health, reports process memory, formats uptime identically, and supplies all detailed gateway status fields. active_connections currently reports active gateway requests instead of psutil network socket count, and OS inspection failure fallbacks differ.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.mongo_healthy", + "gateway-rs/src/storage/runtime.rs::SharedStorage.redis_healthy", + "gateway-rs/src/routes/operations.rs::status", + "gateway-rs/src/routes/operations.rs::memory_usage", + "gateway-rs/src/routes/operations.rs::format_uptime" + ], + "rust_tests": [ + "gateway-rs/src/routes/operations.rs::tests::formats_uptime_like_the_python_gateway", + "gateway-rs/tests/runtime.rs::rust_serves_status_unauthorized_from_rust" + ], + "status": "partial" + }, + "backend-services/utils/ip_policy_util.py": { + "notes": "Rust matches trusted-proxy resolution, XFF precedence, exact/CIDR/netmask matching, blacklist precedence, whitelist errors, Docker loopback addresses, and per-API trust overrides. Rust intentionally does not let a spoofable Host header alone trigger localhost bypass, and its typed audit/error plumbing differs from Python's broad fail-open catches.", + "rust_symbols": [ + "gateway-rs/src/policy/ip.rs::effective_client_ip_for_settings", + "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy" + ], + "rust_tests": [ + "gateway-rs/src/policy/ip.rs::tests::python_ip_pattern_dotted_masks_and_whitespace_match_reference", + "gateway-rs/src/policy/ip.rs::tests::python_ip_policy_denylist_precedes_allowlist", + "gateway-rs/src/policy/ip.rs::tests::localhost_host_header_cannot_bypass_an_ip_allowlist" + ], + "status": "partial" + }, + "backend-services/services/api_service.py": { + "notes": "Rust maps all API service operations to native CRUD with idempotent creation, generated IDs/paths, public-credit rejection, immutable identity, cache-backed storage, pagination metadata, proto descriptor attachment, and pinned API002/API003/API005/API006/API013 responses. Acknowledgement/cursor failure envelopes and a few cache-warming side effects remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::api_routes", + "gateway-rs/src/platform_contract.rs::normalize_create_api", + "gateway-rs/src/platform_contract.rs::normalize_update_api" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts", + "gateway-rs/tests/platform_native.rs::python_api_and_endpoint_crud_lookup_and_missing_contracts" + ], + "status": "partial" + }, + "backend-services/services/routing_service.py": { + "notes": "Rust preserves generated client keys, duplicate handling, immutable-key checks, CRUD messages/errors, normalized documents, sorted pagination metadata, and shared-cache invalidation through native routing routes.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::entity_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::routing_models_match_pydantic_generation_coercion_and_update_exclusion" + ], + "status": "translated" + }, + "backend-services/services/vault_service.py": { + "notes": "Rust preserves all user lookup, email/configuration validation, duplicate handling, encrypted persistence, secret suppression, timestamps, description-only updates, no-change success, deletion, and VAULT001-VAULT008 response behavior.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::vault_routes", + "gateway-rs/src/storage/vault.rs::encrypt" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::vault_lifecycle_encrypts_at_rest_and_never_returns_the_secret" + ], + "status": "translated" + }, + "backend-services/utils/chaos_util.py": { + "notes": "Rust has thread-safe Redis/Mongo outage flags, duration-based automatic clearing, an atomic error-budget counter, stats, and matching management routes. The flags are not yet consulted by native storage operations, so toggling them does not reproduce Python's injected backend failures.", + "rust_symbols": [ + "gateway-rs/src/middleware/chaos.rs::CHAOS_REDIS_OUTAGE", + "gateway-rs/src/middleware/chaos.rs::CHAOS_MONGO_OUTAGE", + "gateway-rs/src/middleware/chaos.rs::CHAOS_ERROR_BUDGET_BURN", + "gateway-rs/src/routes/platform.rs::platform_dispatch" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract", + "gateway-rs/tests/platform_native.rs::tools_permissions_and_required_models_match_python" + ], + "status": "partial" + }, + "backend-services/utils/sanitize_util.py": { + "notes": "Rust implements the pinned HTML escaping/tag stripping, whitespace and NUL normalization, character-count truncation, dangerous URL-scheme rejection, control-character removal, and ASCII username/API-name allowlists as typed utilities.", + "rust_symbols": [ + "gateway-rs/src/validation/sanitize.rs::sanitize_html", + "gateway-rs/src/validation/sanitize.rs::sanitize_input", + "gateway-rs/src/validation/sanitize.rs::sanitize_url", + "gateway-rs/src/validation/sanitize.rs::strip_control_characters", + "gateway-rs/src/validation/sanitize.rs::sanitize_username", + "gateway-rs/src/validation/sanitize.rs::sanitize_api_name" + ], + "rust_tests": [ + "gateway-rs/src/validation/sanitize.rs::tests::sanitizers_match_python_examples_and_character_limits" + ], + "status": "translated" + }, + "backend-services/services/group_service.py": { + "notes": "Rust preserves group existence checks, duplicate/create/update/delete/get behavior, immutable names, no-op and empty updates, cache-backed shared storage, sorted pagination metadata, messages, and GRP001-GRP007 errors.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::entity_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::role_and_group_models_match_pydantic_defaults_coercion_and_empty_updates", + "gateway-rs/tests/roles_groups_parity.rs::missing_group_and_role_contracts_match_python_service_codes" + ], + "status": "translated" + }, + "backend-services/services/role_service.py": { + "notes": "Rust preserves role existence checks, duplicate/create/update/delete/get behavior, immutable names, applied no-op updates, returned updated records, shared-cache state, sorted pagination metadata, messages, and ROLE001-ROLE008 errors.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::entity_routes" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::role_route_permissions_visibility_and_admin_codes_match_python", + "gateway-rs/tests/roles_groups_parity.rs::missing_group_and_role_contracts_match_python_service_codes" + ], + "status": "translated" + }, + "backend-services/utils/bandwidth_util.py": { + "notes": "Rust preserves window aliases/defaults, bucket keys, shared current usage, request-plus-response byte accounting, disabled/zero/missing-user bypass, and the pinned used-at-limit or content-length-over-limit 429 boundary. Storage failures are fail-closed in native external mode rather than Python's best-effort local fallback.", + "rust_symbols": [ + "gateway-rs/src/storage/redis.rs::bandwidth_key", + "gateway-rs/src/policy/bandwidth.rs::enforce_pre_request_limit", + "gateway-rs/src/policy/evaluator.rs::evaluate_request", + "gateway-rs/src/routes/rest.rs::proxy_request" + ], + "rust_tests": [ + "gateway-rs/src/policy/bandwidth.rs::tests::python_bandwidth_limit_blocks_after_usage_reaches_limit", + "gateway-rs/src/policy/bandwidth.rs::tests::python_bandwidth_limit_resets_in_the_next_window" + ], + "status": "partial" + }, + "backend-services/utils/role_util.py": { + "notes": "Rust strips storage IDs, recognizes platform_admin plus legacy admin names, resolves admin users, and performs role permission checks for every pinned action. Typed storage failures return false directly, so Python's intermediate cache warming and validate_platform_role 404-to-500 exception quirk are not reproduced everywhere.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::has_permission", + "gateway-rs/src/routes/platform.rs::is_admin_user", + "gateway-rs/src/routes/platform.rs::is_admin_role", + "gateway-rs/src/policy/roles.rs::is_admin_user" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs::role_route_permissions_visibility_and_admin_codes_match_python", + "gateway-rs/tests/roles_groups_parity.rs::non_admin_managers_cannot_discover_or_manage_bootstrap_admin" + ], + "status": "partial" + }, + "backend-services/utils/auth_util.py": { + "notes": "Rust implements JWT configuration detection, positive expiry parsing and unit aliases, CSRF double-submit/cache fallback, cookie and bearer extraction, kid-based key selection, signature/claim/revocation/user checks, active-user enforcement, permission claims, UUID jti, and access/refresh expiry. Some backend-outage detail mappings, testserver HTTPS heuristics, and legacy helper return conventions remain incomplete.", + "rust_symbols": [ + "gateway-rs/src/policy/auth.rs::verify_request_token", + "gateway-rs/src/routes/platform.rs::login", + "gateway-rs/src/routes/platform.rs::auth_expiry_seconds", + "gateway-rs/src/routes/platform.rs::refresh_expiry_seconds", + "gateway-rs/src/routes/operations.rs::require_manage_gateway" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::authorization_refresh_and_invalidate_match_python", + "gateway-rs/tests/platform_native.rs::https_mode_requires_matching_csrf_and_preserves_request_id" + ], + "status": "partial" + }, + "backend-services/utils/limit_throttle_util.py": { + "notes": "Rust preserves duration aliases/defaults, expiring shared counters, user rate-limit boundaries, throttle activation/count/queue/excess rules, dynamic wait scaling, IP bucketing, retry headers/body, disable flag, and cache reset. Python's process-local fallback after Redis errors and test-runtime minimum-sleep branches are intentionally absent from production-native enforcement.", + "rust_symbols": [ + "gateway-rs/src/policy/rate_limit.rs::duration_to_seconds", + "gateway-rs/src/policy/evaluator.rs::evaluate_request", + "gateway-rs/src/policy/throttle.rs::enforce_throttle", + "gateway-rs/src/routes/platform.rs::ip_rate_limit" + ], + "rust_tests": [ + "gateway-rs/src/policy/throttle.rs::tests::python_test_throttle_dynamic_wait_uses_fractional_seconds", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "status": "partial" + }, + "backend-services/utils/memory_log.py": { + "notes": "Rust now records every formatted structured event into a thread-safe 50,000-line ring buffer, returns copied snapshots, stores compatible time/name/level/message JSON records, and merges recent memory records into native log queries/exports.", + "rust_symbols": [ + "gateway-rs/src/observability/logging.rs::memory_log_snapshot", + "gateway-rs/src/observability/logging.rs::RedactingJsonEvent.format_event", + "gateway-rs/src/routes/platform.rs::read_log_records" + ], + "rust_tests": [ + "gateway-rs/src/observability/logging.rs::tests::json_sink_redacts_free_form_messages_and_sensitive_fields", + "gateway-rs/tests/security_settings_parity.rs::live_logging_endpoints_match_python" + ], + "status": "translated" + }, + "backend-services/utils/wsdl_util.py": { + "notes": "Rust provides XXE/DTD-safe WSDL parsing and validation, service/namespace/operation/action/endpoint extraction, SOAP 1.1/1.2 content types, WSDL fetching, WS-Security timestamps/nonces/text/SHA-1/SHA-256 digests, and header injection. XML serialization whitespace/prefix choices and exact fetch/parser exception strings are not byte-identical.", + "rust_symbols": [ + "gateway-rs/src/routes/discovery.rs::parse_wsdl", + "gateway-rs/src/protocol/soap.rs::prepare_request", + "gateway-rs/src/routes/platform.rs::api_discovery_routes" + ], + "rust_tests": [ + "gateway-rs/src/routes/discovery.rs::tests::parses_wsdl_operations_and_rejects_doctypes", + "gateway-rs/tests/platform_native.rs::memory_mode_parses_and_imports_wsdl_without_an_external_service", + "gateway-rs/tests/live_tests_parity.rs::soap_content_types_and_retry_real_upstream_parity" + ], + "status": "partial" + }, + "backend-services/utils/graphql_util.py": { + "notes": "Rust now matches Python's line-comment and quote stripping, brace depth, regex word complexity, keyword removal, depth limits, introspection fetching, schema operation/type extraction, and subscription discovery within native GraphQL routes. Some malformed schema shapes and standalone network failure return paths remain distributed rather than identical helper calls.", + "rust_symbols": [ + "gateway-rs/src/validation/graphql.rs::calculate_graphql_depth", + "gateway-rs/src/validation/graphql.rs::calculate_graphql_cost", + "gateway-rs/src/validation/graphql.rs::validate_graphql_query", + "gateway-rs/src/routes/platform.rs::api_discovery_routes" + ], + "rust_tests": [ + "gateway-rs/src/validation/graphql.rs::tests::validates_depth_and_cost", + "gateway-rs/tests/python_parity_suite.rs::parity_test_graphql_validation_and_introspection_policy" + ], + "status": "partial" + }, + "backend-services/utils/key_util.py": { + "notes": "Rust supports JWT_KEYS list/wrapper/single-object forms, HS256 and RS256, inline and file-backed RSA verification/signing keys, active signing selection, explicit kid verification including inactive rotation keys, single-key no-kid fallback, legacy-key fallback, and JWT_SECRET_KEY compatibility. Python's five-minute process cache and development import-time DEFAULT_DEV_KEY snapshot are not reproduced.", + "rust_symbols": [ + "gateway-rs/src/policy/auth.rs::select_configured_key", + "gateway-rs/src/routes/platform.rs::sign_token" + ], + "rust_tests": [ + "gateway-rs/src/policy/auth.rs::tests::configured_verification_key_selection_matches_legacy_kid_rules", + "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python" + ], + "status": "partial" + }, + "backend-services/services/endpoint_service.py": { + "notes": "Rust preserves endpoint and endpoint-validation CRUD, immutable identity fields, duplicate/client-URI conflict detection, API linkage, pagination, masking of storage internals, permissions, and the principal END00x response contracts. Python-only pre-generation of Python gRPC modules is not reproduced, and a few endpoint-validation storage failure codes remain consolidated by the native route layer.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::endpoint_routes", + "gateway-rs/src/routes/platform.rs::normalize_endpoint_validation_model" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts", + "gateway-rs/tests/live_tests_parity.rs::live_test_41_soap_and_85_endpoint_validation_parity" + ], + "status": "partial" + }, + "backend-services/services/logging_service.py": { + "notes": "Rust reads file and in-memory structured logs, now continues to the ring buffer when the log directory is absent, parses legacy text records, derives Python-compatible request/user/IP/endpoint/timing/status/type fields, applies date/time, case-insensitive substring, status, timing and exclusion filters, paginates newest-first, computes dashboard statistics, and exports JSON/CSV. File discovery is intentionally bounded and native export/read failure handling is not identical in every filesystem edge case.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::logging_routes", + "gateway-rs/src/routes/platform.rs::read_log_records", + "gateway-rs/src/routes/platform.rs::parse_log_record", + "gateway-rs/src/routes/platform.rs::log_record_matches" + ], + "rust_tests": [ + "gateway-rs/src/routes/platform.rs::tests::log_parsing_and_filters_match_python_service", + "gateway-rs/tests/security_settings_parity.rs::live_logging_endpoints_match_python" + ], + "status": "partial" + }, + "backend-services/services/credit_service.py": { + "notes": "Rust preserves credit-definition validation/CRUD/masking, definition and per-user pagination/search, user-credit upsert/read behavior, and key rotation. Credit definition keys and per-user keys are now encrypted on every write with the compatible field cipher, decrypted only for authorized user-credit reads, and rotation stores user_api_key while creating a missing user record as Python does. Some database-driver-specific error distinctions remain consolidated by shared storage.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::credit_routes", + "gateway-rs/src/routes/platform.rs::encrypt_credit_definition", + "gateway-rs/src/routes/platform.rs::transform_user_credit_keys", + "gateway-rs/src/storage/field_encryption.rs" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::python_credit_definition_masks_secret_key_material", + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision", + "gateway-rs/src/storage/field_encryption.rs::tests::plaintext_values_pass_through_without_an_encryption_marker" + ], + "status": "partial" + }, + "backend-services/services/rate_limit_rule_service.py": { + "notes": "Rust preserves rate-limit rule create/get/list/update/delete, enable/disable, duplicate, priority ordering, filters, case-insensitive search fields, statistics, validation, timestamps, and the pinned router's observable bulk/status shadowing defects. Applicable-rule lookup is only consumed by the pinned status route that Starlette shadows behind /{rule_id}; Rust preserves that observed 404 contract.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", + "gateway-rs/src/routes/platform.rs::rate_limit_management_routes" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts", + "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", + "gateway-rs/tests/platform_native.rs::rate_limit_crud_and_action_envelopes_match_python", + "gateway-rs/tests/platform_native.rs::rate_limit_management_is_public_and_uses_python_priority_search_contracts" + ], + "status": "translated" + }, + "backend-services/services/crud_service.py": { + "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults, and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation now matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. Generated discovery document formatting and some exceptional non-object payload paths are not byte-identical.", + "rust_symbols": [ + "gateway-rs/src/routes/rest.rs::execute_crud", + "gateway-rs/src/routes/rest.rs::validate_crud_schema", + "gateway-rs/src/protocol/crud.rs::execute" + ], + "rust_tests": [ + "gateway-rs/src/routes/rest.rs::tests::validates_crud_schema_and_extracts_resource_ids", + "gateway-rs/src/protocol/crud.rs::tests::discovers_all_crud_operations", + "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows" + ], + "status": "partial" + }, + "backend-services/services/user_service.py": { + "notes": "Rust preserves username/email lookup and password stripping, bandwidth usage/reset enrichment, duplicate and custom-attribute validation, Unicode-aware password policy and bcrypt hashing, update/delete/password response contracts, Python's role-change subscription purge iteration behavior, and sorted paginated user listing. Native routes also enforce v2 super-admin and self-update protections, while cache and database-driver-specific failure distinctions are consolidated.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::user_routes", + "gateway-rs/src/routes/platform.rs::user_by", + "gateway-rs/src/routes/platform.rs::create_user", + "gateway-rs/src/routes/platform.rs::purge_subscriptions_after_role_change" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python", + "gateway-rs/tests/python_parity_suite.rs" + ], + "status": "partial" + }, + "backend-services/utils/transform_util.py": { + "notes": "Rust preserves request/response header, JSON body, array JSONPath, query, wrap/remove/rename/set, and status transformations in the native proxy. Scalar header/query additions now use Python-compatible True/False/None spelling and status maps accept numeric strings. The unused Python TransformError and validate_transform_config helpers have no direct native call equivalents, and invalid HTTP header material is skipped at the typed HeaderMap boundary.", + "rust_symbols": [ + "gateway-rs/src/gateway/transforms.rs::transform_request", + "gateway-rs/src/gateway/transforms.rs::transform_response", + "gateway-rs/src/gateway/transforms.rs::set_path", + "gateway-rs/src/gateway/transforms.rs::take_path" + ], + "rust_tests": [ + "gateway-rs/src/gateway/transforms.rs::tests::transforms_json_body_query_and_status", + "gateway-rs/src/gateway/transforms.rs::tests::transforms_array_paths_like_the_python_gateway" + ], + "status": "partial" + }, + "backend-services/utils/hot_reload_config.py": { + "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. Python's generic in-process set/callback API is not used outside this module; dynamic LOG_LEVEL application and most advertised keys still require restart in Rust and are reported as such by the API.", + "rust_symbols": [ + "gateway-rs/src/hot_reload.rs::HotReloadConfig", + "gateway-rs/src/main.rs::spawn_sighup_reload", + "gateway-rs/src/routes/platform.rs::platform_dispatch" + ], + "rust_tests": [ + "gateway-rs/src/hot_reload.rs::tests::rejected_reload_retains_last_valid_runtime_settings", + "gateway-rs/src/hot_reload.rs::tests::flattens_json_configuration_like_the_python_manager", + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests" + ], + "status": "partial" + }, + "backend-services/utils/http_client.py": { + "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics now count each timed-out attempt as Python does. Reqwest does not expose separate Python httpx write/pool timeout controls, and network exception classes map through native client errors.", + "rust_symbols": [ + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/routes/rest.rs::retry_backoff", + "gateway-rs/src/gateway/circuit_breaker.rs", + "gateway-rs/src/config.rs::python_http_connect_timeout" + ], + "rust_tests": [ + "gateway-rs/src/gateway/circuit_breaker.rs::tests::opens_after_failures_then_half_open_failure_reopens_like_python", + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests", + "gateway-rs/tests/live_tests_parity.rs::soap_content_types_and_retry_real_upstream_parity" + ], + "status": "partial" + }, + "backend-services/utils/demo_seed_util.py": { + "notes": "Rust now implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, metrics, deterministic seeds, and collection-count results, in addition to the admin-only memory-mode demo endpoint. The seeded Rust RNG is reproducible but does not reproduce CPython's Mersenne Twister byte-for-byte, and the compact native analytics aggregator records generated metrics in the current minute rather than reconstructing 400 historical Python MinuteBucket timestamps.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::demo_seed", + "gateway-rs/src/demo_seed.rs::run_seed", + "gateway-rs/src/demo_seed.rs::SeedOptions" + ], + "rust_tests": [ + "gateway-rs/tests/roles_groups_parity.rs", + "gateway-rs/src/demo_seed.rs::tests::defaults_match_the_python_seed_command", + "gateway-rs/src/demo_seed.rs::tests::seeded_generators_are_reproducible", + "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults" + ], + "status": "partial" + }, + "backend-services/utils/doorman_cache_async.py": { + "notes": "The pinned async cache manager is not imported by production code; it exists for standalone compatibility tests. Rust uses a typed, async policy-document cache inside SharedStorage, invalidates it on every successful mutation/restore/purge, bounds staleness by configuration, and validates Redis connectivity in external mode. Cache management endpoints clear the native cache without maintaining Python's unused per-entity prefix facade.", + "rationale": "Unused Python async Redis/memory compatibility facade made obsolete by the native shared-storage policy cache.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.load_policy_documents", + "gateway-rs/src/storage/runtime.rs::SharedStorage.invalidate_policy_cache", + "gateway-rs/src/routes/operations.rs" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart", + "gateway-rs/tests/memory_routes_parity.rs" + ], + "status": "approved_obsolete" + }, + "backend-services/utils/database_async.py": { + "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language-specific; native external mode also validates its Redis dependency during the same connection phase.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/state.rs::AppState.from_config" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart", + "gateway-rs/tests/platform_native.rs::memory_mode_login_crud_import_and_rollback_are_native" + ], + "status": "partial" + }, + "backend-services/utils/async_db.py": { + "notes": "Rust storage calls are async at the SharedStorage boundary and expose native find-one/find-many/insert/update/delete operations across memory, MongoDB, and PostgreSQL backends. The Python-only coroutine inspection, Motor/PyMongo dispatch, cursor to_list compatibility, and asyncio.to_thread shim have no role after removal of Python database drivers.", + "rationale": "Language- and driver-specific async compatibility adapter made obsolete by Rust's typed async storage layer.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.find_many", + "gateway-rs/src/storage/runtime.rs::SharedStorage.find_one", + "gateway-rs/src/storage/runtime.rs::SharedStorage.insert_one", + "gateway-rs/src/storage/runtime.rs::SharedStorage.update_one", + "gateway-rs/src/storage/runtime.rs::SharedStorage.delete_one" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart" + ], + "status": "approved_obsolete" + }, + "backend-services/utils/memory_dump_util.py": { + "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore now decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy. Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model.", + "rust_symbols": [ + "gateway-rs/src/storage/snapshot.rs::dump", + "gateway-rs/src/storage/snapshot.rs::restore", + "gateway-rs/src/storage/snapshot.rs::restore_latest", + "gateway-rs/src/storage/snapshot.rs::restore_python_json_values", + "gateway-rs/src/storage/snapshot.rs::reconcile_bootstrap_admin" + ], + "rust_tests": [ + "gateway-rs/src/storage/snapshot.rs::tests::decrypts_a_dump_created_by_the_python_backend", + "gateway-rs/src/storage/snapshot.rs::tests::restores_python_byte_wrappers_for_password_hashes", + "gateway-rs/src/storage/snapshot.rs::tests::failed_restore_is_atomic_and_exact_file_restore_succeeds" + ], + "status": "partial" + }, + "backend-services/utils/auth_blacklist.py": { + "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery. Native bulk purge currently preserves malformed or missing-expiry JTI rows in external storage even though request-time checks safely ignore them.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::is_revoked", + "gateway-rs/src/routes/platform.rs::authorize", + "gateway-rs/src/storage/runtime.rs::SharedStorage.purge_expired_revocations", + "gateway-rs/src/main.rs::run_revocation_purge" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::expired_or_malformed_jti_revocations_do_not_block_requests", + "gateway-rs/tests/platform_native.rs::authorization_admin_lifecycle_and_revoke_match_python", + "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all" + ], + "status": "partial" + }, + "backend-services/utils/security_settings_util.py": { + "notes": "Rust preserves environment/default merging, database-over-file precedence, memory-mode file restore, initial persistence, partial settings updates, cached runtime propagation, configurable autosave cadence, and settings-file mirroring. The native worker reacts to settings changes without task restart, uses atomic owner-only file writes, and honors enable_auto_save; pinned Python's loop inadvertently dumps whenever memory mode and frequency are set even when enable_auto_save is false.", + "rust_symbols": [ + "gateway-rs/src/storage/security_settings.rs", + "gateway-rs/src/state.rs::MemoryAutosaveConfig", + "gateway-rs/src/storage/snapshot.rs::spawn_autosave", + "gateway-rs/src/routes/platform.rs::upsert_security_settings" + ], + "rust_tests": [ + "gateway-rs/src/storage/security_settings.rs::tests", + "gateway-rs/tests/security_settings_parity.rs" + ], + "status": "partial" + }, + "backend-services/utils/enhanced_metrics_util.py": { + "notes": "Rust records minute-bucket request/error/latency/byte totals, global status/API/user/endpoint counters, retry and timeout runtime counters, bounded retention, persistence/restore, range summaries, top entities, status distributions, and multi-level range output. Native buckets currently retain weighted latency averages rather than every raw latency sample, so percentile and per-endpoint latency output is approximate; top/status entity counters are process-global rather than reconstructed per requested range.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/routes/platform.rs::analytics_overview", + "gateway-rs/src/routes/platform.rs::analytics_timeseries" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts" + ], + "status": "partial" + }, + "backend-services/utils/metrics_util.py": { + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/routes/platform.rs::monitor_metrics" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_accepts_python_range_parameters_parity", + "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity" + ], + "status": "partial" + }, + "backend-services/utils/analytics_aggregator.py": { + "notes": "Rust retains minute metrics for the longer 30-day MetricsStore contract and aggregates range-query output into Python's five-minute (up to 24h), hourly (up to 7d), and daily (longer) levels, preserving request/error/byte totals and request-weighted latency. Native state does not persist three duplicate rollup deques, and its compact points do not retain Python's raw-latency percentile samples or per-bucket unique-user sets.", + "rust_symbols": [ + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_timeseries_range", + "gateway-rs/src/observability/analytics_aggregator.rs::aggregate_points" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::range_queries_use_python_aggregation_levels", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics" + ], + "status": "partial" + }, + "backend-services/utils/analytics_scheduler.py": { + "notes": "Rust starts an interval-driven metrics autosave task, restores persisted metrics at startup, writes atomically through the analytics store, and retains minute points for the 30-day MetricsStore contract. It does not maintain Python's separate scheduled five-minute, hourly, and daily deques; native analytics queries aggregate the retained minute series on demand.", + "rust_symbols": [ + "gateway-rs/src/main.rs::spawn_metrics_autosave", + "gateway-rs/src/main.rs::persist_metrics", + "gateway-rs/src/main.rs::restore_metrics", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request" + ], + "rust_tests": [ + "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics" + ], + "status": "partial" + }, + "backend-services/utils/quota_tracker.py": { + "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior. Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers; the pinned helper itself inconsistently mixes string keys and Redis hashes, and no production Python caller uses those paths.", + "rust_symbols": [ + "gateway-rs/src/policy/quota.rs::quota_usage_status", + "gateway-rs/src/policy/quota.rs::increment_quota_by", + "gateway-rs/src/routes/platform.rs::quota_status", + "gateway-rs/src/routes/platform.rs::quota_period" + ], + "rust_tests": [ + "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", + "gateway-rs/src/policy/quota.rs::tests::quota_increment_is_atomic_and_scoped_to_its_period", + "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" + ], + "status": "partial" + }, + "backend-services/utils/rate_limit_simulator.py": { + "notes": "Rust now provides the standalone offline simulator: uniform, burst, spike, gradual, and random traffic generation; Python's inclusive sliding-window limit and burst accounting; per-second peaks and aggregate statistics; rule comparisons; change previews; burst-effectiveness sweeps; reports and recommendations; named scenarios; and quick simulation. Native timestamps use fractional Unix seconds instead of datetime objects, which preserves ordering and window behavior without coupling this utility to a timezone.", + "rust_symbols": [ + "gateway-rs/src/policy/simulator.rs::generate_requests", + "gateway-rs/src/policy/simulator.rs::simulate_rule", + "gateway-rs/src/policy/simulator.rs::preview_rule_change", + "gateway-rs/src/policy/simulator.rs::test_burst_effectiveness", + "gateway-rs/src/policy/simulator.rs::generate_report", + "gateway-rs/src/policy/simulator.rs::run_scenario", + "gateway-rs/src/policy/simulator.rs::quick_simulate" + ], + "rust_tests": [ + "gateway-rs/src/policy/simulator.rs::tests::generates_python_traffic_patterns", + "gateway-rs/src/policy/simulator.rs::tests::simulates_limit_and_burst_like_python", + "gateway-rs/src/policy/simulator.rs::tests::comparison_and_scenario_helpers_preserve_python_shapes" + ], + "status": "translated" + }, + "backend-services/utils/rate_limiter.py": { + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::WindowCounter", + "gateway-rs/src/storage/cache.rs::TokenBucketCounter", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/policy/tier.rs::enforce", + "gateway-rs/src/storage/runtime.rs::SharedStorage.check_tier_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/rate_limit.rs::tests", + "gateway-rs/src/policy/tier.rs::tests", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "status": "partial" + }, + "backend-services/utils/validation_util.py": { + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "rust_symbols": [ + "gateway-rs/src/validation/json.rs::validate_json_with_registry", + "gateway-rs/src/validation/json.rs::ValidatorRegistry", + "gateway-rs/src/validation/xml.rs::soap_body_object", + "gateway-rs/src/routes/rest.rs::validate_protocol_request_with_registry", + "gateway-rs/src/routes/rest.rs::graphql_validation_schema" + ], + "rust_tests": [ + "gateway-rs/src/validation/json.rs::tests::preserves_python_validation_messages_and_coercion_edges", + "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", + "gateway-rs/src/validation/xml.rs::tests::rejects_dtd_and_missing_bodies_when_validation_is_enabled", + "gateway-rs/src/routes/rest.rs::tests::scopes_graphql_validation_to_the_named_operation" + ], + "status": "partial" + }, + "backend-services/utils/redis_client.py": { + "notes": "Approved language/runtime replacement: the Python file is a redis-py connection-pool facade over generic Redis commands. Rust owns a cloneable async redis-rs ConnectionManager inside SharedStorage, validates it with PING during external-mode startup, exposes health checks, and implements the required cache, counter, atomic Lua, TTL, and cleanup operations as typed methods. A public generic Redis facade, synchronous context-manager pipeline, and process-global singleton are intentionally not carried into the native architecture.", + "rationale": "Python-specific synchronous redis-py adapter and singleton lifecycle are obsolete in the async native storage runtime; required Redis behavior is implemented through typed SharedStorage operations.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window", + "gateway-rs/src/storage/runtime.rs::SharedStorage.redis_healthy" + ], + "rust_tests": [ + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "status": "approved_obsolete" + }, + "backend-services/utils/doorman_cache_util.py": { + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "rust_symbols": [ + "gateway-rs/src/storage/cache.rs::CacheName", + "gateway-rs/src/storage/memory.rs::MemoryStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.set_ephemeral", + "gateway-rs/src/storage/runtime.rs::SharedStorage.clear_gateway_state", + "gateway-rs/src/routes/operations.rs::clear_caches" + ], + "rust_tests": [ + "gateway-rs/src/storage/cache.rs::tests::preserves_python_cache_prefixes", + "gateway-rs/src/storage/cache.rs::tests::expires_window_counters", + "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" + ], + "status": "partial" + }, + "backend-services/utils/constants.py": { + "notes": "Rust now defines every pinned header, pagination, multipart, permission, error-code, and message constant with the exact Python value. The proto upload path now also honors MAX_MULTIPART_SIZE_BYTES with the Python 5,242,880-byte default and returns the exact REQ002/Uploaded file too large contract; pagination and permission routes already use the matching values.", + "rust_symbols": [ + "gateway-rs/src/constants.rs::Headers", + "gateway-rs/src/constants.rs::Defaults", + "gateway-rs/src/constants.rs::Roles", + "gateway-rs/src/constants.rs::ErrorCodes", + "gateway-rs/src/constants.rs::Messages", + "gateway-rs/src/routes/platform.rs::proto_routes" + ], + "rust_tests": [ + "gateway-rs/src/constants.rs::tests::preserves_python_defaults_and_wire_constants", + "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract" + ], + "status": "translated" + }, + "backend-services/utils/database.py": { + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "rust_symbols": [ + "gateway-rs/src/storage/runtime.rs::SharedStorage", + "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", + "gateway-rs/src/storage/runtime.rs::SharedStorage.initialize_core", + "gateway-rs/src/storage/runtime.rs::value_matches", + "gateway-rs/src/storage/runtime.rs::merge_object", + "gateway-rs/src/storage/snapshot.rs" + ], + "rust_tests": [ + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", + "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + ], + "status": "partial" + }, + "backend-services/utils/error_codes.py": { + "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", + "rust_symbols": [ + "gateway-rs/src/error_codes.rs::ErrorCode", + "gateway-rs/src/error_codes.rs::ErrorCodes", + "gateway-rs/src/routes/platform.rs", + "gateway-rs/src/policy/mod.rs::PolicyFailure" + ], + "rust_tests": [ + "gateway-rs/src/error_codes.rs::tests::preserves_representative_python_error_code_values", + "gateway-rs/tests/platform_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "status": "translated" + }, + "backend-services/utils/geo_lookup.py": { + "notes": "Rust now preserves the pinned placeholder lookup (cached UNKNOWN with 24-hour TTL), cached location fields, fail-open unknown/error policy, country block and allow lists, country-specific limits, exact access-denial reasons, sliding 24-hour country counters, sorted geographic distribution, and list retrieval. The native utility uses synchronized typed memory because the pinned module has no production callers; it can be replaced by an external GeoIP/storage provider without changing this contract.", + "rust_symbols": [ + "gateway-rs/src/policy/geo.rs::GeoLocation", + "gateway-rs/src/policy/geo.rs::GeoLookup.lookup_ip", + "gateway-rs/src/policy/geo.rs::GeoLookup.check_geographic_access", + "gateway-rs/src/policy/geo.rs::GeoLookup.get_geographic_distribution" + ], + "rust_tests": [ + "gateway-rs/src/policy/geo.rs::tests::unknown_locations_fail_open_like_python", + "gateway-rs/src/policy/geo.rs::tests::country_lists_limits_and_distribution_match_python" + ], + "status": "translated" + }, + "backend-services/utils/ip_rate_limiter.py": { + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "rust_symbols": [ + "gateway-rs/src/policy/ip.rs::effective_client_ip", + "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", + "gateway-rs/src/policy/rate_limit.rs::enforce_rate_limit", + "gateway-rs/src/storage/runtime.rs::SharedStorage.increment_window" + ], + "rust_tests": [ + "gateway-rs/src/policy/ip.rs::tests::trusts_forwarding_headers_when_enabled", + "gateway-rs/src/policy/ip.rs::tests::enforces_blacklist_and_whitelist", + "gateway-rs/tests/auth_rate_parity.rs" + ], + "status": "partial" + }, + "backend-services/services/gateway_service.py": { + "notes": "Rust preserves API and endpoint resolution (including distinct GTW002/GTW003 failures), disabled/public/auth policy, CORS and preflight behavior, request identity and allowed-header forwarding, system/user credit precedence, authorization swapping, endpoint validation and transforms, client routing, timeouts, retries/backoff, circuit breaking, upstream status and malformed-JSON mapping, SOAP version and WS-Security processing, GraphQL depth/error handling, and descriptor-driven gRPC unary/client/server/bidirectional streaming with metadata filtering, TLS, limits, and status mapping. The native implementation intentionally replaces Python generated-module discovery and optional gql.Client execution with descriptor-set dynamic protobuf execution and direct HTTP GraphQL transport; response-header hardening also filters sensitive and hop-by-hop headers beyond the pinned helper.", + "rust_symbols": [ + "gateway-rs/src/policy/evaluator.rs::evaluate_rest_policy", + "gateway-rs/src/routes/rest.rs::execute_rest", + "gateway-rs/src/protocol/soap.rs", + "gateway-rs/src/protocol/grpc.rs", + "gateway-rs/src/gateway/resolution.rs", + "gateway-rs/src/gateway/retries.rs", + "gateway-rs/src/gateway/transforms.rs" + ], + "rust_tests": [ + "gateway-rs/src/policy/evaluator.rs::tests::returns_no_endpoints_for_api_without_registered_endpoints", + "gateway-rs/src/routes/rest.rs::tests::rejects_malformed_json_from_rest_upstream_like_python", + "gateway-rs/tests/runtime.rs", + "gateway-rs/tests/grpc_native.rs", + "gateway-rs/tests/python_parity_suite.rs" + ], + "status": "partial" + }, + "backend-services/services/tier_service.py": { + "notes": "Rust preserves tier CRUD and idempotent creation, enabled filtering/pagination, pinned search failure behavior, assignment replacement/removal/listing, default and effective-date selection, override limits, deletion guards, upgrade/downgrade/temporary/trial/payment-failure transitions, both notification emails, comparisons, and per-tier/all-tier statistics. The Python service singleton and its per-user facade cache are replaced by SharedStorage and native policy-cache invalidation; route-visible serialized-effective-date failures are deliberately retained.", + "rust_symbols": [ + "gateway-rs/src/routes/platform.rs::tier_crud_routes", + "gateway-rs/src/routes/platform.rs::tier_management_routes", + "gateway-rs/src/routes/platform.rs::replace_tier_assignment", + "gateway-rs/src/routes/platform.rs::send_tier_notification", + "gateway-rs/src/policy/tier.rs::assignment_is_effective" + ], + "rust_tests": [ + "gateway-rs/tests/platform_native.rs::tier_assignment_create_returns_python_assignment_contract", + "gateway-rs/tests/platform_native.rs::tier_actions_and_failure_paths_match_python_contracts", + "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", + "gateway-rs/tests/platform_native.rs::tier_crud_routes_match_python_contracts" + ], + "status": "translated" + }, + "backend-services/utils/prometheus_metrics.py": { + "notes": "Rust preserves enable/disable behavior, the exact histogram buckets and names, nonnegative duration observations, status labels, retry/timeout counters, and Prometheus text rendering; native output also exposes the additive active-request gauge.", + "rust_symbols": [ + "gateway-rs/src/observability/metrics.rs::observe_request", + "gateway-rs/src/observability/metrics.rs::render", + "gateway-rs/src/routes/metrics.rs::metrics" + ], + "rust_tests": [ + "gateway-rs/src/observability/metrics.rs::tests::renders_python_compatible_metric_names", + "gateway-rs/tests/platform_native.rs::prometheus_metrics_exposition_counters_allowlist_and_token_match_python" + ], + "status": "translated" + } + }, + "schema_version": 1 +} diff --git a/scripts/generate_source_coverage_ledger.py b/scripts/generate_source_coverage_ledger.py new file mode 100644 index 00000000..a1595019 --- /dev/null +++ b/scripts/generate_source_coverage_ledger.py @@ -0,0 +1,276 @@ +#!/usr/bin/env python3 +"""Generate and validate the pinned Python-to-Rust source coverage ledger.""" + +from __future__ import annotations + +import argparse +import ast +import json +import subprocess +import sys +from collections import Counter, defaultdict +from dataclasses import dataclass +from pathlib import Path +from typing import Any, Iterator + + +ROOT = Path(__file__).resolve().parents[1] +REFERENCE_PATH = ROOT / "parity/reference.json" +OVERRIDES_PATH = ROOT / "parity/source_coverage_overrides.json" +LEDGER_PATH = ROOT / "parity/source_coverage_ledger.json" +VALID_STATUSES = { + "translated", + "partial", + "missing", + "approved_changed", + "approved_obsolete", + "unreviewed", +} + + +def git_text(*args: str) -> str: + return subprocess.check_output(["git", *args], cwd=ROOT, text=True) + + +def pinned_source_paths(commit: str) -> list[str]: + paths = git_text("ls-tree", "-r", "--name-only", commit, "--", "backend-services").splitlines() + return sorted( + path + for path in paths + if path.endswith(".py") + and not path.startswith("backend-services/tests/") + and not path.startswith("backend-services/live-tests/") + and "/__pycache__/" not in path + ) + + +def domain_for(path: str) -> str: + relative = Path(path).relative_to("backend-services") + if len(relative.parts) == 1: + return "application" + return "/".join(relative.parts[:-1]) + + +def decorator_names(node: ast.AST) -> list[str]: + decorators = getattr(node, "decorator_list", []) + return [ast.unparse(decorator) for decorator in decorators] + + +@dataclass(frozen=True) +class SourceUnit: + kind: str + name: str + line: int + decorators: tuple[str, ...] = () + + +class UnitVisitor(ast.NodeVisitor): + def __init__(self) -> None: + self.parents: list[tuple[str, str]] = [] + self.units: list[SourceUnit] = [] + + def qualified(self, name: str) -> str: + return ".".join([*(parent[0] for parent in self.parents), name]) + + def visit_ClassDef(self, node: ast.ClassDef) -> None: + self.units.append( + SourceUnit("class", self.qualified(node.name), node.lineno, tuple(decorator_names(node))) + ) + self.parents.append((node.name, "class")) + for statement in node.body: + if isinstance(statement, (ast.Assign, ast.AnnAssign)): + targets = statement.targets if isinstance(statement, ast.Assign) else [statement.target] + for target in targets: + if isinstance(target, ast.Name) and not target.id.startswith("_"): + self.units.append(SourceUnit("field", self.qualified(target.id), statement.lineno)) + self.visit(statement) + self.parents.pop() + + def visit_FunctionDef(self, node: ast.FunctionDef) -> None: + parent_kind = self.parents[-1][1] if self.parents else "" + kind = "method" if parent_kind == "class" else "function" + self.units.append( + SourceUnit(kind, self.qualified(node.name), node.lineno, tuple(decorator_names(node))) + ) + self.parents.append((node.name, kind)) + self.generic_visit(node) + self.parents.pop() + + def visit_AsyncFunctionDef(self, node: ast.AsyncFunctionDef) -> None: + parent_kind = self.parents[-1][1] if self.parents else "" + kind = "async_method" if parent_kind == "class" else "async_function" + self.units.append( + SourceUnit(kind, self.qualified(node.name), node.lineno, tuple(decorator_names(node))) + ) + self.parents.append((node.name, kind)) + self.generic_visit(node) + self.parents.pop() + + +def source_units(source: str, path: str) -> Iterator[SourceUnit]: + module = ast.parse(source, filename=path) + yield SourceUnit("module", Path(path).stem, 1) + visitor = UnitVisitor() + visitor.visit(module) + yield from visitor.units + + +def load_overrides() -> tuple[dict[str, dict[str, Any]], dict[str, dict[str, Any]]]: + data = json.loads(OVERRIDES_PATH.read_text()) + if ( + data.get("schema_version") != 1 + or not isinstance(data.get("entries"), dict) + or not isinstance(data.get("file_defaults", {}), dict) + ): + raise ValueError( + "source coverage overrides must contain schema_version=1, entries, and optional file_defaults" + ) + return data["entries"], data.get("file_defaults", {}) + + +def validate_override(unit_id: str, override: dict[str, Any]) -> None: + status = override.get("status") + if status not in VALID_STATUSES - {"unreviewed"}: + raise ValueError(f"{unit_id}: invalid reviewed status {status!r}") + rust_symbols = override.get("rust_symbols", []) + rust_tests = override.get("rust_tests", []) + if not isinstance(rust_symbols, list) or not all(isinstance(item, str) for item in rust_symbols): + raise ValueError(f"{unit_id}: rust_symbols must be a list of strings") + if not isinstance(rust_tests, list) or not all(isinstance(item, str) for item in rust_tests): + raise ValueError(f"{unit_id}: rust_tests must be a list of strings") + if status == "translated" and (not rust_symbols or not rust_tests): + raise ValueError(f"{unit_id}: translated units require Rust symbols and assertion-level tests") + if status == "partial" and not (rust_symbols or rust_tests): + raise ValueError(f"{unit_id}: partial units require existing Rust evidence") + if status.startswith("approved_") and not override.get("rationale"): + raise ValueError(f"{unit_id}: approved dispositions require a rationale") + + +def build_ledger() -> dict[str, Any]: + reference = json.loads(REFERENCE_PATH.read_text()) + commit = reference["commit"] + overrides, file_defaults = load_overrides() + entries: list[dict[str, Any]] = [] + seen: set[str] = set() + used_file_defaults: set[str] = set() + + for path, override in file_defaults.items(): + validate_override(f"{path}::*", override) + + for path in pinned_source_paths(commit): + source = git_text("show", f"{commit}:{path}") + occurrences: Counter[str] = Counter() + for unit in source_units(source, path): + base_id = f"{path}::{unit.kind}:{unit.name}" + occurrences[base_id] += 1 + unit_id = base_id if occurrences[base_id] == 1 else f"{base_id}#{occurrences[base_id]}" + if unit_id in seen: + raise ValueError(f"duplicate source unit ID: {unit_id}") + seen.add(unit_id) + override = overrides.pop(unit_id, None) + if override is None and path in file_defaults: + override = file_defaults[path] + used_file_defaults.add(path) + if override is None: + override = { + "status": "unreviewed", + "rust_symbols": [], + "rust_tests": [], + "notes": "Not yet reviewed against the pinned Python source.", + } + else: + validate_override(unit_id, override) + entries.append( + { + "id": unit_id, + "source": {"path": path, "line": unit.line, "kind": unit.kind}, + "domain": domain_for(path), + "decorators": list(unit.decorators), + "status": override["status"], + "rust_symbols": override.get("rust_symbols", []), + "rust_tests": override.get("rust_tests", []), + "notes": override.get("notes", ""), + **({"rationale": override["rationale"]} if "rationale" in override else {}), + } + ) + + if overrides: + unknown = ", ".join(sorted(overrides)[:10]) + raise ValueError(f"overrides refer to units absent from the pinned reference: {unknown}") + unused_file_defaults = set(file_defaults) - used_file_defaults + if unused_file_defaults: + unknown = ", ".join(sorted(unused_file_defaults)[:10]) + raise ValueError(f"file defaults refer to files absent from the pinned reference: {unknown}") + + status_counts = Counter(entry["status"] for entry in entries) + domain_counts: dict[str, Counter[str]] = defaultdict(Counter) + kind_counts = Counter(entry["source"]["kind"] for entry in entries) + for entry in entries: + domain_counts[entry["domain"]][entry["status"]] += 1 + reviewed = len(entries) - status_counts["unreviewed"] + + return { + "schema_version": 1, + "reference": {"git_ref": reference["git_ref"], "commit": commit}, + "generation": { + "command": "python3 scripts/generate_source_coverage_ledger.py --write", + "status_values": sorted(VALID_STATUSES), + }, + "summary": { + "total_source_units": len(entries), + "reviewed_source_units": reviewed, + "reviewed_percent": round(reviewed * 100 / len(entries), 2) if entries else 100.0, + "status_counts": dict(sorted(status_counts.items())), + "kind_counts": dict(sorted(kind_counts.items())), + "domain_status_counts": { + domain: dict(sorted(counts.items())) for domain, counts in sorted(domain_counts.items()) + }, + }, + "entries": entries, + } + + +def main() -> int: + parser = argparse.ArgumentParser() + mode = parser.add_mutually_exclusive_group(required=True) + mode.add_argument("--write", action="store_true", help="regenerate the checked-in ledger") + mode.add_argument("--check", action="store_true", help="verify the checked-in ledger is current") + args = parser.parse_args() + + try: + ledger = build_ledger() + except (OSError, ValueError, subprocess.CalledProcessError, SyntaxError) as error: + print(f"source coverage ledger error: {error}", file=sys.stderr) + return 1 + + rendered = json.dumps(ledger, indent=2, sort_keys=True) + "\n" + if args.write: + LEDGER_PATH.write_text(rendered) + summary = ledger["summary"] + print( + f"wrote {LEDGER_PATH.relative_to(ROOT)} with " + f"{summary['total_source_units']} source units" + ) + return 0 + + if not LEDGER_PATH.exists() or LEDGER_PATH.read_text() != rendered: + print( + "source coverage ledger is stale; run " + "python3 scripts/generate_source_coverage_ledger.py --write", + file=sys.stderr, + ) + return 1 + + summary = ledger["summary"] + print( + "source coverage ledger verified:", + f"units={summary['total_source_units']}", + f"reviewed={summary['reviewed_source_units']}", + f"reviewed_percent={summary['reviewed_percent']}", + " ".join(f"{status}={count}" for status, count in summary["status_counts"].items()), + ) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/release_check.py b/scripts/release_check.py index 52c7b742..c28e4bf4 100644 --- a/scripts/release_check.py +++ b/scripts/release_check.py @@ -302,6 +302,7 @@ def run_generated_checks(repo_root: Path) -> None: for command in ( [sys.executable, "scripts/check_parity_reference.py"], [sys.executable, "scripts/generate_test_coverage_ledger.py", "--check"], + [sys.executable, "scripts/generate_source_coverage_ledger.py", "--check"], ): completed = subprocess.run(command, cwd=repo_root, check=False) if completed.returncode != 0: diff --git a/scripts/run_e2e.py b/scripts/run_e2e.py index a4f34080..b09ab16b 100644 --- a/scripts/run_e2e.py +++ b/scripts/run_e2e.py @@ -32,7 +32,7 @@ ROOT = Path(__file__).resolve().parents[1] LOCAL_STAGES = ( "Runner/checker regression tests", - "Pinned Python reference and 600-entry coverage ledger", + "Pinned Python reference plus test and production-source coverage ledgers", "Rust formatting, Clippy, and complete Cargo suite", "Production frontend dependency audit", "Frontend dependency install and production build", @@ -255,7 +255,11 @@ def execute(self) -> None: [sys.executable, "-m", "unittest", "discover", "-s", "scripts", "-p", "test_*.py"], verification, ) - self.run("parity-inventory", ["make", "parity-reference", "parity-ledger"], verification) + self.run( + "parity-inventory", + ["make", "parity-reference", "parity-ledger", "parity-source-ledger"], + verification, + ) self.run("rust-checks", ["make", "check"], verification) self.run("frontend-audit", ["make", "web-audit"], verification) self.run("frontend-build", ["make", "web-build"], verification) diff --git a/user-docs/TESTS.md b/user-docs/TESTS.md index b81434a0..2874f5b8 100644 --- a/user-docs/TESTS.md +++ b/user-docs/TESTS.md @@ -19,7 +19,8 @@ make local-e2e `make test-e2e` remains an alias for `make local-e2e`. No separately running Doorman server is needed. This sequential, fail-fast runner: -1. Tests the Python verification scripts and checks the pinned reference/600-entry ledger. +1. Tests the Python verification scripts and checks the pinned reference plus the + test and production-source coverage ledgers. 2. Runs Rust formatting, Clippy, and the full Cargo suite (including protocol, platform, persistence, and process-lifecycle tests). 3. Installs frontend dependencies and builds the dashboard. From 207c6b35f74507f6b3038aab97bc9e253bd9a8fe Mon Sep 17 00:00:00 2001 From: seniorswe <57962648+seniorswe@users.noreply.github.com> Date: Mon, 28 Sep 2026 21:36:21 -0400 Subject: [PATCH 2/6] Rust migration --- docker-compose.yml | 1 + gateway-rs/Cargo.lock | 171 + gateway-rs/Cargo.toml | 4 +- gateway-rs/src/app.rs | 3 +- gateway-rs/src/config.rs | 95 +- gateway-rs/src/demo_seed.rs | 53 +- gateway-rs/src/gateway/transforms.rs | 58 +- gateway-rs/src/hot_reload.rs | 38 + gateway-rs/src/lib.rs | 1 + gateway-rs/src/main.rs | 43 +- gateway-rs/src/middleware/activity.rs | 34 +- gateway-rs/src/middleware/chaos.rs | 40 +- .../src/observability/analytics_aggregator.rs | 465 +- .../src/observability/analytics_models.rs | 634 ++ gateway-rs/src/observability/audit.rs | 94 + gateway-rs/src/observability/logging.rs | 107 +- gateway-rs/src/observability/metrics.rs | 9 + gateway-rs/src/observability/mod.rs | 1 + gateway-rs/src/platform_contract.rs | 15 +- gateway-rs/src/policy/bandwidth.rs | 33 +- gateway-rs/src/policy/evaluator.rs | 62 +- gateway-rs/src/policy/mod.rs | 2 + gateway-rs/src/policy/rate_limit.rs | 82 +- gateway-rs/src/policy/rate_limit_models.rs | 521 + gateway-rs/src/policy/throttle.rs | 37 +- gateway-rs/src/protocol/crud.rs | 361 +- gateway-rs/src/protocol/grpc.rs | 37 +- gateway-rs/src/routes/grpc.rs | 13 +- gateway-rs/src/routes/mod.rs | 1 + gateway-rs/src/routes/operations.rs | 11 + gateway-rs/src/routes/platform.rs | 2830 ++++-- gateway-rs/src/routes/rest.rs | 150 +- gateway-rs/src/routes/tls_admin.rs | 276 + gateway-rs/src/state.rs | 207 + gateway-rs/src/storage/memory.rs | 1 + gateway-rs/src/storage/runtime.rs | 236 +- gateway-rs/src/tls.rs | 197 + gateway-rs/src/tls/policy.rs | 149 + gateway-rs/src/tls/profiles.rs | 394 + gateway-rs/src/tls/secrets.rs | 60 + gateway-rs/src/validation/json.rs | 369 +- gateway-rs/src/validation/xml.rs | 47 +- gateway-rs/tests/bootstrap_admin_parity.rs | 50 + gateway-rs/tests/chaos_storage_parity.rs | 47 + gateway-rs/tests/crud_rest_parity.rs | 269 + .../tests/fixtures/crud_customer_api.proto | 27 + .../tests/fixtures/crud_customer_api.wsdl | 82 + gateway-rs/tests/live_tests_parity.rs | 49 +- gateway-rs/tests/platform_native.rs | 746 +- gateway-rs/tests/roles_groups_parity.rs | 15 +- gateway-rs/tests/runtime.rs | 42 + parity/differential/operation_approvals.json | 14 +- parity/source_coverage_ledger.json | 8872 +++++++++++------ parity/source_coverage_overrides.json | 541 +- parity/test_coverage_ledger.json | 47 +- parity/test_coverage_overrides.json | 39 +- user-docs/02-configuration.md | 6 + web-client/src/app/logging/page.tsx | 10 +- web-client/src/app/tls/page.tsx | 258 + web-client/src/components/Layout.tsx | 9 +- web-client/src/contexts/AuthContext.tsx | 16 +- 61 files changed, 14890 insertions(+), 4191 deletions(-) create mode 100644 gateway-rs/src/observability/analytics_models.rs create mode 100644 gateway-rs/src/policy/rate_limit_models.rs create mode 100644 gateway-rs/src/routes/tls_admin.rs create mode 100644 gateway-rs/src/tls.rs create mode 100644 gateway-rs/src/tls/policy.rs create mode 100644 gateway-rs/src/tls/profiles.rs create mode 100644 gateway-rs/src/tls/secrets.rs create mode 100644 gateway-rs/tests/chaos_storage_parity.rs create mode 100644 gateway-rs/tests/crud_rest_parity.rs create mode 100644 gateway-rs/tests/fixtures/crud_customer_api.proto create mode 100644 gateway-rs/tests/fixtures/crud_customer_api.wsdl create mode 100644 web-client/src/app/tls/page.tsx diff --git a/docker-compose.yml b/docker-compose.yml index 7590791e..9478e0b7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -34,6 +34,7 @@ services: MEM_AUTO_SAVE_FREQ: ${MEM_AUTO_SAVE_FREQ:-300} PYTHONINTMAXSTRDIGITS: ${PYTHONINTMAXSTRDIGITS:-4300} MEM_ENCRYPTION_KEY: ${MEM_ENCRYPTION_KEY:-} + LOGS_ENABLED: ${LOGS_ENABLED:-true} LOGS_DIR: /app/logs volumes: - doorman-generated:/app/data diff --git a/gateway-rs/Cargo.lock b/gateway-rs/Cargo.lock index faa9d46e..cf1c50cd 100644 --- a/gateway-rs/Cargo.lock +++ b/gateway-rs/Cargo.lock @@ -91,6 +91,45 @@ dependencies = [ "rustversion", ] +[[package]] +name = "asn1-rs" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7f43a50ac4fdca5df8e885c21b835997f0a1cdee65494a6847694a98652d9d8" +dependencies = [ + "asn1-rs-derive", + "asn1-rs-impl", + "displaydoc", + "nom", + "num-traits", + "rusticata-macros", + "thiserror", + "time", +] + +[[package]] +name = "asn1-rs-derive" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3109e49b1e4909e9db6515a30c633684d68cdeaa252f215214cb4fa1a5bfee2c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", + "synstructure", +] + +[[package]] +name = "asn1-rs-impl" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "async-compression" version = "0.4.43" @@ -126,6 +165,29 @@ version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" +[[package]] +name = "aws-lc-rs" +version = "1.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b281d307588d634de920874890732659e2e7672f72b5e10e81badc1a8a83621e" +dependencies = [ + "aws-lc-sys", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bff6c3b54fad79a2e60b8102caf565819711497c1f5f092f49508e2f5c31b27" +dependencies = [ + "cc", + "cmake", + "dunce", + "fs_extra", + "pkg-config", +] + [[package]] name = "axum" version = "0.8.9" @@ -339,6 +401,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5add81bb678e6cb321aff7fa0dc7689ad82b112dbc032cea19f91d6b8e3582b9" dependencies = [ "find-msvc-tools", + "jobserver", + "libc", "shlex", ] @@ -386,6 +450,15 @@ dependencies = [ "inout 0.2.2", ] +[[package]] +name = "cmake" +version = "0.1.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678" +dependencies = [ + "cc", +] + [[package]] name = "cmov" version = "0.5.4" @@ -601,6 +674,20 @@ version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4ae5f15dda3c708c0ade84bfee31ccab44a3da4f88015ed22f63732abe300c8" +[[package]] +name = "der-parser" +version = "10.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07da5016415d5a3c4dd39b11ed26f915f52fc4e0dc197d87908bc916e51bc1a6" +dependencies = [ + "asn1-rs", + "displaydoc", + "nom", + "num-bigint", + "num-traits", + "rusticata-macros", +] + [[package]] name = "deranged" version = "0.5.8" @@ -710,6 +797,7 @@ dependencies = [ "thiserror", "time", "tokio", + "tokio-rustls", "tonic", "tower", "tower-http", @@ -717,8 +805,15 @@ dependencies = [ "tracing-subscriber", "url", "uuid", + "x509-parser", ] +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + [[package]] name = "either" version = "1.17.0" @@ -807,6 +902,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + [[package]] name = "funty" version = "2.0.0" @@ -1333,6 +1434,16 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" +[[package]] +name = "jobserver" +version = "0.1.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c00acbd29eabad4a2392fa0e921c874934dbbf4194312ad20f04a0ed67a3cb3" +dependencies = [ + "getrandom 0.4.3", + "libc", +] + [[package]] name = "js-sys" version = "0.3.103" @@ -1483,6 +1594,12 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" version = "0.8.9" @@ -1597,6 +1714,16 @@ dependencies = [ "syn 2.0.119", ] +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + [[package]] name = "nu-ansi-term" version = "0.50.3" @@ -1640,6 +1767,15 @@ dependencies = [ "autocfg", ] +[[package]] +name = "oid-registry" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12f40cff3dde1b6087cc5d5f5d4d65712f34016a03ed60e9c08dcc392736b5b7" +dependencies = [ + "asn1-rs", +] + [[package]] name = "once_cell" version = "1.21.4" @@ -1734,6 +1870,12 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" +[[package]] +name = "pkg-config" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" + [[package]] name = "polyval" version = "0.7.3" @@ -2190,12 +2332,22 @@ dependencies = [ "semver", ] +[[package]] +name = "rusticata-macros" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632" +dependencies = [ + "nom", +] + [[package]] name = "rustls" version = "0.23.43" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0283386ce02abc0151e1761d08802dfe86c173b0b494af5cbc086574e453da06" dependencies = [ + "aws-lc-rs", "log", "once_cell", "ring", @@ -2221,6 +2373,7 @@ version = "0.103.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" dependencies = [ + "aws-lc-rs", "ring", "rustls-pki-types", "untrusted", @@ -2751,6 +2904,7 @@ dependencies = [ "tower-layer", "tower-service", "tracing", + "webpki-roots", ] [[package]] @@ -3299,6 +3453,23 @@ dependencies = [ "tap", ] +[[package]] +name = "x509-parser" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d43b0f71ce057da06bc0851b23ee24f3f86190b07203dd8f567d0b706a185202" +dependencies = [ + "asn1-rs", + "data-encoding", + "der-parser", + "lazy_static", + "nom", + "oid-registry", + "rusticata-macros", + "thiserror", + "time", +] + [[package]] name = "yoke" version = "0.8.3" diff --git a/gateway-rs/Cargo.toml b/gateway-rs/Cargo.toml index 81706071..1db97cdd 100644 --- a/gateway-rs/Cargo.toml +++ b/gateway-rs/Cargo.toml @@ -38,13 +38,15 @@ sha2 = "0.10" thiserror = "2.0" time = { version = "0.3", features = ["formatting"] } tokio = { version = "1.48", features = ["full"] } +tokio-rustls = "0.26" tower = { version = "0.5", features = ["util"] } tower-http = { version = "0.6.8", features = ["catch-panic", "compression-gzip", "trace", "sensitive-headers"] } -tonic = { version = "0.14", features = ["transport", "tls-ring"] } +tonic = { version = "0.14", features = ["transport", "tls-ring", "tls-webpki-roots"] } tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter", "fmt", "json"] } url = "2" uuid = { version = "1.18", features = ["v4"] } +x509-parser = "0.18" bcrypt = "0.19.3" aes-gcm = "0.11.0" hkdf = "0.12.4" diff --git a/gateway-rs/src/app.rs b/gateway-rs/src/app.rs index 2f0cd2df..970d4dea 100644 --- a/gateway-rs/src/app.rs +++ b/gateway-rs/src/app.rs @@ -27,7 +27,7 @@ use crate::{ grpc::grpc_policy_then_execute, grpc_web::grpc_web_policy_then_execute, metrics::metrics, - operations::{caches, health, status}, + operations::{caches, features, health, status}, platform::platform_dispatch, rest::rest_policy_then_proxy, soap::soap_policy_then_execute, @@ -52,6 +52,7 @@ pub fn build_router(state: AppState) -> Router { .route("/soap/{*path}", any(soap_policy_then_execute)) .route("/grpc/{*path}", any(grpc_policy_then_execute)) .route("/health", any(health)) + .route("/features", get(features)) .route("/status", any(status)) .route("/caches", any(caches)) .fallback(gateway_route_not_found) diff --git a/gateway-rs/src/config.rs b/gateway-rs/src/config.rs index 0c2c3346..25bf767a 100644 --- a/gateway-rs/src/config.rs +++ b/gateway-rs/src/config.rs @@ -9,17 +9,28 @@ pub struct Config { pub port: u16, pub connect_timeout: Duration, pub https_only: bool, + pub downstream_tls_mode: DownstreamTlsMode, + pub downstream_tls_cert_file: Option, + pub downstream_tls_key_file: Option, + pub tls_profiles_file: Option, pub content_security_policy: Option, pub compression_enabled: bool, pub compression_level: i32, pub compression_minimum_size: u16, pub strict_response_envelope: bool, pub websockets_enabled: bool, + pub logs_enabled: bool, pub logs_dir: Option, pub security_settings_file: Option, pub shared_storage: SharedStorageConfig, } +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum DownstreamTlsMode { + Proxy, + Native, +} + #[derive(Clone, Debug, Eq, PartialEq)] pub struct SharedStorageConfig { pub storage_mode: String, @@ -197,6 +208,28 @@ impl Config { }; let compression_minimum_size = env_parse::("COMPRESSION_MINIMUM_SIZE", 500)?.min(u64::from(u16::MAX)) as u16; + let logs_enabled = env_bool("LOGS_ENABLED", true); + let downstream_tls_mode = match env::var("DOWNSTREAM_TLS_MODE") + .unwrap_or_else(|_| "proxy".to_owned()) + .to_ascii_lowercase() + .as_str() + { + "proxy" => DownstreamTlsMode::Proxy, + "native" => DownstreamTlsMode::Native, + _ => return Err(ConfigError::InvalidConfiguration( + "DOWNSTREAM_TLS_MODE must be proxy or native".to_owned(), + )), + }; + let downstream_tls_cert_file = env_non_empty("DOWNSTREAM_TLS_CERT_FILE").map(PathBuf::from); + let downstream_tls_key_file = env_non_empty("DOWNSTREAM_TLS_KEY_FILE").map(PathBuf::from); + let tls_profiles_file = env_non_empty("TLS_PROFILES_FILE").map(PathBuf::from); + if downstream_tls_mode == DownstreamTlsMode::Native + && (downstream_tls_cert_file.is_none() || downstream_tls_key_file.is_none()) + { + return Err(ConfigError::InvalidConfiguration( + "native TLS requires DOWNSTREAM_TLS_CERT_FILE and DOWNSTREAM_TLS_KEY_FILE".to_owned(), + )); + } Ok(Self { host: env::var("HOST") @@ -205,6 +238,10 @@ impl Config { port: env_parse("PORT", 3001)?, connect_timeout: python_http_connect_timeout()?, https_only: env_bool("HTTPS_ONLY", false), + downstream_tls_mode, + downstream_tls_cert_file, + downstream_tls_key_file, + tls_profiles_file, content_security_policy: env::var("CONTENT_SECURITY_POLICY") .ok() .filter(|value| !value.trim().is_empty()), @@ -213,10 +250,15 @@ impl Config { compression_minimum_size, strict_response_envelope: env_bool("STRICT_RESPONSE_ENVELOPE", false), websockets_enabled: env_bool("WEBSOCKETS_ENABLED", false), - logs_dir: env_non_empty("LOGS_DIR").map(PathBuf::from).or_else(|| { - let path = PathBuf::from("/app/logs"); - path.exists().then_some(path) - }), + logs_enabled, + logs_dir: logs_enabled + .then(|| { + env_non_empty("LOGS_DIR").map(PathBuf::from).or_else(|| { + let path = PathBuf::from("/app/logs"); + path.exists().then_some(path) + }) + }) + .flatten(), shared_storage, security_settings_file: Some( env::var("SECURITY_SETTINGS_FILE") @@ -242,12 +284,17 @@ impl Config { port: 0, connect_timeout: Duration::from_secs(1), https_only: false, + downstream_tls_mode: DownstreamTlsMode::Proxy, + downstream_tls_cert_file: None, + downstream_tls_key_file: None, + tls_profiles_file: None, content_security_policy: None, compression_enabled: true, compression_level: 6, compression_minimum_size: 500, strict_response_envelope: false, websockets_enabled: false, + logs_enabled: true, logs_dir: None, // Tests opt into an isolated path when exercising file persistence. security_settings_file: None, @@ -541,6 +588,46 @@ mod tests { assert_eq!(config.compression_minimum_size, 500); } + #[test] + fn logs_can_be_disabled_at_environment_level() { + let _lock = ENV_LOCK.get_or_init(|| Mutex::new(())).lock().unwrap(); + let _environment = EnvRestore::set(&[ + ("ENV", "development"), + ("MEM_OR_EXTERNAL", "MEM"), + ("THREADS", "1"), + ("DOORMAN_ADMIN_PASSWORD", "DisabledLogsPassword123!"), + ( + "JWT_SECRET_KEY", + "disabled-logs-signing-key-at-least-32-characters", + ), + ("LOGS_ENABLED", "false"), + ("LOGS_DIR", "/tmp/doorman-disabled-logs-config-test"), + ]); + + let config = Config::from_env().unwrap(); + assert!(!config.logs_enabled); + assert!(config.logs_dir.is_none()); + } + + #[test] + fn native_tls_requires_both_pem_paths() { + let _lock = ENV_LOCK.get_or_init(|| Mutex::new(())).lock().unwrap(); + let _environment = EnvRestore::set(&[ + ("ENV", "development"), + ("MEM_OR_EXTERNAL", "MEM"), + ("THREADS", "1"), + ("DOORMAN_ADMIN_PASSWORD", "NativeTlsPassword123!"), + ("JWT_SECRET_KEY", "native-tls-signing-key-at-least-32-characters"), + ("DOWNSTREAM_TLS_MODE", "native"), + ("DOWNSTREAM_TLS_CERT_FILE", ""), + ("DOWNSTREAM_TLS_KEY_FILE", ""), + ]); + assert!(matches!( + Config::from_env(), + Err(ConfigError::InvalidConfiguration(message)) if message.contains("DOWNSTREAM_TLS_CERT_FILE") + )); + } + #[test] fn builds_python_compatible_storage_urls() { let storage = SharedStorageConfig { diff --git a/gateway-rs/src/demo_seed.rs b/gateway-rs/src/demo_seed.rs index 5be67bf0..43269054 100644 --- a/gateway-rs/src/demo_seed.rs +++ b/gateway-rs/src/demo_seed.rs @@ -453,7 +453,16 @@ fn seed_protos( } fn seed_metrics(users: &[String], apis: &[(String, String)], rng: &mut StdRng) { - for _ in 0..400 { + // Mirrors Python's seed_metrics(minutes=400): backfill 400 historical + // one-minute buckets (oldest first) instead of recording everything into + // the current minute, so a freshly seeded instance shows a real + // multi-hour timeseries. + let now = SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap_or_default() + .as_secs(); + for minutes_ago in (1..=400).rev() { + let timestamp = now.saturating_sub(minutes_ago * 60); for _ in 0..rng.random_range(0..=50) { let status = *choose(&[200_u16, 200, 200, 201, 204, 400, 401, 403, 404, 500], rng); let api = apis @@ -462,7 +471,8 @@ fn seed_metrics(users: &[String], apis: &[(String, String)], rng: &mut StdRng) { let user = users .get(rng.random_range(0..users.len().max(1))) .map(String::as_str); - global_analytics().record_request( + global_analytics().record_request_at( + timestamp, api.as_deref(), user, None, @@ -559,6 +569,45 @@ mod tests { ); } + #[test] + fn seed_metrics_backfills_historical_minute_buckets_like_python() { + let aggregator = crate::observability::analytics_aggregator::AnalyticsAggregator::new(); + let now = std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap() + .as_secs(); + // Mirror seed_metrics' own backfill loop against an isolated aggregator + // (not the process-global one) so the test is hermetic. + for minutes_ago in (1..=400).rev() { + let timestamp = now.saturating_sub(minutes_ago * 60); + aggregator.record_request_at( + timestamp, + Some("rest:demo"), + Some("admin"), + None, + 200, + 42.0, + 0, + 0, + ); + } + let series = aggregator.get_timeseries(); + assert_eq!(series.len(), 400, "one bucket per historical minute"); + let mut timestamps: Vec = series.iter().map(|point| point.timestamp).collect(); + let deduped_len = { + timestamps.dedup(); + timestamps.len() + }; + assert_eq!( + deduped_len, 400, + "each bucket has a distinct minute timestamp" + ); + assert!( + timestamps.windows(2).all(|pair| pair[0] < pair[1]), + "strictly increasing" + ); + } + #[test] fn seeded_generators_are_reproducible() { let mut first = StdRng::seed_from_u64(17); diff --git a/gateway-rs/src/gateway/transforms.rs b/gateway-rs/src/gateway/transforms.rs index 21136c4b..c425f9d9 100644 --- a/gateway-rs/src/gateway/transforms.rs +++ b/gateway-rs/src/gateway/transforms.rs @@ -167,29 +167,32 @@ struct PathPart { } fn path_parts(path: &str) -> Option> { - let path = path.trim().strip_prefix("$.")?; + // Python: only "$." prefixed paths; each segment is either `word[digits]` or a plain key. + let path = path.strip_prefix("$.")?; let mut parts = Vec::new(); for raw in path.split('.') { if raw.is_empty() { continue; } - let (field, index) = if let Some((field, raw_index)) = raw.split_once('[') { - let index = raw_index.strip_suffix(']')?.parse().ok()?; - (field, Some(index)) - } else { - (raw, None) - }; - if field.is_empty() - || !field - .chars() - .all(|character| character.is_ascii_alphanumeric() || character == '_') - { - return None; - } - parts.push(PathPart { - field: field.to_owned(), - index, + let indexed = raw.strip_suffix(']').and_then(|head| { + let (field, digits) = head.split_once('[')?; + let word = !field.is_empty() + && field + .chars() + .all(|character| character.is_alphanumeric() || character == '_'); + let numeric = !digits.is_empty() && digits.chars().all(|c| c.is_ascii_digit()); + (word && numeric).then_some((field, digits)) }); + match indexed { + Some((field, digits)) => parts.push(PathPart { + field: field.to_owned(), + index: Some(digits.parse().ok()?), + }), + None => parts.push(PathPart { + field: raw.to_owned(), + index: None, + }), + } } (!parts.is_empty()).then_some(parts) } @@ -347,4 +350,25 @@ mod tests { assert_eq!(value["items"][2]["created"], true); assert_eq!(value["tags"], serde_json::json!(["old", "new"])); } + + #[test] + fn jsonpath_segments_accept_any_plain_key_like_python() { + let config = serde_json::json!({"request": {"body": { + "remove": ["$.a-b"], + "set": {"$.first-name": "x", "$.p q.r": 1}, + "rename": {"$.old key": "$.new-key"} + }}}); + let (_, body, _) = transform_request( + HeaderMap::new(), + br#"{"a-b":1,"old key":"v"}"#.to_vec(), + None, + Some(&config), + ); + let value: Value = serde_json::from_slice(&body).unwrap(); + assert!(value.get("a-b").is_none()); + assert_eq!(value["first-name"], "x"); + assert_eq!(value["p q"]["r"], 1); + assert_eq!(value["new-key"], "v"); + assert!(value.get("old key").is_none()); + } } diff --git a/gateway-rs/src/hot_reload.rs b/gateway-rs/src/hot_reload.rs index 13f65feb..03e4d5d1 100644 --- a/gateway-rs/src/hot_reload.rs +++ b/gateway-rs/src/hot_reload.rs @@ -110,6 +110,14 @@ impl HotReloadConfig { .values .write() .map_err(|_| "hot-reload configuration lock is poisoned".to_owned())?; + // Python applies LOG_LEVEL immediately via a registered callback + // (`logging.getLogger().setLevel(new_value)`); apply it to the live + // tracing subscriber here instead of only recording it as reloaded. + if let Some(Value::String(level)) = loaded.get("LOG_LEVEL") + && values.get("LOG_LEVEL") != loaded.get("LOG_LEVEL") + { + crate::observability::logging::set_log_level(level); + } *values = loaded; Ok(()) } @@ -218,6 +226,36 @@ fn parse_env_value(value: &str) -> Value { mod tests { use super::*; + #[test] + fn log_level_changes_are_applied_without_erroring_the_reload() { + // The dynamic-apply path runs even when no tracing subscriber has been + // initialized in this test binary (`set_log_level` then safely no-ops); + // what this guards is that reload() itself never fails because of it, + // and that the new value is recorded either way. + // SAFETY: test-only; no other test in this crate reads LOG_LEVEL. + unsafe { + env::set_var("LOG_LEVEL", "debug"); + } + let config = HotReloadConfig::new(None); + assert_eq!( + config.dump().get("LOG_LEVEL").and_then(Value::as_str), + Some("debug") + ); + // SAFETY: test-only; no other test in this crate reads LOG_LEVEL. + unsafe { + env::set_var("LOG_LEVEL", "warn"); + } + assert!(config.reload().is_ok()); + assert_eq!( + config.dump().get("LOG_LEVEL").and_then(Value::as_str), + Some("warn") + ); + // SAFETY: test-only. + unsafe { + env::remove_var("LOG_LEVEL"); + } + } + #[test] fn rejected_reload_retains_last_valid_runtime_settings() { let directory = diff --git a/gateway-rs/src/lib.rs b/gateway-rs/src/lib.rs index 3519988a..6c2faef7 100644 --- a/gateway-rs/src/lib.rs +++ b/gateway-rs/src/lib.rs @@ -15,6 +15,7 @@ mod python_scalar; pub mod routes; pub mod state; pub mod storage; +pub mod tls; pub mod validation; pub use app::build_router; diff --git a/gateway-rs/src/main.rs b/gateway-rs/src/main.rs index d2b7fa84..f9db4185 100644 --- a/gateway-rs/src/main.rs +++ b/gateway-rs/src/main.rs @@ -15,12 +15,16 @@ use doorman_gateway::{ routes::platform::backfill_grpc_descriptors, state::{GatewayRuntime, MemoryAutosaveConfig}, storage::{runtime::SharedStorage, security_settings, snapshot}, + tls::{TlsConnectionInfo, TlsListener}, }; use tokio::net::TcpListener; use tracing::{error, info, warn}; #[tokio::main] async fn main() -> Result<(), Box> { + // Reqwest, Tonic, and the native listener enable different Rustls feature sets. + // Select one provider before any of them construct TLS configuration. + let _ = tokio_rustls::rustls::crypto::ring::default_provider().install_default(); doorman_gateway::observability::init(); match env::args().nth(1).as_deref() { @@ -108,16 +112,41 @@ async fn main() -> Result<(), Box> { } spawn_sighup_reload(state.hot_reload.clone()); - let app = build_router(state); + let tls_config = state.reload_tls_from_storage().await?; + let app = build_router(state.clone()); let listener = TcpListener::bind(&bind_addr).await?; + let reload_state = state.clone(); + let reload_task = tokio::spawn(async move { + let mut interval = tokio::time::interval(Duration::from_secs(15)); + interval.tick().await; + loop { + interval.tick().await; + if let Err(error) = reload_state.reload_tls_from_storage().await { + warn!(%error, "TLS reload rejected; retaining active configuration"); + } + } + }); + info!(address = %bind_addr, "Doorman Rust gateway listening"); - axum::serve( - listener, - app.into_make_service_with_connect_info::(), - ) - .with_graceful_shutdown(shutdown_signal()) - .await?; + if let Some(tls_config) = tls_config { + let listener = TlsListener::new(listener, tls_config); + state.set_tls_listener_handle(listener.reload_handle()); + axum::serve( + listener, + app.into_make_service_with_connect_info::(), + ) + .with_graceful_shutdown(shutdown_signal()) + .await?; + } else { + axum::serve( + listener, + app.into_make_service_with_connect_info::(), + ) + .with_graceful_shutdown(shutdown_signal()) + .await?; + } + reload_task.abort(); // Axum has now drained active requests. Stop writers before the final dump // so an older autosave cannot replace the state committed during draining. diff --git a/gateway-rs/src/middleware/activity.rs b/gateway-rs/src/middleware/activity.rs index c9266075..0026046b 100644 --- a/gateway-rs/src/middleware/activity.rs +++ b/gateway-rs/src/middleware/activity.rs @@ -79,6 +79,18 @@ pub async fn track_active_requests( .extensions() .get::>() .map(|value| value.0.ip().to_string()); + let user_agent = request + .headers() + .get(axum::http::header::USER_AGENT) + .and_then(|value| value.to_str().ok()) + .map(str::to_owned); + // Python's SecurityAuditMiddleware._should_audit: every modification + // method anywhere, plus every /platform/* request (its own comment notes + // the narrower vault/auth/tiers checks are already subsumed by this + // catch-all, since those paths all start with /platform/ too). + let should_audit_platform_request = + matches!(method.as_str(), "POST" | "PUT" | "DELETE" | "PATCH") + || path.starts_with("/platform/"); let record_analytics = path.starts_with("/api/") || path.starts_with("/grpc-web/"); let bytes_in = estimated_request_size(&request); let is_test = test_request(request.headers()); @@ -106,9 +118,25 @@ pub async fn track_active_requests( .active_requests .fetch_sub(1, Ordering::Relaxed); observe_request(&state.runtime, elapsed, status); - let fallback_api = api_key(&path); + // Only fall back to a path-derived API key for a response the gateway + // actually handled. A bare 404 means the route never resolved to a real + // API (context.api was never set), so recording analytics for it would + // fabricate a data point Python never produces -- its equivalent crashes + // deep in the service before any metrics are recorded for an unknown API. + let fallback_api = (status != 404).then(|| api_key(&path)).flatten(); let effective_api = context.api.as_deref().or(fallback_api.as_deref()); + if should_audit_platform_request { + crate::observability::audit::platform_request( + context.username.as_deref().unwrap_or("anonymous"), + &method, + &path, + status, + elapsed.as_secs_f64() * 1000.0, + user_agent.as_deref(), + ); + } + if record_analytics { state .runtime @@ -156,7 +184,9 @@ pub async fn track_active_requests( } } - if let Some(logs_dir) = state.config.logs_dir.as_deref() { + if state.config.logs_enabled + && let Some(logs_dir) = state.config.logs_dir.as_deref() + { let endpoint = context.endpoint.as_deref().unwrap_or(&path); let upstream = context .upstream diff --git a/gateway-rs/src/middleware/chaos.rs b/gateway-rs/src/middleware/chaos.rs index 7a53fea8..013274ea 100644 --- a/gateway-rs/src/middleware/chaos.rs +++ b/gateway-rs/src/middleware/chaos.rs @@ -46,7 +46,15 @@ pub async fn latency_injection(req: Request, next: Next) -> Response { enabled, req.headers() .get("x-doorman-latency") - .and_then(|value| value.to_str().ok()), + // Starlette decodes header bytes as latin-1. + .map(|value| { + value + .as_bytes() + .iter() + .map(|b| char::from(*b)) + .collect::() + }) + .as_deref(), ) { tokio::time::sleep(Duration::from_millis(delay)).await; } @@ -57,10 +65,27 @@ fn injected_latency_ms(enabled: bool, value: Option<&str>) -> Option { if !enabled { return None; } - let delay = value?.trim().parse::().ok()?.clamp(0, 5_000); + let text = crate::python_scalar::strip(value?); + let delay = match crate::python_scalar::parse_integer(text) { + Some(parsed) => parsed.clamp(0, 5_000), + // Python ints are unbounded; only magnitude beyond i128 needs the sign. + None if is_oversized_integer(text) => { + if text.starts_with('-') { + 0 + } else { + 5_000 + } + } + None => return None, + }; (delay > 0).then_some(delay as u64) } +fn is_oversized_integer(text: &str) -> bool { + let digits = text.strip_prefix(['+', '-']).unwrap_or(text); + digits.len() > 38 && digits.chars().all(|c| c.is_ascii_digit()) && digits.len() <= 4_300 +} + #[cfg(test)] mod tests { use super::injected_latency_ms; @@ -74,5 +99,16 @@ mod tests { assert_eq!(injected_latency_ms(true, Some("0")), None); assert_eq!(injected_latency_ms(true, Some(" 125 ")), Some(125)); assert_eq!(injected_latency_ms(true, Some("9000")), Some(5_000)); + assert_eq!(injected_latency_ms(true, Some("+1_0")), Some(10)); + assert_eq!(injected_latency_ms(true, Some("12")), Some(12)); + assert_eq!(injected_latency_ms(true, Some("1__0")), None); + assert_eq!( + injected_latency_ms(true, Some(&"9".repeat(60))), + Some(5_000) + ); + assert_eq!( + injected_latency_ms(true, Some(&format!("-{}", "9".repeat(60)))), + None + ); } } diff --git a/gateway-rs/src/observability/analytics_aggregator.rs b/gateway-rs/src/observability/analytics_aggregator.rs index cd7e0e90..39724ee1 100644 --- a/gateway-rs/src/observability/analytics_aggregator.rs +++ b/gateway-rs/src/observability/analytics_aggregator.rs @@ -16,6 +16,43 @@ pub struct AggregatedPoint { pub latency_ms: f64, pub bytes_in: u64, pub bytes_out: u64, + /// Bounded ring buffer of raw per-request latencies for this minute bucket, + /// mirroring Python's `MinuteBucket.latencies` deque. Not persisted to disk, + /// matching Python's `to_dict`/`from_dict`, which omit it. + #[serde(skip)] + pub latencies_ms: VecDeque, +} + +/// Mirrors Python's `os.getenv('METRICS_PCT_SAMPLES', '500')` cap on the +/// per-bucket raw-latency sample deque. +fn metrics_pct_samples() -> usize { + std::env::var("METRICS_PCT_SAMPLES") + .ok() + .and_then(|value| value.parse::().ok()) + .filter(|value| *value > 0) + .unwrap_or(500) +} + +impl AggregatedPoint { + /// Python's `snapshot()` percentile formula: sort the retained samples and + /// index at `max(0, int(0.95 * len) - 1)`. + pub fn p95_ms(&self) -> f64 { + if self.latencies_ms.is_empty() { + return 0.0; + } + let mut sorted: Vec = self.latencies_ms.iter().copied().collect(); + sorted.sort_by(|a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal)); + let index = ((0.95 * sorted.len() as f64) as usize).saturating_sub(1); + sorted[index.min(sorted.len() - 1)] + } + + fn push_latency_sample(&mut self, duration_ms: f64) { + let cap = metrics_pct_samples(); + self.latencies_ms.push_back(duration_ms); + while self.latencies_ms.len() > cap { + self.latencies_ms.pop_front(); + } + } } #[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)] @@ -25,6 +62,17 @@ pub struct EntityCounter { pub error_count: u64, } +#[derive(Debug, Clone, Default, PartialEq)] +pub struct EndpointEntity { + pub name: String, + pub count: u64, + pub error_count: u64, + pub avg_ms: f64, + /// (p50, p75, p90, p95, p99) over the range's pooled raw-latency samples, + /// using Python's `PercentileMetrics.calculate` sorted-index formula. + pub percentiles: (f64, f64, f64, f64, f64), +} + #[derive(Debug, Serialize, Deserialize, Default)] struct PythonMetricFile { #[serde(default)] @@ -83,8 +131,35 @@ struct PythonMetricBucket { endpoint_metrics: HashMap, } +/// Per-minute (count, error_count) for every entity name seen in that minute, +/// mirroring Python's `MinuteBucket.api_counts`/`user_counts`/per-endpoint +/// metrics. Kept in lockstep with `points` (same timestamps, same pruning) so +/// a time-scoped top-N query can be reconstructed for any [start, end] window +/// instead of only a process-global all-time total. +#[derive(Debug, Clone, Default)] +struct MinuteEntities { + timestamp: u64, + api: HashMap, + user: HashMap, + endpoint: HashMap, +} + +/// Per-endpoint, per-minute totals plus a capped raw-latency sample deque, so +/// a range-scoped query can compute both a real `avg_ms` (`total_ms / count`) +/// and real percentiles, matching Python's `EndpointMetrics.total_ms/count` +/// and `EndpointMetrics.get_percentiles()` instead of the fixed placeholders +/// the route used to return. +#[derive(Debug, Clone, Default)] +struct EndpointBucket { + count: u64, + errors: u64, + total_ms: f64, + latencies_ms: VecDeque, +} + pub struct AnalyticsAggregator { points: RwLock>, + entity_minutes: RwLock>, api_counters: RwLock>, api_error_counters: RwLock>, user_counters: RwLock>, @@ -98,6 +173,7 @@ impl AnalyticsAggregator { pub fn new() -> Self { Self { points: RwLock::new(VecDeque::with_capacity(43_200)), + entity_minutes: RwLock::new(VecDeque::with_capacity(43_200)), api_counters: RwLock::new(HashMap::new()), api_error_counters: RwLock::new(HashMap::new()), user_counters: RwLock::new(HashMap::new()), @@ -123,7 +199,38 @@ impl AnalyticsAggregator { .duration_since(UNIX_EPOCH) .unwrap_or_default() .as_secs(); - let minute_ts = (now / 60) * 60; + self.record_request_at( + now, + api_name, + username, + endpoint, + status, + duration_ms, + bytes_in, + bytes_out, + ); + } + + /// Like `record_request`, but files the sample under an explicit unix + /// timestamp rather than "now". Used by the demo seed to backfill + /// historical minute buckets the way Python's `seed_metrics` does, so a + /// freshly seeded instance shows a real multi-hour timeseries instead of + /// one spike in the current minute. Callers must invoke this in + /// non-decreasing `timestamp_secs` order, matching the append-only + /// bucket layout `record_request` relies on. + #[allow(clippy::too_many_arguments)] + pub fn record_request_at( + &self, + timestamp_secs: u64, + api_name: Option<&str>, + username: Option<&str>, + endpoint: Option<&str>, + status: u16, + duration_ms: f64, + bytes_in: u64, + bytes_out: u64, + ) { + let minute_ts = (timestamp_secs / 60) * 60; let is_error = status >= 400; increment(&self.status_counters, status, true); @@ -153,22 +260,177 @@ impl AnalyticsAggregator { last.bytes_out += bytes_out; last.latency_ms = ((last.latency_ms * previous as f64) + duration_ms) / last.requests as f64; - return; + last.push_latency_sample(duration_ms); + } else { + if points.len() >= 43_200 { + points.pop_front(); + } + let mut point = AggregatedPoint { + timestamp: minute_ts, + requests: 1, + errors: u64::from(is_error), + latency_ms: duration_ms, + bytes_in, + bytes_out, + latencies_ms: VecDeque::new(), + }; + point.push_latency_sample(duration_ms); + points.push_back(point); } - if points.len() >= 43_200 { - points.pop_front(); + } + + if let Ok(mut minutes) = self.entity_minutes.write() { + let bucket = if minutes + .back() + .is_some_and(|last| last.timestamp == minute_ts) + { + minutes.back_mut().unwrap() + } else { + if minutes.len() >= 43_200 { + minutes.pop_front(); + } + minutes.push_back(MinuteEntities { + timestamp: minute_ts, + ..Default::default() + }); + minutes.back_mut().unwrap() + }; + if let Some(api) = api_name { + let entry = bucket.api.entry(api.to_owned()).or_default(); + entry.0 += 1; + entry.1 += u64::from(is_error); + } + if let Some(user) = username { + let entry = bucket.user.entry(user.to_owned()).or_default(); + entry.0 += 1; + entry.1 += u64::from(is_error); + } + if let Some(endpoint) = endpoint { + let entry = bucket.endpoint.entry(endpoint.to_owned()).or_default(); + entry.count += 1; + entry.errors += u64::from(is_error); + entry.total_ms += duration_ms; + let cap = metrics_pct_samples(); + entry.latencies_ms.push_back(duration_ms); + while entry.latencies_ms.len() > cap { + entry.latencies_ms.pop_front(); + } } - points.push_back(AggregatedPoint { - timestamp: minute_ts, - requests: 1, - errors: u64::from(is_error), - latency_ms: duration_ms, - bytes_in, - bytes_out, - }); } } + /// Time-scoped equivalent of `get_top_apis`/`get_top_users`/`get_top_endpoints`, + /// reconstructing totals from only the minute buckets in `[start_ts, end_ts]` + /// instead of the process-global all-time counters. Mirrors Python's + /// `enhanced_metrics_store.get_snapshot(start_ts, end_ts)`-backed top lists. + fn top_entities_in_range( + &self, + start_ts: u64, + end_ts: u64, + limit: usize, + select: impl Fn(&MinuteEntities) -> &HashMap, + ) -> Vec { + let mut totals: HashMap = HashMap::new(); + if let Ok(minutes) = self.entity_minutes.read() { + for bucket in minutes + .iter() + .filter(|bucket| bucket.timestamp >= start_ts && bucket.timestamp <= end_ts) + { + for (name, (count, errors)) in select(bucket) { + let entry = totals.entry(name.clone()).or_default(); + entry.0 += count; + entry.1 += errors; + } + } + } + let mut items = totals + .into_iter() + .map(|(name, (count, error_count))| EntityCounter { + name, + count, + error_count, + }) + .collect::>(); + items.sort_by(|left, right| { + right + .count + .cmp(&left.count) + .then_with(|| left.name.cmp(&right.name)) + }); + items.truncate(limit); + items + } + + pub fn get_top_apis_in_range( + &self, + start_ts: u64, + end_ts: u64, + limit: usize, + ) -> Vec { + self.top_entities_in_range(start_ts, end_ts, limit, |bucket| &bucket.api) + } + + pub fn get_top_users_in_range( + &self, + start_ts: u64, + end_ts: u64, + limit: usize, + ) -> Vec { + self.top_entities_in_range(start_ts, end_ts, limit, |bucket| &bucket.user) + } + + /// Like `get_top_apis_in_range`/`get_top_users_in_range`, but also + /// reconstructs a real `avg_ms` per endpoint from the range's pooled + /// `total_ms`, matching Python's `EndpointMetrics.total_ms / count` + /// (`enhanced_metrics_util.py`'s `top_endpoints` builder) instead of the + /// fixed `0.0` the route previously returned. + pub fn get_top_endpoints_in_range( + &self, + start_ts: u64, + end_ts: u64, + limit: usize, + ) -> Vec { + let mut totals: HashMap = HashMap::new(); + if let Ok(minutes) = self.entity_minutes.read() { + for bucket in minutes + .iter() + .filter(|bucket| bucket.timestamp >= start_ts && bucket.timestamp <= end_ts) + { + for (name, sample) in &bucket.endpoint { + let entry = totals.entry(name.clone()).or_default(); + entry.count += sample.count; + entry.errors += sample.errors; + entry.total_ms += sample.total_ms; + entry + .latencies_ms + .extend(sample.latencies_ms.iter().copied()); + } + } + } + let mut items = totals + .into_iter() + .map(|(name, bucket)| EndpointEntity { + name, + count: bucket.count, + error_count: bucket.errors, + avg_ms: if bucket.count == 0 { + 0.0 + } else { + bucket.total_ms / bucket.count as f64 + }, + percentiles: pooled_percentiles(bucket.latencies_ms.iter().copied()), + }) + .collect::>(); + items.sort_by(|left, right| { + right + .count + .cmp(&left.count) + .then_with(|| left.name.cmp(&right.name)) + }); + items.truncate(limit); + items + } + pub fn get_timeseries(&self) -> Vec { self.points .read() @@ -311,6 +573,7 @@ impl AnalyticsAggregator { }, bytes_in: bucket.bytes_in, bytes_out: bucket.bytes_out, + latencies_ms: VecDeque::new(), }) .collect::>(); while points.len() > 43_200 { @@ -355,6 +618,9 @@ fn aggregate_points(points: Vec, interval: u64) -> Vec) -> (f64, f64, f64, f64, f64) { + let mut values: Vec = samples.collect(); + if values.is_empty() { + return (0.0, 0.0, 0.0, 0.0, 0.0); + } + values.sort_by(|left, right| left.total_cmp(right)); + let n = values.len(); + let percentile = |fraction: f64| values[((fraction * n as f64) as usize).saturating_sub(1)]; + ( + percentile(0.50), + percentile(0.75), + percentile(0.90), + percentile(0.95), + percentile(0.99), + ) +} + fn increment(map: &RwLock>, key: K, enabled: bool) where K: Eq + std::hash::Hash, @@ -437,6 +723,92 @@ pub fn global_analytics() -> &'static Arc { mod tests { use super::*; + /// `METRICS_PCT_SAMPLES` is process-global; Rust's default test harness + /// runs tests in parallel threads within one process, so any test that + /// sets it (or is sensitive to its ambient value while pushing several + /// samples) must serialize against every other such test to avoid a + /// cross-test race. + static METRICS_PCT_SAMPLES_LOCK: std::sync::OnceLock> = + std::sync::OnceLock::new(); + + #[test] + fn top_entities_in_range_reconstructs_from_only_the_selected_minutes() { + let aggregator = AnalyticsAggregator::new(); + // Minute 0: alice hits `api-a` twice (one error). + aggregator.record_request_at(0, Some("api-a"), Some("alice"), Some("/x"), 200, 1.0, 0, 0); + aggregator.record_request_at(0, Some("api-a"), Some("alice"), Some("/x"), 500, 1.0, 0, 0); + // Minute 120 (outside the queried window below): bob hits `api-b` three times. + aggregator.record_request_at(120, Some("api-b"), Some("bob"), Some("/y"), 200, 1.0, 0, 0); + aggregator.record_request_at(120, Some("api-b"), Some("bob"), Some("/y"), 200, 1.0, 0, 0); + aggregator.record_request_at(120, Some("api-b"), Some("bob"), Some("/y"), 200, 1.0, 0, 0); + + // Query only minute 0's window: api-b/bob must not appear at all. + let top_apis = aggregator.get_top_apis_in_range(0, 59, 10); + assert_eq!(top_apis.len(), 1); + assert_eq!(top_apis[0].name, "api-a"); + assert_eq!(top_apis[0].count, 2); + assert_eq!(top_apis[0].error_count, 1); + + let top_users = aggregator.get_top_users_in_range(0, 59, 10); + assert_eq!( + top_users, + vec![EntityCounter { + name: "alice".to_owned(), + count: 2, + error_count: 1 + }] + ); + + // Querying the full range picks up both minutes, with api-b (3) ranked above api-a (2). + let both = aggregator.get_top_apis_in_range(0, 200, 10); + assert_eq!(both.len(), 2); + assert_eq!(both[0].name, "api-b"); + assert_eq!(both[0].count, 3); + assert_eq!(both[1].name, "api-a"); + } + + #[test] + fn get_top_endpoints_in_range_computes_a_real_avg_ms_like_python() { + let aggregator = AnalyticsAggregator::new(); + aggregator.record_request_at(0, None, None, Some("/orders"), 200, 10.0, 0, 0); + aggregator.record_request_at(0, None, None, Some("/orders"), 500, 30.0, 0, 0); + aggregator.record_request_at(120, None, None, Some("/orders"), 200, 1000.0, 0, 0); + + let endpoints = aggregator.get_top_endpoints_in_range(0, 59, 10); + assert_eq!(endpoints.len(), 1); + assert_eq!(endpoints[0].name, "/orders"); + assert_eq!(endpoints[0].count, 2); + assert_eq!(endpoints[0].error_count, 1); + // (10 + 30) / 2 = 20, not diluted by the out-of-range 1000ms sample. + assert_eq!(endpoints[0].avg_ms, 20.0); + } + + #[test] + fn get_top_endpoints_in_range_computes_real_percentiles_like_python() { + // Sensitive to the ambient METRICS_PCT_SAMPLES cap (pushes samples + // past a small cap set by another test would otherwise evict some). + let _guard = METRICS_PCT_SAMPLES_LOCK + .get_or_init(|| std::sync::Mutex::new(())) + .lock(); + let aggregator = AnalyticsAggregator::new(); + for latency in [10.0, 20.0, 30.0, 40.0, 100.0] { + aggregator.record_request_at(0, None, None, Some("/orders"), 200, latency, 0, 0); + } + // Out-of-range sample must not pollute the pooled percentiles. + aggregator.record_request_at(120, None, None, Some("/orders"), 200, 99999.0, 0, 0); + + let endpoints = aggregator.get_top_endpoints_in_range(0, 59, 10); + assert_eq!(endpoints.len(), 1); + // Sorted: [10, 20, 30, 40, 100], n=5. + // p50: k=max(0,int(0.5*5)-1)=1 -> 20 + // p95: k=max(0,int(0.95*5)-1)=3 -> 40 + // p99: k=max(0,int(0.99*5)-1)=3 -> 40 + let (p50, _p75, _p90, p95, p99) = endpoints[0].percentiles; + assert_eq!(p50, 20.0); + assert_eq!(p95, 40.0); + assert_eq!(p99, 40.0); + } + #[test] fn persists_and_restores_python_compatible_metrics() { let directory = @@ -471,7 +843,24 @@ mod tests { assert!(original.get_top_endpoints(10).is_empty()); original.load_from_file(&path).unwrap(); - assert_eq!(original.get_timeseries(), before_points); + // Raw latency samples are intentionally not persisted, matching Python's + // MinuteBucket.to_dict()/from_dict(), which omit the `latencies` deque. + let restored: Vec = original + .get_timeseries() + .into_iter() + .map(|mut point| { + point.latencies_ms.clear(); + point + }) + .collect(); + let expected: Vec = before_points + .into_iter() + .map(|mut point| { + point.latencies_ms.clear(); + point + }) + .collect(); + assert_eq!(restored, expected); assert_eq!(original.get_status_distribution(), before_statuses); assert_eq!(original.get_top_apis(10), before_apis); assert_eq!(original.get_top_users(10), before_users); @@ -490,6 +879,7 @@ mod tests { latency_ms: 10.0, bytes_in: 3, bytes_out: 4, + latencies_ms: VecDeque::new(), }, AggregatedPoint { timestamp: 599, @@ -498,6 +888,7 @@ mod tests { latency_ms: 40.0, bytes_in: 5, bytes_out: 6, + latencies_ms: VecDeque::new(), }, AggregatedPoint { timestamp: 601, @@ -506,6 +897,7 @@ mod tests { latency_ms: 20.0, bytes_in: 7, bytes_out: 8, + latencies_ms: VecDeque::new(), }, ]; let five_minute = aggregate_points(points.clone(), 300); @@ -518,4 +910,51 @@ mod tests { assert_eq!(aggregate_points(points.clone(), 3_600).len(), 1); assert_eq!(aggregate_points(points, 86_400).len(), 1); } + + #[test] + fn p95_matches_python_sorted_index_formula() { + // Python: arr.sort(); k = max(0, int(0.95 * len(arr)) - 1); p95 = arr[k] + let mut point = AggregatedPoint::default(); + for ms in [10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0] { + point.push_latency_sample(ms); + } + // len=10 -> k = max(0, int(9.5)-1) = 8 -> sorted[8] = 90.0 + assert_eq!(point.p95_ms(), 90.0); + + let empty = AggregatedPoint::default(); + assert_eq!(empty.p95_ms(), 0.0); + + let mut single = AggregatedPoint::default(); + single.push_latency_sample(42.0); + assert_eq!(single.p95_ms(), 42.0); + } + + #[test] + fn latency_sample_deque_is_capped_like_python_metrics_pct_samples() { + let _guard = METRICS_PCT_SAMPLES_LOCK + .get_or_init(|| std::sync::Mutex::new(())) + .lock(); + unsafe { + std::env::set_var("METRICS_PCT_SAMPLES", "3"); + } + let mut point = AggregatedPoint::default(); + for ms in [1.0, 2.0, 3.0, 4.0, 5.0] { + point.push_latency_sample(ms); + } + assert_eq!(point.latencies_ms, VecDeque::from([3.0, 4.0, 5.0])); + unsafe { + std::env::remove_var("METRICS_PCT_SAMPLES"); + } + } + + #[test] + fn record_request_tracks_raw_latency_samples_for_percentiles() { + let aggregator = AnalyticsAggregator::new(); + aggregator.record_request(Some("api"), Some("user"), Some("/e"), 200, 10.0, 0, 0); + aggregator.record_request(Some("api"), Some("user"), Some("/e"), 200, 90.0, 0, 0); + let points = aggregator.get_timeseries(); + assert_eq!(points.len(), 1); + assert_eq!(points[0].latencies_ms.len(), 2); + assert_eq!(points[0].p95_ms(), 10.0); // k = max(0, int(0.95*2)-1) = 0 -> sorted[0] + } } diff --git a/gateway-rs/src/observability/analytics_models.rs b/gateway-rs/src/observability/analytics_models.rs new file mode 100644 index 00000000..3733b87f --- /dev/null +++ b/gateway-rs/src/observability/analytics_models.rs @@ -0,0 +1,634 @@ +use std::collections::{BTreeMap, BTreeSet, VecDeque}; + +use serde::{Deserialize, Serialize}; +use serde_json::{Map, Value, json}; + +#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)] +pub enum AggregationLevel { + #[serde(rename = "minute")] + Minute, + #[serde(rename = "5minute")] + FiveMinute, + #[serde(rename = "hour")] + Hour, + #[serde(rename = "day")] + Day, +} + +impl AggregationLevel { + pub const fn as_str(self) -> &'static str { + match self { + Self::Minute => "minute", + Self::FiveMinute => "5minute", + Self::Hour => "hour", + Self::Day => "day", + } + } + + fn parse(value: &str) -> Result { + match value { + "minute" => Ok(Self::Minute), + "5minute" => Ok(Self::FiveMinute), + "hour" => Ok(Self::Hour), + "day" => Ok(Self::Day), + _ => Err(format!("{value:?} is not a valid AggregationLevel")), + } + } +} + +#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)] +pub enum MetricType { + #[serde(rename = "request_count")] + RequestCount, + #[serde(rename = "error_rate")] + ErrorRate, + #[serde(rename = "response_time")] + ResponseTime, + #[serde(rename = "bandwidth")] + Bandwidth, + #[serde(rename = "status_code")] + StatusCode, + #[serde(rename = "latency_percentile")] + LatencyPercentile, +} + +#[derive(Clone, Debug, Default, PartialEq, Serialize)] +pub struct PercentileMetrics { + pub p50: f64, + pub p75: f64, + pub p90: f64, + pub p95: f64, + pub p99: f64, + pub min: f64, + pub max: f64, +} + +impl PercentileMetrics { + pub fn calculate(latencies: &[f64]) -> Self { + if latencies.is_empty() { + return Self::default(); + } + let mut sorted = latencies.to_vec(); + sorted.sort_by(f64::total_cmp); + let percentile = |value: f64| { + let index = ((value * sorted.len() as f64) as usize) + .saturating_sub(1) + .min(sorted.len() - 1); + sorted[index] + }; + Self { + p50: percentile(0.50), + p75: percentile(0.75), + p90: percentile(0.90), + p95: percentile(0.95), + p99: percentile(0.99), + min: sorted[0], + max: sorted[sorted.len() - 1], + } + } + + pub fn to_dict(&self) -> Value { + serde_json::to_value(self).expect("percentiles are JSON representable") + } + + fn from_value(value: &Value) -> Self { + Self { + p50: float_field(value, "p50"), + p75: float_field(value, "p75"), + p90: float_field(value, "p90"), + p95: float_field(value, "p95"), + p99: float_field(value, "p99"), + min: float_field(value, "min"), + max: float_field(value, "max"), + } + } +} + +#[derive(Clone, Debug, PartialEq)] +pub struct EndpointMetrics { + pub endpoint_uri: String, + pub method: String, + pub count: i64, + pub error_count: i64, + pub total_ms: f64, + pub latencies: VecDeque, + pub status_counts: BTreeMap, +} + +impl EndpointMetrics { + pub fn new(endpoint_uri: impl Into, method: impl Into) -> Self { + Self { + endpoint_uri: endpoint_uri.into(), + method: method.into(), + count: 0, + error_count: 0, + total_ms: 0.0, + latencies: VecDeque::new(), + status_counts: BTreeMap::new(), + } + } + + pub fn add(&mut self, milliseconds: f64, status: i64, max_samples: usize) { + self.count += 1; + self.error_count += i64::from(status >= 400); + self.total_ms += milliseconds; + *self.status_counts.entry(status).or_default() += 1; + push_bounded(&mut self.latencies, milliseconds, max_samples); + } + + pub fn get_percentiles(&self) -> PercentileMetrics { + PercentileMetrics::calculate(&self.latencies.iter().copied().collect::>()) + } + + pub fn to_dict(&mut self) -> Value { + let percentiles = self.get_percentiles(); + json!({ + "endpoint_uri": self.endpoint_uri, + "method": self.method, + "count": self.count, + "error_count": self.error_count, + "error_rate": ratio(self.error_count, self.count), + "avg_ms": if self.count > 0 { self.total_ms / self.count as f64 } else { 0.0 }, + "percentiles": percentiles.to_dict(), + "status_counts": integer_map(&self.status_counts), + }) + } + + pub fn from_dict(value: &Value) -> Result { + let count = int_field(value, "count")?; + Ok(Self { + endpoint_uri: string_field(value, "endpoint_uri"), + method: string_field(value, "method"), + count, + error_count: int_field(value, "error_count")?, + total_ms: float_field(value, "avg_ms") * count as f64, + latencies: VecDeque::new(), + status_counts: int_map(value.get("status_counts"))?, + }) + } +} + +#[derive(Clone, Debug, PartialEq)] +pub struct EnhancedMinuteBucket { + pub start_ts: i64, + pub count: i64, + pub error_count: i64, + pub total_ms: f64, + pub bytes_in: i64, + pub bytes_out: i64, + pub upstream_timeouts: i64, + pub retries: i64, + pub status_counts: BTreeMap, + pub api_counts: BTreeMap, + pub api_error_counts: BTreeMap, + pub user_counts: BTreeMap, + pub latencies: VecDeque, + pub endpoint_metrics: BTreeMap, + pub unique_users: BTreeSet, + pub request_sizes: VecDeque, + pub response_sizes: VecDeque, +} + +impl EnhancedMinuteBucket { + pub fn new(start_ts: i64) -> Self { + Self { + start_ts, + count: 0, + error_count: 0, + total_ms: 0.0, + bytes_in: 0, + bytes_out: 0, + upstream_timeouts: 0, + retries: 0, + status_counts: BTreeMap::new(), + api_counts: BTreeMap::new(), + api_error_counts: BTreeMap::new(), + user_counts: BTreeMap::new(), + latencies: VecDeque::new(), + endpoint_metrics: BTreeMap::new(), + unique_users: BTreeSet::new(), + request_sizes: VecDeque::new(), + response_sizes: VecDeque::new(), + } + } + + #[allow(clippy::too_many_arguments)] + pub fn add_request( + &mut self, + milliseconds: f64, + status: i64, + username: Option<&str>, + api_key: Option<&str>, + endpoint_uri: Option<&str>, + method: Option<&str>, + bytes_in: i64, + bytes_out: i64, + max_samples: usize, + ) { + self.count += 1; + self.error_count += i64::from(status >= 400); + self.total_ms += milliseconds; + self.bytes_in += bytes_in; + self.bytes_out += bytes_out; + *self.status_counts.entry(status).or_default() += 1; + if let Some(api_key) = api_key.filter(|value| !value.is_empty()) { + *self.api_counts.entry(api_key.to_owned()).or_default() += 1; + if status >= 400 { + *self.api_error_counts.entry(api_key.to_owned()).or_default() += 1; + } + } + if let Some(username) = username.filter(|value| !value.is_empty()) { + *self.user_counts.entry(username.to_owned()).or_default() += 1; + self.unique_users.insert(username.to_owned()); + } + push_bounded(&mut self.latencies, milliseconds, max_samples); + if let (Some(endpoint_uri), Some(method)) = ( + endpoint_uri.filter(|value| !value.is_empty()), + method.filter(|value| !value.is_empty()), + ) { + self.endpoint_metrics + .entry(format!("{method}:{endpoint_uri}")) + .or_insert_with(|| EndpointMetrics::new(endpoint_uri, method)) + .add(milliseconds, status, max_samples); + } + if bytes_in > 0 { + push_bounded(&mut self.request_sizes, bytes_in, max_samples); + } + if bytes_out > 0 { + push_bounded(&mut self.response_sizes, bytes_out, max_samples); + } + } + + pub fn get_percentiles(&self) -> PercentileMetrics { + PercentileMetrics::calculate(&self.latencies.iter().copied().collect::>()) + } + + pub fn get_unique_user_count(&self) -> usize { + self.unique_users.len() + } + + pub fn get_top_endpoints(&mut self, limit: usize) -> Vec { + let mut endpoints = self + .endpoint_metrics + .values_mut() + .map(EndpointMetrics::to_dict) + .collect::>(); + endpoints.sort_by(|left, right| { + int_value(right.get("count")).cmp(&int_value(left.get("count"))) + }); + endpoints.truncate(limit); + endpoints + } + + pub fn to_dict(&mut self) -> Value { + let percentiles = self.get_percentiles(); + let endpoints = self + .endpoint_metrics + .iter_mut() + .map(|(key, value)| (key.clone(), value.to_dict())) + .collect::>(); + let average_response_size = if self.response_sizes.is_empty() { + 0.0 + } else { + self.response_sizes.iter().sum::() as f64 / self.response_sizes.len() as f64 + }; + json!({ + "start_ts": self.start_ts, "count": self.count, "error_count": self.error_count, + "total_ms": self.total_ms, "bytes_in": self.bytes_in, "bytes_out": self.bytes_out, + "upstream_timeouts": self.upstream_timeouts, "retries": self.retries, + "status_counts": integer_map(&self.status_counts), "api_counts": self.api_counts, + "api_error_counts": self.api_error_counts, "user_counts": self.user_counts, + "percentiles": percentiles.to_dict(), "unique_users": self.get_unique_user_count(), + "unique_users_list": self.unique_users, "endpoint_metrics": endpoints, + "avg_response_size": average_response_size, + }) + } + + pub fn from_dict(value: &Value) -> Result { + let mut bucket = Self::new(int_field(value, "start_ts")?); + bucket.count = int_field(value, "count")?; + bucket.error_count = int_field(value, "error_count")?; + bucket.total_ms = float_field(value, "total_ms"); + bucket.bytes_in = int_field(value, "bytes_in")?; + bucket.bytes_out = int_field(value, "bytes_out")?; + bucket.upstream_timeouts = int_field(value, "upstream_timeouts")?; + bucket.retries = int_field(value, "retries")?; + bucket.status_counts = int_map(value.get("status_counts"))?; + bucket.api_counts = string_int_map(value.get("api_counts"))?; + bucket.api_error_counts = string_int_map(value.get("api_error_counts"))?; + bucket.user_counts = string_int_map(value.get("user_counts"))?; + if let Some(endpoints) = value.get("endpoint_metrics").and_then(Value::as_object) { + for (key, endpoint) in endpoints { + if let Ok(endpoint) = EndpointMetrics::from_dict(endpoint) { + bucket.endpoint_metrics.insert(key.clone(), endpoint); + } + } + } + bucket.unique_users = value + .get("unique_users_list") + .and_then(Value::as_array) + .map(|items| items.iter().map(py_string).collect()) + .unwrap_or_else(|| bucket.user_counts.keys().cloned().collect()); + Ok(bucket) + } +} + +#[derive(Clone, Debug, PartialEq)] +pub struct AggregatedMetrics { + pub start_ts: i64, + pub end_ts: i64, + pub level: AggregationLevel, + pub count: i64, + pub error_count: i64, + pub total_ms: f64, + pub bytes_in: i64, + pub bytes_out: i64, + pub unique_users: i64, + pub status_counts: BTreeMap, + pub api_counts: BTreeMap, + pub percentiles: Option, + pub unique_users_set: BTreeSet, +} + +impl AggregatedMetrics { + pub fn to_dict(&self) -> Value { + json!({ + "start_ts": self.start_ts, "end_ts": self.end_ts, "level": self.level, + "count": self.count, "error_count": self.error_count, + "error_rate": ratio(self.error_count, self.count), + "avg_ms": if self.count > 0 { self.total_ms / self.count as f64 } else { 0.0 }, + "bytes_in": self.bytes_in, "bytes_out": self.bytes_out, + "unique_users": self.unique_users, "status_counts": integer_map(&self.status_counts), + "api_counts": self.api_counts, + "percentiles": self.percentiles.as_ref().map(PercentileMetrics::to_dict), + "unique_users_list": self.unique_users_set, + }) + } + + pub fn from_dict(value: &Value) -> Result { + let level = AggregationLevel::parse( + value + .get("level") + .and_then(Value::as_str) + .unwrap_or("minute"), + )?; + Ok(Self { + start_ts: int_field(value, "start_ts")?, + end_ts: int_field(value, "end_ts")?, + level, + count: int_field(value, "count")?, + error_count: int_field(value, "error_count")?, + total_ms: float_field(value, "total_ms"), + bytes_in: int_field(value, "bytes_in")?, + bytes_out: int_field(value, "bytes_out")?, + unique_users: int_field(value, "unique_users")?, + status_counts: int_map(value.get("status_counts"))?, + api_counts: string_int_map(value.get("api_counts"))?, + percentiles: value + .get("percentiles") + .filter(|value| !value.is_null()) + .map(PercentileMetrics::from_value), + unique_users_set: value + .get("unique_users_list") + .and_then(Value::as_array) + .map(|items| items.iter().map(py_string).collect()) + .unwrap_or_default(), + }) + } +} + +#[derive(Clone, Debug, PartialEq)] +pub struct AnalyticsSnapshot { + pub start_ts: i64, + pub end_ts: i64, + pub total_requests: i64, + pub total_errors: i64, + pub error_rate: f64, + pub avg_response_ms: f64, + pub percentiles: PercentileMetrics, + pub total_bytes_in: i64, + pub total_bytes_out: i64, + pub unique_users: i64, + pub series: Vec, + pub top_apis: Vec<(String, i64)>, + pub top_users: Vec<(String, i64)>, + pub top_endpoints: Vec, + pub status_distribution: BTreeMap, +} + +impl AnalyticsSnapshot { + pub fn to_dict(&self) -> Value { + json!({ + "start_ts": self.start_ts, + "end_ts": self.end_ts, + "summary": { + "total_requests": self.total_requests, "total_errors": self.total_errors, + "error_rate": self.error_rate, "avg_response_ms": self.avg_response_ms, + "percentiles": self.percentiles.to_dict(), "total_bytes_in": self.total_bytes_in, + "total_bytes_out": self.total_bytes_out, "unique_users": self.unique_users, + }, + "series": self.series, + "top_apis": self.top_apis.iter().map(|(api, count)| json!({"api": api, "count": count})).collect::>(), + "top_users": self.top_users.iter().map(|(user, count)| json!({"user": user, "count": count})).collect::>(), + "top_endpoints": self.top_endpoints, + "status_distribution": self.status_distribution, + }) + } +} + +fn ratio(numerator: i64, denominator: i64) -> f64 { + if denominator > 0 { + numerator as f64 / denominator as f64 + } else { + 0.0 + } +} + +fn push_bounded(values: &mut VecDeque, value: T, maximum: usize) { + values.push_back(value); + while values.len() > maximum { + values.pop_front(); + } +} + +fn integer_map(values: &BTreeMap) -> Value { + Value::Object( + values + .iter() + .map(|(key, value)| (key.to_string(), json!(value))) + .collect(), + ) +} + +fn int_map(value: Option<&Value>) -> Result, String> { + value + .and_then(Value::as_object) + .into_iter() + .flatten() + .map(|(key, value)| { + Ok(( + key.parse::().map_err(|error| error.to_string())?, + int_value(Some(value)), + )) + }) + .collect() +} + +fn string_int_map(value: Option<&Value>) -> Result, String> { + Ok(value + .and_then(Value::as_object) + .into_iter() + .flatten() + .map(|(key, value)| (key.clone(), int_value(Some(value)))) + .collect()) +} + +fn int_field(value: &Value, key: &str) -> Result { + Ok(value.get(key).map_or(0, |value| int_value(Some(value)))) +} + +fn int_value(value: Option<&Value>) -> i64 { + value + .and_then(|value| { + value + .as_i64() + .or_else(|| value.as_str().and_then(|value| value.parse::().ok())) + }) + .unwrap_or(0) +} + +fn float_field(value: &Value, key: &str) -> f64 { + value + .get(key) + .and_then(|value| { + value + .as_f64() + .or_else(|| value.as_str().and_then(|value| value.parse::().ok())) + }) + .unwrap_or(0.0) +} + +fn string_field(value: &Value, key: &str) -> String { + value.get(key).map(py_string).unwrap_or_default() +} + +fn py_string(value: &Value) -> String { + match value { + Value::Null => "None".to_owned(), + Value::Bool(value) => if *value { "True" } else { "False" }.to_owned(), + Value::String(value) => value.clone(), + _ => value.to_string(), + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn percentile_selection_matches_python_floor_index_algorithm() { + assert_eq!( + PercentileMetrics::calculate(&[]), + PercentileMetrics::default() + ); + let metrics = PercentileMetrics::calculate(&[50.0, 10.0, 40.0, 20.0, 30.0]); + assert_eq!(metrics.p50, 20.0); + assert_eq!(metrics.p75, 30.0); + assert_eq!(metrics.p90, 40.0); + assert_eq!(metrics.p95, 40.0); + assert_eq!(metrics.p99, 40.0); + assert_eq!((metrics.min, metrics.max), (10.0, 50.0)); + } + + #[test] + fn endpoint_and_minute_bucket_tracking_round_trip_like_python() { + let mut bucket = EnhancedMinuteBucket::new(1_700_000_000); + for milliseconds in [10.0, 20.0, 30.0] { + bucket.add_request( + milliseconds, + 200, + Some("alice"), + Some("rest:demo"), + Some("/items"), + Some("GET"), + 5, + 10, + 2, + ); + } + bucket.add_request( + 40.0, + 500, + Some("bob"), + Some("rest:demo"), + Some("/other"), + Some("POST"), + 0, + 20, + 2, + ); + assert_eq!(bucket.count, 4); + assert_eq!(bucket.error_count, 1); + assert_eq!( + bucket.latencies.iter().copied().collect::>(), + vec![30.0, 40.0] + ); + assert_eq!(bucket.get_unique_user_count(), 2); + assert_eq!(bucket.get_top_endpoints(1)[0]["count"], 3); + let value = bucket.to_dict(); + assert_eq!(value["avg_response_size"], 15.0); + let restored = EnhancedMinuteBucket::from_dict(&value).unwrap(); + assert_eq!(restored.count, 4); + assert_eq!( + restored.unique_users, + BTreeSet::from(["alice".to_owned(), "bob".to_owned()]) + ); + assert_eq!(restored.endpoint_metrics["GET:/items"].total_ms, 60.0); + assert!(restored.latencies.is_empty()); + } + + #[test] + fn aggregated_metrics_and_snapshot_shapes_match_python() { + let aggregated = AggregatedMetrics::from_dict(&json!({ + "start_ts": "100", "end_ts": 200, "level": "5minute", "count": 4, + "error_count": 1, "total_ms": 50.0, "bytes_in": 8, "bytes_out": 9, + "unique_users": 2, "status_counts": {"200": 3, "500": 1}, + "api_counts": {"rest:demo": 4}, "percentiles": {"p95": 20}, + "unique_users_list": ["alice", "bob"] + })) + .unwrap(); + let value = aggregated.to_dict(); + assert_eq!(value["level"], "5minute"); + assert_eq!(value["error_rate"], 0.25); + assert_eq!(value["avg_ms"], 12.5); + assert_eq!(value["percentiles"]["p95"], 20.0); + + let snapshot = AnalyticsSnapshot { + start_ts: 100, + end_ts: 200, + total_requests: 4, + total_errors: 1, + error_rate: 0.25, + avg_response_ms: 12.5, + percentiles: PercentileMetrics::default(), + total_bytes_in: 8, + total_bytes_out: 9, + unique_users: 2, + series: vec![json!({"count": 4})], + top_apis: vec![("rest:demo".to_owned(), 4)], + top_users: vec![("alice".to_owned(), 3)], + top_endpoints: vec![json!({"endpoint_uri": "/items"})], + status_distribution: BTreeMap::from([("200".to_owned(), 3)]), + }; + let snapshot = snapshot.to_dict(); + assert_eq!(snapshot["summary"]["total_requests"], 4); + assert_eq!( + snapshot["top_apis"][0], + json!({"api": "rest:demo", "count": 4}) + ); + assert_eq!( + snapshot["top_users"][0], + json!({"user": "alice", "count": 3}) + ); + } +} diff --git a/gateway-rs/src/observability/audit.rs b/gateway-rs/src/observability/audit.rs index 2acd3c4c..73deee6f 100644 --- a/gateway-rs/src/observability/audit.rs +++ b/gateway-rs/src/observability/audit.rs @@ -123,6 +123,34 @@ pub fn management_mutation(actor: &str, action: &str, target: &str, status: &str ); } +/// Mirrors Python's `SecurityAuditMiddleware`: a generic audit event for +/// every modification request and every `/platform/*` request (including +/// reads), independent of the specific named `management_mutation` events +/// application code already emits for successful mutations -- Python's own +/// middleware runs unconditionally alongside those, so this is intentionally +/// additional coverage, not a replacement. +pub fn platform_request( + actor: &str, + method: &str, + path: &str, + status_code: u16, + duration_ms: f64, + user_agent: Option<&str>, +) { + tracing::info!( + actor = %redacted_value("actor", actor), + action = %format!("{method} {path}"), + target = "platform", + status = if status_code < 400 { "success" } else { "failure" }, + method, + path, + status_code, + duration_ms, + user_agent, + "platform audit event" + ); +} + pub fn global_ip_deny(target: &str, reason: &str, source_ip: Option<&str>) { tracing::info!( action = "ip.global_deny", @@ -230,4 +258,70 @@ mod tests { assert_eq!(record["nested"][0], REDACTED); assert_eq!(record["nested"][1], "safe"); } + + #[test] + fn platform_request_emits_pythons_middleware_shaped_audit_event() { + use std::{ + io, + sync::{Arc, Mutex}, + }; + + use tracing_subscriber::fmt::MakeWriter; + + #[derive(Clone, Default)] + struct CapturedLog(Arc>>); + impl io::Write for CapturedLog { + fn write(&mut self, buffer: &[u8]) -> io::Result { + self.0.lock().unwrap().extend_from_slice(buffer); + Ok(buffer.len()) + } + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } + } + impl<'writer> MakeWriter<'writer> for CapturedLog { + type Writer = Self; + fn make_writer(&'writer self) -> Self::Writer { + self.clone() + } + } + + let capture = CapturedLog::default(); + let subscriber = tracing_subscriber::fmt() + .json() + .with_writer(capture.clone()) + .finish(); + tracing::subscriber::with_default(subscriber, || { + super::platform_request( + "alice", + "GET", + "/platform/user", + 200, + 12.5, + Some("test-agent"), + ); + }); + let output = String::from_utf8(capture.0.lock().unwrap().clone()).unwrap(); + let event: serde_json::Value = + serde_json::from_str(output.lines().next().unwrap()).unwrap(); + assert_eq!(event["fields"]["actor"], "alice"); + assert_eq!(event["fields"]["action"], "GET /platform/user"); + assert_eq!(event["fields"]["target"], "platform"); + assert_eq!(event["fields"]["status"], "success"); + assert_eq!(event["fields"]["status_code"], 200); + + // A failing status (>= 400) maps to Python's status='failure'. + let capture = CapturedLog::default(); + let subscriber = tracing_subscriber::fmt() + .json() + .with_writer(capture.clone()) + .finish(); + tracing::subscriber::with_default(subscriber, || { + super::platform_request("bob", "DELETE", "/platform/user/bob", 403, 1.0, None); + }); + let output = String::from_utf8(capture.0.lock().unwrap().clone()).unwrap(); + let event: serde_json::Value = + serde_json::from_str(output.lines().next().unwrap()).unwrap(); + assert_eq!(event["fields"]["status"], "failure"); + } } diff --git a/gateway-rs/src/observability/logging.rs b/gateway-rs/src/observability/logging.rs index e87b994b..9d8d8852 100644 --- a/gateway-rs/src/observability/logging.rs +++ b/gateway-rs/src/observability/logging.rs @@ -1,6 +1,6 @@ use std::{ collections::VecDeque, - fmt, + env, fmt, sync::{LazyLock, Mutex}, }; @@ -9,12 +9,15 @@ use tracing::{ field::{Field, Visit}, }; use tracing_subscriber::{ - EnvFilter, + EnvFilter, Registry, fmt::{ FmtContext, format::{FormatEvent, FormatFields, Writer}, }, + layer::SubscriberExt, registry::LookupSpan, + reload, + util::SubscriberInitExt, }; use crate::observability::audit::redact_record; @@ -24,6 +27,9 @@ static MEMORY_LOGS: LazyLock>> = LazyLock::new(|| Mutex::new(VecDeque::with_capacity(MEMORY_LOG_CAPACITY))); pub fn memory_log_snapshot() -> Vec { + if !stored_logs_enabled() { + return Vec::new(); + } MEMORY_LOGS .lock() .map(|logs| logs.iter().cloned().collect()) @@ -31,6 +37,9 @@ pub fn memory_log_snapshot() -> Vec { } fn remember_log(entry: &str) { + if !stored_logs_enabled() { + return; + } if let Ok(mut logs) = MEMORY_LOGS.lock() { if logs.len() == MEMORY_LOG_CAPACITY { logs.pop_front(); @@ -39,6 +48,18 @@ fn remember_log(entry: &str) { } } +fn stored_logs_enabled() -> bool { + env::var("LOGS_ENABLED") + .ok() + .map(|value| { + matches!( + value.to_ascii_lowercase().as_str(), + "1" | "true" | "yes" | "on" + ) + }) + .unwrap_or(true) +} + /// Formats complete tracing events as JSON only after recursively removing secrets. /// /// The formatter is deliberately applied at the sink boundary so a future @@ -126,15 +147,52 @@ impl Visit for JsonFieldVisitor { } } +/// Handle to the live `EnvFilter`, letting `hot_reload` apply Python's dynamic +/// `LOG_LEVEL` behavior (`logging.getLogger().setLevel(new_value)`) without a +/// process restart, instead of only reporting the change as applied. +static RELOAD_HANDLE: Mutex>> = Mutex::new(None); + +fn default_filter() -> EnvFilter { + EnvFilter::try_from_default_env() + .unwrap_or_else(|_| EnvFilter::new("doorman_gateway=info,tower_http=info")) +} + pub fn init() { - let filter = EnvFilter::try_from_default_env() - .unwrap_or_else(|_| EnvFilter::new("doorman_gateway=info,tower_http=info")); - let _ = tracing_subscriber::fmt() - .with_env_filter(filter) - .event_format(RedactingJsonEvent) + let (filter, handle) = reload::Layer::new(default_filter()); + if let Ok(mut slot) = RELOAD_HANDLE.lock() { + *slot = Some(handle); + } + let _ = tracing_subscriber::registry() + .with(filter) + .with( + tracing_subscriber::fmt::layer() + .event_format(RedactingJsonEvent) + .with_writer(std::io::stdout), + ) .try_init(); } +/// Applies a new `LOG_LEVEL` (or full `EnvFilter` directive string) to the +/// running subscriber. Returns `false` when no subscriber has been +/// initialized yet (e.g. in unit tests) or the directive is invalid, in +/// which case the caller should not report the change as applied. +pub fn set_log_level(directive: &str) -> bool { + let Ok(slot) = RELOAD_HANDLE.lock() else { + return false; + }; + let Some(handle) = slot.as_ref() else { + return false; + }; + reload_handle_with(handle, directive) +} + +fn reload_handle_with(handle: &reload::Handle, directive: &str) -> bool { + let Ok(new_filter) = EnvFilter::builder().parse(directive) else { + return false; + }; + handle.reload(new_filter).is_ok() +} + #[cfg(test)] mod tests { use std::{ @@ -142,9 +200,9 @@ mod tests { sync::{Arc, Mutex}, }; - use tracing_subscriber::fmt::MakeWriter; + use tracing_subscriber::{fmt::MakeWriter, layer::SubscriberExt}; - use super::{RedactingJsonEvent, memory_log_snapshot}; + use super::{RedactingJsonEvent, default_filter, memory_log_snapshot, reload_handle_with}; #[derive(Clone, Default)] struct CapturedLog(Arc>>); @@ -199,4 +257,35 @@ mod tests { .is_ok_and(|entry| entry["message"] == event["fields"]["message"]) })); } + + #[test] + fn dynamic_log_level_reload_takes_effect_without_a_restart() { + // Mirrors Python's hot_config callback: `logging.getLogger().setLevel(new_value)` + // applies immediately, rather than only being reported as reloaded. + let (filter, handle) = tracing_subscriber::reload::Layer::new(default_filter()); + let capture = CapturedLog::default(); + let subscriber = tracing_subscriber::registry().with(filter).with( + tracing_subscriber::fmt::layer() + .event_format(RedactingJsonEvent) + .with_writer(capture.clone()), + ); + + tracing::subscriber::with_default(subscriber, || { + tracing::debug!("before raising the level"); + assert!(reload_handle_with(&handle, "debug")); + tracing::debug!("after raising the level"); + }); + + let output = String::from_utf8(capture.0.lock().unwrap().clone()).unwrap(); + assert!( + !output.contains("before raising the level"), + "debug should be filtered out at the default info level: {output}" + ); + assert!( + output.contains("after raising the level"), + "debug should pass through once the filter is reloaded to debug: {output}" + ); + + assert!(!reload_handle_with(&handle, "((not a valid filter")); + } } diff --git a/gateway-rs/src/observability/metrics.rs b/gateway-rs/src/observability/metrics.rs index 2e1cec87..5f390ce8 100644 --- a/gateway-rs/src/observability/metrics.rs +++ b/gateway-rs/src/observability/metrics.rs @@ -94,6 +94,15 @@ pub fn render(runtime: &GatewayRuntime) -> String { "doorman_active_requests {}", runtime.active_requests.load(Ordering::Relaxed) ); + output.push_str("# HELP doorman_tls_reload_total TLS configuration reload outcomes\n# TYPE doorman_tls_reload_total counter\n"); + let _ = writeln!(output, "doorman_tls_reload_total{{result=\"success\"}} {}", runtime.tls_reload_success_total.load(Ordering::Relaxed)); + let _ = writeln!(output, "doorman_tls_reload_total{{result=\"failure\"}} {}", runtime.tls_reload_failure_total.load(Ordering::Relaxed)); + output.push_str("# HELP doorman_tls_certificate_expiry_timestamp_seconds Certificate expiry as Unix time\n# TYPE doorman_tls_certificate_expiry_timestamp_seconds gauge\n"); + if let Ok(expiries) = runtime.tls_certificate_expiries.lock() { + for (profile, expiry) in expiries.iter() { + let _ = writeln!(output, "doorman_tls_certificate_expiry_timestamp_seconds{{profile=\"{profile}\"}} {expiry}"); + } + } output } diff --git a/gateway-rs/src/observability/mod.rs b/gateway-rs/src/observability/mod.rs index 56168612..3b045483 100644 --- a/gateway-rs/src/observability/mod.rs +++ b/gateway-rs/src/observability/mod.rs @@ -1,4 +1,5 @@ pub mod analytics_aggregator; +pub mod analytics_models; pub mod audit; pub mod email; pub mod logging; diff --git a/gateway-rs/src/platform_contract.rs b/gateway-rs/src/platform_contract.rs index 77f1474c..08afa649 100644 --- a/gateway-rs/src/platform_contract.rs +++ b/gateway-rs/src/platform_contract.rs @@ -60,6 +60,9 @@ const OBJECT_FIELDS: &[&str] = &[ ]; const RUST_EXTENSION_FIELDS: &[&str] = &[ + "api_client_tls_policy", + "api_upstream_tls_profile", + "api_upstream_tls_profiles", "api_wsdl_content", "api_openapi_schema", "api_graphql_schema", @@ -107,7 +110,10 @@ pub fn normalize_create_api(payload: &Value) -> Result> { pub fn normalize_update_api(payload: &Value) -> Result> { let mut normalized = normalize_api_fields(payload, true)?; if let Some(values) = normalized.as_object_mut() { - values.retain(|_, value| !value.is_null()); + values.retain(|field, value| { + !value.is_null() + || matches!(field.as_str(), "api_client_tls_policy" | "api_upstream_tls_profile" | "api_upstream_tls_profiles") + }); } Ok(normalized) } @@ -410,10 +416,13 @@ mod tests { let value = normalize_update_api(&json!({ "api_name": 123, "api_public": "yes", - "api_description": null + "api_description": null, + "api_client_tls_policy": null, + "api_upstream_tls_profile": null })) .unwrap(); - assert_eq!(value, json!({"api_name": "123", "api_public": true})); + assert_eq!(value, json!({"api_name": "123", "api_public": true, + "api_client_tls_policy": null, "api_upstream_tls_profile": null})); } #[test] diff --git a/gateway-rs/src/policy/bandwidth.rs b/gateway-rs/src/policy/bandwidth.rs index 5bfff3d8..d10e543b 100644 --- a/gateway-rs/src/policy/bandwidth.rs +++ b/gateway-rs/src/policy/bandwidth.rs @@ -1,13 +1,26 @@ use http::StatusCode; use serde_json::Value; -use super::{PolicyFailure, PolicyStage, rate_limit::duration_to_seconds}; +use super::{PolicyFailure, PolicyStage}; use crate::storage::{ cache::WindowCounter, models::{bool_field, string_field, u64_field}, redis::bandwidth_key, }; +/// Python `_window_to_seconds`: strips every trailing `s`; unknown or empty windows are one day. +pub fn window_seconds(window: &str) -> u64 { + match window.to_ascii_lowercase().trim_end_matches('s') { + "second" => 1, + "minute" => 60, + "hour" => 3600, + "day" => 86400, + "week" => 604800, + "month" => 2592000, + _ => 86400, + } +} + pub fn enforce_pre_request_limit( username: &str, user: &Value, @@ -25,7 +38,7 @@ pub fn enforce_pre_request_limit( return Ok(()); } let window = string_field(user, "bandwidth_limit_window").unwrap_or("day"); - let seconds = duration_to_seconds(window); + let seconds = window_seconds(window); let bucket = (now_seconds / seconds) * seconds; let used = counter.get(&bandwidth_key(username, seconds, bucket), now_seconds); if used >= limit || used + content_length > limit { @@ -45,6 +58,22 @@ mod tests { use super::*; use serde_json::json; + #[test] + fn window_mapping_matches_python_defaults() { + for (window, seconds) in [ + ("second", 1), + ("Minutes", 60), + ("hourss", 3600), + ("week", 604800), + ("month", 2592000), + ("year", 86400), + ("fortnight", 86400), + ("", 86400), + ] { + assert_eq!(window_seconds(window), seconds, "{window}"); + } + } + #[test] fn rejects_over_limit_request_body() { let user = json!({ diff --git a/gateway-rs/src/policy/evaluator.rs b/gateway-rs/src/policy/evaluator.rs index 05588016..fac3bfdf 100644 --- a/gateway-rs/src/policy/evaluator.rs +++ b/gateway-rs/src/policy/evaluator.rs @@ -30,6 +30,7 @@ use crate::{ redis::{bandwidth_key, rate_limit_key, throttle_key}, runtime::SharedStorage, }, + tls::{policy::{ClientTlsFailure, ClientTlsPolicy}, profiles::{TlsProfiles, select_upstream_profile}}, }; #[derive(Clone, Debug)] @@ -40,14 +41,18 @@ pub struct PolicyRequest { pub direct_ip: Option, pub now_millis: u64, pub content_length: u64, + pub peer_certificates: Vec>, + pub native_tls: bool, + pub is_preflight: bool, } -#[derive(Clone, Debug, Default)] +#[derive(Clone, Default)] pub struct PolicyRuntime { pub rate_counter: WindowCounter, pub rate_bucket_counter: TokenBucketCounter, pub throttle_counter: WindowCounter, pub bandwidth_counter: WindowCounter, + pub tls_profiles: std::sync::Arc, } pub fn evaluate_rest_policy( @@ -127,6 +132,12 @@ pub fn evaluate_rest_policy( )); } let endpoint = find_endpoint(&documents.endpoints, &api, method, &route.endpoint_uri).cloned(); + if !request.is_preflight { + let policy = ClientTlsPolicy::from_documents(&api, endpoint.as_ref()) + .map_err(client_tls_failure)?; + policy.enforce(&request.peer_certificates, &runtime.tls_profiles, request.native_tls) + .map_err(client_tls_failure)?; + } let api_public = bool_field(&api, "api_public").unwrap_or(false); let api_auth_required = bool_field(&api, "api_auth_required").unwrap_or(true); @@ -308,6 +319,16 @@ pub fn evaluate_rest_policy( &route.endpoint_uri, client_key, ) { + let profile = select_upstream_profile(&api, endpoint.as_ref(), &upstream.url) + .map_err(|_| PolicyFailure::new(PolicyStage::Resolution, StatusCode::SERVICE_UNAVAILABLE, "TLS004", "Upstream TLS binding is invalid"))?; + if let Some(id) = profile.as_deref() { + if !matches!(url::Url::parse(&upstream.url).ok().map(|url| url.scheme().to_owned()).as_deref(), Some("https" | "grpcs")) + || !runtime.tls_profiles.upstreams.contains_key(id) + { + return Err(PolicyFailure::new(PolicyStage::Resolution, StatusCode::SERVICE_UNAVAILABLE, "TLS004", "Upstream TLS profile is unavailable")); + } + } + decision.upstream_tls_profile_id = profile; decision.upstream = Some(upstream.url); decision.routing_key = Some(upstream.key); decision.routing_servers = upstream.servers; @@ -317,6 +338,15 @@ pub fn evaluate_rest_policy( Ok(Some(decision)) } +fn client_tls_failure(failure: ClientTlsFailure) -> PolicyFailure { + let (status, code, message) = match failure { + ClientTlsFailure::Missing => (StatusCode::UNAUTHORIZED, "TLS001", "Client certificate required"), + ClientTlsFailure::Invalid => (StatusCode::FORBIDDEN, "TLS002", "Client certificate is not authorized"), + ClientTlsFailure::Configuration => (StatusCode::SERVICE_UNAVAILABLE, "TLS003", "Client TLS policy is unavailable"), + }; + PolicyFailure::new(PolicyStage::Authentication, status, code, message) +} + fn default_http_read_timeout_ms() -> u64 { env::var("HTTP_READ_TIMEOUT") .ok() @@ -361,9 +391,9 @@ pub async fn evaluate_shared_effects( })?; let rate_enabled = bool_field_default(user, "rate_limit_enabled", false) - || user.get("rate_limit_duration").is_some(); + || super::rate_limit::truthy_count(user, "rate_limit_duration").is_some(); if rate_enabled { - let limit = u64_field(user, "rate_limit_duration").unwrap_or(60); + let limit = super::rate_limit::truthy_count(user, "rate_limit_duration").unwrap_or(60); let window = super::rate_limit::duration_to_seconds( string_field(user, "rate_limit_duration_type").unwrap_or("minute"), ) @@ -381,17 +411,18 @@ pub async fn evaluate_shared_effects( } let throttle_enabled = bool_field_default(user, "throttle_enabled", false) - || user.get("throttle_duration").is_some() - || user.get("throttle_queue_limit").is_some(); + || super::rate_limit::truthy_count(user, "throttle_duration").is_some() + || super::rate_limit::truthy_count(user, "throttle_queue_limit").is_some(); if throttle_enabled { - let limit = u64_field(user, "throttle_duration").unwrap_or(10); + let limit = super::rate_limit::truthy_count(user, "throttle_duration").unwrap_or(10); let window = super::rate_limit::duration_to_seconds( string_field(user, "throttle_duration_type").unwrap_or("second"), ) .max(1); let key = throttle_key(username, request.now_millis / (window * 1000)); let count = shared_counter(storage, &key, window, mutate).await?; - let queue_limit = u64_field(user, "throttle_queue_limit").unwrap_or(10); + let queue_limit = + super::rate_limit::truthy_count(user, "throttle_queue_limit").unwrap_or(10); let excess = count.saturating_sub(limit); if queue_limit > 0 && (count > queue_limit || excess > queue_limit) { return Err(PolicyFailure::new( @@ -409,10 +440,9 @@ pub async fn evaluate_shared_effects( if bool_field(user, "bandwidth_limit_enabled") != Some(false) { if let Some(limit) = u64_field(user, "bandwidth_limit_bytes").filter(|limit| *limit > 0) { - let window = super::rate_limit::duration_to_seconds( + let window = super::bandwidth::window_seconds( string_field(user, "bandwidth_limit_window").unwrap_or("day"), - ) - .max(1); + ); let now_seconds = request.now_millis / 1000; let bucket = (now_seconds / window) * window; let key = bandwidth_key(username, window, bucket); @@ -628,6 +658,9 @@ mod tests { direct_ip: Some("10.0.0.2".parse().unwrap()), now_millis: 0, content_length: 0, + peer_certificates: Vec::new(), + native_tls: false, + is_preflight: false, }; let failure = evaluate_rest_policy( &mut documents, @@ -678,6 +711,9 @@ mod tests { direct_ip: None, now_millis: 0, content_length: 0, + peer_certificates: Vec::new(), + native_tls: false, + is_preflight: false, }; let failure = evaluate_rest_policy( &mut documents, @@ -707,6 +743,9 @@ mod tests { direct_ip: None, now_millis: 0, content_length: 0, + peer_certificates: Vec::new(), + native_tls: false, + is_preflight: false, }; let failure = evaluate_rest_policy( &mut documents, @@ -753,6 +792,9 @@ mod tests { direct_ip: None, now_millis: 0, content_length: 0, + peer_certificates: Vec::new(), + native_tls: false, + is_preflight: false, }; let decision = evaluate_rest_policy( &mut documents, diff --git a/gateway-rs/src/policy/mod.rs b/gateway-rs/src/policy/mod.rs index 3dd8a7c7..1fe10cd4 100644 --- a/gateway-rs/src/policy/mod.rs +++ b/gateway-rs/src/policy/mod.rs @@ -11,6 +11,7 @@ pub mod groups; pub mod ip; pub mod quota; pub mod rate_limit; +pub mod rate_limit_models; pub mod roles; pub mod simulator; pub mod subscription; @@ -78,6 +79,7 @@ pub struct PolicyDecision { pub tier_rate_limit_enabled: bool, pub tier_limit_status: Option, pub upstream: Option, + pub upstream_tls_profile_id: Option, pub upstream_path: Option, pub allowed_headers: Vec, pub throttle_delay_ms: Option, diff --git a/gateway-rs/src/policy/rate_limit.rs b/gateway-rs/src/policy/rate_limit.rs index b350d17c..1436d71e 100644 --- a/gateway-rs/src/policy/rate_limit.rs +++ b/gateway-rs/src/policy/rate_limit.rs @@ -22,6 +22,19 @@ pub fn duration_to_seconds(duration: &str) -> u64 { } } +/// Python truthiness for a numeric limit field: `bool(x)` / `int(x or default)`. +pub fn truthy_count(value: &Value, field: &str) -> Option { + match value.get(field) { + Some(Value::Number(number)) => number + .as_u64() + .or_else(|| number.as_f64().map(|float| float as u64)) + .filter(|count| *count != 0), + Some(Value::String(raw)) if !raw.is_empty() => raw.parse().ok(), + Some(Value::Bool(true)) => Some(1), + _ => None, + } +} + pub fn enforce_rate_limit( username: &str, user: &Value, @@ -30,11 +43,11 @@ pub fn enforce_rate_limit( now_millis: u64, ) -> Result<(), PolicyFailure> { let rate_enabled = bool_field_default(user, "rate_limit_enabled", false) - || user.get("rate_limit_duration").is_some(); + || truthy_count(user, "rate_limit_duration").is_some(); if !rate_enabled { return Ok(()); } - let limit = u64_field(user, "rate_limit_duration").unwrap_or(60); + let limit = truthy_count(user, "rate_limit_duration").unwrap_or(60); let duration = string_field(user, "rate_limit_duration_type").unwrap_or("minute"); let window = duration_to_seconds(duration); let window_millis = window * 1000; @@ -85,21 +98,28 @@ pub fn enforce_rate_limit( "Rate limit exceeded", )) } else { - if algorithm.eq_ignore_ascii_case("hybrid") - && u64_field(user, "rate_limit_burst_allowance").unwrap_or(0) > 0 - && !bucket_counter.take( - &format!("rate_hybrid_bucket:{username}"), - limit.saturating_add(u64_field(user, "rate_limit_burst_allowance").unwrap_or(0)), - window_millis, - now_millis, - ) - { - return Err(PolicyFailure::new( - PolicyStage::RateLimit, - StatusCode::TOO_MANY_REQUESTS, - "Rate limit exceeded", - "Rate limit exceeded", - )); + if algorithm.eq_ignore_ascii_case("hybrid") { + let burst = u64_field(user, "rate_limit_burst_allowance").unwrap_or(0); + if burst > 0 + && !bucket_counter.take( + &format!("rate_hybrid_bucket:{username}"), + limit, + window_millis, + now_millis, + ) + { + let window_start = window_index.saturating_mul(window); + let burst_key = format!("burst:user:{username}:{window_start}"); + if counter.get(&burst_key, now_seconds) >= burst { + return Err(PolicyFailure::new( + PolicyStage::RateLimit, + StatusCode::TOO_MANY_REQUESTS, + "Rate limit exceeded", + "Rate limit exceeded", + )); + } + counter.incr(&burst_key, window * 2, now_seconds); + } } Ok(()) } @@ -126,7 +146,7 @@ mod tests { } #[test] - fn zero_limit_is_a_graceful_rate_limit_denial() { + fn zero_limit_falls_back_to_python_default_instead_of_denying() { let user = json!({ "rate_limit_enabled": true, "rate_limit_duration": 0, @@ -134,7 +154,12 @@ mod tests { }); let counter = WindowCounter::default(); let buckets = TokenBucketCounter::default(); - assert!(enforce_rate_limit("invalid", &user, &counter, &buckets, 60_000).is_err()); + // Python: `int(user.get('rate_limit_duration') or 60)` treats 0 as unset. + assert!(enforce_rate_limit("invalid", &user, &counter, &buckets, 60_000).is_ok()); + let disabled = json!({"rate_limit_duration": 0}); + for _ in 0..100 { + assert!(enforce_rate_limit("off", &disabled, &counter, &buckets, 60_000).is_ok()); + } } #[test] @@ -187,6 +212,25 @@ mod tests { assert!(enforce_rate_limit("dana", &user, &counter, &buckets, 0).is_err()); } + #[test] + fn hybrid_mode_uses_a_separate_windowed_burst_counter_like_python() { + let user = json!({ + "rate_limit_enabled": true, + "rate_limit_duration": 2, + "rate_limit_duration_type": "second", + "rate_limit_algorithm": "hybrid", + "rate_limit_burst_allowance": 1, + }); + let counter = WindowCounter::default(); + let buckets = TokenBucketCounter::default(); + assert!(buckets.take("rate_hybrid_bucket:erin", 2, 1_000, 0)); + assert!(buckets.take("rate_hybrid_bucket:erin", 2, 1_000, 0)); + + assert!(enforce_rate_limit("erin", &user, &counter, &buckets, 0).is_ok()); + assert_eq!(counter.get("burst:user:erin:0", 0), 1); + assert!(enforce_rate_limit("erin", &user, &counter, &buckets, 0).is_err()); + } + #[test] fn concurrent_requests_share_one_atomic_rate_window() { let user = Arc::new(json!({ diff --git a/gateway-rs/src/policy/rate_limit_models.rs b/gateway-rs/src/policy/rate_limit_models.rs new file mode 100644 index 00000000..956ce4d7 --- /dev/null +++ b/gateway-rs/src/policy/rate_limit_models.rs @@ -0,0 +1,521 @@ +use std::{collections::BTreeMap, fmt, str::FromStr}; + +use serde::{Deserialize, Serialize}; +use serde_json::{Value, json}; + +macro_rules! string_enum { + ($name:ident { $($variant:ident => $value:literal),+ $(,)? }) => { + #[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)] + pub enum $name { + $(#[serde(rename = $value)] $variant),+ + } + + impl $name { + pub const fn as_str(self) -> &'static str { + match self { $(Self::$variant => $value),+ } + } + } + + impl fmt::Display for $name { + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + formatter.write_str(self.as_str()) + } + } + + impl FromStr for $name { + type Err = String; + + fn from_str(value: &str) -> Result { + match value { + $($value => Ok(Self::$variant),)+ + _ => Err(format!("{value:?} is not a valid {}", stringify!($name))), + } + } + } + }; +} + +string_enum!(RuleType { + PerUser => "per_user", + PerApi => "per_api", + PerEndpoint => "per_endpoint", + PerIp => "per_ip", + PerUserApi => "per_user_api", + PerUserEndpoint => "per_user_endpoint", + Global => "global", +}); + +string_enum!(TimeWindow { + Second => "second", + Minute => "minute", + Hour => "hour", + Day => "day", + Month => "month", +}); + +string_enum!(TierName { + Free => "free", + Pro => "pro", + Enterprise => "enterprise", + Custom => "custom", +}); + +string_enum!(QuotaType { + Requests => "requests", + Bandwidth => "bandwidth", + ComputeTime => "compute_time", +}); + +#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] +pub struct RateLimitRule { + pub rule_id: String, + pub rule_type: RuleType, + pub time_window: TimeWindow, + pub limit: i64, + #[serde(default)] + pub target_identifier: Option, + #[serde(default)] + pub burst_allowance: i64, + #[serde(default)] + pub priority: i64, + #[serde(default = "default_true")] + pub enabled: bool, + #[serde(default)] + pub created_at: Option, + #[serde(default)] + pub updated_at: Option, + #[serde(default)] + pub created_by: Option, + #[serde(default)] + pub description: Option, +} + +impl RateLimitRule { + pub fn to_dict(&self) -> Value { + serde_json::to_value(self).expect("rate-limit rule is JSON representable") + } + + pub fn from_dict(value: Value) -> Result { + serde_json::from_value(value) + } +} + +#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] +#[serde(default, deny_unknown_fields)] +pub struct TierLimits { + pub requests_per_second: Option, + pub requests_per_minute: Option, + pub requests_per_hour: Option, + pub requests_per_day: Option, + pub requests_per_month: Option, + pub burst_per_second: i64, + pub burst_per_minute: i64, + pub burst_per_hour: i64, + pub monthly_request_quota: Option, + pub daily_request_quota: Option, + pub monthly_bandwidth_quota: Option, + pub enable_throttling: bool, + pub max_queue_time_ms: i64, +} + +impl Default for TierLimits { + fn default() -> Self { + Self { + requests_per_second: None, + requests_per_minute: None, + requests_per_hour: None, + requests_per_day: None, + requests_per_month: None, + burst_per_second: 0, + burst_per_minute: 0, + burst_per_hour: 0, + monthly_request_quota: None, + daily_request_quota: None, + monthly_bandwidth_quota: None, + enable_throttling: false, + max_queue_time_ms: 5_000, + } + } +} + +impl TierLimits { + pub fn to_dict(&self) -> Value { + serde_json::to_value(self).expect("tier limits are JSON representable") + } + + pub fn from_dict(value: Value) -> Result { + serde_json::from_value(value) + } +} + +#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] +pub struct Tier { + pub tier_id: String, + pub name: TierName, + pub display_name: String, + pub limits: TierLimits, + #[serde(default)] + pub description: Option, + #[serde(default)] + pub price_monthly: Option, + #[serde(default)] + pub price_yearly: Option, + #[serde(default)] + pub features: Vec, + #[serde(default)] + pub is_default: bool, + #[serde(default = "default_true")] + pub enabled: bool, + #[serde(default)] + pub created_at: Option, + #[serde(default)] + pub updated_at: Option, +} + +impl Tier { + pub fn to_dict(&self) -> Value { + serde_json::to_value(self).expect("tier is JSON representable") + } + + pub fn from_dict(value: Value) -> Result { + serde_json::from_value(value) + } +} + +#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] +pub struct UserTierAssignment { + pub user_id: String, + pub tier_id: String, + #[serde(default)] + pub override_limits: Option, + #[serde(default)] + pub effective_from: Option, + #[serde(default)] + pub effective_until: Option, + #[serde(default)] + pub assigned_at: Option, + #[serde(default)] + pub assigned_by: Option, + #[serde(default)] + pub notes: Option, +} + +impl UserTierAssignment { + pub fn to_dict(&self) -> Value { + serde_json::to_value(self).expect("tier assignment is JSON representable") + } +} + +#[derive(Clone, Debug, PartialEq)] +pub struct QuotaUsage { + pub key: String, + pub quota_type: QuotaType, + pub current_usage: i64, + pub limit: i64, + pub reset_at: String, + pub burst_usage: i64, + pub burst_limit: i64, +} + +impl QuotaUsage { + pub fn remaining(&self) -> i64 { + 0.max(self.limit - self.current_usage) + } + + pub fn percentage_used(&self) -> f64 { + if self.limit == 0 { + 0.0 + } else { + self.current_usage as f64 / self.limit as f64 * 100.0 + } + } + + pub fn is_exhausted(&self) -> bool { + self.current_usage >= self.limit + } + + pub fn to_dict(&self) -> Value { + json!({ + "key": self.key, + "quota_type": self.quota_type, + "current_usage": self.current_usage, + "limit": self.limit, + "remaining": self.remaining(), + "percentage_used": self.percentage_used(), + "reset_at": self.reset_at, + "burst_usage": self.burst_usage, + "burst_limit": self.burst_limit, + "is_exhausted": self.is_exhausted(), + }) + } +} + +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct RateLimitCounter { + pub key: String, + pub window_start: i64, + pub window_size: i64, + pub count: i64, + pub limit: i64, + pub burst_count: i64, + pub burst_limit: i64, +} + +impl RateLimitCounter { + pub fn remaining(&self) -> i64 { + 0.max(self.limit - self.count) + } + + pub fn is_limited(&self) -> bool { + self.count >= self.limit + } + + pub fn reset_at(&self) -> i64 { + self.window_start + self.window_size + } + + pub fn to_dict(&self) -> Value { + json!({ + "key": self.key, + "window_start": self.window_start, + "window_size": self.window_size, + "count": self.count, + "limit": self.limit, + "remaining": self.remaining(), + "reset_at": self.reset_at(), + "burst_count": self.burst_count, + "burst_limit": self.burst_limit, + "is_limited": self.is_limited(), + }) + } +} + +#[derive(Clone, Debug, PartialEq)] +pub struct UsageHistoryRecord { + pub timestamp: String, + pub user_id: Option, + pub api_name: Option, + pub endpoint_uri: Option, + pub ip_address: Option, + pub request_count: i64, + pub blocked_count: i64, + pub burst_used: i64, + pub period: String, +} + +impl UsageHistoryRecord { + pub fn to_dict(&self) -> Value { + json!({ + "timestamp": self.timestamp, + "user_id": self.user_id, + "api_name": self.api_name, + "endpoint_uri": self.endpoint_uri, + "ip_address": self.ip_address, + "request_count": self.request_count, + "blocked_count": self.blocked_count, + "burst_used": self.burst_used, + "period": self.period, + }) + } +} + +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct RateLimitInfo { + pub limit: i64, + pub remaining: i64, + pub reset_at: i64, + pub retry_after: Option, + pub burst_limit: i64, + pub burst_remaining: i64, + pub tier: Option, +} + +impl RateLimitInfo { + pub fn to_headers(&self) -> BTreeMap { + let mut headers = BTreeMap::from([ + ("X-RateLimit-Limit".to_owned(), self.limit.to_string()), + ( + "X-RateLimit-Remaining".to_owned(), + self.remaining.to_string(), + ), + ("X-RateLimit-Reset".to_owned(), self.reset_at.to_string()), + ]); + if let Some(retry_after) = self.retry_after { + headers.insert( + "X-RateLimit-Retry-After".to_owned(), + retry_after.to_string(), + ); + headers.insert("Retry-After".to_owned(), retry_after.to_string()); + } + if self.burst_limit > 0 { + headers.insert( + "X-RateLimit-Burst-Limit".to_owned(), + self.burst_limit.to_string(), + ); + headers.insert( + "X-RateLimit-Burst-Remaining".to_owned(), + self.burst_remaining.to_string(), + ); + } + headers + } + + pub fn to_dict(&self) -> Value { + json!({ + "limit": self.limit, + "remaining": self.remaining, + "reset_at": self.reset_at, + "retry_after": self.retry_after, + "burst_limit": self.burst_limit, + "burst_remaining": self.burst_remaining, + "tier": self.tier, + }) + } +} + +pub const fn get_time_window_seconds(window: TimeWindow) -> i64 { + match window { + TimeWindow::Second => 1, + TimeWindow::Minute => 60, + TimeWindow::Hour => 3_600, + TimeWindow::Day => 86_400, + TimeWindow::Month => 2_592_000, + } +} + +pub fn generate_redis_key( + rule_type: RuleType, + identifier: &str, + window: TimeWindow, + window_start: i64, +) -> String { + let type_prefix = rule_type.as_str().replace("per_", ""); + format!( + "ratelimit:{type_prefix}:{identifier}:{}:{window_start}", + window.as_str() + ) +} + +pub fn generate_quota_key(user_id: &str, quota_type: QuotaType, period: &str) -> String { + format!( + "quota:user:{user_id}:{}:month:{period}", + quota_type.as_str() + ) +} + +const fn default_true() -> bool { + true +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn rule_and_tier_round_trips_preserve_python_defaults_and_wire_values() { + let rule = RateLimitRule::from_dict(json!({ + "rule_id": "rule_001", "rule_type": "per_user", "time_window": "minute", + "limit": 100, "created_at": "2025-12-01T10:20:30" + })) + .unwrap(); + assert_eq!(rule.burst_allowance, 0); + assert!(rule.enabled); + assert_eq!(rule.to_dict()["created_at"], "2025-12-01T10:20:30"); + assert!( + RateLimitRule::from_dict( + json!({"rule_id":"bad", "rule_type":"unknown", "time_window":"minute", "limit":1}) + ) + .is_err() + ); + + let tier = Tier::from_dict(json!({ + "tier_id": "tier_free", "name": "free", "display_name": "Free Plan", + "limits": {"requests_per_minute": 60} + })) + .unwrap(); + assert_eq!(tier.limits.max_queue_time_ms, 5_000); + assert!(tier.enabled); + assert_eq!(tier.to_dict()["features"], json!([])); + assert!(TierLimits::from_dict(json!({"unknown": 1})).is_err()); + } + + #[test] + fn computed_usage_counter_and_history_shapes_match_python() { + let usage = QuotaUsage { + key: "quota:user:alice:requests:month:2025-12".to_owned(), + quota_type: QuotaType::Requests, + current_usage: 25, + limit: 100, + reset_at: "2026-01-01T00:00:00".to_owned(), + burst_usage: 2, + burst_limit: 5, + }; + assert_eq!(usage.remaining(), 75); + assert_eq!(usage.percentage_used(), 25.0); + assert!(!usage.is_exhausted()); + assert_eq!(usage.to_dict()["quota_type"], "requests"); + + let counter = RateLimitCounter { + key: "k".to_owned(), + window_start: 100, + window_size: 60, + count: 11, + limit: 10, + burst_count: 1, + burst_limit: 2, + }; + assert_eq!(counter.remaining(), 0); + assert!(counter.is_limited()); + assert_eq!(counter.reset_at(), 160); + assert_eq!(counter.to_dict()["is_limited"], true); + + let history = UsageHistoryRecord { + timestamp: "2025-12-01T00:00:00".to_owned(), + user_id: Some("alice".to_owned()), + api_name: None, + endpoint_uri: None, + ip_address: None, + request_count: 3, + blocked_count: 1, + burst_used: 1, + period: "minute".to_owned(), + }; + assert_eq!(history.to_dict()["period"], "minute"); + } + + #[test] + fn response_headers_windows_and_storage_keys_match_python() { + let info = RateLimitInfo { + limit: 100, + remaining: 4, + reset_at: 1_701_504_000, + retry_after: Some(7), + burst_limit: 20, + burst_remaining: 3, + tier: Some("pro".to_owned()), + }; + let headers = info.to_headers(); + assert_eq!(headers["X-RateLimit-Limit"], "100"); + assert_eq!(headers["Retry-After"], "7"); + assert_eq!(headers["X-RateLimit-Burst-Remaining"], "3"); + assert_eq!(info.to_dict()["tier"], "pro"); + assert_eq!(get_time_window_seconds(TimeWindow::Month), 2_592_000); + assert_eq!( + generate_redis_key( + RuleType::PerUser, + "john_doe", + TimeWindow::Minute, + 1_701_504_000 + ), + "ratelimit:user:john_doe:minute:1701504000" + ); + assert_eq!( + generate_redis_key(RuleType::Global, "all", TimeWindow::Second, 10), + "ratelimit:global:all:second:10" + ); + assert_eq!( + generate_quota_key("john_doe", QuotaType::Requests, "2025-12"), + "quota:user:john_doe:requests:month:2025-12" + ); + } +} diff --git a/gateway-rs/src/policy/throttle.rs b/gateway-rs/src/policy/throttle.rs index df0183b1..5a218838 100644 --- a/gateway-rs/src/policy/throttle.rs +++ b/gateway-rs/src/policy/throttle.rs @@ -1,10 +1,13 @@ use http::StatusCode; use serde_json::Value; -use super::{PolicyFailure, PolicyStage, rate_limit::duration_to_seconds}; +use super::{ + PolicyFailure, PolicyStage, + rate_limit::{duration_to_seconds, truthy_count}, +}; use crate::storage::{ cache::WindowCounter, - models::{bool_field_default, f64_field, string_field, u64_field}, + models::{bool_field_default, f64_field, string_field}, redis::throttle_key, }; @@ -20,13 +23,13 @@ pub fn enforce_throttle( now_millis: u64, ) -> Result { let enabled = bool_field_default(user, "throttle_enabled", false) - || user.get("throttle_duration").is_some() - || user.get("throttle_queue_limit").is_some(); + || truthy_count(user, "throttle_duration").is_some() + || truthy_count(user, "throttle_queue_limit").is_some(); if !enabled { return Ok(ThrottleOutcome::default()); } - let throttle_limit = u64_field(user, "throttle_duration").unwrap_or(10); + let throttle_limit = truthy_count(user, "throttle_duration").unwrap_or(10); let duration = string_field(user, "throttle_duration_type").unwrap_or("second"); let window = duration_to_seconds(duration); let window_ms = window.max(1) * 1000; @@ -36,7 +39,7 @@ pub fn enforce_throttle( window, now_millis / 1000, ); - let queue_limit = u64_field(user, "throttle_queue_limit").unwrap_or(10); + let queue_limit = truthy_count(user, "throttle_queue_limit").unwrap_or(10); if queue_limit > 0 && count > queue_limit { return Err(queue_limit_exceeded()); } @@ -74,6 +77,28 @@ mod tests { use super::*; use serde_json::json; + #[test] + fn falsy_throttle_fields_are_unset_like_python() { + let counter = WindowCounter::default(); + let user = json!({"throttle_duration": 0, "throttle_queue_limit": 0}); + for now in 0..30 { + assert_eq!( + enforce_throttle("zed", &user, &counter, now) + .unwrap() + .delay_ms, + None + ); + } + // Enabled with a zero queue limit: `int(0 or 10)` gives a queue limit of 10. + let user = + json!({"throttle_enabled": true, "throttle_duration": 1, "throttle_queue_limit": 0}); + let results = (0..12) + .map(|_| enforce_throttle("yan", &user, &counter, 0).is_ok()) + .collect::>(); + assert!(results[..10].iter().all(|ok| *ok)); + assert!(!results[10]); + } + #[test] fn returns_delay_before_queue_limit() { let user = json!({ diff --git a/gateway-rs/src/protocol/crud.rs b/gateway-rs/src/protocol/crud.rs index 56b0dd7d..4d645561 100644 --- a/gateway-rs/src/protocol/crud.rs +++ b/gateway-rs/src/protocol/crud.rs @@ -50,6 +50,7 @@ pub async fn execute( } let query = request.uri().query().unwrap_or_default().to_owned(); let request_path = request.uri().path().to_owned(); + let is_get = request.method() == http::Method::GET; let grpc_web_target = request .extensions() .get::() @@ -79,8 +80,8 @@ pub async fn execute( }; let response = match protocol { DataPlaneProtocol::Graphql => execute_graphql(state, decision, &body).await, - DataPlaneProtocol::Soap => execute_soap(state, decision, &query, &body).await, - DataPlaneProtocol::Grpc => execute_grpc(state, decision, &query, &body).await, + DataPlaneProtocol::Soap => execute_soap(state, decision, is_get, &query, &body).await, + DataPlaneProtocol::Grpc => execute_grpc(state, decision, is_get, &query, &body).await, DataPlaneProtocol::GrpcWeb => { execute_grpc_web( state, @@ -99,6 +100,12 @@ pub async fn execute( }; Ok(match response { Ok(response) => response, + // Python's CRUD SOAP handler turns every failure into a 500 fault that + // `process_soap_response` renders as the generic unknown-error message. + Err(error) if protocol == DataPlaneProtocol::Soap => { + tracing::debug!(error = %error, "SOAP CRUD failed"); + soap_python_fault() + } Err(StorageError::InvalidDocument(error)) => { if protocol == DataPlaneProtocol::GrpcWeb { crate::protocol::grpc::web_trailer_response( @@ -320,14 +327,16 @@ async fn execute_graphql( async fn execute_soap( state: &AppState, decision: &PolicyDecision, + is_get: bool, query: &str, body: &[u8], ) -> Result { - if query - .split('&') - .any(|part| part.eq_ignore_ascii_case("wsdl")) + if is_get + && query + .split('&') + .any(|part| part.split('=').next().is_some_and(|key| key == "wsdl")) { - return Ok(xml_response(StatusCode::OK, soap_wsdl(decision))); + return Ok(soap_xml_response(soap_wsdl(decision))); } let xml = std::str::from_utf8(body) .map_err(|error| StorageError::InvalidDocument(error.to_string()))?; @@ -346,70 +355,65 @@ async fn execute_soap( "Invalid SOAP envelope".to_owned(), )); } - let operation = Regex::new( - r"(?s)<(?:[A-Za-z_][A-Za-z0-9_.-]*:)?(createItem|listItems|getItem|updateItem|deleteItem)\b", - ) - .expect("static SOAP operation regex") - .captures(xml) - .and_then(|captures| captures.get(1)) - .map(|value| value.as_str()) - .ok_or_else(|| StorageError::InvalidDocument("Unknown SOAP CRUD operation".to_owned()))?; + // Python's CRUD SOAP handler implements only createItem and listItems; + // getItem is "not supported yet" and everything else is unknown. + let operation = Regex::new(r"(?s)<(?:[A-Za-z_][A-Za-z0-9_.-]*:)?(createItem|listItems)\b") + .expect("static SOAP operation regex") + .captures(xml) + .and_then(|captures| captures.get(1)) + .map(|value| value.as_str()) + .ok_or_else(|| StorageError::InvalidDocument("Unknown SOAP CRUD operation".to_owned()))?; let (storage, collection) = storage_collection(state, decision)?; - let result = match operation { - "listItems" => Value::Array(storage.crud_list(collection).await?), - "getItem" => { - let id = xml_element(xml, "id")?; - storage - .crud_find_one(collection, &id) - .await? - .unwrap_or(Value::Null) - } - "createItem" => { + let (response_tag, result_xml) = match operation { + "listItems" => ( + "listItemsResponse", + format!( + "{}", + python_json_dumps(&Value::Array(storage.crud_list(collection).await?)) + ), + ), + _ => { let input = xml_element(xml, "input")?; + if input.is_empty() { + return Err(StorageError::InvalidDocument( + "Missing input element or empty".to_owned(), + )); + } let mut input: Value = serde_json::from_str(&xml_unescape(&input))?; + if !input.is_object() { + return Err(StorageError::InvalidDocument( + "SOAP CRUD input must be a JSON object".to_owned(), + )); + } validate_crud_schema(decision.crud_schema.as_ref(), &input, false)?; if input.get("_id").is_none() { input["_id"] = Value::String(uuid::Uuid::new_v4().to_string()); } storage.crud_insert(collection, &input).await?; - input - } - "updateItem" => { - let id = xml_element(xml, "id")?; - let input = xml_element(xml, "input")?; - let input: Value = serde_json::from_str(&xml_unescape(&input))?; - validate_crud_schema(decision.crud_schema.as_ref(), &input, true)?; - storage - .crud_update(collection, &id, &input) - .await? - .unwrap_or(Value::Null) - } - "deleteItem" => { - let id = xml_element(xml, "id")?; - Value::Bool(storage.crud_delete(collection, &id).await?) + ( + "createItemResponse", + format!("{}", python_json_dumps(&input)), + ) } - _ => unreachable!(), }; - let response_tag = format!("{operation}Response"); - let json = serde_json::to_string(&result)?; - Ok(xml_response( - StatusCode::OK, - format!( - "{}", - xml_escape(&json) - ), - )) + let api_name = decision.api_name.as_deref().unwrap_or_default(); + let tns = format!("http://doorman.dev/{}", xml_escape(api_name)); + Ok(soap_xml_response(format!( + "\n\n \n \n {result_xml}\n \n \n" + ))) } async fn execute_grpc( state: &AppState, decision: &PolicyDecision, + is_get: bool, query: &str, body: &[u8], ) -> Result { - if query - .split('&') - .any(|part| part.eq_ignore_ascii_case("proto")) + if is_get + && query + .split('&') + .any(|part| part.split('=').next().is_some_and(|key| key == "proto")) { return Ok(( StatusCode::OK, @@ -565,17 +569,171 @@ fn xml_response(status: StatusCode, body: String) -> Response { } fn soap_wsdl(decision: &PolicyDecision) -> String { - let name = xml_escape(decision.api_name.as_deref().unwrap_or("Crud")); + let name = xml_escape(decision.api_name.as_deref().unwrap_or_default()); + let tns = format!("http://doorman.dev/{name}"); format!( - "" + r#" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + "# + ) +} + +/// `text/xml` response carrying the raw body, as Python's SOAP CRUD returns it. +fn soap_xml_response(body: String) -> Response { + (StatusCode::OK, [(header::CONTENT_TYPE, "text/xml")], body).into_response() +} + +/// What `process_soap_response` renders for the CRUD handler's 500 fault. +fn soap_python_fault() -> Response { + ( + StatusCode::INTERNAL_SERVER_ERROR, + [(header::CONTENT_TYPE, "text/xml")], + "An unknown error occurred in SOAP response", ) + .into_response() +} + +/// Python `json.dumps` defaults: `", "` / `": "` separators and ASCII escaping. +fn python_json_dumps(value: &Value) -> String { + fn dump(value: &Value, out: &mut String) { + match value { + Value::Null => out.push_str("null"), + Value::Bool(flag) => out.push_str(if *flag { "true" } else { "false" }), + Value::Number(number) => out.push_str(&number.to_string()), + Value::String(text) => dump_string(text, out), + Value::Array(items) => { + out.push('['); + for (index, item) in items.iter().enumerate() { + if index > 0 { + out.push_str(", "); + } + dump(item, out); + } + out.push(']'); + } + Value::Object(map) => { + out.push('{'); + for (index, (key, item)) in map.iter().enumerate() { + if index > 0 { + out.push_str(", "); + } + dump_string(key, out); + out.push_str(": "); + dump(item, out); + } + out.push('}'); + } + } + } + fn dump_string(text: &str, out: &mut String) { + out.push('"'); + for character in text.chars() { + match character { + '"' => out.push_str("\\\""), + '\\' => out.push_str("\\\\"), + '\n' => out.push_str("\\n"), + '\r' => out.push_str("\\r"), + '\t' => out.push_str("\\t"), + '\u{8}' => out.push_str("\\b"), + '\u{c}' => out.push_str("\\f"), + character if (' '..='~').contains(&character) => out.push(character), + character => { + let mut units = [0u16; 2]; + for unit in character.encode_utf16(&mut units) { + out.push_str(&format!("\\u{unit:04x}")); + } + } + } + } + out.push('"'); + } + let mut out = String::new(); + dump(value, &mut out); + out } fn crud_proto(decision: &PolicyDecision) -> String { - let mut package = decision - .api_name - .as_deref() - .unwrap_or("crud") + let raw = decision.api_name.as_deref().unwrap_or_default(); + let mut package = raw .chars() .map(|character| { if character.is_ascii_alphanumeric() || character == '_' { @@ -585,13 +743,42 @@ fn crud_proto(decision: &PolicyDecision) -> String { } }) .collect::(); - if package.is_empty() { - package.push_str("crud"); - } else if package.starts_with(|character: char| character.is_ascii_digit()) { + let mut service = package.chars(); + let service = service + .next() + .map(|first| first.to_uppercase().collect::() + &service.as_str().to_lowercase()) + .unwrap_or_default(); + if package.starts_with(|character: char| character.is_ascii_digit()) { package.insert(0, '_'); } + let type_map = |declared: &str| match declared { + "number" => "double", + "integer" => "int32", + "boolean" => "bool", + "array" => "repeated string", + _ => "string", + }; + let fields = decision + .crud_schema + .as_ref() + .and_then(Value::as_object) + .map(|schema| { + schema + .iter() + .enumerate() + .map(|(index, (field, rules))| { + let declared = rules + .get("type") + .and_then(Value::as_str) + .unwrap_or("string"); + format!(" {} {field} = {};", type_map(declared), index + 1) + }) + .collect::>() + .join("\n") + }) + .unwrap_or_default(); format!( - "syntax = \"proto3\";\npackage {package};\nservice CrudService {{ rpc CreateItem (CrudRequest) returns (CrudReply); rpc ListItems (CrudRequest) returns (CrudReply); rpc GetItem (CrudRequest) returns (CrudReply); rpc UpdateItem (CrudRequest) returns (CrudReply); rpc DeleteItem (CrudRequest) returns (CrudReply); }}\nmessage CrudRequest {{ string id = 1; string input = 2; }}\nmessage CrudReply {{ string result = 1; bool ok = 2; }}\n" + "syntax = \"proto3\";\n\npackage {package};\n\nservice {service}Service {{\n rpc CreateItem (CreateItemRequest) returns (CreateItemResponse);\n rpc ListItems (ListItemsRequest) returns (ListItemsResponse);\n}}\n\nmessage CreateItemRequest {{\n{fields}\n}}\n\nmessage CreateItemResponse {{\n string result = 1; // JSON string of created object\n}}\n\nmessage ListItemsRequest {{}}\n\nmessage ListItemsResponse {{\n string items = 1; // JSON string of list\n}}\n" ) } @@ -633,32 +820,40 @@ mod tests { use super::*; #[test] - fn discovers_all_crud_operations() { + fn discovery_documents_match_python_templates() { let decision = PolicyDecision { api_name: Some("customer-api".to_owned()), + crud_schema: Some(serde_json::json!({ + "name": {"type": "string"}, "age": {"type": "integer"}, + "score": {"type": "number"}, "ok": {"type": "boolean"}, + "tags": {"type": "array"}, "meta": {"type": "object"} + })), ..Default::default() }; let wsdl = soap_wsdl(&decision); - let proto = crud_proto(&decision); - for operation in [ - "createItem", - "listItems", - "getItem", - "updateItem", - "deleteItem", - ] { - assert!(wsdl.contains(operation)); - } - for operation in [ - "CreateItem", - "ListItems", - "GetItem", - "UpdateItem", - "DeleteItem", - ] { - assert!(proto.contains(operation)); - } - assert!(proto.contains("package customer_api;")); + assert!( + wsdl.starts_with("\n\n \n " + )); + assert!(wsdl.contains("location=\"http://localhost:8080/api/soap/customer-api\"")); + assert!(wsdl.ends_with("\n ")); + assert!(!wsdl.contains("getItem")); + assert_eq!( + crud_proto(&decision), + include_str!("../../tests/fixtures/crud_customer_api.proto") + ); + } + + #[test] + fn python_json_dumps_matches_json_dumps_defaults() { + let value = + serde_json::json!({"a": [1, 2.5, null, true], "n": "caf\u{e9} \u{1f600}\n\"q\""}); + assert_eq!( + python_json_dumps(&value), + r#"{"a": [1, 2.5, null, true], "n": "caf\u00e9 \ud83d\ude00\n\"q\""}"# + ); } #[test] diff --git a/gateway-rs/src/protocol/grpc.rs b/gateway-rs/src/protocol/grpc.rs index 9e937ec4..060eb376 100644 --- a/gateway-rs/src/protocol/grpc.rs +++ b/gateway-rs/src/protocol/grpc.rs @@ -19,7 +19,7 @@ use tonic::{ Request, Status, codec::{Codec, DecodeBuf, Decoder, EncodeBuf, Encoder}, metadata::{Ascii, MetadataKey, MetadataValue}, - transport::{Channel, Endpoint}, + transport::Channel, }; use crate::{ @@ -77,7 +77,7 @@ pub async fn execute_json_gateway( } pub async fn execute_web_gateway( - _state: &AppState, + state: &AppState, decision: &PolicyDecision, headers: &HeaderMap, body: &[u8], @@ -195,25 +195,9 @@ pub async fn execute_web_gateway( return web_trailer_response(text_mode, tonic::Code::Unavailable, "Invalid upstream"); } }; - let channel = match Endpoint::from_shared(endpoint) { - Ok(endpoint) => match endpoint - .connect_timeout(Duration::from_millis(decision.request_timeout_ms.max(1))) - .timeout(Duration::from_millis(decision.request_timeout_ms.max(1))) - .connect() - .await - { - Ok(channel) => channel, - Err(_) => { - return web_trailer_response( - text_mode, - tonic::Code::Unavailable, - "Upstream unavailable", - ); - } - }, - Err(_) => { - return web_trailer_response(text_mode, tonic::Code::Unavailable, "Invalid upstream"); - } + let channel = match state.grpc_channel(&endpoint, decision.upstream_tls_profile_id.as_deref(), decision.request_timeout_ms).await { + Ok(channel) => channel, + Err(_) => return web_trailer_response(text_mode, tonic::Code::Unavailable, "Upstream unavailable"), }; let path = match PathAndQuery::try_from(format!( "/{}/{}", @@ -369,7 +353,7 @@ pub(crate) fn web_body_response(text_mode: bool, body: Vec) -> Response { } async fn execute( - _state: &AppState, + state: &AppState, decision: &PolicyDecision, headers: &HeaderMap, body: &[u8], @@ -425,16 +409,13 @@ async fn execute( "No upstream servers configured".to_owned(), )); }; - let endpoint = Endpoint::from_shared(normalize_endpoint(upstream)?) - .map_err(|error| GrpcGatewayError::Transport(error.to_string()))? - .connect_timeout(Duration::from_millis(decision.request_timeout_ms.max(1))) - .timeout(Duration::from_millis(decision.request_timeout_ms.max(1))); + let endpoint = normalize_endpoint(upstream)?; let attempts = decision .retry_count .max(env_u32("GRPC_MAX_RETRIES", 0)) .saturating_add(1); for attempt in 0..attempts { - let result = match endpoint.clone().connect().await { + let result = match state.grpc_channel(&endpoint, decision.upstream_tls_profile_id.as_deref(), decision.request_timeout_ms).await { Ok(channel) => { invoke( channel, @@ -461,7 +442,7 @@ async fn execute( Err(primary_error) => { // The Python gateway makes one final compatibility attempt without the // protobuf package. Some legacy gRPC services register that path. - let fallback = match endpoint.clone().connect().await { + let fallback = match state.grpc_channel(&endpoint, decision.upstream_tls_profile_id.as_deref(), decision.request_timeout_ms).await { Ok(channel) => { invoke( channel, diff --git a/gateway-rs/src/routes/grpc.rs b/gateway-rs/src/routes/grpc.rs index 6cd2967b..57096443 100644 --- a/gateway-rs/src/routes/grpc.rs +++ b/gateway-rs/src/routes/grpc.rs @@ -16,17 +16,12 @@ pub async fn grpc_policy_then_execute( State(state): State, mut request: Request, ) -> Result { - let proto_discovery = request.method() == http::Method::GET - && request.uri().query().is_some_and(|query| { - query - .split('&') - .any(|part| part.eq_ignore_ascii_case("proto")) - }); + // Python's gRPC gateway route accepts both POST and GET (the latter used + // for proto discovery as well as plain GET calls), plus OPTIONS for CORS. if !matches!( request.method(), - &http::Method::POST | &http::Method::OPTIONS - ) && !proto_discovery - { + &http::Method::POST | &http::Method::GET | &http::Method::OPTIONS + ) { return Ok(http::StatusCode::METHOD_NOT_ALLOWED.into_response()); } let path = request.uri().path(); diff --git a/gateway-rs/src/routes/mod.rs b/gateway-rs/src/routes/mod.rs index 460c2d0d..6acb7b68 100644 --- a/gateway-rs/src/routes/mod.rs +++ b/gateway-rs/src/routes/mod.rs @@ -7,3 +7,4 @@ pub mod operations; pub mod platform; pub mod rest; pub mod soap; +pub mod tls_admin; diff --git a/gateway-rs/src/routes/operations.rs b/gateway-rs/src/routes/operations.rs index d93637a7..b89da596 100644 --- a/gateway-rs/src/routes/operations.rs +++ b/gateway-rs/src/routes/operations.rs @@ -33,6 +33,11 @@ struct StatusResponse { uptime: String, } +#[derive(Serialize)] +pub struct FeaturesResponse { + logs_enabled: bool, +} + #[derive(Clone, Copy)] enum GatewayOperation { Status, @@ -49,6 +54,12 @@ pub async fn health( Ok(Json(HealthResponse { status: "online" }).into_response()) } +pub async fn features(State(state): State) -> Json { + Json(FeaturesResponse { + logs_enabled: state.config.logs_enabled, + }) +} + pub async fn status( State(state): State, request: Request, diff --git a/gateway-rs/src/routes/platform.rs b/gateway-rs/src/routes/platform.rs index f9db9571..b59f4618 100644 --- a/gateway-rs/src/routes/platform.rs +++ b/gateway-rs/src/routes/platform.rs @@ -36,7 +36,9 @@ use crate::{ response_compat::MessageEnvelope, }, observability::{ - analytics_aggregator::{AggregatedPoint, EntityCounter, global_analytics}, + analytics_aggregator::{ + AggregatedPoint, EndpointEntity, EntityCounter, global_analytics, pooled_percentiles, + }, audit::{self, global_ip_deny}, }, platform_contract::{normalize_create_api, normalize_update_api}, @@ -68,6 +70,17 @@ impl DescriptorBackfill { } } +fn python_truthy(value: &Value) -> bool { + match value { + Value::Null => false, + Value::Bool(value) => *value, + Value::Number(value) => value.as_f64().is_some_and(|value| value != 0.0), + Value::String(value) => !value.is_empty(), + Value::Array(value) => !value.is_empty(), + Value::Object(value) => !value.is_empty(), + } +} + #[derive(Serialize)] struct AccessClaims { sub: String, @@ -201,6 +214,38 @@ pub async fn platform_dispatch( &request_id, ); } + if (content_type_is_json(&headers) || body.is_empty()) + && is_tier_typed_mutation(path, &method) + && normalize_tier_request(path, &method, &mut payload).is_err() + { + return error( + StatusCode::UNPROCESSABLE_ENTITY, + "VAL001", + "Validation Error", + &request_id, + ); + } + // A request with no body at all is a 422 for every route whose Python + // counterpart declares a required typed body parameter, regardless of + // Content-Type (see requires_nonempty_json_body). + if body.is_empty() && requires_nonempty_json_body(path, &method) { + return error( + StatusCode::UNPROCESSABLE_ENTITY, + "VAL001", + "Validation Error", + &request_id, + ); + } + // Python's body: dict[str, Any] parameter has no default, so a request + // with no body at all is a 422 even though an explicit `{}` is valid. + if path == "/config/import" && method == Method::POST && (body.is_empty() || !payload.is_object()) { + return error( + StatusCode::UNPROCESSABLE_ENTITY, + "VAL001", + "Validation Error", + &request_id, + ); + } if path == "/authorization" && method == Method::POST { if let Some(response) = auth_account_rate_limit( @@ -317,6 +362,16 @@ pub async fn platform_dispatch( }; let username = claims.sub.clone().unwrap_or_default(); + if path == "/tls" || path.starts_with("/tls/") { + let response = if has_permission(&state, &username, "manage_security").await { + crate::routes::tls_admin::dispatch(&state, path, &method, payload, &request_id).await + } else { + error(StatusCode::FORBIDDEN, "TLSA001", "manage_security is required", &request_id) + }; + audit_management_request(&username, &method, path, &response); + return with_platform_activity_context(response, &username, path); + } + if path.starts_with("/authorization") { let response = authorization_routes( &state, @@ -619,7 +674,7 @@ pub async fn platform_dispatch( } } } - (Method::POST, "/demo/seed") => demo_seed(&state, &username, &request_id).await, + (Method::POST, "/demo/seed") => demo_seed(&state, &username, &query, &request_id).await, (Method::POST, "/tools/cors/check") => { if !has_permission(&state, &username, "manage_security").await { error( @@ -1032,7 +1087,7 @@ async fn tier_delete_route( .await { Ok(assignments) => assignments.len(), - Err(_) => return unexpected(request_id), + Err(_) => return tier_detail_failure("delete", request_id), }; if assigned > 0 { return http_detail( @@ -1051,7 +1106,7 @@ async fn tier_delete_route( &format!("Tier {tier_id} not found"), request_id, ), - Err(_) => unexpected(request_id), + Err(_) => tier_detail_failure("delete", request_id), } } @@ -1088,9 +1143,13 @@ async fn tier_crud_routes( Ok(value) => value, Err(()) => return tier_pagination_error("limit", request_id), }; - let enabled_only = query - .get("enabled_only") - .is_some_and(|value| value.eq_ignore_ascii_case("true")); + let enabled_only = match query.get("enabled_only") { + Some(value) => match pydantic_bool_string(value) { + Some(value) => value, + None => return tier_pagination_error("enabled_only", request_id), + }, + None => false, + }; let search = query .get("search") .map(|value| value.to_ascii_lowercase()) @@ -1149,14 +1208,10 @@ async fn tier_crud_routes( request_id, ); }; - let Some(name) = payload - .get("name") - .and_then(Value::as_str) - .filter(|value| matches!(*value, "free" | "pro" | "enterprise" | "custom")) - else { + let Some(name) = payload.get("name").and_then(Value::as_str) else { return validation_errors( vec![ - json!({"loc": ["body", "name"], "msg": "value is not a valid enumeration member", "type": "type_error.enum"}), + json!({"loc": ["body", "name"], "msg": "field required", "type": "value_error.missing"}), ], request_id, ); @@ -1177,10 +1232,34 @@ async fn tier_crud_routes( request_id, ); }; - if let Ok(Some(existing)) = storage + let fallback = || { + success( + StatusCode::CREATED, + tier_response(json!({ + "tier_id": tier_id, "name": name, "display_name": display_name, + "description": payload.get("description").cloned().unwrap_or(Value::Null), + "limits": tier_limits_response(limits), + "price_monthly": payload.get("price_monthly").cloned().unwrap_or(Value::Null), + "price_yearly": payload.get("price_yearly").cloned().unwrap_or(Value::Null), + "features": payload.get("features").cloned().unwrap_or_else(|| json!([])), + "is_default": payload.get("is_default").cloned().unwrap_or_else(|| json!(false)), + "enabled": payload.get("enabled").cloned().unwrap_or_else(|| json!(true)), + "created_at": Value::Null, "updated_at": Value::Null, + })), + request_id, + ) + }; + if !matches!(name, "free" | "pro" | "enterprise" | "custom") { + return fallback(); + } + let existing = match storage .find_one("tiers", &json!({"tier_id": tier_id})) .await { + Ok(existing) => existing, + Err(_) => return fallback(), + }; + if let Some(existing) = existing { return success(StatusCode::CREATED, tier_response(existing), request_id); } let now = timestamp_now_naive(); @@ -1200,7 +1279,7 @@ async fn tier_crud_routes( }); return match storage.insert_one("tiers", tier.clone()).await { Ok(_) => success(StatusCode::CREATED, tier_response(tier), request_id), - Err(_) => unexpected(request_id), + Err(_) => fallback(), }; } if suffix.is_empty() { @@ -1222,7 +1301,7 @@ async fn tier_crud_routes( &format!("Tier {suffix} not found"), request_id, ), - Err(_) => unexpected(request_id), + Err(_) => tier_detail_failure("get", request_id), }; } if method == Method::PUT { @@ -1254,7 +1333,7 @@ async fn tier_crud_routes( &format!("Tier {suffix} not found"), request_id, ), - Err(_) => unexpected(request_id), + Err(_) => tier_detail_failure("update", request_id), }; } error( @@ -1288,6 +1367,414 @@ fn tier_pagination_error(field: &str, request_id: &str) -> Response { ) } +fn tier_detail_failure(operation: &str, request_id: &str) -> Response { + let detail = match operation { + "get" => "Failed to get tier", + "update" => "Failed to update tier", + "delete" => "Failed to delete tier", + "assign" => "Failed to assign user", + "get_assignment" => "Failed to get assignment", + "get_user_tier" => "Failed to get user tier", + "remove_assignment" => "Failed to remove assignment", + "list_users" => "Failed to list users", + "upgrade" => "Failed to upgrade tier", + "downgrade" => "Failed to downgrade tier", + "temporary-upgrade" => "Failed to create temporary upgrade", + "trial/start" => "Failed to start trial", + "payment/failure" => "Failed to handle payment failure", + "compare" => "Failed to compare tiers", + _ => "An unexpected error occurred", + }; + http_detail(StatusCode::INTERNAL_SERVER_ERROR, detail, request_id) +} + +fn tier_statistics_failure(request_id: &str) -> Response { + error( + StatusCode::INTERNAL_SERVER_ERROR, + "TIER999", + "Failed to get statistics", + request_id, + ) +} + +fn pydantic_bool_string(value: &str) -> Option { + security_setting_bool(&Value::String(value.to_owned())) +} + +fn is_tier_typed_mutation(path: &str, method: &Method) -> bool { + if method == Method::POST { + return matches!( + path, + "/tiers" + | "/tiers/" + | "/tiers/assignments" + | "/tiers/upgrade" + | "/tiers/downgrade" + | "/tiers/temporary-upgrade" + | "/tiers/trial/start" + | "/tiers/payment/failure" + | "/tiers/compare" + ); + } + method == Method::PUT + && path + .strip_prefix("/tiers/") + .is_some_and(|suffix| !suffix.is_empty() && !suffix.contains('/')) +} + +fn tier_model_string(value: Option<&Value>, required: bool) -> Result, ()> { + match value { + Some(Value::Null) if !required => Ok(None), + Some(value) => security_setting_string(value) + .map(|value| Some(Value::String(value))) + .ok_or(()), + None if !required => Ok(None), + None => Err(()), + } +} + +fn tier_model_integer(value: Option<&Value>, default: Option) -> Result, ()> { + match value { + Some(Value::Null) if default.is_none() => Ok(Some(Value::Null)), + Some(value) => rate_rule_integer(value) + .map(|value| Some(json!(value))) + .ok_or(()), + None => Ok(default.map(|value| json!(value))), + } +} + +fn tier_model_float(value: Option<&Value>) -> Result, ()> { + let Some(value) = value else { + return Ok(None); + }; + if value.is_null() { + return Ok(None); + } + let parsed = match value { + Value::Number(value) => value.as_f64(), + Value::String(value) => value.parse::().ok(), + Value::Bool(value) => Some(if *value { 1.0 } else { 0.0 }), + _ => None, + } + .filter(|value| value.is_finite()) + .ok_or(())?; + serde_json::Number::from_f64(parsed) + .map(Value::Number) + .map(Some) + .ok_or(()) +} + +fn tier_model_datetime(value: &Value) -> Option { + let numeric = match value { + Value::Number(value) => value.as_f64(), + Value::Bool(value) => Some(if *value { 1.0 } else { 0.0 }), + Value::String(value) => value.trim().parse::().ok(), + _ => None, + }; + if let Some(mut seconds) = numeric { + if seconds.is_nan() { + return None; + } + if seconds > 3e20 { + return Some(json!("9999-12-31T23:59:59.999999")); + } + if seconds < -3e20 { + return Some(json!("0001-01-01T00:00:00")); + } + while seconds.abs() > 2e10 { + seconds /= 1_000.0; + } + let micros = (seconds * 1_000_000.0).round_ties_even() as i128; + let datetime = time::OffsetDateTime::from_unix_timestamp_nanos(micros * 1_000).ok()?; + return Some(Value::String(format_tier_datetime(datetime, Some(0)))); + } + + static DATETIME: OnceLock = OnceLock::new(); + let value = value.as_str()?; + let captures = DATETIME + .get_or_init(|| { + Regex::new( + r"^(\d{4})-(\d{1,2})-(\d{1,2})[T ](\d{1,2}):(\d{1,2})(?::(\d{1,2})(?:\.(\d{1,12}))?)?(Z|[+-]\d{2}(?::?\d{2})?)?$", + ) + .expect("tier datetime regex") + }) + .captures(value)?; + let number = |index| captures.get(index)?.as_str().parse::().ok(); + let year = captures.get(1)?.as_str().parse::().ok()?; + let month = time::Month::try_from(number(2)?).ok()?; + let day = number(3)?; + let hour = number(4)?; + let minute = number(5)?; + let second = captures + .get(6) + .map_or(Some(0), |value| value.as_str().parse::().ok())?; + let micros = captures.get(7).map_or(Some(0), |value| { + let digits = value.as_str(); + let padded = format!("{digits:0<6}"); + padded[..6].parse::().ok() + })?; + let date = time::Date::from_calendar_date(year, month, day).ok()?; + let time = time::Time::from_hms_micro(hour, minute, second, micros).ok()?; + let offset_minutes = match captures.get(8).map(|value| value.as_str()) { + None => None, + Some("Z") => Some(0), + Some(offset) => { + let sign = if offset.starts_with('-') { -1 } else { 1 }; + let digits = &offset[1..]; + let hours = digits.get(..2)?.parse::().ok()?; + let minutes = match digits.len() { + 2 => 0, + 4 => digits.get(2..)?.parse::().ok()?, + 5 if digits.as_bytes().get(2) == Some(&b':') => { + digits.get(3..)?.parse::().ok()? + } + _ => return None, + }; + if hours >= 24 || minutes >= 60 { + return None; + } + Some(sign * (hours * 60 + minutes)) + } + }; + let datetime = time::PrimitiveDateTime::new(date, time).assume_utc(); + Some(Value::String(format_tier_datetime( + datetime, + offset_minutes, + ))) +} + +fn format_tier_datetime(datetime: time::OffsetDateTime, offset_minutes: Option) -> String { + let mut value = format!( + "{:04}-{:02}-{:02}T{:02}:{:02}:{:02}", + datetime.year(), + u8::from(datetime.month()), + datetime.day(), + datetime.hour(), + datetime.minute(), + datetime.second(), + ); + if datetime.microsecond() != 0 { + write!(value, ".{:06}", datetime.microsecond()).expect("write to string"); + } + if let Some(minutes) = offset_minutes { + let sign = if minutes < 0 { '-' } else { '+' }; + let minutes = minutes.abs(); + write!(value, "{sign}{:02}:{:02}", minutes / 60, minutes % 60).expect("write to string"); + } + value +} + +fn normalize_tier_limits(value: &Value) -> Result { + let input = value.as_object().ok_or(())?; + let mut output = Map::new(); + for field in [ + "requests_per_second", + "requests_per_minute", + "requests_per_hour", + "requests_per_day", + "requests_per_month", + "monthly_request_quota", + "daily_request_quota", + "monthly_bandwidth_quota", + ] { + if let Some(value) = tier_model_integer(input.get(field), None)? { + output.insert(field.to_owned(), value); + } + } + for (field, default) in [ + ("burst_per_second", 0), + ("burst_per_minute", 0), + ("burst_per_hour", 0), + ("max_queue_time_ms", 5_000), + ] { + output.insert( + field.to_owned(), + tier_model_integer(input.get(field), Some(default))?.ok_or(())?, + ); + } + output.insert( + "enable_throttling".to_owned(), + json!(match input.get("enable_throttling") { + Some(value) => security_setting_bool(value).ok_or(())?, + None => false, + }), + ); + Ok(Value::Object(output)) +} + +fn tier_model_features(value: Option<&Value>, default: bool) -> Result, ()> { + let Some(value) = value else { + return Ok(default.then(|| json!([]))); + }; + if value.is_null() { + return Ok(None); + } + let values = value.as_array().ok_or(())?; + let values = values + .iter() + .map(|value| security_setting_string(value).map(Value::String).ok_or(())) + .collect::, _>>()?; + Ok(Some(Value::Array(values))) +} + +fn insert_tier_optional(output: &mut Map, field: &str, value: Option) { + if let Some(value) = value { + output.insert(field.to_owned(), value); + } +} + +fn normalize_tier_create_or_update(payload: &Value, create: bool) -> Result { + let input = payload.as_object().ok_or(())?; + let mut output = Map::new(); + for field in ["tier_id", "name", "display_name"] { + if create || input.contains_key(field) { + insert_tier_optional( + &mut output, + field, + tier_model_string(input.get(field), create)?, + ); + } + } + if let Some(value) = tier_model_string(input.get("description"), false)? { + output.insert("description".to_owned(), value); + } + if create || input.contains_key("limits") { + match input.get("limits") { + Some(Value::Null) if !create => {} + Some(value) => { + output.insert("limits".to_owned(), normalize_tier_limits(value)?); + } + None if create => return Err(()), + None => {} + } + } + for field in ["price_monthly", "price_yearly"] { + insert_tier_optional(&mut output, field, tier_model_float(input.get(field))?); + } + insert_tier_optional( + &mut output, + "features", + tier_model_features(input.get("features"), create)?, + ); + for (field, default) in [("is_default", false), ("enabled", true)] { + match input.get(field) { + Some(Value::Null) if !create => {} + Some(value) => { + output.insert( + field.to_owned(), + json!(security_setting_bool(value).ok_or(())?), + ); + } + None if create => { + output.insert(field.to_owned(), json!(default)); + } + None => {} + } + } + Ok(Value::Object(output)) +} + +fn tier_action_string( + input: &Map, + output: &mut Map, + field: &str, + required: bool, +) -> Result<(), ()> { + insert_tier_optional( + output, + field, + tier_model_string(input.get(field), required)?, + ); + Ok(()) +} + +fn normalize_tier_request(path: &str, method: &Method, payload: &mut Value) -> Result<(), ()> { + if path == "/tiers/compare" { + let input = payload.as_array().ok_or(())?; + *payload = Value::Array( + input + .iter() + .map(|value| security_setting_string(value).map(Value::String).ok_or(())) + .collect::, _>>()?, + ); + return Ok(()); + } + if matches!(path, "/tiers" | "/tiers/") { + *payload = normalize_tier_create_or_update(payload, true)?; + return Ok(()); + } + if method == Method::PUT { + *payload = normalize_tier_create_or_update(payload, false)?; + return Ok(()); + } + + let input = payload.as_object().ok_or(())?; + let mut output = Map::new(); + tier_action_string(input, &mut output, "user_id", true)?; + match path { + "/tiers/assignments" => { + tier_action_string(input, &mut output, "tier_id", true)?; + for field in ["effective_from", "effective_until"] { + if let Some(value) = input.get(field).filter(|value| !value.is_null()) { + output.insert(field.to_owned(), tier_model_datetime(value).ok_or(())?); + } + } + if let Some(value) = input + .get("override_limits") + .filter(|value| !value.is_null()) + { + output.insert("override_limits".to_owned(), normalize_tier_limits(value)?); + } + tier_action_string(input, &mut output, "notes", false)?; + } + "/tiers/upgrade" => { + tier_action_string(input, &mut output, "new_tier_id", true)?; + output.insert( + "immediate".to_owned(), + json!(match input.get("immediate") { + Some(value) => security_setting_bool(value).ok_or(())?, + None => true, + }), + ); + if let Some(value) = input.get("scheduled_date").filter(|value| !value.is_null()) { + output.insert( + "scheduled_date".to_owned(), + tier_model_datetime(value).ok_or(())?, + ); + } + } + "/tiers/downgrade" => { + tier_action_string(input, &mut output, "new_tier_id", true)?; + output.insert( + "grace_period_days".to_owned(), + tier_model_integer(input.get("grace_period_days"), Some(0))?.ok_or(())?, + ); + } + "/tiers/temporary-upgrade" => { + tier_action_string(input, &mut output, "temp_tier_id", true)?; + let duration = input + .get("duration_days") + .filter(|value| !value.is_null()) + .and_then(rate_rule_integer) + .ok_or(())?; + output.insert("duration_days".to_owned(), json!(duration)); + } + "/tiers/trial/start" => { + tier_action_string(input, &mut output, "tier_id", true)?; + output.insert( + "days".to_owned(), + tier_model_integer(input.get("days"), Some(14))?.ok_or(())?, + ); + } + "/tiers/payment/failure" => { + tier_action_string(input, &mut output, "reason", false)?; + } + _ => return Err(()), + } + *payload = Value::Object(output); + Ok(()) +} + fn tier_limits_response(limits: &Value) -> Value { let mut response = limits.clone(); for field in [ @@ -1335,6 +1822,19 @@ fn tier_response(tier: Value) -> Value { }) } +fn tier_assignment_response(assignment: Value) -> Value { + json!({ + "user_id": assignment.get("user_id").cloned().unwrap_or(Value::Null), + "tier_id": assignment.get("tier_id").cloned().unwrap_or(Value::Null), + "override_limits": assignment.get("override_limits").cloned().unwrap_or(Value::Null), + "effective_from": assignment.get("effective_from").cloned().unwrap_or(Value::Null), + "effective_until": assignment.get("effective_until").cloned().unwrap_or(Value::Null), + "assigned_at": assignment.get("assigned_at").cloned().unwrap_or(Value::Null), + "assigned_by": assignment.get("assigned_by").cloned().unwrap_or(Value::Null), + "notes": assignment.get("notes").cloned().unwrap_or(Value::Null), + }) +} + async fn tier_management_routes( state: &AppState, path: &str, @@ -1387,13 +1887,14 @@ async fn tier_management_routes( request_id, ); } - if storage + let tier_exists = match storage .find_one("tiers", &json!({"tier_id": &tier_id})) .await - .ok() - .flatten() - .is_none() { + Ok(tier) => tier.is_some(), + Err(_) => return tier_detail_failure("assign", request_id), + }; + if !tier_exists { // Oracle: tier_service.assign_user_to_tier raises ValueError here, // which the FastAPI route exposes as a 400 detail response. return http_detail( @@ -1402,11 +1903,13 @@ async fn tier_management_routes( request_id, ); } - let existing = storage + let existing = match storage .find_one("user_tier_assignments", &json!({"user_id": &user_id})) .await - .ok() - .flatten(); + { + Ok(existing) => existing, + Err(_) => return tier_detail_failure("assign", request_id), + }; // Match UserTierAssignment.to_dict(), including explicit nulls. In // particular, this is a replacement on reassignment: fields omitted // from the new request must not survive from the previous assignment. @@ -1437,7 +1940,7 @@ async fn tier_management_routes( }; return match result { Ok(()) => success(StatusCode::CREATED, assignment, request_id), - Err(_) => unexpected(request_id), + Err(_) => tier_detail_failure("assign", request_id), }; } if let Some(rest) = suffix.strip_prefix("assignments/") { @@ -1448,19 +1951,31 @@ async fn tier_management_routes( .await { Ok(true) => message(StatusCode::OK, "Assignment removed", request_id), - _ => http_detail( + Ok(false) => http_detail( StatusCode::NOT_FOUND, &format!("No assignment found for user {user_id}"), request_id, ), + Err(_) => tier_detail_failure("remove_assignment", request_id), }; } if method == Method::GET { - let assignment = storage + let assignment = match storage .find_one("user_tier_assignments", &json!({"user_id": user_id})) .await - .ok() - .flatten(); + { + Ok(assignment) => assignment, + Err(_) => { + return tier_detail_failure( + if rest.ends_with("/tier") { + "get_user_tier" + } else { + "get_assignment" + }, + request_id, + ); + } + }; if rest.ends_with("/tier") { // UserTierAssignment.to_dict serializes datetimes, while the // pinned dataclass loader leaves those strings unparsed. @@ -1495,20 +2010,20 @@ async fn tier_management_routes( .await }; return match tier { - Ok(Some(tier)) => success(StatusCode::OK, strip_internal(tier), request_id), - _ => http_detail( + Ok(Some(tier)) => success(StatusCode::OK, tier_response(tier), request_id), + Ok(None) => http_detail( StatusCode::NOT_FOUND, &format!("No tier found for user {user_id}"), request_id, ), + Err(_) => tier_detail_failure("get_user_tier", request_id), }; } return match assignment { - Some(value) => success(StatusCode::OK, strip_internal(value), request_id), - None => error( + Some(value) => success(StatusCode::OK, tier_assignment_response(value), request_id), + None => http_detail( StatusCode::NOT_FOUND, - "TIER404", - "Assignment not found", + &format!("No assignment found for user {user_id}"), request_id, ), }; @@ -1516,34 +2031,37 @@ async fn tier_management_routes( } if suffix.ends_with("/users") && method == Method::GET { let tier_id = suffix.trim_end_matches("/users"); - let skip = query - .get("skip") - .and_then(|value| value.parse::().ok()) - .unwrap_or(0); - let limit = query - .get("limit") - .and_then(|value| value.parse::().ok()) - .unwrap_or(100); - let users = storage + let skip = match tier_pagination(query, "skip", 0, 0, usize::MAX) { + Ok(value) => value, + Err(()) => return tier_pagination_error("skip", request_id), + }; + let limit = match tier_pagination(query, "limit", 100, 1, 1_000) { + Ok(value) => value, + Err(()) => return tier_pagination_error("limit", request_id), + }; + let users = match storage .find_many("user_tier_assignments", &json!({"tier_id": tier_id})) .await - .unwrap_or_default() - .into_iter() - .skip(skip) - .take(limit) - .map(strip_internal) - .collect::>(); + { + Ok(users) => users, + Err(_) => return tier_detail_failure("list_users", request_id), + } + .into_iter() + .skip(skip) + .take(limit) + .map(tier_assignment_response) + .collect::>(); return success(StatusCode::OK, json!(users), request_id); } if suffix == "statistics/all" && method == Method::GET { - let tiers = storage - .find_many("tiers", &json!({})) - .await - .unwrap_or_default(); - let assignments = storage - .find_many("user_tier_assignments", &json!({})) - .await - .unwrap_or_default(); + let tiers = match storage.find_many("tiers", &json!({})).await { + Ok(tiers) => tiers, + Err(_) => return tier_statistics_failure(request_id), + }; + let assignments = match storage.find_many("user_tier_assignments", &json!({})).await { + Ok(assignments) => assignments, + Err(_) => return tier_statistics_failure(request_id), + }; let result: Vec = tiers .into_iter() .map(|tier| { @@ -1580,10 +2098,13 @@ async fn tier_management_routes( } if suffix.ends_with("/statistics") && method == Method::GET { let tier_id = suffix.trim_end_matches("/statistics"); - let assignments = storage + let assignments = match storage .find_many("user_tier_assignments", &json!({"tier_id": tier_id})) .await - .unwrap_or_default(); + { + Ok(assignments) => assignments, + Err(_) => return tier_statistics_failure(request_id), + }; let total_users = assignments.len(); let active_users = assignments .iter() @@ -1603,23 +2124,20 @@ async fn tier_management_routes( ); } if suffix == "compare" && method == Method::POST { - let ids = payload - .as_array() - .cloned() - .or_else(|| { - payload - .get("tier_ids") - .or_else(|| payload.get("tiers")) - .and_then(Value::as_array) - .cloned() + let ids = payload.as_array().cloned().unwrap_or_default(); + let stored = match storage.find_many("tiers", &json!({})).await { + Ok(tiers) => tiers, + Err(_) => return tier_detail_failure("compare", request_id), + }; + // TierService loops over the requested identifiers, so input order and + // duplicates are observable and must not be replaced by collection order. + let tiers = ids + .iter() + .filter_map(|tier_id| { + stored + .iter() + .find(|tier| tier.get("tier_id") == Some(tier_id)) }) - .unwrap_or_default(); - let tiers = storage - .find_many("tiers", &json!({})) - .await - .unwrap_or_default() - .into_iter() - .filter(|tier| ids.contains(tier.get("tier_id").unwrap_or(&Value::Null))) .map(|tier| { json!({ "tier_id": tier.get("tier_id").cloned().unwrap_or(Value::Null), @@ -1653,7 +2171,7 @@ async fn tier_management_routes( let serialized_effective_dates = match tier_assignment_has_serialized_effective_dates(storage, user_id).await { Ok(value) => value, - Err(_) => return unexpected(request_id), + Err(_) => return tier_detail_failure(suffix, request_id), }; if serialized_effective_dates { let detail = match suffix { @@ -1665,6 +2183,14 @@ async fn tier_management_routes( return http_detail(StatusCode::INTERNAL_SERVER_ERROR, detail, request_id); } } + let current_tier_id = if matches!(suffix, "upgrade" | "downgrade" | "payment/failure") { + match tier_action_current_tier_id(storage, user_id).await { + Ok(tier_id) => tier_id.unwrap_or_else(|| "default".to_owned()), + Err(_) => return tier_detail_failure(suffix, request_id), + } + } else { + "default".to_owned() + }; let (tier_id, effective_from, effective_until, notes, assigned_by, missing_status) = match suffix { "upgrade" => { @@ -1692,14 +2218,7 @@ async fn tier_management_routes( tier_id.to_owned(), effective_from, Value::Null, - format!( - "Upgraded from {}", - tier_action_current_tier_id(storage, user_id) - .await - .ok() - .flatten() - .unwrap_or_else(|| "default".to_owned()) - ), + format!("Upgraded from {current_tier_id}"), Value::Null, StatusCode::BAD_REQUEST, ) @@ -1723,12 +2242,7 @@ async fn tier_management_routes( Value::String(effective_from), Value::Null, format!( - "Downgraded from {} with {grace_days} day grace period", - tier_action_current_tier_id(storage, user_id) - .await - .ok() - .flatten() - .unwrap_or_else(|| "default".to_owned()) + "Downgraded from {current_tier_id} with {grace_days} day grace period" ), Value::Null, StatusCode::BAD_REQUEST, @@ -1782,7 +2296,7 @@ async fn tier_management_routes( request_id, ); } - Err(_) => return unexpected(request_id), + Err(_) => return tier_detail_failure(suffix, request_id), }; let Some(tier_id) = default_tier.get("tier_id").and_then(Value::as_str) else { return http_detail( @@ -1795,14 +2309,7 @@ async fn tier_management_routes( tier_id.to_owned(), Value::String(timestamp_after_days(0)), Value::Null, - format!( - "Downgraded from {} with 0 day grace period", - tier_action_current_tier_id(storage, user_id) - .await - .ok() - .flatten() - .unwrap_or_else(|| "default".to_owned()) - ), + format!("Downgraded from {current_tier_id} with 0 day grace period"), json!("system:payment_failure"), StatusCode::BAD_REQUEST, ) @@ -1821,7 +2328,7 @@ async fn tier_management_routes( request_id, ); } - Err(_) => return unexpected(request_id), + Err(_) => return tier_detail_failure(suffix, request_id), }; let notification_effective_from = effective_from.clone(); return match replace_tier_assignment( @@ -1849,7 +2356,7 @@ async fn tier_management_routes( .await; success(StatusCode::OK, assignment, request_id) } - Err(_) => unexpected(request_id), + Err(_) => tier_detail_failure(suffix, request_id), }; } error( @@ -1999,7 +2506,7 @@ async fn rate_limit_management_routes( return http_detail(StatusCode::NOT_FOUND, "Rule status not found", request_id); } if suffix == "search" && method == Method::GET { - let Some(term) = query.get("q").map(|value| value.to_ascii_lowercase()) else { + let Some(term) = query.get("q") else { return rate_rule_validation("q", "field required", "value_error.missing", request_id); }; // The pinned async in-memory backend does not evaluate the Mongo @@ -2008,6 +2515,13 @@ async fn rate_limit_management_routes( if storage.is_memory() { return success(StatusCode::OK, json!([]), request_id); } + let pattern = match regex::RegexBuilder::new(term) + .case_insensitive(true) + .build() + { + Ok(pattern) => pattern, + Err(_) => return rate_rule_failure("search", request_id), + }; let mut rules = match storage.find_many("rate_limit_rules", &json!({})).await { Ok(rules) => rules, Err(_) => { @@ -2025,7 +2539,7 @@ async fn rate_limit_management_routes( ["rule_id", "description", "target_identifier"] .iter() .filter_map(|field| rule.get(*field).and_then(Value::as_str)) - .any(|field| field.to_ascii_lowercase().contains(&term)) + .any(|field| pattern.is_match(field)) }); rules.sort_by_key(|rule| { std::cmp::Reverse(rule.get("priority").and_then(Value::as_i64).unwrap_or(0)) @@ -2039,7 +2553,7 @@ async fn rate_limit_management_routes( if suffix == "statistics/summary" && method == Method::GET { let rules = match storage.find_many("rate_limit_rules", &json!({})).await { Ok(rules) => rules, - Err(_) => return unexpected(request_id), + Err(_) => return rate_rule_failure("statistics", request_id), }; let enabled = rules .iter() @@ -2086,14 +2600,53 @@ async fn rate_limit_management_routes( && matches!(operation, "delete" | "enable" | "disable") { // The pinned Python app's bulk routes are internally inconsistent: - // `/bulk/enable` and `/bulk/disable` are shadowed by `{rule_id}` and - // fail as a missing rule, while its delete service raises a 500. - // Preserve the observed wire behavior instead of implementing the - // advertised OpenAPI success responses. + // `/bulk/enable` and `/bulk/disable` are shadowed by `{rule_id}`. The + // in-memory backend lacks delete_many, so non-empty bulk deletes fail; + // its early empty-list return and external-storage success remain live. return if operation == "delete" { - http_detail( - StatusCode::INTERNAL_SERVER_ERROR, - "Failed to delete rules", + let Some(rule_ids) = payload.get("rule_ids").and_then(Value::as_array) else { + return rate_rule_validation( + "rule_ids", + "field required", + "value_error.missing", + request_id, + ); + }; + let rule_ids = match rule_ids + .iter() + .map(|value| security_setting_string(value).ok_or(())) + .collect::, _>>() + { + Ok(rule_ids) => rule_ids, + Err(()) => { + return rate_rule_validation( + "rule_ids", + "str type expected", + "type_error.str", + request_id, + ); + } + }; + if rule_ids.is_empty() { + return success(StatusCode::OK, json!({"deleted_count": 0}), request_id); + } + if storage.is_memory() { + return rate_rule_failure("bulk/delete", request_id); + } + let mut deleted_count = 0; + for rule_id in rule_ids { + match storage + .delete_one("rate_limit_rules", &json!({"rule_id": rule_id})) + .await + { + Ok(true) => deleted_count += 1, + Ok(false) => {} + Err(_) => return rate_rule_failure("bulk/delete", request_id), + } + } + success( + StatusCode::OK, + json!({"deleted_count": deleted_count}), request_id, ) } else { @@ -2121,26 +2674,25 @@ async fn rate_limit_management_routes( &format!("Rule {id} not found"), request_id, ), - Err(_) => unexpected(request_id), + Err(_) => rate_rule_failure(parts[1], request_id), }; } if parts[1] == "duplicate" { - let Some(mut rule) = storage + let mut rule = match storage .find_one("rate_limit_rules", &json!({"rule_id": id})) .await - .ok() - .flatten() - else { - return http_detail( - StatusCode::BAD_REQUEST, - &format!("Source rule {id} not found"), - request_id, - ); + { + Ok(Some(rule)) => rule, + Ok(None) => { + return http_detail( + StatusCode::BAD_REQUEST, + &format!("Source rule {id} not found"), + request_id, + ); + } + Err(_) => return rate_rule_failure("duplicate", request_id), }; - let Some(new_rule_id) = payload - .get("new_rule_id") - .and_then(security_setting_string) - .filter(|value| !value.is_empty()) + let Some(new_rule_id) = payload.get("new_rule_id").and_then(security_setting_string) else { return rate_rule_validation( "new_rule_id", @@ -2149,17 +2701,19 @@ async fn rate_limit_management_routes( request_id, ); }; - if matches!( - storage - .find_one("rate_limit_rules", &json!({"rule_id": new_rule_id})) - .await, - Ok(Some(_)) - ) { - return http_detail( - StatusCode::BAD_REQUEST, - &format!("Rule with ID {new_rule_id} already exists"), - request_id, - ); + match storage + .find_one("rate_limit_rules", &json!({"rule_id": new_rule_id})) + .await + { + Ok(Some(_)) => { + return http_detail( + StatusCode::BAD_REQUEST, + &format!("Rule with ID {new_rule_id} already exists"), + request_id, + ); + } + Ok(None) => {} + Err(_) => return rate_rule_failure("duplicate", request_id), } rule["rule_id"] = json!(new_rule_id); rule["description"] = json!(format!("Copy of {id}")); @@ -2170,7 +2724,7 @@ async fn rate_limit_management_routes( } return match storage.insert_one("rate_limit_rules", rule).await { Ok(rule) => success(StatusCode::CREATED, rate_rule_response(rule), request_id), - Err(_) => unexpected(request_id), + Err(_) => rate_rule_failure("duplicate", request_id), }; } } @@ -2253,7 +2807,7 @@ async fn rate_limit_crud_routes( }; let mut rules = match storage.find_many("rate_limit_rules", &json!({})).await { Ok(rules) => rules, - Err(_) => return unexpected(request_id), + Err(_) => return rate_rule_failure("list", request_id), }; rules.sort_by_key(|rule| { std::cmp::Reverse(rule.get("priority").and_then(Value::as_i64).unwrap_or(0)) @@ -2280,11 +2834,7 @@ async fn rate_limit_crud_routes( request_id, ); } - let Some(rule_id) = payload - .get("rule_id") - .and_then(security_setting_string) - .filter(|value| !value.is_empty()) - else { + let Some(rule_id) = payload.get("rule_id").and_then(security_setting_string) else { return rate_rule_validation( "rule_id", "field required", @@ -2437,17 +2987,19 @@ async fn rate_limit_crud_routes( request_id, ); } - if matches!( - storage - .find_one("rate_limit_rules", &json!({"rule_id": rule_id})) - .await, - Ok(Some(_)) - ) { - return http_detail( - StatusCode::BAD_REQUEST, - &format!("Rule with ID {rule_id} already exists"), - request_id, - ); + match storage + .find_one("rate_limit_rules", &json!({"rule_id": rule_id})) + .await + { + Ok(Some(_)) => { + return http_detail( + StatusCode::BAD_REQUEST, + &format!("Rule with ID {rule_id} already exists"), + request_id, + ); + } + Ok(None) => {} + Err(_) => return rate_rule_failure("create", request_id), } let rule = json!({ "rule_id": rule_id, @@ -2464,7 +3016,7 @@ async fn rate_limit_crud_routes( }); return match storage.insert_one("rate_limit_rules", rule.clone()).await { Ok(_) => success(StatusCode::CREATED, rate_rule_response(rule), request_id), - Err(_) => unexpected(request_id), + Err(_) => rate_rule_failure("create", request_id), }; } if suffix.is_empty() { @@ -2486,7 +3038,7 @@ async fn rate_limit_crud_routes( &format!("Rule {suffix} not found"), request_id, ), - Err(_) => unexpected(request_id), + Err(_) => rate_rule_failure("get", request_id), }; } if method == Method::PUT { @@ -2582,7 +3134,7 @@ async fn rate_limit_crud_routes( &format!("Rule {suffix} not found"), request_id, ), - Err(_) => unexpected(request_id), + Err(_) => rate_rule_failure("update", request_id), }; } if method == Method::DELETE { @@ -2600,7 +3152,7 @@ async fn rate_limit_crud_routes( &format!("Rule {suffix} not found"), request_id, ), - Err(_) => unexpected(request_id), + Err(_) => rate_rule_failure("delete", request_id), }; } error( @@ -2627,6 +3179,27 @@ fn rate_rule_validation( ) } +fn rate_rule_failure(operation: &str, request_id: &str) -> Response { + let detail = match operation { + "create" => "Failed to create rule", + "list" => "Failed to list rules", + "search" => "Failed to search rules", + "get" => "Failed to get rule", + "update" => "Failed to update rule", + "delete" => "Failed to delete rule", + "enable" => "Failed to enable rule", + "disable" => "Failed to disable rule", + "bulk/delete" => "Failed to delete rules", + "bulk/enable" => "Failed to enable rules", + "bulk/disable" => "Failed to disable rules", + "duplicate" => "Failed to duplicate rule", + "statistics" => "Failed to get statistics", + "status" => "Failed to get rate limit status", + _ => "An unexpected error occurred", + }; + http_detail(StatusCode::INTERNAL_SERVER_ERROR, detail, request_id) +} + fn rate_rule_integer(value: &Value) -> Option { match value { Value::Number(value) => value.as_i64().or_else(|| { @@ -2708,16 +3281,34 @@ async fn entity_routes( request_id, ); } - if spec.collection != "roles" - && let Err(message_text) = validate_pagination(query) - { - return error(StatusCode::BAD_REQUEST, "PAG001", &message_text, request_id); + if spec.collection != "roles" { + // Python's `get_groups`/`get_routings` type `page`/`page_size` as + // typed FastAPI query params (a non-numeric value never reaches the + // handler and produces FastAPI's own 422), matching roles above. + if let Some(response) = + int_query_validation_error(query, &["page", "page_size"], request_id) + { + return response; + } + if let Err(message_text) = validate_pagination(query) { + return error(StatusCode::BAD_REQUEST, "PAG001", &message_text, request_id); + } } let mut items = match storage.find_many(spec.collection, &json!({})).await { Ok(items) => items.into_iter().map(strip_internal).collect::>(), Err(_) => return unexpected(request_id), }; if spec.collection == "roles" { + // Python's `get_roles(page: int = ..., page_size: int = ...)` are + // typed FastAPI query params: a non-numeric value never reaches the + // handler and instead produces FastAPI's own 422 validation body. + // Unlike the other collections above, this branch previously parsed + // page/page_size with `.unwrap_or(1)`, silently accepting garbage. + if let Some(response) = + int_query_validation_error(query, &["page", "page_size"], request_id) + { + return response; + } items.sort_by_key(|role| { role.get("role_name") .and_then(Value::as_str) @@ -2930,7 +3521,13 @@ async fn entity_routes( success(StatusCode::OK, strip_internal(item), request_id) } Ok(None) => error( - StatusCode::NOT_FOUND, + // Python's routing retrieval also returns 400 (RTG004) for a + // missing client_key, unlike groups/roles which use 404 here. + if spec.collection == "routings" { + StatusCode::BAD_REQUEST + } else { + StatusCode::NOT_FOUND + }, spec.not_found_code, if spec.collection == "roles" { "Role does not exist" @@ -2972,6 +3569,19 @@ async fn entity_routes( request_id, ); } + // Python's update/delete service methods for groups and routings return + // 400 (not 404) when the target doesn't exist, matching the roles + // convention below rather than the generic 404 used elsewhere. + if matches!(spec.collection, "groups" | "routings") + && matches!(storage.find_one(spec.collection, &filter).await, Ok(None)) + { + return error( + StatusCode::BAD_REQUEST, + spec.not_found_code, + "Resource not found", + request_id, + ); + } if spec.collection == "roles" { match storage.find_one(spec.collection, &filter).await { Ok(Some(_)) => {} @@ -3160,6 +3770,22 @@ fn merge_proto_metadata(target: &mut Value, source: &Value) { } } +async fn lock_tls_binding_mutation( + state: &AppState, + payload: &Value, + prefix: &str, +) -> Result, ()> { + let has_binding = ["client_tls_policy", "upstream_tls_profile", "upstream_tls_profiles"] + .iter() + .any(|field| payload.get(format!("{prefix}_{field}")).is_some_and(|value| !value.is_null())); + if !has_binding { + return Ok(None); + } + let guard = state.storage.as_ref().ok_or(())?.tls_mutation_lock().await.map_err(|_| ())?; + state.reload_tls_from_storage().await.map_err(|_| ())?; + Ok(Some(guard)) +} + async fn api_routes( state: &AppState, path: &str, @@ -3174,6 +3800,14 @@ async fn api_routes( }; let suffix = path.strip_prefix("/api").unwrap_or("").trim_matches('/'); if method == Method::GET && (suffix.is_empty() || suffix == "all") { + // Python's `get_apis(page: int = ..., page_size: int = ...)` typed + // FastAPI query params: a non-numeric value produces a 422, not a + // silently-defaulted page or a custom 400 PAG001 body. + if let Some(response) = + int_query_validation_error(query, &["page", "page_size"], request_id) + { + return response; + } if let Err(message_text) = validate_pagination(query) { return error(StatusCode::BAD_REQUEST, "PAG001", &message_text, request_id); } @@ -3206,6 +3840,22 @@ async fn api_routes( Ok(payload) => payload, Err(errors) => return validation_errors(errors, request_id), }; + let _tls_guard = match lock_tls_binding_mutation(state, &payload, "api").await { + Ok(guard) => guard, + Err(()) => return error(StatusCode::SERVICE_UNAVAILABLE, "TLS004", "TLS profiles are unavailable", request_id), + }; + if let Some(policy) = payload.get("api_client_tls_policy").filter(|value| !value.is_null()) { + if crate::tls::policy::ClientTlsPolicy::validate_value( + policy, + &state.tls_snapshot().profiles, + state.config.downstream_tls_mode == crate::config::DownstreamTlsMode::Native, + ).is_err() { + return error(StatusCode::BAD_REQUEST, "TLS003", "Invalid client TLS policy", request_id); + } + } + if crate::tls::profiles::validate_upstream_bindings(&payload, "api", &state.tls_snapshot().profiles).is_err() { + return error(StatusCode::BAD_REQUEST, "TLS004", "Invalid upstream TLS binding", request_id); + } let name = payload["api_name"] .as_str() .expect("validated API name") @@ -3312,6 +3962,22 @@ async fn api_routes( Ok(payload) => payload, Err(errors) => return validation_errors(errors, request_id), }; + let _tls_guard = match lock_tls_binding_mutation(state, &payload, "api").await { + Ok(guard) => guard, + Err(()) => return error(StatusCode::SERVICE_UNAVAILABLE, "TLS004", "TLS profiles are unavailable", request_id), + }; + if let Some(policy) = payload.get("api_client_tls_policy").filter(|value| !value.is_null()) { + if crate::tls::policy::ClientTlsPolicy::validate_value( + policy, + &state.tls_snapshot().profiles, + state.config.downstream_tls_mode == crate::config::DownstreamTlsMode::Native, + ).is_err() { + return error(StatusCode::BAD_REQUEST, "TLS003", "Invalid client TLS policy", request_id); + } + } + if crate::tls::profiles::validate_upstream_bindings(&payload, "api", &state.tls_snapshot().profiles).is_err() { + return error(StatusCode::BAD_REQUEST, "TLS004", "Invalid upstream TLS binding", request_id); + } let Some(updates) = payload.as_object() else { return unexpected(request_id); }; @@ -3448,6 +4114,13 @@ async fn user_routes( .unwrap_or("") .trim_matches('/'); if method == Method::GET && (suffix.is_empty() || suffix == "all") { + // Python's `get_users(page: int = ..., page_size: int = ...)` typed + // FastAPI query params: a non-numeric value produces a 422. + if let Some(response) = + int_query_validation_error(query, &["page", "page_size"], request_id) + { + return response; + } if let Err(message_text) = validate_pagination(query) { return error(StatusCode::BAD_REQUEST, "PAG001", &message_text, request_id); } @@ -3545,16 +4218,19 @@ async fn user_routes( request_id, ); } - if active_user == target - && !has_permission(state, active_user, "manage_users").await - && !self_update_fields_are_safe(&payload) - { - return error( - StatusCode::FORBIDDEN, - "USR023", - "Users without manage_users may not update restricted fields", - request_id, - ); + if active_user == target && !has_permission(state, active_user, "manage_users").await { + let attempted = restricted_self_update_fields(&payload); + if !attempted.is_empty() { + return error( + StatusCode::FORBIDDEN, + "USR023", + &format!( + "Cannot modify restricted fields without manage_users permission: {}", + attempted.join(", ") + ), + request_id, + ); + } } let existing = match storage .find_one("users", &json!({"username": target})) @@ -3855,18 +4531,82 @@ async fn endpoint_routes( return error(StatusCode::FORBIDDEN, code, text, request_id); } let filter = json!({"endpoint_id": endpoint_id}); - return document_by_method( - state, - "endpoint_validations", - filter, - method, - payload, - username, - "manage_endpoints", - "Endpoint validation", + if method == Method::GET { + return match storage.find_one("endpoint_validations", &filter).await { + Ok(Some(validation)) => { + success(StatusCode::OK, strip_internal(validation), request_id) + } + Ok(None) => error( + StatusCode::BAD_REQUEST, + "END018", + "Endpoint validation does not exist", + request_id, + ), + Err(_) => unexpected(request_id), + }; + } + if method == Method::PUT { + if payload.get("validation_enabled") == Some(&Value::Bool(false)) { + return error( + StatusCode::BAD_REQUEST, + "END020", + "Validation enabled is required", + request_id, + ); + } + match storage + .find_one("endpoints", &json!({"endpoint_id": endpoint_id})) + .await + { + Ok(Some(_)) => {} + Ok(None) => { + return error( + StatusCode::BAD_REQUEST, + "END022", + "Endpoint does not exist", + request_id, + ); + } + Err(_) => return unexpected(request_id), + } + return match storage + .update_one("endpoint_validations", &filter, &payload) + .await + { + Ok(_) => message( + StatusCode::OK, + "Endpoint validation updated successfully", + request_id, + ), + Err(_) => error( + StatusCode::BAD_REQUEST, + "END023", + "Unable to update endpoint validation", + request_id, + ), + }; + } + if method == Method::DELETE { + return match storage.delete_one("endpoint_validations", &filter).await { + Ok(_) => message( + StatusCode::OK, + "Endpoint validation deleted successfully", + request_id, + ), + Err(_) => error( + StatusCode::BAD_REQUEST, + "END019", + "Unable to delete endpoint validation", + request_id, + ), + }; + } + return error( + StatusCode::METHOD_NOT_ALLOWED, + "GTW004", + "Method not allowed", request_id, - ) - .await; + ); } if (suffix == "endpoint/validation" || suffix == "validation") && method == Method::POST { if normalize_endpoint_validation_model(&mut payload, true).is_err() { @@ -3885,14 +4625,48 @@ async fn endpoint_routes( request_id, ); } - if payload.get("endpoint_id").is_none() { + let endpoint_id = payload + .get("endpoint_id") + .and_then(Value::as_str) + .unwrap_or_default(); + if endpoint_id.is_empty() { return error( StatusCode::BAD_REQUEST, - "VAL001", - "endpoint_id is required", + "END013", + "Endpoint ID is required", request_id, ); } + match storage + .find_one("endpoint_validations", &json!({"endpoint_id": endpoint_id})) + .await + { + Ok(Some(_)) => { + return error( + StatusCode::BAD_REQUEST, + "END017", + "Endpoint validation already exists", + request_id, + ); + } + Ok(None) => {} + Err(_) => return unexpected(request_id), + } + match storage + .find_one("endpoints", &json!({"endpoint_id": endpoint_id})) + .await + { + Ok(Some(_)) => {} + Ok(None) => { + return error( + StatusCode::BAD_REQUEST, + "END015", + "Endpoint does not exist", + request_id, + ); + } + Err(_) => return unexpected(request_id), + } return match storage.insert_one("endpoint_validations", payload).await { Ok(_) => { audit::management_mutation( @@ -3907,7 +4681,12 @@ async fn endpoint_routes( request_id, ) } - Err(_) => unexpected(request_id), + Err(_) => error( + StatusCode::BAD_REQUEST, + "END016", + "Unable to create endpoint validation", + request_id, + ), }; } if method == Method::POST && suffix.is_empty() { @@ -3919,6 +4698,22 @@ async fn endpoint_routes( request_id, ); } + let _tls_guard = match lock_tls_binding_mutation(state, &payload, "endpoint").await { + Ok(guard) => guard, + Err(()) => return error(StatusCode::SERVICE_UNAVAILABLE, "TLS004", "TLS profiles are unavailable", request_id), + }; + if let Some(policy) = payload.get("endpoint_client_tls_policy").filter(|value| !value.is_null()) { + if crate::tls::policy::ClientTlsPolicy::validate_value( + policy, + &state.tls_snapshot().profiles, + state.config.downstream_tls_mode == crate::config::DownstreamTlsMode::Native, + ).is_err() { + return error(StatusCode::BAD_REQUEST, "TLS003", "Invalid client TLS policy", request_id); + } + } + if crate::tls::profiles::validate_upstream_bindings(&payload, "endpoint", &state.tls_snapshot().profiles).is_err() { + return error(StatusCode::BAD_REQUEST, "TLS004", "Invalid upstream TLS binding", request_id); + } if !has_permission(state, username, "manage_endpoints").await { return error( StatusCode::FORBIDDEN, @@ -4024,7 +4819,12 @@ async fn endpoint_routes( request_id, ) } - Err(_) => unexpected(request_id), + Err(_) => error( + StatusCode::BAD_REQUEST, + "END003", + "Unable to insert endpoint", + request_id, + ), }; } let parts = suffix.split('/').collect::>(); @@ -4062,6 +4862,28 @@ async fn endpoint_routes( request_id, ); } + let _tls_guard = if method == Method::PUT { + match lock_tls_binding_mutation(state, &payload, "endpoint").await { + Ok(guard) => guard, + Err(()) => return error(StatusCode::SERVICE_UNAVAILABLE, "TLS004", "TLS profiles are unavailable", request_id), + } + } else { + None + }; + if method == Method::PUT { + if let Some(policy) = payload.get("endpoint_client_tls_policy").filter(|value| !value.is_null()) { + if crate::tls::policy::ClientTlsPolicy::validate_value( + policy, + &state.tls_snapshot().profiles, + state.config.downstream_tls_mode == crate::config::DownstreamTlsMode::Native, + ).is_err() { + return error(StatusCode::BAD_REQUEST, "TLS003", "Invalid client TLS policy", request_id); + } + } + if crate::tls::profiles::validate_upstream_bindings(&payload, "endpoint", &state.tls_snapshot().profiles).is_err() { + return error(StatusCode::BAD_REQUEST, "TLS004", "Invalid upstream TLS binding", request_id); + } + } let uri = format!("/{}", parts[3..].join("/")); let filter = json!({"endpoint_method": parts[0], "api_name": parts[1], "api_version": parts[2], "endpoint_uri": uri}); if method == Method::PUT { @@ -4175,7 +4997,12 @@ async fn endpoint_routes( "Endpoint does not exist for the requested API name, version and URI", request_id, ), - Err(_) => unexpected(request_id), + Err(_) => error( + StatusCode::BAD_REQUEST, + "END009", + "Unable to delete endpoint", + request_id, + ), }; } if method == Method::GET { @@ -4190,114 +5017,22 @@ async fn endpoint_routes( Err(_) => unexpected(request_id), }; } - return document_by_method( - state, - "endpoints", - filter, - method, - payload, - username, - "manage_endpoints", - "Endpoint", - request_id, - ) - .await; + if method == Method::PUT { + return match storage.update_one("endpoints", &filter, &payload).await { + Ok(Some(_)) => message(StatusCode::OK, "Endpoint updated successfully", request_id), + Ok(None) | Err(_) => error( + StatusCode::BAD_REQUEST, + "END003", + "Unable to update endpoint", + request_id, + ), + }; + } } error( StatusCode::NOT_FOUND, "EPT002", - "Endpoint not found", - request_id, - ) -} - -#[allow(clippy::too_many_arguments)] -async fn document_by_method( - state: &AppState, - collection: &str, - filter: Value, - method: &Method, - payload: Value, - username: &str, - permission: &str, - label: &str, - request_id: &str, -) -> Response { - let Some(storage) = &state.storage else { - return unexpected(request_id); - }; - if method == Method::GET { - return match storage.find_one(collection, &filter).await { - Ok(Some(item)) => success(StatusCode::OK, strip_internal(item), request_id), - Ok(None) => error( - StatusCode::NOT_FOUND, - "EPT002", - &format!("{label} not found"), - request_id, - ), - Err(_) => unexpected(request_id), - }; - } - if !has_permission(state, username, permission).await { - return error( - StatusCode::FORBIDDEN, - "END010", - "Insufficient permissions", - request_id, - ); - } - if method == Method::PUT { - return match storage.update_one(collection, &filter, &payload).await { - Ok(Some(_)) => { - audit::management_mutation( - username, - &format!("{}.update", label.to_ascii_lowercase().replace(' ', "_")), - &filter.to_string(), - "success", - ); - message( - StatusCode::OK, - &format!("{label} updated successfully"), - request_id, - ) - } - Ok(None) => error( - StatusCode::NOT_FOUND, - "EPT002", - &format!("{label} not found"), - request_id, - ), - Err(_) => unexpected(request_id), - }; - } - if method == Method::DELETE { - return match storage.delete_one(collection, &filter).await { - Ok(true) => { - audit::management_mutation( - username, - &format!("{}.delete", label.to_ascii_lowercase().replace(' ', "_")), - &filter.to_string(), - "success", - ); - message( - StatusCode::OK, - &format!("{label} deleted successfully"), - request_id, - ) - } - Ok(false) => error( - StatusCode::NOT_FOUND, - "EPT002", - &format!("{label} not found"), - request_id, - ), - Err(_) => unexpected(request_id), - }; - } - error( - StatusCode::METHOD_NOT_ALLOWED, - "GTW004", - "Method not allowed", + "Endpoint not found", request_id, ) } @@ -4794,7 +5529,10 @@ fn normalize_endpoint_model(payload: &mut Value, create: bool) -> Result<(), ()> | "client_uri" | "api_id" | "endpoint_id" - ) && (create || !value.is_null()) + | "endpoint_client_tls_policy" + | "endpoint_upstream_tls_profile" + | "endpoint_upstream_tls_profiles" + ) && (create || !value.is_null() || matches!(field.as_str(), "endpoint_client_tls_policy" | "endpoint_upstream_tls_profile" | "endpoint_upstream_tls_profiles")) }); for (field, configured_minimum, configured_maximum) in [ ("api_name", 1, 50), @@ -5011,8 +5749,12 @@ fn normalize_credit_model(payload: &mut Value, create: bool) -> Result<(), ()> { } continue; } - let value = security_setting_string(value).ok_or(())?; - object.insert(field.to_owned(), json!(value)); + let value = if field == "api_key_rotation_expires" { + tier_model_datetime(value).ok_or(())? + } else { + json!(security_setting_string(value).ok_or(())?) + }; + object.insert(field.to_owned(), value); } else if create { object.insert(field.to_owned(), Value::Null); } @@ -5589,10 +6331,20 @@ async fn authorization_routes( "Your token has been invalidated", request_id, ); - response.headers_mut().append( - header::SET_COOKIE, - HeaderValue::from_static("access_token_cookie=; Path=/; Max-Age=0; HttpOnly"), - ); + // Python scopes the deleted cookie to COOKIE_DOMAIN unless the host is a + // local/dev host, and clears both the primary and dev cookie names. + let domain_attribute = cookie_domain(headers) + .map(|domain| format!("; Domain={domain}")) + .unwrap_or_default(); + for cookie_name in ["access_token_cookie", "access_token_cookie_dev"] { + response.headers_mut().append( + header::SET_COOKIE, + HeaderValue::from_str(&format!( + "{cookie_name}=; Path=/; Max-Age=0; HttpOnly{domain_attribute}" + )) + .unwrap(), + ); + } return response; } let parts = path @@ -6240,7 +6992,11 @@ async fn readiness(state: &AppState, privileged: bool, request_id: &str) -> Resp vec![json!({"error": "storage is unavailable"})], ) }; - let ready = mongo_ok && redis_ok && missing_grpc_descriptors == 0; + let now = SystemTime::now().duration_since(UNIX_EPOCH).map(|time| time.as_secs() as i64).unwrap_or(i64::MAX); + let tls_certificates_valid = state.runtime.tls_certificate_expiries.lock() + .map(|expiries| expiries.values().all(|expiry| *expiry > now)) + .unwrap_or(false); + let ready = mongo_ok && redis_ok && missing_grpc_descriptors == 0 && tls_certificates_valid; let status = if ready { "ready" } else { "degraded" }; if !privileged { return success(StatusCode::OK, json!({"status": status}), request_id); @@ -6254,7 +7010,8 @@ async fn readiness(state: &AppState, privileged: bool, request_id: &str) -> Resp "mode": if memory_only { "memory" } else { "mongodb" }, "cache_backend": if memory_only { "memory" } else { "redis" }, "missing_grpc_descriptors": missing_grpc_descriptors, - "grpc_descriptor_errors": grpc_descriptor_errors + "grpc_descriptor_errors": grpc_descriptor_errors, + "tls_certificates_valid": tls_certificates_valid }), request_id, ) @@ -6440,7 +7197,7 @@ async fn monitor_metrics( "test_count": 0, "error_count": point.errors, "avg_ms": point.latency_ms, - "p95_ms": 0.0, + "p95_ms": point.p95_ms(), "bytes_in": point.bytes_in, "bytes_out": point.bytes_out, "error_rate": if point.requests == 0 { 0.0 } else { point.errors as f64 / point.requests as f64 }, @@ -6467,6 +7224,48 @@ async fn monitor_metrics( .sum::() / total_requests as f64 }; + // Python's MetricsStore.snapshot: top_apis/top_users/unique_users are + // aggregated only from the buckets in the selected range (with a + // documented global fallback when the range attributed no traffic), + // not from the process-global all-time counters. + let (range_start, range_end) = ( + selected.first().map_or(0, |point| point.timestamp), + selected.last().map_or(u64::MAX, |point| point.timestamp), + ); + let range_top_apis = analytics.get_top_apis_in_range(range_start, range_end, 10); + let top_apis: Vec<(String, u64)> = if range_top_apis.is_empty() { + analytics + .get_top_apis(10) + .into_iter() + .map(|entry| (entry.name, entry.count)) + .collect() + } else { + range_top_apis + .into_iter() + .map(|entry| (entry.name, entry.count)) + .collect() + }; + let range_top_users = analytics.get_top_users_in_range(range_start, range_end, 10); + let (top_users, unique_users): (Vec<(String, u64)>, usize) = if range_top_users.is_empty() { + let global = analytics.get_top_users(10); + let count = global.len(); + ( + global + .into_iter() + .map(|entry| (entry.name, entry.count)) + .collect(), + count, + ) + } else { + let count = range_top_users.len(); + ( + range_top_users + .into_iter() + .map(|entry| (entry.name, entry.count)) + .collect(), + count, + ) + }; success( StatusCode::OK, json!({ @@ -6478,9 +7277,9 @@ async fn monitor_metrics( "avg_response_ms": average_response_ms, "status_counts": analytics.get_status_distribution(), "series": series, - "top_apis": analytics.get_top_apis(10), - "top_users": analytics.get_top_users(10), - "unique_users": analytics.user_count(), + "top_apis": top_apis, + "top_users": top_users, + "unique_users": unique_users, "total_upstream_timeouts": 0, "total_retries": 0, "total_bytes_in": state.runtime.total_bytes_in.load(std::sync::atomic::Ordering::Relaxed), @@ -6493,91 +7292,333 @@ async fn monitor_metrics( async fn monitor_report( state: &AppState, query: &HashMap, - _request_id: &str, + request_id: &str, ) -> Response { + let start = query.get("start").map(String::as_str).unwrap_or(""); + let end = query.get("end").map(String::as_str).unwrap_or(""); + let start_ts = match parse_report_timestamp(start) { + Ok(ts) => ts, + Err(message_text) => { + return error(StatusCode::BAD_REQUEST, "MON003", &message_text, request_id); + } + }; + let end_ts = match parse_report_timestamp(end) { + Ok(ts) => ts, + Err(message_text) => { + return error(StatusCode::BAD_REQUEST, "MON003", &message_text, request_id); + } + }; + if end_ts < start_ts { + return error( + StatusCode::BAD_REQUEST, + "MON003", + "End date must be after start date", + request_id, + ); + } + + let (start_date, start_time_str) = report_date_time_utc(start_ts); + let (end_date, end_time_str) = report_date_time_utc(end_ts); + let directory = state + .config + .logs_dir + .clone() + .unwrap_or_else(|| std::path::PathBuf::from("platform-logs")); + let mut log_query = HashMap::new(); + log_query.insert("start_date".to_owned(), start_date); + log_query.insert("end_date".to_owned(), end_date); + log_query.insert("start_time".to_owned(), start_time_str); + log_query.insert("end_time".to_owned(), end_time_str); + // Python pages through up to 100 * 1000 = 100,000 log-service results; + // read_log_records already bounds total bytes read via MAX_LOG_EXPORT_BYTES. + let logs = read_log_records(&directory, &log_query, 100_000).unwrap_or_default(); + + let mut total = 0u64; + let mut errors = 0u64; + let mut total_ms = 0.0f64; + let mut status_counts: std::collections::BTreeMap = std::collections::BTreeMap::new(); + let mut api_totals: std::collections::HashMap = std::collections::HashMap::new(); + let mut api_errors: std::collections::HashMap = std::collections::HashMap::new(); + let mut user_totals: std::collections::HashMap = std::collections::HashMap::new(); + for record in &logs { + let endpoint = record.get("endpoint").and_then(Value::as_str).unwrap_or(""); + if endpoint.is_empty() || endpoint == "/platform" || endpoint.starts_with("/platform/") { + continue; + } + total += 1; + let status_code = record + .get("status_code") + .and_then(Value::as_str) + .and_then(|value| value.parse::().ok()) + .or_else(|| { + record + .get("status_code") + .and_then(Value::as_u64) + .map(|value| value as u16) + }); + let level = record + .get("level") + .and_then(Value::as_str) + .unwrap_or("") + .to_ascii_uppercase(); + let is_error = status_code.is_some_and(|code| code >= 400) + || !matches!(level.as_str(), "INFO" | "DEBUG"); + if is_error { + errors += 1; + } + if let Some(code) = status_code { + *status_counts.entry(code).or_default() += 1; + } + if let Some(response_time) = record.get("response_time").and_then(log_number) { + total_ms += response_time; + } + let api_key = report_api_from_endpoint(endpoint); + *api_totals.entry(api_key.clone()).or_default() += 1; + if is_error { + *api_errors.entry(api_key).or_default() += 1; + } + if let Some(username) = record + .get("user") + .and_then(Value::as_str) + .filter(|value| !value.is_empty()) + { + *user_totals.entry(username.to_owned()).or_default() += 1; + } + } + let analytics = global_analytics(); - let points = analytics.get_timeseries(); - let total_requests = points.iter().map(|point| point.requests).sum::(); - let total_errors = points.iter().map(|point| point.errors).sum::(); - let total_ms = points - .iter() - .map(|point| point.latency_ms * point.requests as f64) - .sum::(); - let average_ms = if total_requests == 0 { + let points_in_range = analytics + .get_timeseries() + .into_iter() + .filter(|point| { + point.timestamp >= start_ts.max(0) as u64 && point.timestamp <= end_ts.max(0) as u64 + }) + .collect::>(); + // Python's own defensive fallback: if no log lines matched (e.g. logs + // rotated away), reconstruct totals from the retained metrics buckets + // instead of reporting an empty period. + if total == 0 { + total = points_in_range.iter().map(|point| point.requests).sum(); + errors = points_in_range.iter().map(|point| point.errors).sum(); + total_ms = points_in_range + .iter() + .map(|point| point.latency_ms * point.requests as f64) + .sum(); + for (status, count) in analytics.get_status_distribution() { + if let Ok(code) = status.parse::() { + *status_counts.entry(code).or_default() += count; + } + } + for entry in analytics.get_top_apis_in_range( + start_ts.max(0) as u64, + end_ts.max(0) as u64, + usize::MAX, + ) { + api_totals.insert(entry.name.clone(), entry.count); + if entry.error_count > 0 { + api_errors.insert(entry.name, entry.error_count); + } + } + for entry in analytics.get_top_users_in_range( + start_ts.max(0) as u64, + end_ts.max(0) as u64, + usize::MAX, + ) { + user_totals.insert(entry.name, entry.count); + } + } + + let total_bytes_in: u64 = points_in_range.iter().map(|point| point.bytes_in).sum(); + let total_bytes_out: u64 = points_in_range.iter().map(|point| point.bytes_out).sum(); + let mut daily_bandwidth: std::collections::BTreeMap = + std::collections::BTreeMap::new(); + for point in &points_in_range { + let day_ts = (point.timestamp / 86_400) * 86_400; + let entry = daily_bandwidth.entry(day_ts).or_default(); + entry.0 += point.bytes_in; + entry.1 += point.bytes_out; + } + + let average_ms = if total == 0 { 0.0 } else { - total_ms / total_requests as f64 + total_ms / total as f64 }; - let successes = total_requests.saturating_sub(total_errors); - let success_rate = if total_requests == 0 { + let successes = total.saturating_sub(errors); + let success_rate = if total == 0 { 0.0 } else { - successes as f64 * 100.0 / total_requests as f64 + successes as f64 * 100.0 / total as f64 }; - let start = query.get("start").map(String::as_str).unwrap_or(""); - let end = query.get("end").map(String::as_str).unwrap_or(""); + let mut csv = String::new(); let _ = writeln!(csv, "Report,From,{},To,{}", csv_cell(start), csv_cell(end)); csv.push_str("Overview\n"); - let _ = writeln!(csv, "total_requests,{total_requests}"); - let _ = writeln!(csv, "total_errors,{total_errors}"); + let _ = writeln!(csv, "total_requests,{total}"); + let _ = writeln!(csv, "total_errors,{errors}"); let _ = writeln!(csv, "successes,{successes}"); let _ = writeln!(csv, "success_rate,{success_rate:.2}%"); let _ = writeln!(csv, "avg_response_ms,{average_ms:.2}"); csv.push_str("\nBandwidth Overview\n"); - let bytes_in = state - .runtime - .total_bytes_in - .load(std::sync::atomic::Ordering::Relaxed); - let bytes_out = state - .runtime - .total_bytes_out - .load(std::sync::atomic::Ordering::Relaxed); - let _ = writeln!(csv, "total_bytes_in,{bytes_in}"); - let _ = writeln!(csv, "total_bytes_out,{bytes_out}"); - let _ = writeln!(csv, "total_bytes,{}", bytes_in.saturating_add(bytes_out)); + let _ = writeln!(csv, "total_bytes_in,{total_bytes_in}"); + let _ = writeln!(csv, "total_bytes_out,{total_bytes_out}"); + let _ = writeln!( + csv, + "total_bytes,{}", + total_bytes_in.saturating_add(total_bytes_out) + ); csv.push_str("\nStatus Codes\nstatus,count\n"); - let mut status_counts = analytics - .get_status_distribution() - .into_iter() - .collect::>(); - status_counts.sort_by_key(|(status, _)| status.parse::().unwrap_or(u16::MAX)); - for (status, count) in status_counts { - let _ = writeln!(csv, "{},{}", csv_cell(&status), count); + for (status, count) in &status_counts { + let _ = writeln!(csv, "{status},{count}"); } csv.push_str("\nAPI Usage\napi,total,errors,successes,success_rate\n"); - for api in analytics.get_top_apis(analytics.api_count()) { - let successes = api.count.saturating_sub(api.error_count); - let rate = if api.count == 0 { + let mut apis = api_totals.into_iter().collect::>(); + apis.sort_by(|left, right| right.1.cmp(&left.1).then_with(|| left.0.cmp(&right.0))); + for (api, count) in apis { + let err = api_errors.get(&api).copied().unwrap_or_default(); + let succ = count.saturating_sub(err); + let rate = if count == 0 { 0.0 } else { - successes as f64 * 100.0 / api.count as f64 + succ as f64 * 100.0 / count as f64 }; + let _ = writeln!(csv, "{},{count},{err},{succ},{rate:.2}%", csv_cell(&api)); + } + csv.push_str("\nUser Usage\nusername,requests\n"); + let mut users = user_totals.into_iter().collect::>(); + users.sort_by(|left, right| right.1.cmp(&left.1).then_with(|| left.0.cmp(&right.0))); + for (user, count) in users { + let _ = writeln!(csv, "{},{count}", csv_cell(&user)); + } + csv.push_str("\nBandwidth (per day, UTC)\ndate,bytes_in,bytes_out,total\n"); + for (day_ts, (bytes_in, bytes_out)) in daily_bandwidth { + let (date_str, _) = report_date_time_utc(day_ts as i64); let _ = writeln!( csv, - "{},{},{},{},{rate:.2}%", - csv_cell(&api.name), - api.count, - api.error_count, - successes + "{date_str},{bytes_in},{bytes_out},{}", + bytes_in.saturating_add(bytes_out) ); } - csv.push_str("\nUser Usage\nusername,requests\n"); - for user in analytics.get_top_users(analytics.user_count()) { - let _ = writeln!(csv, "{},{}", csv_cell(&user.name), user.count); + + let mut response = ([(header::CONTENT_TYPE, "text/csv; charset=utf-8")], csv).into_response(); + if let Ok(value) = HeaderValue::from_str(&format!( + "attachment; filename=doorman_report_{start}_to_{end}.csv" + )) { + response + .headers_mut() + .insert(header::CONTENT_DISPOSITION, value); + } + response +} + +/// `api` key derivation matching Python's `_api_from_endpoint` in +/// `monitor_routes.py::generate_report`. +fn report_api_from_endpoint(endpoint: &str) -> String { + if let Some(rest) = endpoint.strip_prefix("/api/rest/") { + let parts = rest.split('/').collect::>(); + return format!("rest:{}", parts.first().copied().unwrap_or("unknown")); + } + if let Some(rest) = endpoint.strip_prefix("/api/graphql/") { + let name = rest + .rsplit('/') + .next() + .filter(|value| !value.is_empty()) + .unwrap_or("unknown"); + return format!("graphql:{name}"); + } + if let Some(rest) = endpoint.strip_prefix("/api/soap/") { + let name = rest + .rsplit('/') + .next() + .filter(|value| !value.is_empty()) + .unwrap_or("unknown"); + return format!("soap:{name}"); + } + "platform".to_owned() +} + +/// Python's `_parse_ts`: try `%Y-%m-%dT%H:%M`, then `%Y-%m-%d`, then a +/// best-effort ISO-8601 fallback via `datetime.fromisoformat`. A naive +/// `datetime.strptime(...).timestamp()` in Python interprets the value in the +/// process's local timezone; this deployment (like the pinned reference's +/// container images) runs in UTC, so the two are equivalent here. +fn parse_report_timestamp(value: &str) -> Result { + let invalid = || "Invalid date format. Use YYYY-MM-DD or YYYY-MM-DDTHH:MM".to_owned(); + let parse_date = |text: &str| -> Option { + let mut parts = text.splitn(3, '-'); + let year = parts.next()?.parse::().ok()?; + let month = parts.next()?.parse::().ok()?; + let day = parts.next()?.parse::().ok()?; + time::Date::from_calendar_date(year, time::Month::try_from(month).ok()?, day).ok() + }; + let parse_time = |text: &str| -> Option { + // Strict "%H:%M" callers pass exactly two fields; the fromisoformat + // fallback below may also hand this "%H:%M:%S[.ffffff]", in which + // case the seconds (whole part only; unix timestamps here are + // second-resolution) are preserved rather than silently dropped. + let mut fields = text.splitn(3, ':'); + let hour = fields.next()?; + let minute = fields.next()?; + let second = fields + .next() + .and_then(|value| value.split(['.', ',']).next()) + .unwrap_or("0"); + time::Time::from_hms( + hour.parse().ok()?, + minute.parse().ok()?, + second.parse().ok()?, + ) + .ok() + }; + let to_ts = |date: time::Date, time_value: time::Time| { + time::PrimitiveDateTime::new(date, time_value) + .assume_utc() + .unix_timestamp() + }; + + if let Some((date_part, time_part)) = value.split_once('T') + && let (Some(date), Some(time_value)) = (parse_date(date_part), parse_time(time_part)) + { + return Ok(to_ts(date, time_value)); } + if let Some(date) = parse_date(value) { + return Ok(to_ts(date, time::Time::MIDNIGHT)); + } + // fromisoformat fallback: accept "date time" (space separator) and an + // optional trailing "Z"/offset the two strict formats above reject. + let normalized = value.trim().replace('Z', "+00:00"); + let date_part = normalized.split(['T', ' ']).next().unwrap_or_default(); + let Some(date) = parse_date(date_part) else { + return Err(invalid()); + }; + let time_part = normalized + .split_once(['T', ' ']) + .map(|(_, rest)| rest) + .map(|rest| rest.split(['+', '-']).next().unwrap_or_default()) + .unwrap_or_default(); + let time_value = if time_part.is_empty() { + time::Time::MIDNIGHT + } else { + parse_time(time_part).ok_or_else(invalid)? + }; + Ok(to_ts(date, time_value)) +} +/// Formats a unix timestamp as UTC `(YYYY-MM-DD, HH:MM)`, matching Python's +/// `datetime.fromtimestamp(ts, timezone.utc).strftime(...)`. +fn report_date_time_utc(timestamp: i64) -> (String, String) { + let Ok(value) = time::OffsetDateTime::from_unix_timestamp(timestamp) else { + return (String::new(), String::new()); + }; ( - [ - (header::CONTENT_TYPE, "text/csv; charset=utf-8"), - ( - header::CONTENT_DISPOSITION, - "attachment; filename=doorman_report.csv", - ), - ], - csv, + format!( + "{:04}-{:02}-{:02}", + value.year(), + value.month() as u8, + value.day() + ), + format!("{:02}:{:02}", value.hour(), value.minute()), ) - .into_response() } fn csv_cell(value: &str) -> String { @@ -6587,14 +7628,18 @@ fn csv_cell(value: &str) -> String { value.to_owned() } } -fn analytics_query_error( +/// Matches FastAPI's automatic validation of a typed integer query parameter +/// (e.g. `page: int = 1`): a present-but-non-numeric value never reaches the +/// route handler and instead produces a 422 with this `detail` shape, rather +/// than being silently coerced to a default. +fn int_query_validation_error( query: &HashMap, - has_limit: bool, + fields: &[&str], request_id: &str, ) -> Option { - for field in ["start_ts", "end_ts"] { + for field in fields { if query - .get(field) + .get(*field) .is_some_and(|value| value.parse::().is_err()) { return Some(validation_errors( @@ -6607,6 +7652,17 @@ fn analytics_query_error( )); } } + None +} + +fn analytics_query_error( + query: &HashMap, + has_limit: bool, + request_id: &str, +) -> Option { + if let Some(response) = int_query_validation_error(query, &["start_ts", "end_ts"], request_id) { + return Some(response); + } if !has_limit { return None; } @@ -6689,26 +7745,23 @@ fn analytics_limit(query: &HashMap) -> usize { .clamp(1, 100) } +/// Python's `PercentileMetrics.calculate`: pool every raw latency sample from +/// every bucket (not per-bucket averages), sort, and index each percentile at +/// `max(0, int(p * n) - 1)`. fn analytics_percentiles(points: &[AggregatedPoint]) -> Value { - let mut values = points + let values: Vec = points .iter() - .map(|point| point.latency_ms) - .collect::>(); - values.sort_by(|left, right| left.total_cmp(right)); - let percentile = |fraction: f64| { - if values.is_empty() { - 0.0 - } else { - let index = ((values.len() - 1) as f64 * fraction).round() as usize; - values[index] - } - }; + .flat_map(|point| point.latencies_ms.iter().copied()) + .collect(); + let (min, max) = ( + values.iter().copied().fold(f64::INFINITY, f64::min), + values.iter().copied().fold(f64::NEG_INFINITY, f64::max), + ); + let (p50, p75, p90, p95, p99) = pooled_percentiles(values.iter().copied()); json!({ - "p50": percentile(0.50), - "p75": percentile(0.75), - "p90": percentile(0.90), - "p95": percentile(0.95), - "p99": percentile(0.99) + "p50": p50, "p75": p75, "p90": p90, "p95": p95, "p99": p99, + "min": if values.is_empty() { 0.0 } else { min }, + "max": if values.is_empty() { 0.0 } else { max } }) } @@ -6716,19 +7769,20 @@ fn analytics_entity(entity: &EntityCounter, key: &str) -> Value { json!({key: entity.name, "count": entity.count}) } -fn analytics_endpoint(entity: &EntityCounter) -> Value { +fn analytics_endpoint(entity: &EndpointEntity) -> Value { let error_rate = if entity.count == 0 { 0.0 } else { entity.error_count as f64 / entity.count as f64 }; + let (p50, p75, p90, p95, p99) = entity.percentiles; json!({ "endpoint_uri": entity.name, "count": entity.count, "error_count": entity.error_count, "error_rate": error_rate, - "avg_ms": 0.0, - "percentiles": {"p50": 0.0, "p75": 0.0, "p90": 0.0, "p95": 0.0, "p99": 0.0} + "avg_ms": entity.avg_ms, + "percentiles": {"p50": p50, "p75": p75, "p90": p90, "p95": p95, "p99": p99} }) } @@ -6752,13 +7806,7 @@ fn analytics_series_point(point: &AggregatedPoint, metric_type: Option<&str>) -> value.insert("avg_ms".to_owned(), json!(point.latency_ms)); value.insert( "percentiles".to_owned(), - json!({ - "p50": point.latency_ms, - "p75": point.latency_ms, - "p90": point.latency_ms, - "p95": point.latency_ms, - "p99": point.latency_ms - }), + analytics_percentiles(std::slice::from_ref(point)), ); } Some("bandwidth") => { @@ -6773,13 +7821,7 @@ fn analytics_series_point(point: &AggregatedPoint, metric_type: Option<&str>) -> value.insert("avg_ms".to_owned(), json!(point.latency_ms)); value.insert( "percentiles".to_owned(), - json!({ - "p50": point.latency_ms, - "p75": point.latency_ms, - "p90": point.latency_ms, - "p95": point.latency_ms, - "p99": point.latency_ms - }), + analytics_percentiles(std::slice::from_ref(point)), ); value.insert("bytes_in".to_owned(), json!(point.bytes_in)); value.insert("bytes_out".to_owned(), json!(point.bytes_out)); @@ -6814,44 +7856,53 @@ fn analytics_top(kind: &str, query: &HashMap, request_id: &str) let (start_ts, end_ts) = analytics_time_range(query); let limit = analytics_limit(query); let analytics = global_analytics(); + let (start_bound, end_bound) = (start_ts.max(0) as u64, end_ts.max(0) as u64); let response = match kind { "api" => { - let entries = analytics - .get_top_apis(limit) + // Reconstructed from only the minute buckets in [start_ts, end_ts], + // matching Python's enhanced_metrics_store.get_snapshot-backed top_apis + // rather than an all-time process-global total. + let all = analytics.get_top_apis_in_range(start_bound, end_bound, usize::MAX); + let entries = all .iter() + .take(limit) .map(|entry| analytics_entity(entry, "api")) .collect::>(); json!({ "time_range": {"start_ts": start_ts, "end_ts": end_ts}, "top_apis": entries, - "total_apis": analytics.api_count() + "total_apis": all.len() }) } "user" => { - let entries = analytics - .get_top_users(limit) + let all = analytics.get_top_users_in_range(start_bound, end_bound, usize::MAX); + let entries = all .iter() + .take(limit) .map(|entry| analytics_entity(entry, "user")) .collect::>(); json!({ "time_range": {"start_ts": start_ts, "end_ts": end_ts}, "top_users": entries, - "total_users": analytics.user_count() + "total_users": all.len() }) } _ => { - let mut entries = analytics - .get_top_endpoints(analytics.endpoint_count()) - .iter() - .map(analytics_endpoint) - .collect::>(); + let all = analytics.get_top_endpoints_in_range(start_bound, end_bound, usize::MAX); + let mut entries = all.iter().map(analytics_endpoint).collect::>(); + let total_endpoints = entries.len(); let sort_by = query.get("sort_by").map(String::as_str).unwrap_or("count"); - if sort_by == "error_rate" { + let sort_key = match sort_by { + "error_rate" => Some("error_rate"), + "avg_ms" => Some("avg_ms"), + _ => None, + }; + if let Some(key) = sort_key { entries.sort_by(|left, right| { - right["error_rate"] + right[key] .as_f64() .unwrap_or_default() - .total_cmp(&left["error_rate"].as_f64().unwrap_or_default()) + .total_cmp(&left[key].as_f64().unwrap_or_default()) }); } entries.truncate(limit); @@ -6859,7 +7910,7 @@ fn analytics_top(kind: &str, query: &HashMap, request_id: &str) "time_range": {"start_ts": start_ts, "end_ts": end_ts}, "sort_by": sort_by, "top_endpoints": entries, - "total_endpoints": analytics.endpoint_count() + "total_endpoints": total_endpoints }) } }; @@ -7406,28 +8457,139 @@ async fn config_import( let Some(storage) = &state.storage else { return unexpected(request_id); }; - let imported = match storage - .import_configuration_atomically( - &payload, + let mut snapshot_data = Map::new(); + for collection in ["apis", "endpoints", "roles", "groups", "routings"] { + let values = match storage.find_many(collection, &json!({})).await { + Ok(values) => values.into_iter().map(strip_internal).collect::>(), + Err(_) => return unexpected(request_id), + }; + snapshot_data.insert(collection.to_owned(), json!(values)); + } + let timestamp = timestamp_now_naive().replace('T', " "); + if storage + .insert_one( + "config_snapshots", json!({ "snapshot_id": Uuid::new_v4().to_string(), - "created_at": timestamp_now(), - "actor": username + "timestamp": timestamp, + "created_by": username, + "data": snapshot_data, }), ) .await + .is_err() { - Ok(imported) => imported, - Err(_) => return unexpected(request_id), - }; + return unexpected(request_id); + } + let mut imported = Map::new(); + for collection in ["apis", "endpoints", "roles", "groups", "routings"] { + let values = match payload.get(collection) { + None => Vec::new(), + Some(value) if !python_truthy_json(value) => Vec::new(), + Some(Value::Array(values)) => values.clone(), + Some(_) => return unexpected(request_id), + }; + let mut count = 0; + for value in values { + let Some(document) = value.as_object() else { + return unexpected(request_id); + }; + if config_upsert(storage, collection, document).await.is_err() { + return unexpected(request_id); + } + count += 1; + } + imported.insert(collection.to_owned(), json!(count)); + } audit::management_mutation(username, "config.import", "configuration", "success"); - success(StatusCode::OK, json!({"imported": imported}), request_id) + success( + StatusCode::OK, + json!({"imported": Value::Object(imported)}), + request_id, + ) +} + +async fn config_upsert( + storage: &SharedStorage, + collection: &str, + document: &Map, +) -> Result<(), crate::storage::runtime::StorageError> { + let required: &[&str] = match collection { + "apis" => &["api_name", "api_version"], + "endpoints" => &["api_name", "api_version", "endpoint_method", "endpoint_uri"], + "roles" => &["role_name"], + "groups" => &["group_name"], + "routings" => &["client_key"], + _ => return Ok(()), + }; + if required.iter().any(|field| { + document + .get(*field) + .is_none_or(|value| !python_truthy_json(value)) + }) { + return Ok(()); + } + let filter = Value::Object( + required + .iter() + .map(|field| ((*field).to_owned(), document[*field].clone())) + .collect(), + ); + let mut value = Value::Object(document.clone()); + strip_mongo_id(&mut value); + if collection == "endpoints" { + if let Some(api) = storage + .find_one( + "apis", + &json!({ + "api_name": document["api_name"], + "api_version": document["api_version"], + }), + ) + .await? + && let Some(api_id) = api.get("api_id") + { + value["api_id"] = api_id.clone(); + } + if value.get("endpoint_id").is_none() { + value["endpoint_id"] = json!(Uuid::new_v4().to_string()); + } + } + let existing = storage.find_one(collection, &filter).await?; + if collection == "apis" { + if existing.is_none() { + if value.get("api_id").is_none() { + value["api_id"] = json!(Uuid::new_v4().to_string()); + } + if value.get("api_path").is_none() { + value["api_path"] = json!(format!( + "/{}/{}", + python_string(&document["api_name"]), + python_string(&document["api_version"]), + )); + } + } else if value.get("api_id").is_none() + && let Some(api_id) = existing.as_ref().and_then(|api| api.get("api_id")) + { + value["api_id"] = api_id.clone(); + } + } + if existing.is_some() { + storage.update_one(collection, &filter, &value).await?; + } else { + storage.insert_one(collection, value).await?; + } + Ok(()) +} + +fn python_string(value: &Value) -> String { + security_setting_string(value).unwrap_or_else(|| value.to_string()) } async fn config_rollback( state: &AppState, username: &str, - payload: Value, + _payload: Value, request_id: &str, ) -> Response { if !has_permission(state, username, "manage_gateway").await { @@ -7440,70 +8602,56 @@ async fn config_rollback( let Some(storage) = &state.storage else { return unexpected(request_id); }; - let requested_snapshot_id = payload.get("snapshot_id").and_then(Value::as_str); - let snapshot = if let Some(snapshot_id) = requested_snapshot_id { - match storage - .find_one("config_snapshots", &json!({"snapshot_id": snapshot_id})) - .await - { - Ok(Some(snapshot)) => snapshot, - Ok(None) => { - return error( - StatusCode::NOT_FOUND, - "CFG404", - "Configuration snapshot not found", - request_id, - ); - } - Err(_) => return unexpected(request_id), - } - } else { - let snapshots = match storage.find_many("config_snapshots", &json!({})).await { - Ok(snapshots) => snapshots, - Err(_) => return unexpected(request_id), - }; - let Some(snapshot) = snapshots.into_iter().max_by(|left, right| { - left.get("created_at") - .and_then(Value::as_str) - .cmp(&right.get("created_at").and_then(Value::as_str)) - }) else { - return error( - StatusCode::NOT_FOUND, - "CFG404", - "No snapshot found", + let snapshots = match storage.find_many("config_snapshots", &json!({})).await { + Ok(snapshots) => snapshots, + Err(_) => { + return http_detail( + StatusCode::INTERNAL_SERVER_ERROR, + "Rollback failed", request_id, ); - }; - snapshot + } }; - let Some(data) = snapshot.get("data").and_then(Value::as_object) else { + let Some(snapshot) = snapshots.into_iter().max_by(|left, right| { + left.get("timestamp") + .and_then(Value::as_str) + .cmp(&right.get("timestamp").and_then(Value::as_str)) + }) else { return error( - StatusCode::BAD_REQUEST, - "CFG007", - "Configuration snapshot is invalid", + StatusCode::NOT_FOUND, + "CFG404", + "No snapshot found", + request_id, + ); + }; + let Some(data) = snapshot.get("data").and_then(Value::as_object) else { + return http_detail( + StatusCode::INTERNAL_SERVER_ERROR, + "Rollback failed", request_id, ); }; - let mut replacements = Vec::new(); for collection in ["apis", "endpoints", "roles", "groups", "routings"] { let Some(values) = data.get(collection).and_then(Value::as_array) else { - return error( - StatusCode::BAD_REQUEST, - "CFG007", - "Configuration snapshot is invalid", + return http_detail( + StatusCode::INTERNAL_SERVER_ERROR, + "Rollback failed", request_id, ); }; - replacements.push((collection.to_owned(), values.clone())); - } - if storage - .replace_collections_atomically(&replacements, None) - .await - .is_err() - { - return unexpected(request_id); + if storage + .replace_collection(collection, values.clone()) + .await + .is_err() + { + return http_detail( + StatusCode::INTERNAL_SERVER_ERROR, + "Rollback failed", + request_id, + ); + } } - let restored_to = snapshot.get("created_at").cloned().unwrap_or(Value::Null); + let restored_to = snapshot.get("timestamp").cloned().unwrap_or(Value::Null); let snapshot_id = snapshot.get("snapshot_id").cloned().unwrap_or(Value::Null); audit::management_mutation( username, @@ -7555,7 +8703,15 @@ async fn analytics_detail( endpoint.name.starts_with(&endpoint_prefix) || endpoint.name.starts_with(&gateway_prefix) }) - .map(analytics_endpoint) + .map(|endpoint| { + analytics_endpoint(&EndpointEntity { + name: endpoint.name.clone(), + count: endpoint.count, + error_count: endpoint.error_count, + avg_ms: 0.0, + percentiles: (0.0, 0.0, 0.0, 0.0, 0.0), + }) + }) .collect::>(); return success( StatusCode::OK, @@ -7664,43 +8820,72 @@ fn restart_required_keys() -> Value { ) } -async fn demo_seed(state: &AppState, username: &str, request_id: &str) -> Response { - if username != "admin" { +async fn demo_seed( + state: &AppState, + username: &str, + query: &HashMap, + request_id: &str, +) -> Response { + // Python: `if not await is_admin_user(username)` -- a role-based admin + // check, not a literal username comparison. + if !is_admin_user(state, username).await { return error( StatusCode::FORBIDDEN, - "AUTH006", - "Admin access required", + "DEMO001", + "Permission denied to run seeder", request_id, ); } let Some(storage) = &state.storage else { return unexpected(request_id); }; + // Python has no such gate and will happily seed a real MongoDB; Rust + // deliberately refuses outside memory mode as an additional safety guard + // against seeding synthetic data into a production database. This is a + // documented approved addition, not a parity gap, so it uses its own + // error code rather than colliding with DEMO001 above. if !storage.is_memory() { return error( StatusCode::BAD_REQUEST, - "DEMO001", + "DEMO002", "Demo seed is available only in memory mode", request_id, ); } - for (name, version, server) in [ - ("customers", "v1", "http://localhost:8080"), - ("orders", "v1", "http://localhost:8081"), - ("weather", "v1", "http://localhost:8082"), - ] { - if storage - .find_one("apis", &json!({"api_name": name, "api_version": version})) - .await - .ok() - .flatten() - .is_none() - { - let _ = storage.insert_one("apis", json!({"api_name": name, "api_version": version, "api_id": Uuid::new_v4().to_string(), "api_path": format!("/{name}/{version}"), "api_servers": [server], "api_type": "REST", "api_public": false, "api_auth_required": true, "active": true})).await; - let _ = storage.insert_one("endpoints", json!({"api_name": name, "api_version": version, "endpoint_id": Uuid::new_v4().to_string(), "endpoint_method": "GET", "endpoint_uri": "/status", "client_uri": "/status", "endpoint_description": "Demo status"})).await; + let query_usize = |key: &str, default: usize| { + query + .get(key) + .and_then(|value| value.parse::().ok()) + .unwrap_or(default) + }; + let options = crate::demo_seed::SeedOptions { + users: query_usize("users", 40), + apis: query_usize("apis", 15), + endpoints: query_usize("endpoints", 6), + groups: query_usize("groups", 8), + protos: query_usize("protos", 6), + logs: query_usize("logs", 1500), + seed: query + .get("seed") + .and_then(|value| value.parse::().ok()), + }; + match crate::demo_seed::run_seed(storage, &options).await { + Ok(mut result) => { + if let Some(object) = result.as_object_mut() { + object.insert("message".to_owned(), json!("Seed completed")); + } + success(StatusCode::OK, result, request_id) + } + Err(error_value) => { + tracing::error!(error = %error_value, "demo seed error"); + error( + StatusCode::INTERNAL_SERVER_ERROR, + "DEMO999", + "Failed to seed demo data", + request_id, + ) } } - message(StatusCode::OK, "Demo data seeded successfully", request_id) } #[derive(Debug, Clone, PartialEq, Eq)] @@ -8410,6 +9595,13 @@ async fn credit_routes( .and_then(Value::as_str) .cmp(&right.get("api_credit_group").and_then(Value::as_str)) }); + // Python's `list_credit_definitions(page: int = 1, page_size: int = 50)` + // typed FastAPI query params: a non-numeric value produces a 422. + if let Some(response) = + int_query_validation_error(query, &["page", "page_size"], request_id) + { + return response; + } if let Err(message_text) = validate_pagination(query) { return error(StatusCode::BAD_REQUEST, "PAG001", &message_text, request_id); } @@ -8446,6 +9638,13 @@ async fn credit_routes( request_id, ); } + // Python's `get_all_users_credits(page: int = 1, page_size: int = 10, ...)` + // typed FastAPI query params: a non-numeric value produces a 422. + if let Some(response) = + int_query_validation_error(query, &["page", "page_size"], request_id) + { + return response; + } if let Err(message_text) = validate_pagination(query) { return error(StatusCode::BAD_REQUEST, "PAG001", &message_text, request_id); } @@ -8925,10 +10124,6 @@ async fn quota_routes( let Some(storage) = &state.storage else { return unexpected(request_id); }; - let (tier, limits) = match quota_tier_and_limits(storage, username).await { - Ok(value) => value, - Err(_) => return unexpected(request_id), - }; if path == "/quota/usage/history" && method == Method::GET { return success( StatusCode::OK, @@ -8936,6 +10131,10 @@ async fn quota_routes( request_id, ); } + let (tier, limits) = match quota_tier_and_limits(storage, username).await { + Ok(value) => value, + Err(_) => return quota_route_failure(path, request_id), + }; if path == "/quota/usage/export" && method == Method::POST { let Some(limits) = limits.as_ref() else { return http_detail( @@ -8946,7 +10145,7 @@ async fn quota_routes( }; let quotas = match quota_values(storage, username, limits).await { Ok(quotas) => quotas, - Err(_) => return unexpected(request_id), + Err(_) => return quota_route_failure(path, request_id), }; // The pinned Python export intentionally contains request quotas only; // monthly bandwidth is present in the dashboard but not this payload. @@ -8956,7 +10155,7 @@ async fn quota_routes( .collect::>(); let export_data = json!({ "user_id": username, - "export_date": timestamp_now(), + "export_date": timestamp_now_naive(), "quotas": export_quotas.iter().map(|quota| quota_export_value(quota)).collect::>(), }); if query.get("format").is_some_and(|format| format == "csv") { @@ -8997,7 +10196,7 @@ async fn quota_routes( && candidate .get("enabled") .and_then(Value::as_bool) - .unwrap_or(true) + == Some(true) }) .map(|candidate| { json!({ @@ -9008,7 +10207,7 @@ async fn quota_routes( }) }) .collect::>(), - Err(_) => return unexpected(request_id), + Err(_) => return quota_route_failure(path, request_id), }; success( StatusCode::OK, @@ -9070,7 +10269,7 @@ async fn quota_routes( }; let quotas = match quota_values(storage, username, limits).await { Ok(quotas) => quotas, - Err(_) => return unexpected(request_id), + Err(_) => return quota_route_failure(path, request_id), }; let request_quotas = quotas.iter().filter(|quota| { quota["quota_type"] @@ -9136,7 +10335,7 @@ async fn quota_routes( }; return match quota_status(storage, username, quota_type, limit).await { Ok(status) => success(StatusCode::OK, status, request_id), - Err(_) => unexpected(request_id), + Err(_) => quota_route_failure(path, request_id), }; } error( @@ -9147,6 +10346,17 @@ async fn quota_routes( ) } +fn quota_route_failure(path: &str, request_id: &str) -> Response { + let detail = match path { + "/quota/usage/history" => "Failed to get usage history", + "/quota/usage/export" => "Failed to export usage data", + "/quota/tier/info" => "Failed to get tier info", + "/quota/burst/status" => "Failed to get burst status", + _ => "Failed to get quota status", + }; + http_detail(StatusCode::INTERNAL_SERVER_ERROR, detail, request_id) +} + async fn quota_tier_and_limits( storage: &SharedStorage, username: &str, @@ -9222,11 +10432,14 @@ async fn quota_status( limit: u64, ) -> Result { let (counter_type, period_key, reset_at) = quota_period(name); + // QuotaTracker.check_quota deliberately fails open when Redis is + // unavailable, returning zero usage with the configured limit intact. let current_usage = storage .current_counter(&format!( "quota:user:{username}:{counter_type}:month:{period_key}:usage" )) - .await?; + .await + .unwrap_or(0); let percentage_used = current_usage as f64 / limit as f64 * 100.0; Ok(json!({ "quota_type": name, @@ -10102,29 +11315,65 @@ pub async fn backfill_grpc_descriptors(storage: &SharedStorage) -> DescriptorBac }; let mut backfill = DescriptorBackfill::default(); for api in apis { - if !api + let grpc_configured = api .get("api_type") .and_then(Value::as_str) .is_some_and(|kind| kind.eq_ignore_ascii_case("GRPC")) - || !bool_field_default(&api, "active", true) - { + || api.get("api_grpc_proto_source").is_some_and(python_truthy) + || api.get("api_grpc_package").is_some_and(python_truthy); + if !grpc_configured || api.get("active") == Some(&Value::Bool(false)) { continue; } - let Some(source) = api.get("api_grpc_proto_source").and_then(Value::as_str) else { - continue; - }; backfill.scanned += 1; if api .get("api_grpc_descriptor_set") - .and_then(Value::as_str) - .is_some_and(|descriptor| !descriptor.trim().is_empty()) + .is_some_and(python_truthy) { backfill.skipped += 1; continue; } - let api_name = api.get("api_name").cloned().unwrap_or(Value::Null); - let api_version = api.get("api_version").cloned().unwrap_or(Value::Null); - match compile_proto(source) { + let api_name = api + .get("api_name") + .and_then(Value::as_str) + .unwrap_or_default(); + let api_version = api + .get("api_version") + .and_then(Value::as_str) + .unwrap_or_default(); + let api_label = format!("{api_name}/{api_version}"); + if api_name.is_empty() || api_version.is_empty() { + backfill.errors.push(json!({ + "api": api_label, + "error": "API name/version is missing", + })); + continue; + } + let Some(source) = api + .get("api_grpc_proto_source") + .and_then(Value::as_str) + .filter(|source| !source.is_empty()) + else { + backfill.errors.push(json!({ + "api": api_label, + "error": "Proto source not found", + })); + continue; + }; + let max_proto_size = env::var("MAX_PROTO_SIZE_BYTES") + .ok() + .and_then(|value| value.parse::().ok()) + .unwrap_or(1024 * 1024); + let source = match validate_proto_content(source.as_bytes(), max_proto_size) { + Ok(source) => source, + Err(error_value) => { + backfill.errors.push(json!({ + "api": api_label, + "error": error_value.chars().take(500).collect::(), + })); + continue; + } + }; + match compile_proto(&source) { Ok((descriptor, digest)) => { let filter = json!({"api_name": api_name, "api_version": api_version}); match storage @@ -10140,18 +11389,18 @@ pub async fn backfill_grpc_descriptors(storage: &SharedStorage) -> DescriptorBac { Ok(Some(_)) => backfill.updated += 1, Ok(None) => backfill.errors.push(json!({ - "api": filter.get("api_name"), + "api": api_label, "error": "API disappeared while descriptor backfill was running", })), Err(error_value) => backfill.errors.push(json!({ - "api": filter.get("api_name"), + "api": api_label, "error": error_value.to_string(), })), } } Err(error_value) => backfill.errors.push(json!({ - "api": api_name, - "error": error_value, + "api": api_label, + "error": error_value.chars().take(500).collect::(), })), } } @@ -10167,6 +11416,25 @@ async fn proto_routes( username: &str, request_id: &str, ) -> Response { + if method == Method::POST { + let max_size = env::var(crate::constants::Defaults::MAX_MULTIPART_SIZE_BYTES_ENV) + .ok() + .and_then(|value| value.parse::().ok()) + .unwrap_or(crate::constants::Defaults::MAX_MULTIPART_SIZE_BYTES_DEFAULT); + if headers + .get(header::CONTENT_LENGTH) + .and_then(|value| value.to_str().ok()) + .and_then(|value| value.parse::().ok()) + .is_some_and(|length| length > max_size) + { + return error( + StatusCode::PAYLOAD_TOO_LARGE, + crate::constants::ErrorCodes::REQUEST_TOO_LARGE, + crate::constants::Messages::FILE_TOO_LARGE, + request_id, + ); + } + } if !has_permission(state, username, "manage_apis").await { let (code, message_text) = if method == Method::PUT { ("API008", "You do not have permission to update proto files") @@ -10274,20 +11542,12 @@ async fn proto_routes( ); } if method == Method::POST || method == Method::PUT { - let max_size = env::var(crate::constants::Defaults::MAX_MULTIPART_SIZE_BYTES_ENV) + let max_proto_size = env::var("MAX_PROTO_SIZE_BYTES") .ok() .and_then(|value| value.parse::().ok()) - .unwrap_or(crate::constants::Defaults::MAX_MULTIPART_SIZE_BYTES_DEFAULT); - let source = match extract_proto_source(headers, body) { - Ok(source) if source.len() <= max_size => source, - Ok(_) => { - return error( - StatusCode::PAYLOAD_TOO_LARGE, - crate::constants::ErrorCodes::REQUEST_TOO_LARGE, - crate::constants::Messages::FILE_TOO_LARGE, - request_id, - ); - } + .unwrap_or(1024 * 1024); + let content = match extract_proto_source(headers, body) { + Ok(content) => content, Err(error_value) => { return error( StatusCode::BAD_REQUEST, @@ -10301,26 +11561,29 @@ async fn proto_routes( ); } }; - if source.contains('`') - || source.contains("$(") - || !(source.contains("syntax") - || source.contains("message") - || source.contains("service")) - { - return error( - StatusCode::BAD_REQUEST, - "REQ002", - "Invalid proto file", - request_id, - ); - } + let source = match validate_proto_content(&content, max_proto_size) { + Ok(source) => source, + Err(error_value) => { + return error( + StatusCode::BAD_REQUEST, + crate::constants::ErrorCodes::REQUEST_FILE_TYPE, + &format!("Invalid proto file: {error_value}"), + request_id, + ); + } + }; let (descriptor, digest) = match compile_proto(&source) { Ok(result) => result, Err(error_value) => { + let message_text = if method == Method::PUT { + "Failed to generate gRPC code from proto file".to_owned() + } else { + format!("Failed to generate gRPC code: {error_value}") + }; return error( StatusCode::INTERNAL_SERVER_ERROR, "API009", - &format!("Failed to generate gRPC descriptor: {error_value}"), + &message_text, request_id, ); } @@ -10397,13 +11660,13 @@ async fn proto_routes( ) } -fn extract_proto_source(headers: &HeaderMap, body: &[u8]) -> Result { +fn extract_proto_source(headers: &HeaderMap, body: &[u8]) -> Result, String> { let content_type = headers .get(header::CONTENT_TYPE) .and_then(|value| value.to_str().ok()) .unwrap_or(""); if !content_type.starts_with("multipart/form-data") { - return String::from_utf8(body.to_vec()).map_err(|_| "Proto file must be UTF-8".to_owned()); + return Ok(body.to_vec()); } let boundary = content_type .split("boundary=") @@ -10411,9 +11674,19 @@ fn extract_proto_source(headers: &HeaderMap, body: &[u8]) -> Result Result Option { - for line in source.lines() { - let trimmed = line.trim(); - if let Some(rest) = trimmed.strip_prefix("package") { - let pkg = rest.trim().trim_matches(';').trim(); - if !pkg.is_empty() - && pkg - .chars() - .all(|c| c.is_alphanumeric() || c == '_' || c == '.') - { - return Some(pkg.to_owned()); - } - } + static PACKAGE: OnceLock = OnceLock::new(); + PACKAGE + .get_or_init(|| Regex::new(r"\bpackage\s+([a-zA-Z0-9_.]+)\s*;").unwrap()) + .captures(source) + .and_then(|captures| captures.get(1)) + .map(|package| package.as_str().to_owned()) +} + +fn validate_proto_content(content: &[u8], max_size: usize) -> Result { + if content.len() > max_size { + return Err(format!("File too large (max {max_size} bytes)")); + } + if content.contains(&0) { + return Err("Invalid proto file: binary content detected".to_owned()); + } + let source = std::str::from_utf8(content) + .map_err(|_| "Invalid proto file: not valid UTF-8".to_owned())?; + if !(source.contains("syntax") || source.contains("message") || source.contains("service")) { + return Err("Invalid proto file: missing proto syntax (syntax/message/service)".to_owned()); + } + static SUSPICIOUS: OnceLock = OnceLock::new(); + if SUSPICIOUS + .get_or_init(|| Regex::new(r"`|\$\(|;\s*(?:rm|mv|cp|chmod|cat|wget|curl)").unwrap()) + .is_match(source) + { + return Err("Invalid proto file: suspicious content detected".to_owned()); } - None + Ok(source.to_owned()) } fn compile_proto(source: &str) -> Result<(String, String), String> { @@ -10523,6 +11807,14 @@ async fn logging_routes( username: &str, request_id: &str, ) -> Response { + if !state.config.logs_enabled { + return error( + StatusCode::NOT_FOUND, + "GTW003", + "Platform route does not exist", + request_id, + ); + } if method != Method::GET { return error( StatusCode::METHOD_NOT_ALLOWED, @@ -11312,13 +12604,23 @@ fn password_hash(user: &Value) -> Option { } } -fn self_update_fields_are_safe(payload: &Value) -> bool { - matches!( - payload.as_object(), - Some(fields) if fields.keys().all(|field| { - !matches!(field.as_str(), "role" | "groups" | "active" | "username") +/// Restricted fields the caller attempted to set, sorted like Python's +/// `sorted(attempted_restricted)`. Python only counts a field as "attempted" +/// when its incoming value is not null, so a null-valued restricted field is +/// treated as safe here too. +fn restricted_self_update_fields(payload: &Value) -> Vec { + let Some(fields) = payload.as_object() else { + return Vec::new(); + }; + let mut restricted: Vec = fields + .iter() + .filter(|(field, value)| { + matches!(field.as_str(), "role" | "groups" | "active" | "username") && !value.is_null() }) - ) + .map(|(field, _)| field.clone()) + .collect(); + restricted.sort(); + restricted } fn bootstrap_admin_update_fields_are_safe(payload: &Value) -> bool { @@ -11672,6 +12974,39 @@ fn is_typed_json_mutation(path: &str, method: &Method) -> bool { .any(|prefix| path == *prefix || path.starts_with(&format!("{prefix}/"))) } +/// Routes whose Python counterpart declares a required (non-Optional) typed +/// Pydantic body parameter, so FastAPI's global RequestValidationError +/// handler returns 422 VAL001 for a request with no body at all -- before +/// authentication, permission, or existence checks run -- regardless of +/// Content-Type. Confirmed against the pinned reference for every listed +/// route; routes with an `Optional`/defaulted body (memory dump/restore, +/// security settings) are deliberately excluded. +fn requires_nonempty_json_body(path: &str, method: &Method) -> bool { + match method { + &Method::POST => { + path == "/credit/rotate-key" + || (path.starts_with("/proto/") && path != "/proto/descriptors/backfill") + || (path.starts_with("/rate-limits/") && path.ends_with("/duplicate")) + } + &Method::PUT => { + path.starts_with("/api/") + || path.starts_with("/endpoint/") + || path.starts_with("/group/") + || path.starts_with("/proto/") + || (path.starts_with("/rate-limits/") && !path.ends_with("/duplicate")) + || path.starts_with("/role/") + || path.starts_with("/routing/") + || ((path.starts_with("/user/") || path.starts_with("/users/")) + && !path.ends_with("/update-password")) + || path.starts_with("/vault/") + || (path + .strip_prefix("/tiers/") + .is_some_and(|suffix| !suffix.is_empty() && !suffix.contains('/'))) + } + _ => false, + } +} + fn is_subscription_mutation(path: &str, method: &Method) -> bool { matches!(method, &Method::POST) && matches!( @@ -11906,7 +13241,7 @@ fn unexpected(request_id: &str) -> Response { ) } -fn json_response(status: StatusCode, payload: Value, request_id: &str) -> Response { +pub(crate) fn json_response(status: StatusCode, payload: Value, request_id: &str) -> Response { let body = serde_json::to_vec(&payload).unwrap_or_else(|_| b"{}".to_vec()); let length = body.len().to_string(); let mut response = ( @@ -11940,12 +13275,6 @@ fn env_bool(name: &str, default: bool) -> bool { .unwrap_or(default) } -fn timestamp_now() -> String { - time::OffsetDateTime::now_utc() - .format(&time::format_description::well_known::Rfc3339) - .unwrap_or_else(|_| "1970-01-01T00:00:00Z".to_owned()) -} - // VaultService stores `datetime.now(UTC).isoformat()` directly. Unlike the // RFC3339 formatter used elsewhere, that Python spelling ends in `+00:00`. fn timestamp_now_python_utc() -> String { @@ -11998,6 +13327,297 @@ fn unix_seconds() -> u64 { mod tests { use super::*; + #[test] + fn parse_report_timestamp_matches_pythons_strptime_cascade() { + // "%Y-%m-%dT%H:%M" + assert_eq!( + parse_report_timestamp("2024-01-15T10:30").unwrap(), + 1_705_314_600 + ); + // "%Y-%m-%d" (midnight UTC) + assert_eq!(parse_report_timestamp("2024-01-15").unwrap(), 1_705_276_800); + // fromisoformat fallback: space separator and a trailing Z. + assert_eq!( + parse_report_timestamp("2024-01-15T10:30:00Z").unwrap(), + 1_705_314_600 + ); + // Seconds in the fromisoformat fallback are preserved, not truncated. + assert_eq!( + parse_report_timestamp("2024-01-15T10:30:45Z").unwrap(), + 1_705_314_645 + ); + assert!(parse_report_timestamp("not-a-date").is_err()); + assert_eq!( + parse_report_timestamp("garbage").unwrap_err(), + "Invalid date format. Use YYYY-MM-DD or YYYY-MM-DDTHH:MM" + ); + } + + #[test] + fn report_date_time_utc_matches_python_strftime() { + assert_eq!( + report_date_time_utc(1_705_314_600), + ("2024-01-15".to_owned(), "10:30".to_owned()) + ); + } + + #[test] + fn report_api_from_endpoint_matches_python_classification() { + assert_eq!( + report_api_from_endpoint("/api/rest/orders/v1/list"), + "rest:orders" + ); + // Matches Python: `ep.split('/')` on "/api/rest/" yields a trailing + // empty segment, so `parts[3]` is "" rather than ever reaching the + // `len(parts) > 3` "unknown" fallback (unreachable via this prefix). + assert_eq!(report_api_from_endpoint("/api/rest/"), "rest:"); + assert_eq!( + report_api_from_endpoint("/api/graphql/catalog"), + "graphql:catalog" + ); + assert_eq!( + report_api_from_endpoint("/api/soap/billing"), + "soap:billing" + ); + assert_eq!(report_api_from_endpoint("/platform/users"), "platform"); + } + + #[test] + fn analytics_percentiles_pools_raw_samples_like_python_percentile_metrics() { + let mut a = AggregatedPoint { + timestamp: 0, + requests: 2, + ..Default::default() + }; + a.latencies_ms.extend([10.0, 20.0]); + let mut b = AggregatedPoint { + timestamp: 60, + requests: 1, + ..Default::default() + }; + b.latencies_ms.extend([100.0]); + // Pooled sorted samples: [10, 20, 100], n = 3. + // k = max(0, int(p*3) - 1): p50 -> int(1.5)-1=0 -> 10; p95 -> int(2.85)-1=1 -> 20. + let result = analytics_percentiles(&[a, b]); + assert_eq!(result["p50"], json!(10.0)); + assert_eq!(result["p95"], json!(20.0)); + assert_eq!(result["min"], json!(10.0)); + assert_eq!(result["max"], json!(100.0)); + + let empty = analytics_percentiles(&[]); + assert_eq!(empty["p50"], json!(0.0)); + assert_eq!(empty["min"], json!(0.0)); + } + + #[test] + fn restricted_self_update_fields_matches_python_attempted_set() { + // Null-valued restricted fields are not "attempted" in Python, since it + // filters `v is not None` before intersecting with the restricted set. + assert!(restricted_self_update_fields(&json!({"email": "a@b.com"})).is_empty()); + assert!(restricted_self_update_fields(&json!({"role": null})).is_empty()); + assert_eq!( + restricted_self_update_fields(&json!({ + "username": "new", "active": true, "role": "admin", "email": "a@b.com" + })), + vec!["active", "role", "username"] + ); + } + + #[test] + fn tier_request_models_coerce_scalars_and_apply_defaults() { + let mut create = json!({ + "tier_id": 7, + "name": "not-an-enum", + "display_name": true, + "limits": {"requests_per_minute": "12", "enable_throttling": "yes"}, + "price_monthly": "19.5", + "features": [1, false], + "enabled": "off", + "ignored": "field" + }); + normalize_tier_request("/tiers", &Method::POST, &mut create).unwrap(); + assert_eq!(create["tier_id"], "7"); + assert_eq!(create["name"], "not-an-enum"); + assert_eq!(create["display_name"], "True"); + assert_eq!(create["limits"]["requests_per_minute"], 12); + assert_eq!(create["limits"]["burst_per_second"], 0); + assert_eq!(create["limits"]["max_queue_time_ms"], 5000); + assert_eq!(create["limits"]["enable_throttling"], true); + assert_eq!(create["price_monthly"], 19.5); + assert_eq!(create["features"], json!(["1", "False"])); + assert_eq!(create["is_default"], false); + assert_eq!(create["enabled"], false); + assert!(create.get("ignored").is_none()); + + let mut action = json!({ + "user_id": 42, + "new_tier_id": false, + "grace_period_days": "3", + "ignored": true + }); + normalize_tier_request("/tiers/downgrade", &Method::POST, &mut action).unwrap(); + assert_eq!( + action, + json!({"user_id": "42", "new_tier_id": "False", "grace_period_days": 3}) + ); + + let mut assignment = json!({ + "user_id": "dated", + "tier_id": "pro", + "effective_from": 0, + "effective_until": "2020-1-2 3:04:05.12Z" + }); + normalize_tier_request("/tiers/assignments", &Method::POST, &mut assignment).unwrap(); + assert_eq!(assignment["effective_from"], "1970-01-01T00:00:00+00:00"); + assert_eq!( + assignment["effective_until"], + "2020-01-02T03:04:05.120000+00:00" + ); + } + + #[test] + fn tier_request_models_reject_invalid_shapes_and_drop_update_nulls() { + for mut invalid in [ + json!({"tier_id": "x", "name": "free", "display_name": "X", "limits": []}), + json!({"user_id": "x", "temp_tier_id": "pro", "duration_days": null}), + json!({"user_id": "x", "new_tier_id": "pro", "immediate": "sometimes"}), + json!({"user_id": "x", "tier_id": "pro", "effective_from": "not-a-date"}), + json!({"tier_ids": ["free"]}), + ] { + let (path, method) = if invalid.get("effective_from").is_some() { + ("/tiers/assignments", Method::POST) + } else if invalid.get("tier_id").is_some() { + ("/tiers", Method::POST) + } else if invalid.get("temp_tier_id").is_some() { + ("/tiers/temporary-upgrade", Method::POST) + } else if invalid.get("new_tier_id").is_some() { + ("/tiers/upgrade", Method::POST) + } else { + ("/tiers/compare", Method::POST) + }; + assert!(normalize_tier_request(path, &method, &mut invalid).is_err()); + } + + let mut update = json!({ + "display_name": null, + "limits": null, + "enabled": null, + "features": null, + "price_monthly": null, + "description": null + }); + normalize_tier_request("/tiers/pro", &Method::PUT, &mut update).unwrap(); + assert_eq!(update, json!({})); + + for (value, expected) in [ + ("true", Some(true)), + ("YES", Some(true)), + ("on", Some(true)), + ("1", Some(true)), + ("false", Some(false)), + ("No", Some(false)), + ("off", Some(false)), + ("0", Some(false)), + (" true ", None), + ] { + assert_eq!(pydantic_bool_string(value), expected); + } + } + + #[tokio::test] + async fn tier_exception_envelopes_match_each_python_route() { + for (operation, detail) in [ + ("get", "Failed to get tier"), + ("update", "Failed to update tier"), + ("delete", "Failed to delete tier"), + ("assign", "Failed to assign user"), + ("get_assignment", "Failed to get assignment"), + ("get_user_tier", "Failed to get user tier"), + ("remove_assignment", "Failed to remove assignment"), + ("list_users", "Failed to list users"), + ("upgrade", "Failed to upgrade tier"), + ("downgrade", "Failed to downgrade tier"), + ("temporary-upgrade", "Failed to create temporary upgrade"), + ("trial/start", "Failed to start trial"), + ("payment/failure", "Failed to handle payment failure"), + ("compare", "Failed to compare tiers"), + ] { + let response = tier_detail_failure(operation, "tier-error"); + assert_eq!(response.status(), StatusCode::INTERNAL_SERVER_ERROR); + let body = axum::body::to_bytes(response.into_body(), 1024) + .await + .unwrap(); + assert_eq!( + serde_json::from_slice::(&body).unwrap()["detail"], + detail + ); + } + + let response = tier_statistics_failure("tier-error"); + assert_eq!(response.status(), StatusCode::INTERNAL_SERVER_ERROR); + let body = axum::body::to_bytes(response.into_body(), 1024) + .await + .unwrap(); + let body: Value = serde_json::from_slice(&body).unwrap(); + assert_eq!(body["error_code"], "TIER999"); + assert_eq!(body["error_message"], "Failed to get statistics"); + } + + #[tokio::test] + async fn rate_rule_exception_envelopes_match_each_python_route() { + for (operation, detail) in [ + ("create", "Failed to create rule"), + ("list", "Failed to list rules"), + ("search", "Failed to search rules"), + ("get", "Failed to get rule"), + ("update", "Failed to update rule"), + ("delete", "Failed to delete rule"), + ("enable", "Failed to enable rule"), + ("disable", "Failed to disable rule"), + ("bulk/delete", "Failed to delete rules"), + ("bulk/enable", "Failed to enable rules"), + ("bulk/disable", "Failed to disable rules"), + ("duplicate", "Failed to duplicate rule"), + ("statistics", "Failed to get statistics"), + ("status", "Failed to get rate limit status"), + ] { + let response = rate_rule_failure(operation, "rule-error"); + assert_eq!(response.status(), StatusCode::INTERNAL_SERVER_ERROR); + let body = axum::body::to_bytes(response.into_body(), 1024) + .await + .unwrap(); + assert_eq!( + serde_json::from_slice::(&body).unwrap()["detail"], + detail + ); + } + } + + #[tokio::test] + async fn quota_exception_envelopes_match_each_python_route() { + for (path, detail) in [ + ("/quota/status", "Failed to get quota status"), + ( + "/quota/status/monthly_requests", + "Failed to get quota status", + ), + ("/quota/usage/history", "Failed to get usage history"), + ("/quota/usage/export", "Failed to export usage data"), + ("/quota/tier/info", "Failed to get tier info"), + ("/quota/burst/status", "Failed to get burst status"), + ] { + let response = quota_route_failure(path, "quota-error"); + assert_eq!(response.status(), StatusCode::INTERNAL_SERVER_ERROR); + let body = axum::body::to_bytes(response.into_body(), 1024) + .await + .unwrap(); + assert_eq!( + serde_json::from_slice::(&body).unwrap()["detail"], + detail + ); + } + } + #[test] fn log_parsing_and_filters_match_python_service() { let record = parse_log_record( @@ -12294,13 +13914,13 @@ mod tests { #[test] fn self_updates_without_user_management_cannot_change_authorization_fields() { - assert!(self_update_fields_are_safe( + assert!(restricted_self_update_fields( &json!({"email": "user@example.com", "custom_attributes": {}, "rate_limit_duration": 1}) - )); - assert!(!self_update_fields_are_safe(&json!({"groups": ["admin"]}))); - assert!(!self_update_fields_are_safe(&json!({"role": "admin"}))); - assert!(!self_update_fields_are_safe(&json!({"active": true}))); - assert!(!self_update_fields_are_safe(&json!({"username": "other"}))); + ).is_empty()); + assert!(!restricted_self_update_fields(&json!({"groups": ["admin"]})).is_empty()); + assert!(!restricted_self_update_fields(&json!({"role": "admin"})).is_empty()); + assert!(!restricted_self_update_fields(&json!({"active": true})).is_empty()); + assert!(!restricted_self_update_fields(&json!({"username": "other"})).is_empty()); } #[test] diff --git a/gateway-rs/src/routes/rest.rs b/gateway-rs/src/routes/rest.rs index 43df768c..ba353c5d 100644 --- a/gateway-rs/src/routes/rest.rs +++ b/gateway-rs/src/routes/rest.rs @@ -77,7 +77,8 @@ pub async fn rest_policy_then_proxy( let peer = request .extensions() .get::>() - .map(|value| value.0.ip()); + .map(|value| value.0.ip()) + .or_else(|| request.extensions().get::>().map(|value| value.0.peer.ip())); let headers = request.headers().clone(); let content_length = headers .get(header::CONTENT_LENGTH) @@ -100,6 +101,12 @@ pub async fn rest_policy_then_proxy( direct_ip: peer, now_millis: now_millis(), content_length, + peer_certificates: request.extensions() + .get::>() + .map(|info| info.0.peer_certificates.clone()) + .unwrap_or_default(), + native_tls: request.extensions().get::>().is_some(), + is_preflight: request.method() == http::Method::OPTIONS, }; let documents = if let Some(injected) = &state.policy_documents { @@ -120,7 +127,7 @@ pub async fn rest_policy_then_proxy( &mut documents, &policy_request, &state.config.shared_storage, - &PolicyRuntime::default(), + &PolicyRuntime { tls_profiles: state.tls_snapshot().profiles.clone(), ..PolicyRuntime::default() }, ) { Ok(Some(mut decision)) => { if let Some(storage) = &state.storage { @@ -211,7 +218,7 @@ pub async fn rest_policy_then_proxy( "1" | "true" | "yes" | "on" ) }) - && failure.error_code == "GTW003" + && matches!(failure.error_code.as_str(), "GTW002" | "GTW003") { return Ok(StatusCode::METHOD_NOT_ALLOWED.into_response()); } @@ -322,6 +329,22 @@ async fn execute_rest( ) .into_response()); }; + if !matches!(protocol, DataPlaneProtocol::Grpc | DataPlaneProtocol::GrpcWeb) + && decision.upstream_tls_profile_id.as_deref() + .and_then(|id| state.tls_snapshot().profiles.upstreams.get(id).cloned()) + .is_some_and(|profile| profile.server_name.is_some()) + { + return Ok((StatusCode::SERVICE_UNAVAILABLE, Json(PolicyErrorBody { + error_code: "TLS004".to_owned(), + error_message: "HTTP upstream TLS server-name override is unsupported".to_owned(), + })).into_response()); + } + let Some(proxy_client) = state.proxy_client_for(decision.upstream_tls_profile_id.as_deref()) else { + return Ok((StatusCode::SERVICE_UNAVAILABLE, Json(PolicyErrorBody { + error_code: "TLS004".to_owned(), + error_message: "Upstream TLS profile is unavailable".to_owned(), + })).into_response()); + }; if !circuit_allows(&state.runtime.circuits, &circuit_key) { return Ok(( StatusCode::SERVICE_UNAVAILABLE, @@ -513,8 +536,7 @@ async fn execute_rest( let mut attempt = 0_u32; let upstream = loop { attempt += 1; - let result = state - .proxy_client + let result = proxy_client .request(parts.method.clone(), target.clone()) .headers(headers.clone()) .timeout(std::time::Duration::from_millis( @@ -752,7 +774,10 @@ async fn execute_crud( } } http::Method::POST => { - let mut value = parse_crud_body(&body)?; + let mut value = parse_crud_body(&body); + if !value.is_object() { + return Ok(crud_internal_error(&crud_post_non_object_message(&value))); + } if value.get("_id").is_none() { value["_id"] = Value::String(uuid::Uuid::new_v4().to_string()); } @@ -770,7 +795,36 @@ async fn execute_crud( "Resource ID required for update", )); }; - let value = parse_crud_body(&body)?; + let value = parse_crud_body(&body); + if !value.is_object() { + let has_schema = decision + .crud_schema + .as_ref() + .and_then(Value::as_object) + .is_some_and(|schema| !schema.is_empty()); + if has_schema { + return Ok(crud_internal_error(&format!( + "'{}' object has no attribute 'get'", + python_type_name(&value) + ))); + } + // Python checks existence first, then `$set`s the raw body. + let Some(existing) = storage.crud_find_one(collection, resource_id).await? + else { + return Ok(policy_error_response( + StatusCode::NOT_FOUND, + "CRUD404", + "Resource not found", + )); + }; + if python_truthy(&value) { + return Ok(crud_internal_error(&format!( + "'{}' object has no attribute 'items'", + python_type_name(&value) + ))); + } + return Ok(crud_success(StatusCode::OK, existing)); + } validate_crud_schema(decision.crud_schema.as_ref(), &value, true)?; storage .crud_update(collection, resource_id, &value) @@ -828,7 +882,6 @@ async fn execute_crud( Json(serde_json::json!({ "error_code": "CRUD400", "error_message": "Validation failed", - "response": {"errors": error.split("; ").collect::>()} })), ) .into_response()) @@ -863,15 +916,59 @@ fn crud_resource_id(path: &str) -> Option<&str> { (endpoint.len() > 1).then(|| *endpoint.last().expect("endpoint is non-empty")) } -fn parse_crud_body(body: &[u8]) -> Result { +fn parse_crud_body(body: &[u8]) -> Value { // Python treats request.json() failures as an empty object for CRUD REST. - let value: Value = serde_json::from_slice(body).unwrap_or_else(|_| serde_json::json!({})); - if !value.is_object() { - return Err(crate::storage::runtime::StorageError::InvalidDocument( - "CRUD request body must be a JSON object".to_owned(), - )); + serde_json::from_slice(body).unwrap_or_else(|_| serde_json::json!({})) +} + +fn python_type_name(value: &Value) -> &'static str { + match value { + Value::Null => "NoneType", + Value::Bool(_) => "bool", + Value::Number(number) if number.is_f64() => "float", + Value::Number(_) => "int", + Value::String(_) => "str", + Value::Array(_) => "list", + Value::Object(_) => "dict", + } +} + +fn python_truthy(value: &Value) -> bool { + match value { + Value::Null => false, + Value::Bool(flag) => *flag, + Value::Number(number) => number.as_f64().is_none_or(|number| number != 0.0), + Value::String(text) => !text.is_empty(), + Value::Array(items) => !items.is_empty(), + Value::Object(map) => !map.is_empty(), + } +} + +/// The exception text Python's `CrudService.handle_rest` raises for a +/// non-object POST body (`'_id' not in body`, then `body['_id'] = ...`). +fn crud_post_non_object_message(value: &Value) -> String { + let has_id = match value { + Value::Array(items) => items.iter().any(|item| item.as_str() == Some("_id")), + Value::String(text) => text.contains("_id"), + _ => false, + }; + match value { + Value::Array(_) => "list indices must be integers or slices, not str".to_owned(), + Value::String(_) if has_id => "string indices must be integers, not 'str'".to_owned(), + Value::String(_) => "'str' object does not support item assignment".to_owned(), + other => format!( + "argument of type '{}' is not iterable", + python_type_name(other) + ), } - Ok(value) +} + +fn crud_internal_error(message: &str) -> Response { + policy_error_response( + StatusCode::INTERNAL_SERVER_ERROR, + "CRUD999", + &format!("Internal CRUD error: {message}"), + ) } pub(crate) fn validate_crud_schema( @@ -1164,13 +1261,17 @@ fn graphql_validation_schema(schema: &Value, query: &str) -> Value { let Some(mapping) = mapping else { return serde_json::json!({}); }; - let prefix = format!("{operation}."); + // Python: `field_path.startswith(operation)` then `field_path[len(operation) + 1:]`, + // which skips one character whether or not it is the `.` separator. Value::Object( mapping .iter() .filter_map(|(path, rules)| { - path.strip_prefix(&prefix) - .map(|path| (path.to_owned(), rules.clone())) + path.strip_prefix(operation).map(|rest| { + let mut rest = rest.chars(); + rest.next(); + (rest.as_str().to_owned(), rules.clone()) + }) }) .collect(), ) @@ -1860,6 +1961,19 @@ mod tests { ); } + #[test] + fn graphql_scope_uses_python_startswith_and_skips_one_character() { + let schema = json!({"validation_schema": { + "getUser.id": {"required": true}, + "getUserX/name": {"required": true}, + "getOther.id": {"required": true} + }}); + assert_eq!( + graphql_validation_schema(&schema, "query getUser($id: ID){ user }"), + json!({"id": {"required": true}, "/name": {"required": true}}) + ); + } + #[test] fn rejects_unsafe_soap_but_preserves_legacy_passthrough_without_a_schema() { let legacy = br#""#; diff --git a/gateway-rs/src/routes/tls_admin.rs b/gateway-rs/src/routes/tls_admin.rs new file mode 100644 index 00000000..9779f39e --- /dev/null +++ b/gateway-rs/src/routes/tls_admin.rs @@ -0,0 +1,276 @@ +use axum::response::Response; +use http::{Method, StatusCode}; +use serde_json::{Value, json}; + +use crate::{ + config::DownstreamTlsMode, + routes::platform::json_response, + state::AppState, + tls::{profiles::TlsProfiles, secrets, server_config_from_pem_with_roots}, +}; + +fn reply(status: StatusCode, value: Value, request_id: &str) -> Response { + json_response(status, value, request_id) +} + +fn error(status: StatusCode, message: &str, request_id: &str) -> Response { + reply(status, json!({"error_code": "TLSA002", "error_message": message}), request_id) +} + +pub async fn dispatch(state: &AppState, path: &str, method: &Method, payload: Value, request_id: &str) -> Response { + let Some(storage) = &state.storage else { + return error(StatusCode::SERVICE_UNAVAILABLE, "TLS profile storage is unavailable", request_id); + }; + let _mutation_guard = if matches!(*method, Method::POST | Method::PUT | Method::DELETE) { + match storage.tls_mutation_lock().await { + Ok(guard) => Some(guard), + Err(_) => return error(StatusCode::SERVICE_UNAVAILABLE, "TLS profile mutation lock is unavailable", request_id), + } + } else { + None + }; + let documents = match storage.find_many("tls_profiles", &json!({})).await { + Ok(documents) => documents, + Err(_) => return error(StatusCode::SERVICE_UNAVAILABLE, "TLS profile storage is unavailable", request_id), + }; + if path == "/tls/profiles" && *method == Method::GET { + let mut items = Vec::new(); + let file = match TlsProfiles::load_file(state.config.tls_profiles_file.as_deref()) { + Ok(file) => file, + Err(_) => return error(StatusCode::SERVICE_UNAVAILABLE, "File TLS profiles are unavailable", request_id), + }; + for id in file.client_cas.keys() { items.push(json!({"id": id, "kind": "client_ca", "source": "file", "read_only": true})); } + for id in file.upstreams.keys() { items.push(json!({"id": id, "kind": "upstream", "source": "file", "read_only": true})); } + for doc in &documents { + if doc.get("kind").and_then(Value::as_str) == Some("listener") { continue; } + items.push(public_metadata(doc)); + } + return reply(StatusCode::OK, json!({"profiles": items}), request_id); + } + if path == "/tls/listener" { + if *method == Method::GET { + let active = documents.iter().find(|doc| doc.get("kind").and_then(Value::as_str) == Some("listener")); + let from_admin = state.tls_listener_from_admin(); + return reply(StatusCode::OK, json!({"source": if from_admin {"admin"} else {"file"}, "revision": if from_admin {active.and_then(|doc| doc.get("revision"))} else {None}, "has_override": active.is_some()}), request_id); + } + if *method == Method::DELETE { + let Some(previous) = documents.iter().find(|doc| doc.get("kind").and_then(Value::as_str) == Some("listener")) else { + return error(StatusCode::NOT_FOUND, "Listener override not found", request_id); + }; + if !matches!(storage.delete_one("tls_profiles", &json!({"id": "listener"})).await, Ok(true)) { + return error(StatusCode::SERVICE_UNAVAILABLE, "Listener override could not be removed", request_id); + } + if state.reload_tls_from_storage().await.is_err() { + let _ = storage.insert_one("tls_profiles", previous.clone()).await; + return error(StatusCode::SERVICE_UNAVAILABLE, "Mounted listener certificate could not be activated", request_id); + } + return reply(StatusCode::OK, json!({"message": "Mounted listener certificate activated"}), request_id); + } + if *method != Method::PUT { + return error(StatusCode::METHOD_NOT_ALLOWED, "Method not allowed", request_id); + } + if state.config.downstream_tls_mode != DownstreamTlsMode::Native { + return error(StatusCode::BAD_REQUEST, "Native TLS mode is required", request_id); + } + let (Some(cert), Some(key)) = (payload.get("cert_pem").and_then(Value::as_str), payload.get("key_pem").and_then(Value::as_str)) else { + return error(StatusCode::BAD_REQUEST, "Certificate and key PEM are required", request_id); + }; + if cert.len() > 256 * 1024 || key.len() > 256 * 1024 { + return error(StatusCode::BAD_REQUEST, "TLS material is too large", request_id); + } + if server_config_from_pem_with_roots(cert.as_bytes(), key.as_bytes(), Some(state.tls_snapshot().profiles.combined_client_roots())).is_err() { + return error(StatusCode::BAD_REQUEST, "Certificate and key are invalid", request_id); + } + let sealed_cert = match secrets::seal("listener", "cert_pem", cert.as_bytes()) { + Ok(value) => value, + Err(_) => return error(StatusCode::SERVICE_UNAVAILABLE, "TLS secret encryption is not configured", request_id), + }; + let sealed_key = match secrets::seal("listener", "key_pem", key.as_bytes()) { + Ok(value) => value, + Err(_) => return error(StatusCode::SERVICE_UNAVAILABLE, "TLS secret encryption is not configured", request_id), + }; + let previous = documents.iter().find(|doc| doc.get("kind").and_then(Value::as_str) == Some("listener")); + let doc = json!({"id": "listener", "kind": "listener", "cert_pem": sealed_cert, "key_pem": sealed_key, "revision": previous.and_then(|doc| doc.get("revision")).and_then(Value::as_u64).unwrap_or(0) + 1}); + let result = if previous.is_some() { + storage.update_one("tls_profiles", &json!({"id": "listener"}), &doc).await.map(|result| result.is_some()) + } else { + storage.insert_one("tls_profiles", doc).await.map(|_| true) + }; + if !matches!(result, Ok(true)) { + return error(StatusCode::SERVICE_UNAVAILABLE, "Listener certificate could not be activated", request_id); + } + if state.reload_tls_from_storage().await.is_err() { + if let Some(previous) = previous { + let _ = storage.update_one("tls_profiles", &json!({"id": "listener"}), previous).await; + } else { + let _ = storage.delete_one("tls_profiles", &json!({"id": "listener"})).await; + } + return error(StatusCode::SERVICE_UNAVAILABLE, "Listener certificate could not be activated", request_id); + } + return reply(StatusCode::OK, json!({"message": "Listener certificate activated"}), request_id); + } + if path == "/tls/profiles" && *method == Method::POST { + let Some(id) = payload.get("id").and_then(Value::as_str) else { + return error(StatusCode::BAD_REQUEST, "Profile ID is required", request_id); + }; + if documents.iter().any(|doc| doc.get("id").and_then(Value::as_str) == Some(id)) { + return error(StatusCode::CONFLICT, "Profile ID already exists", request_id); + } + let Some(doc) = seal_profile(&payload) else { + return error(StatusCode::BAD_REQUEST, "Invalid profile or TLS secret key", request_id); + }; + let mut candidate = documents.clone(); + candidate.push(doc.clone()); + if !valid_candidate(state, &candidate) { + return error(StatusCode::BAD_REQUEST, "Profile material is invalid or ID collides with a file profile", request_id); + } + if storage.insert_one("tls_profiles", doc).await.is_err() { + return error(StatusCode::SERVICE_UNAVAILABLE, "Profile could not be stored", request_id); + } + if state.reload_tls_from_storage().await.is_err() { + let _ = storage.delete_one("tls_profiles", &json!({"id": id})).await; + return error(StatusCode::SERVICE_UNAVAILABLE, "Profile could not be activated", request_id); + } + return reply(StatusCode::CREATED, json!({"id": id}), request_id); + } + let Some(id) = path.strip_prefix("/tls/profiles/").filter(|id| !id.is_empty() && !id.contains('/')) else { + return error(StatusCode::NOT_FOUND, "TLS route not found", request_id); + }; + let Some(existing) = documents.iter().find(|doc| doc.get("id").and_then(Value::as_str) == Some(id)) else { + return error(StatusCode::NOT_FOUND, "Profile not found", request_id); + }; + if existing.get("kind").and_then(Value::as_str) == Some("listener") { + return error(StatusCode::NOT_FOUND, "Profile not found", request_id); + } + if *method == Method::GET { + return reply(StatusCode::OK, public_metadata(existing), request_id); + } + if *method == Method::DELETE { + if profile_referenced(state, id).await { + return error(StatusCode::CONFLICT, "Profile is referenced by an API or endpoint", request_id); + } + if !matches!(storage.delete_one("tls_profiles", &json!({"id": id})).await, Ok(true)) { + return error(StatusCode::SERVICE_UNAVAILABLE, "Profile could not be deleted", request_id); + } + if state.reload_tls_from_storage().await.is_err() { + let _ = storage.insert_one("tls_profiles", existing.clone()).await; + return error(StatusCode::SERVICE_UNAVAILABLE, "Profile could not be deleted", request_id); + } + return reply(StatusCode::OK, json!({"message": "Profile deleted"}), request_id); + } + if *method == Method::PUT { + let mut submitted = payload; + submitted["id"] = json!(id); + let Some(mut replacement) = seal_profile(&submitted) else { + return error(StatusCode::BAD_REQUEST, "Invalid profile or TLS secret key", request_id); + }; + if replacement.get("kind") != existing.get("kind") { + return error(StatusCode::BAD_REQUEST, "Profile type cannot be changed", request_id); + } + replacement["revision"] = json!(existing.get("revision").and_then(Value::as_u64).unwrap_or(0) + 1); + let mut candidate = documents.clone(); + if let Some(target) = candidate.iter_mut().find(|doc| doc.get("id").and_then(Value::as_str) == Some(id)) { + *target = replacement.clone(); + } + if !valid_candidate(state, &candidate) { + return error(StatusCode::BAD_REQUEST, "Profile material is invalid", request_id); + } + if !matches!(storage.update_one("tls_profiles", &json!({"id": id}), &replacement).await, Ok(Some(_))) { + return error(StatusCode::SERVICE_UNAVAILABLE, "Profile could not be activated", request_id); + } + if state.reload_tls_from_storage().await.is_err() { + let _ = storage.update_one("tls_profiles", &json!({"id": id}), existing).await; + return error(StatusCode::SERVICE_UNAVAILABLE, "Profile could not be activated", request_id); + } + return reply(StatusCode::OK, json!({"id": id}), request_id); + } + error(StatusCode::METHOD_NOT_ALLOWED, "Method not allowed", request_id) +} + +fn seal_profile(payload: &Value) -> Option { + let id = payload.get("id")?.as_str()?; + let kind = payload.get("kind")?.as_str()?; + if !matches!(kind, "client_ca" | "upstream") { return None; } + if kind == "client_ca" && (payload.get("cert_pem").and_then(Value::as_str).is_some() || payload.get("key_pem").and_then(Value::as_str).is_some() || payload.get("server_name").and_then(Value::as_str).is_some()) { + return None; + } + let mut doc = json!({"id": id, "kind": kind, "source": "admin", "revision": 1}); + for field in ["ca_pem", "cert_pem", "key_pem"] { + if let Some(value) = payload.get(field).and_then(Value::as_str) { + if value.len() > 256 * 1024 { return None; } + doc[field] = json!(secrets::seal(id, field, value.as_bytes()).ok()?); + } else { + doc[field] = Value::Null; + } + } + if let Some(server_name) = payload.get("server_name").and_then(Value::as_str) { + doc["server_name"] = json!(server_name); + } else { + doc["server_name"] = Value::Null; + } + Some(doc) +} + +fn valid_candidate(state: &AppState, documents: &[Value]) -> bool { + let Ok(mut profiles) = TlsProfiles::load_file(state.config.tls_profiles_file.as_deref()) else { return false; }; + profiles.merge_admin_documents(documents).is_ok() +} + +fn public_metadata(doc: &Value) -> Value { + json!({"id": doc.get("id"), "kind": doc.get("kind"), "source": "admin", "revision": doc.get("revision"), "read_only": false}) +} + +async fn profile_referenced(state: &AppState, id: &str) -> bool { + let Some(storage) = &state.storage else { return true; }; + for (collection, prefix) in [("apis", "api"), ("endpoints", "endpoint")] { + let Ok(documents) = storage.find_many(collection, &json!({})).await else { return true; }; + for doc in documents { + if doc.get(format!("{prefix}_client_tls_policy")).and_then(|policy| policy.get("ca_profile_id")).and_then(Value::as_str) == Some(id) + || doc.get(format!("{prefix}_upstream_tls_profile")).and_then(Value::as_str) == Some(id) + || doc.get(format!("{prefix}_upstream_tls_profiles")).and_then(Value::as_object) + .is_some_and(|map| map.values().any(|value| value.as_str() == Some(id))) + { + return true; + } + } + } + false +} + +#[cfg(test)] +mod tests { + use std::{process::{Command, Stdio}, sync::Arc}; + + use super::*; + use crate::{config::Config, storage::runtime::SharedStorage}; + + #[tokio::test] + async fn invalid_stored_listener_uses_mounted_certificate_and_can_be_reset() { + let _ = tokio_rustls::rustls::crypto::ring::default_provider().install_default(); + let directory = std::env::temp_dir().join(format!("doorman-tls-recovery-{}", uuid::Uuid::new_v4())); + std::fs::create_dir(&directory).unwrap(); + let cert = directory.join("listener.pem"); + let key = directory.join("listener.key"); + let generated = Command::new("openssl") + .args(["req", "-x509", "-newkey", "rsa:2048", "-nodes", "-days", "2", "-subj", "/CN=localhost", "-keyout"]) + .arg(&key).arg("-out").arg(&cert) + .stdout(Stdio::null()).stderr(Stdio::null()).status().unwrap(); + assert!(generated.success()); + + let mut config = Config::for_test(String::new()); + config.downstream_tls_mode = DownstreamTlsMode::Native; + config.downstream_tls_cert_file = Some(cert); + config.downstream_tls_key_file = Some(key); + let storage = Arc::new(SharedStorage::connect(&config.shared_storage).await.unwrap()); + storage.insert_one("tls_profiles", json!({"id": "listener", "kind": "listener", "cert_pem": "invalid", "key_pem": "invalid"})).await.unwrap(); + let mut state = AppState::new(config).unwrap(); + state.storage = Some(storage.clone()); + + assert!(state.reload_tls_from_storage().await.unwrap().is_some()); + assert!(!state.tls_listener_from_admin()); + let response = dispatch(&state, "/tls/listener", &Method::DELETE, Value::Null, "test").await; + assert_eq!(response.status(), StatusCode::OK); + assert!(storage.find_one("tls_profiles", &json!({"id": "listener"})).await.unwrap().is_none()); + std::fs::remove_dir_all(directory).unwrap(); + } +} diff --git a/gateway-rs/src/state.rs b/gateway-rs/src/state.rs index 1c6b8a26..62cbba53 100644 --- a/gateway-rs/src/state.rs +++ b/gateway-rs/src/state.rs @@ -11,6 +11,9 @@ use reqwest::{Client, redirect::Policy}; use serde_json::Value; use thiserror::Error; use tokio::sync::watch; +use tokio_rustls::rustls::ServerConfig; +use sha2::{Digest, Sha256}; +use tonic::transport::{Certificate as GrpcCertificate, Channel, ClientTlsConfig, Endpoint, Identity as GrpcIdentity}; use crate::{ config::Config, @@ -20,6 +23,7 @@ use crate::{ models::PolicyDocuments, runtime::{SharedStorage, StorageError}, }, + tls::{TlsReloadHandle, profiles::{TlsProfileError, TlsProfiles}, secrets::TlsSecretError, server_config_from_pem_with_roots}, validation::json::ValidatorRegistry, }; @@ -29,12 +33,24 @@ pub enum StateError { Http(#[from] reqwest::Error), #[error("required shared storage is unavailable: {0}")] Storage(#[from] StorageError), + #[error("TLS profiles could not be loaded: {0}")] + TlsProfiles(#[from] TlsProfileError), + #[error("TLS material could not be read: {0}")] + TlsIo(#[from] std::io::Error), + #[error("TLS secret could not be decrypted: {0}")] + TlsSecret(#[from] TlsSecretError), } #[derive(Clone)] pub struct AppState { pub config: Config, pub proxy_client: Client, + tls_snapshot: Arc>>, + tls_listener_handle: Arc>>, + tls_listener_hash: Arc>>, + tls_listener_from_admin: Arc, + tls_reload_lock: Arc>, + grpc_channels: Arc>>, pub policy_documents: Option>>, pub storage: Option>, pub runtime: Arc, @@ -42,6 +58,13 @@ pub struct AppState { pub validators: Arc, } +pub struct TlsSnapshot { + pub revision: u64, + pub profiles: Arc, + fingerprint: [u8; 32], + http_clients: HashMap, +} + pub struct GatewayRuntime { pub started_at: Instant, pub active_requests: AtomicU64, @@ -59,6 +82,9 @@ pub struct GatewayRuntime { pub revocation_purge_healthy: AtomicBool, pub activity_log_healthy: AtomicBool, pub security_audit_log_healthy: AtomicBool, + pub tls_reload_success_total: AtomicU64, + pub tls_reload_failure_total: AtomicU64, + pub tls_certificate_expiries: Mutex>, memory_autosave_updates: watch::Sender, } @@ -149,6 +175,9 @@ impl Default for GatewayRuntime { revocation_purge_healthy: AtomicBool::new(true), activity_log_healthy: AtomicBool::new(true), security_audit_log_healthy: AtomicBool::new(true), + tls_reload_success_total: AtomicU64::new(0), + tls_reload_failure_total: AtomicU64::new(0), + tls_certificate_expiries: Mutex::new(BTreeMap::new()), memory_autosave_updates, } } @@ -176,6 +205,17 @@ impl AppState { Ok(Self { config, proxy_client, + tls_snapshot: Arc::new(std::sync::RwLock::new(Arc::new(TlsSnapshot { + revision: 0, + profiles: Arc::new(TlsProfiles::default()), + fingerprint: [0; 32], + http_clients: HashMap::new(), + }))), + tls_listener_handle: Arc::new(Mutex::new(None)), + tls_listener_hash: Arc::new(Mutex::new(None)), + tls_listener_from_admin: Arc::new(AtomicBool::new(false)), + tls_reload_lock: Arc::new(tokio::sync::Mutex::new(())), + grpc_channels: Arc::new(Mutex::new(HashMap::new())), policy_documents: None, storage: None, runtime: Arc::new(GatewayRuntime::default()), @@ -186,12 +226,179 @@ impl AppState { pub async fn from_config(config: Config) -> Result { let mut state = Self::new(config)?; + state.publish_tls_profiles(TlsProfiles::load_file(state.config.tls_profiles_file.as_deref())?)?; let storage = SharedStorage::connect(&state.config.shared_storage).await?; storage.initialize_core().await?; state.storage = Some(Arc::new(storage)); Ok(state) } + pub fn tls_snapshot(&self) -> Arc { + self.tls_snapshot.read().expect("TLS snapshot lock poisoned").clone() + } + + pub fn publish_tls_profiles(&self, profiles: TlsProfiles) -> Result<(), StateError> { + let fingerprint = profiles.fingerprint(); + if self.tls_snapshot().fingerprint == fingerprint { + return Ok(()); + } + let expiries = profiles.certificate_expiries(); + let mut http_clients = HashMap::new(); + for (id, profile) in &profiles.upstreams { + let mut builder = Client::builder() + .user_agent("doorman-gateway/2.0.0 (compatible; httpx/0.27)") + .connect_timeout(self.config.connect_timeout) + .redirect(Policy::none()) + .pool_max_idle_per_host(32) + .tcp_keepalive(std::time::Duration::from_secs(60)); + if !profile.ca_pem.is_empty() { + for cert in reqwest::Certificate::from_pem_bundle(&profile.ca_pem)? { + builder = builder.add_root_certificate(cert); + } + } + if let (Some(cert), Some(key)) = (&profile.client_cert_pem, &profile.client_key_pem) { + let mut identity = cert.clone(); + identity.push(b'\n'); + identity.extend_from_slice(key); + builder = builder.identity(reqwest::Identity::from_pem(&identity)?); + } + http_clients.insert(id.clone(), builder.build()?); + } + let revision = self.tls_snapshot().revision.saturating_add(1); + let snapshot = Arc::new(TlsSnapshot { revision, profiles: Arc::new(profiles), fingerprint, http_clients }); + *self.tls_snapshot.write().expect("TLS snapshot lock poisoned") = snapshot; + self.grpc_channels.lock().expect("gRPC cache lock poisoned").clear(); + let mut active_expiries = self.runtime.tls_certificate_expiries.lock().expect("TLS expiry lock poisoned"); + active_expiries.retain(|name, _| name == "listener"); + active_expiries.extend(expiries); + self.runtime.tls_reload_success_total.fetch_add(1, std::sync::atomic::Ordering::Relaxed); + Ok(()) + } + + pub fn set_tls_listener_handle(&self, handle: TlsReloadHandle) { + *self.tls_listener_handle.lock().expect("TLS listener handle lock poisoned") = Some(handle); + } + + pub fn tls_listener_from_admin(&self) -> bool { + self.tls_listener_from_admin.load(std::sync::atomic::Ordering::Relaxed) + } + + pub async fn reload_tls_from_storage(&self) -> Result, StateError> { + let result = self.reload_tls_from_storage_inner().await; + if result.is_err() { + self.runtime.tls_reload_failure_total.fetch_add(1, std::sync::atomic::Ordering::Relaxed); + } + result + } + + async fn reload_tls_from_storage_inner(&self) -> Result, StateError> { + let _guard = self.tls_reload_lock.lock().await; + let mut profiles = TlsProfiles::load_file(self.config.tls_profiles_file.as_deref())?; + let documents = match &self.storage { + Some(storage) => storage.find_many("tls_profiles", &serde_json::json!({})).await?, + None => Vec::new(), + }; + profiles.merge_admin_documents(&documents)?; + let listener = if self.config.downstream_tls_mode == crate::config::DownstreamTlsMode::Native { + let admin_listener = documents.iter().find(|document| document.get("kind").and_then(Value::as_str) == Some("listener")); + let roots = profiles.combined_client_roots(); + let admin_material = admin_listener.map(|document| -> Result<_, StateError> { + let id = document.get("id").and_then(Value::as_str).unwrap_or("listener"); + let cert = document.get("cert_pem").and_then(Value::as_str).ok_or(TlsProfileError::Invalid("listener certificate missing".to_owned()))?; + let key = document.get("key_pem").and_then(Value::as_str).ok_or(TlsProfileError::Invalid("listener key missing".to_owned()))?; + let cert = crate::tls::secrets::open(id, "cert_pem", cert)?; + let key = crate::tls::secrets::open(id, "key_pem", key)?; + let config = server_config_from_pem_with_roots(&cert, &key, Some(roots.clone()))?; + Ok((cert, key, config, true)) + }); + let (cert, key, config, from_admin) = match admin_material { + Some(Ok(material)) => material, + Some(Err(error)) => { + tracing::warn!(%error, "admin TLS listener certificate rejected; using mounted certificate"); + let cert = std::fs::read(self.config.downstream_tls_cert_file.as_deref().expect("validated TLS certificate path"))?; + let key = std::fs::read(self.config.downstream_tls_key_file.as_deref().expect("validated TLS key path"))?; + let config = server_config_from_pem_with_roots(&cert, &key, Some(roots))?; + (cert, key, config, false) + } + None => { + let cert = std::fs::read(self.config.downstream_tls_cert_file.as_deref().expect("validated TLS certificate path"))?; + let key = std::fs::read(self.config.downstream_tls_key_file.as_deref().expect("validated TLS key path"))?; + let config = server_config_from_pem_with_roots(&cert, &key, Some(roots))?; + (cert, key, config, false) + } + }; + let mut hasher = Sha256::new(); + hasher.update(&cert); + hasher.update(&key); + hasher.update(profiles.fingerprint()); + let hash: [u8; 32] = hasher.finalize().into(); + let expiry = crate::tls::certificate_expiry_timestamp(&cert)?; + Some((config, hash, expiry, from_admin)) + } else { + None + }; + self.publish_tls_profiles(profiles)?; + if let Some((config, hash, expiry, from_admin)) = &listener { + let mut active = self.tls_listener_hash.lock().expect("TLS listener hash lock poisoned"); + if active.as_ref() != Some(hash) { + if let Some(handle) = self.tls_listener_handle.lock().expect("TLS listener handle lock poisoned").as_ref() { + handle.publish(config.clone()); + } + *active = Some(*hash); + self.runtime.tls_reload_success_total.fetch_add(1, std::sync::atomic::Ordering::Relaxed); + } + self.runtime.tls_certificate_expiries.lock().expect("TLS expiry lock poisoned").insert("listener".to_owned(), *expiry); + self.tls_listener_from_admin.store(*from_admin, std::sync::atomic::Ordering::Relaxed); + } + Ok(listener.map(|(config, _, _, _)| config)) + } + + pub fn proxy_client_for(&self, profile_id: Option<&str>) -> Option { + match profile_id { + Some(id) => self.tls_snapshot().http_clients.get(id).cloned(), + None => Some(self.proxy_client.clone()), + } + } + + pub async fn grpc_channel( + &self, + endpoint: &str, + profile_id: Option<&str>, + timeout_ms: u64, + ) -> Result { + let snapshot = self.tls_snapshot(); + let key = (snapshot.revision, endpoint.to_owned(), profile_id.unwrap_or_default().to_owned(), timeout_ms); + if let Some(channel) = self.grpc_channels.lock().map_err(|_| "gRPC channel cache unavailable")?.get(&key).cloned() { + return Ok(channel); + } + let mut target = Endpoint::from_shared(endpoint.to_owned()).map_err(|error| error.to_string())? + .connect_timeout(std::time::Duration::from_millis(timeout_ms.max(1))) + .timeout(std::time::Duration::from_millis(timeout_ms.max(1))); + if let Some(id) = profile_id { + let profile = snapshot.profiles.upstreams.get(id).ok_or("gRPC TLS profile is unavailable")?; + let mut tls = ClientTlsConfig::new(); + if !profile.ca_pem.is_empty() { + tls = tls.ca_certificate(GrpcCertificate::from_pem(profile.ca_pem.clone())); + } + if let (Some(cert), Some(key)) = (&profile.client_cert_pem, &profile.client_key_pem) { + tls = tls.identity(GrpcIdentity::from_pem(cert.clone(), key.clone())); + } + if let Some(server_name) = &profile.server_name { + tls = tls.domain_name(server_name.clone()); + } + target = target.tls_config(tls).map_err(|error| error.to_string())?; + } + let channel = target.connect().await.map_err(|error| error.to_string())?; + let mut cache = self.grpc_channels.lock().map_err(|_| "gRPC channel cache unavailable")?; + if cache.len() >= 128 { + if let Some(oldest) = cache.keys().next().cloned() { + cache.remove(&oldest); + } + } + cache.insert(key, channel.clone()); + Ok(channel) + } + pub fn with_policy_documents(mut self, documents: PolicyDocuments) -> Self { self.policy_documents = Some(Arc::new(Mutex::new(documents))); self diff --git a/gateway-rs/src/storage/memory.rs b/gateway-rs/src/storage/memory.rs index 1baac34d..a7430958 100644 --- a/gateway-rs/src/storage/memory.rs +++ b/gateway-rs/src/storage/memory.rs @@ -46,6 +46,7 @@ impl MemoryStorage { "user_tier_assignments", "rate_limit_rules", "config_snapshots", + "tls_profiles", ] { collections.insert(name.to_owned(), Vec::new()); } diff --git a/gateway-rs/src/storage/runtime.rs b/gateway-rs/src/storage/runtime.rs index 5b1cf26d..2b36fc16 100644 --- a/gateway-rs/src/storage/runtime.rs +++ b/gateway-rs/src/storage/runtime.rs @@ -25,6 +25,29 @@ pub struct SharedStorage { memory: Option, policy_cache: Arc>>, policy_cache_ttl: Duration, + tls_mutation_mutex: Arc>, + tls_mutation_key: String, +} + +pub struct TlsMutationGuard { + _local: tokio::sync::OwnedMutexGuard<()>, + redis: Option<(ConnectionManager, String, String)>, + renewal: Option>, +} + +impl Drop for TlsMutationGuard { + fn drop(&mut self) { + if let Some(renewal) = self.renewal.take() { + renewal.abort(); + } + if let Some((mut redis, key, token)) = self.redis.take() { + tokio::spawn(async move { + let _: redis::RedisResult = redis::cmd("EVAL") + .arg("if redis.call('GET', KEYS[1]) == ARGV[1] then return redis.call('DEL', KEYS[1]) else return 0 end") + .arg(1).arg(key).arg(token).query_async(&mut redis).await; + }); + } + } } #[derive(Clone)] @@ -82,6 +105,8 @@ impl SharedStorage { memory: Some(MemoryStorage::new()), policy_cache: Arc::new(tokio::sync::RwLock::new(None)), policy_cache_ttl: Duration::from_secs(config.policy_cache_ttl_seconds), + tls_mutation_mutex: Arc::new(tokio::sync::Mutex::new(())), + tls_mutation_key: String::new(), }); } let client = Client::with_uri_str(config.mongo_uri()).await?; @@ -98,9 +123,49 @@ impl SharedStorage { memory: None, policy_cache: Arc::new(tokio::sync::RwLock::new(None)), policy_cache_ttl: Duration::from_secs(config.policy_cache_ttl_seconds), + tls_mutation_mutex: Arc::new(tokio::sync::Mutex::new(())), + tls_mutation_key: format!("doorman:tls-mutation:{}", config.mongo_database), }) } + pub async fn tls_mutation_lock(&self) -> Result { + let local = self.tls_mutation_mutex.clone().lock_owned().await; + let Some(mut redis) = self.redis.clone() else { + return Ok(TlsMutationGuard { _local: local, redis: None, renewal: None }); + }; + let key = self.tls_mutation_key.clone(); + let token = uuid::Uuid::new_v4().to_string(); + let deadline = Instant::now() + Duration::from_secs(30); + loop { + let acquired: Option = redis::cmd("SET") + .arg(&key).arg(&token).arg("NX").arg("PX").arg(30_000) + .query_async(&mut redis).await?; + if acquired.is_some() { + break; + } + if Instant::now() >= deadline { + return Err(StorageError::InvalidDocument("TLS mutation lock timed out".to_owned())); + } + tokio::time::sleep(Duration::from_millis(50)).await; + } + let mut renewal_redis = redis.clone(); + let renewal_key = key.clone(); + let renewal_token = token.clone(); + let renewal = tokio::spawn(async move { + loop { + tokio::time::sleep(Duration::from_secs(10)).await; + let renewed: redis::RedisResult = redis::cmd("EVAL") + .arg("if redis.call('GET', KEYS[1]) == ARGV[1] then return redis.call('PEXPIRE', KEYS[1], 30000) else return 0 end") + .arg(1).arg(&renewal_key).arg(&renewal_token) + .query_async(&mut renewal_redis).await; + if !matches!(renewed, Ok(1)) { + break; + } + } + }); + Ok(TlsMutationGuard { _local: local, redis: Some((redis, key, token)), renewal: Some(renewal) }) + } + async fn ensure_indexes(database: &Database) -> Result<(), StorageError> { let indexes = [ ("users", doc! {"username": 1}, true), @@ -131,6 +196,7 @@ impl SharedStorage { ("vault_entries", doc! {"username": 1, "key_name": 1}, true), ("vault_entries", doc! {"username": 1}, false), ("config_snapshots", doc! {"snapshot_id": 1}, true), + ("tls_profiles", doc! {"id": 1}, true), ( "revocations", doc! {"type": 1, "username": 1, "jti": 1}, @@ -185,30 +251,74 @@ impl SharedStorage { .await?; } } - if self + let existing_admin = self .find_one("users", &serde_json::json!({"username": "admin"})) - .await? - .is_none() - { - let password = std::env::var("DOORMAN_ADMIN_PASSWORD").map_err(|_| { - StorageError::InvalidDocument( - "DOORMAN_ADMIN_PASSWORD is required for admin initialization".to_owned(), - ) - })?; + .await?; + let admin_credentials = || -> Result<(String, String), StorageError> { + let password = std::env::var("DOORMAN_ADMIN_PASSWORD") + .ok() + .filter(|value| !value.is_empty()) + .ok_or_else(|| { + StorageError::InvalidDocument( + "DOORMAN_ADMIN_PASSWORD is required for admin initialization".to_owned(), + ) + })?; let password = bcrypt::hash(password, bcrypt::DEFAULT_COST).map_err(|error| { StorageError::InvalidDocument(format!("failed to hash admin password: {error}")) })?; - self.insert_one("users", serde_json::json!({ - "username": "admin", - "email": std::env::var("DOORMAN_ADMIN_EMAIL").unwrap_or_else(|_| "admin@doorman.dev".to_owned()), - "password": password, - "role": "admin", "groups": ["ALL", "admin"], "ui_access": true, - "rate_limit_duration": 1, "rate_limit_duration_type": "second", - "throttle_duration": 1, "throttle_duration_type": "second", - "throttle_wait_duration": 0, "throttle_wait_duration_type": "second", - "throttle_queue_limit": 1, "throttle_enabled": null, - "custom_attributes": {"custom_key": "custom_value"}, "active": true - })).await?; + let email = std::env::var("DOORMAN_ADMIN_EMAIL") + .ok() + .filter(|value| !value.is_empty()) + .unwrap_or_else(|| "admin@doorman.dev".to_owned()); + Ok((email, password)) + }; + match existing_admin { + None => { + let (email, password) = admin_credentials()?; + self.insert_one( + "users", + serde_json::json!({ + "username": "admin", "email": email, "password": password, + "role": "admin", "groups": ["ALL", "admin"], "ui_access": true, + "rate_limit_duration": 1, "rate_limit_duration_type": "second", + "throttle_duration": 1, "throttle_duration_type": "second", + "throttle_wait_duration": 0, "throttle_wait_duration_type": "second", + "throttle_queue_limit": 1, "throttle_enabled": null, + "custom_attributes": {"custom_key": "custom_value"}, "active": true + }), + ) + .await?; + } + Some(admin) => { + // Mongo-mode repair: restore only missing bootstrap fields. + let mut repairs = serde_json::Map::new(); + if admin.get("ui_access") != Some(&Value::Bool(true)) { + repairs.insert("ui_access".to_owned(), Value::Bool(true)); + } + let missing = |field: &str| { + admin + .get(field) + .is_none_or(|v| v.is_null() || v.as_str() == Some("")) + }; + if missing("email") { + let email = std::env::var("DOORMAN_ADMIN_EMAIL") + .ok() + .filter(|value| !value.is_empty()) + .unwrap_or_else(|| "admin@doorman.dev".to_owned()); + repairs.insert("email".to_owned(), Value::String(email)); + } + if missing("password") { + repairs.insert("password".to_owned(), Value::String(admin_credentials()?.1)); + } + if !repairs.is_empty() { + self.update_one( + "users", + &serde_json::json!({"username": "admin"}), + &Value::Object(repairs), + ) + .await?; + } + } } Ok(()) } @@ -239,6 +349,33 @@ impl SharedStorage { Ok(()) } + /// Python's InMemoryCollection raises while the chaos Mongo outage flag is set. + fn chaos_mongo_guard(&self) -> Result<(), StorageError> { + if self.memory.is_some() { + Self::chaos_guard("mongo")?; + } + Ok(()) + } + + fn chaos_guard(backend: &str) -> Result<(), StorageError> { + use crate::middleware::chaos::{ + CHAOS_ERROR_BUDGET_BURN, CHAOS_MONGO_OUTAGE, CHAOS_REDIS_OUTAGE, + }; + use std::sync::atomic::Ordering; + let flag = if backend == "redis" { + &CHAOS_REDIS_OUTAGE + } else { + &CHAOS_MONGO_OUTAGE + }; + if flag.load(Ordering::Relaxed) { + CHAOS_ERROR_BUDGET_BURN.fetch_add(1, Ordering::Relaxed); + return Err(StorageError::InvalidDocument(format!( + "chaos: simulated {backend} outage" + ))); + } + Ok(()) + } + pub fn is_memory(&self) -> bool { self.memory.is_some() } @@ -249,6 +386,7 @@ impl SharedStorage { value: Value, ttl_seconds: u64, ) -> Result<(), StorageError> { + Self::chaos_guard("redis")?; if let Some(memory) = &self.memory { memory.set_value(key, value, ttl_seconds).await; return Ok(()); @@ -260,6 +398,7 @@ impl SharedStorage { } pub async fn get_ephemeral(&self, key: &str) -> Result, StorageError> { + Self::chaos_guard("redis")?; if let Some(memory) = &self.memory { return Ok(memory.get_value(key).await); } @@ -630,6 +769,7 @@ impl SharedStorage { collection: &str, filter: &Value, ) -> Result, StorageError> { + self.chaos_mongo_guard()?; if let Some(memory) = &self.memory { let collections = memory.collections.read().await; return Ok(collections @@ -658,6 +798,7 @@ impl SharedStorage { collection: &str, filter: &Value, ) -> Result, StorageError> { + self.chaos_mongo_guard()?; if let Some(memory) = &self.memory { let collections = memory.collections.read().await; return Ok(collections @@ -680,6 +821,7 @@ impl SharedStorage { collection: &str, mut value: Value, ) -> Result { + self.chaos_mongo_guard()?; if value.get("_id").is_none() { value["_id"] = Value::String(uuid::Uuid::new_v4().to_string()); } @@ -710,6 +852,7 @@ impl SharedStorage { filter: &Value, updates: &Value, ) -> Result, StorageError> { + self.chaos_mongo_guard()?; if let Some(memory) = &self.memory { let mut collections = memory.collections.write().await; let Some(item) = collections @@ -759,6 +902,7 @@ impl SharedStorage { filter: &Value, mut replacement: Value, ) -> Result, StorageError> { + self.chaos_mongo_guard()?; if let Some(memory) = &self.memory { let mut collections = memory.collections.write().await; let Some(item) = collections @@ -801,6 +945,7 @@ impl SharedStorage { } pub async fn delete_one(&self, collection: &str, filter: &Value) -> Result { + self.chaos_mongo_guard()?; if let Some(memory) = &self.memory { let mut collections = memory.collections.write().await; let items = collections.entry(collection.to_owned()).or_default(); @@ -834,6 +979,11 @@ impl SharedStorage { let records = collections.entry("revocations".to_owned()).or_default(); let before = records.len(); records.retain(|record| { + // Python's purge_expired_tokens treats a missing/malformed expires_at + // as 0 and deletes it, which would silently un-revoke a token on data + // corruption. Rust deliberately keeps such rows instead (approved + // security-safe divergence) and relies on the request-time check to + // keep ignoring them safely. let expired_jti = record.get("type").and_then(Value::as_str) == Some("jti") && record .get("expires_at") @@ -1368,6 +1518,15 @@ mod parity_tests { use super::*; use serde_json::json; + #[tokio::test] + async fn tls_mutation_lock_serializes_cloned_memory_storage() { + let storage = SharedStorage::connect(&crate::config::SharedStorageConfig::default()).await.unwrap(); + let first = storage.tls_mutation_lock().await.unwrap(); + assert!(tokio::time::timeout(Duration::from_millis(20), storage.clone().tls_mutation_lock()).await.is_err()); + drop(first); + tokio::time::timeout(Duration::from_secs(1), storage.tls_mutation_lock()).await.unwrap().unwrap(); + } + #[test] fn memory_filters_match_python_or_and_in_contracts() { let item = json!({"name": "alice", "role": "admin"}); @@ -1382,6 +1541,43 @@ mod parity_tests { assert!(!value_matches(&item, &json!({"name": {"$in": ["bob"]}}))); } + #[tokio::test] + async fn purge_expired_revocations_preserves_malformed_and_missing_expiry() { + // Deliberate divergence from Python's purge_expired_tokens, which treats a + // missing/malformed expires_at as 0 and deletes it -- that would silently + // un-revoke a token on data corruption. Rust keeps these rows; the + // request-time revocation check already ignores them safely. + let config = crate::config::SharedStorageConfig::default(); + let storage = SharedStorage::connect(&config).await.unwrap(); + storage + .insert_one( + "revocations", + json!({"type": "jti", "username": "u", "jti": "no-expiry"}), + ) + .await + .unwrap(); + storage + .insert_one( + "revocations", + json!({"type": "jti", "username": "u", "jti": "bad-expiry", "expires_at": "nope"}), + ) + .await + .unwrap(); + storage + .insert_one( + "revocations", + json!({"type": "jti", "username": "u", "jti": "expired", "expires_at": 1u64}), + ) + .await + .unwrap(); + let removed = storage.purge_expired_revocations(1_000).await.unwrap(); + assert_eq!(removed, 1); + let remaining = storage.find_many("revocations", &json!({})).await.unwrap(); + assert_eq!(remaining.len(), 2); + assert!(remaining.iter().any(|record| record["jti"] == "no-expiry")); + assert!(remaining.iter().any(|record| record["jti"] == "bad-expiry")); + } + #[test] fn memory_updates_set_null_and_dotted_fields_like_python() { let mut item = json!({"profile": "old", "keep": true}); diff --git a/gateway-rs/src/tls.rs b/gateway-rs/src/tls.rs new file mode 100644 index 00000000..b7617bde --- /dev/null +++ b/gateway-rs/src/tls.rs @@ -0,0 +1,197 @@ +use std::{ + fs, + io, + net::SocketAddr, + path::Path, + sync::{Arc, RwLock}, + time::Duration, +}; + +use axum::{extract::connect_info::Connected, serve::{IncomingStream, Listener}}; +use futures_util::{StreamExt, future::BoxFuture, stream::FuturesUnordered}; +use sha2::{Digest, Sha256}; +use tokio::net::{TcpListener, TcpStream}; +use tokio_rustls::{TlsAcceptor, TlsStream, rustls::{RootCertStore, ServerConfig, server::WebPkiClientVerifier, pki_types::{CertificateDer, PrivateKeyDer, pem::PemObject}}}; +use x509_parser::parse_x509_certificate; + +pub mod profiles; +pub mod policy; +pub mod secrets; + +const HANDSHAKE_TIMEOUT: Duration = Duration::from_secs(10); +const MAX_PENDING_HANDSHAKES: usize = 256; + +#[derive(Clone, Debug)] +pub struct TlsConnectionInfo { + pub peer: SocketAddr, + pub peer_certificates: Vec>, +} + +impl Connected> for TlsConnectionInfo { + fn connect_info(stream: IncomingStream<'_, TlsListener>) -> Self { + stream.remote_addr().clone() + } +} + +pub fn server_config(cert_file: &Path, key_file: &Path) -> io::Result { + server_config_from_pem(&fs::read(cert_file)?, &fs::read(key_file)?) +} + +pub fn server_config_from_pem(cert_pem: &[u8], key_pem: &[u8]) -> io::Result { + server_config_from_pem_with_roots(cert_pem, key_pem, None) +} + +pub fn server_config_from_pem_with_roots(cert_pem: &[u8], key_pem: &[u8], roots: Option) -> io::Result { + let certs = CertificateDer::pem_slice_iter(cert_pem) + .collect::, _>>() + .map_err(invalid_pem)?; + if certs.is_empty() { + return Err(io::Error::new(io::ErrorKind::InvalidData, "TLS certificate file is empty")); + } + let (_, leaf) = parse_x509_certificate(certs[0].as_ref()) + .map_err(|_| io::Error::new(io::ErrorKind::InvalidData, "TLS certificate is not X.509"))?; + if !leaf.validity().is_valid() { + return Err(io::Error::new(io::ErrorKind::InvalidData, "TLS certificate is not currently valid")); + } + let key = PrivateKeyDer::from_pem_slice(key_pem).map_err(invalid_pem)?; + let verifier = match roots { + Some(roots) if !roots.is_empty() => WebPkiClientVerifier::builder(Arc::new(roots)) + .allow_unauthenticated() + .build() + .map_err(invalid_pem)?, + _ => WebPkiClientVerifier::no_client_auth(), + }; + let mut config = ServerConfig::builder() + .with_client_cert_verifier(verifier) + .with_single_cert(certs, key) + .map_err(|error| io::Error::new(io::ErrorKind::InvalidData, error))?; + config.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec()]; + Ok(config) +} + +pub fn certificate_expiry_timestamp(pem: &[u8]) -> io::Result { + let mut min_expiry = None; + for cert in CertificateDer::pem_slice_iter(pem) { + let cert = cert.map_err(invalid_pem)?; + let (_, parsed) = parse_x509_certificate(cert.as_ref()) + .map_err(|_| io::Error::new(io::ErrorKind::InvalidData, "certificate is not X.509"))?; + let expiry = parsed.validity().not_after.timestamp(); + min_expiry = Some(min_expiry.map_or(expiry, |prior: i64| prior.min(expiry))); + } + min_expiry.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "PEM contains no certificate")) +} + +fn invalid_pem(error: impl std::error::Error + Send + Sync + 'static) -> io::Error { + io::Error::new(io::ErrorKind::InvalidData, error) +} + +pub struct TlsListener { + listener: TcpListener, + config: Arc>>, + pending: FuturesUnordered, TlsConnectionInfo)>>>, +} + +impl TlsListener { + pub fn new(listener: TcpListener, config: ServerConfig) -> Self { + Self { + listener, + config: Arc::new(RwLock::new(Arc::new(config))), + pending: FuturesUnordered::new(), + } + } + + pub fn reload_handle(&self) -> TlsReloadHandle { + TlsReloadHandle(self.config.clone()) + } +} + +#[derive(Clone)] +pub struct TlsReloadHandle(Arc>>); + +impl TlsReloadHandle { + pub fn publish(&self, config: ServerConfig) { + *self.0.write().expect("TLS configuration lock poisoned") = Arc::new(config); + } +} + +pub fn spawn_file_reload( + cert_file: std::path::PathBuf, + key_file: std::path::PathBuf, + handle: TlsReloadHandle, + roots: Option, +) -> tokio::task::JoinHandle<()> { + tokio::spawn(async move { + let mut interval = tokio::time::interval(Duration::from_secs(15)); + let mut active_hash = None; + loop { + interval.tick().await; + let materials = tokio::try_join!(tokio::fs::read(&cert_file), tokio::fs::read(&key_file)); + let (cert_pem, key_pem) = match materials { + Ok(materials) => materials, + Err(error) => { + tracing::warn!(%error, "TLS certificate reload could not read mounted files"); + continue; + } + }; + let mut hasher = Sha256::new(); + hasher.update(&cert_pem); + hasher.update(&key_pem); + let hash: [u8; 32] = hasher.finalize().into(); + if active_hash == Some(hash) { + continue; + } + match server_config_from_pem_with_roots(&cert_pem, &key_pem, roots.clone()) { + Ok(config) => { + handle.publish(config); + active_hash = Some(hash); + tracing::info!("TLS listener certificate reloaded"); + } + Err(error) => tracing::warn!(%error, "TLS certificate reload rejected; retaining active certificate"), + } + } + }) +} + +impl Listener for TlsListener { + type Io = TlsStream; + type Addr = TlsConnectionInfo; + + async fn accept(&mut self) -> (Self::Io, Self::Addr) { + loop { + tokio::select! { + accepted = self.listener.accept(), if self.pending.len() < MAX_PENDING_HANDSHAKES => { + match accepted { + Ok((stream, peer)) => { + let config = self.config.read().expect("TLS configuration lock poisoned").clone(); + let acceptor = TlsAcceptor::from(config); + self.pending.push(Box::pin(async move { + let stream = tokio::time::timeout(HANDSHAKE_TIMEOUT, acceptor.accept(stream)) + .await + .map_err(|_| io::Error::new(io::ErrorKind::TimedOut, "TLS handshake timed out"))??; + let certificates = stream.get_ref().1.peer_certificates() + .map(|chain| chain.iter().map(|cert| cert.as_ref().to_vec()).collect()) + .unwrap_or_default(); + Ok((TlsStream::Server(stream), TlsConnectionInfo { peer, peer_certificates: certificates })) + })); + } + Err(error) => { + tracing::warn!(%error, "TLS listener accept failed"); + tokio::time::sleep(Duration::from_millis(100)).await; + } + } + } + completed = self.pending.next(), if !self.pending.is_empty() => { + match completed { + Some(Ok(connected)) => return connected, + Some(Err(error)) => tracing::debug!(%error, "TLS handshake rejected"), + None => {} + } + } + } + } + } + + fn local_addr(&self) -> io::Result { + Ok(TlsConnectionInfo { peer: self.listener.local_addr()?, peer_certificates: Vec::new() }) + } +} diff --git a/gateway-rs/src/tls/policy.rs b/gateway-rs/src/tls/policy.rs new file mode 100644 index 00000000..017ae38f --- /dev/null +++ b/gateway-rs/src/tls/policy.rs @@ -0,0 +1,149 @@ +use serde::Deserialize; +use serde_json::Value; +use tokio_rustls::rustls::{pki_types::{CertificateDer, UnixTime}, server::WebPkiClientVerifier}; +use x509_parser::{extensions::GeneralName, parse_x509_certificate}; + +use super::profiles::TlsProfiles; + +#[derive(Clone, Debug, Default, Deserialize)] +#[serde(rename_all = "lowercase")] +pub enum ClientTlsMode { + #[default] + Off, + Optional, + Required, +} + +#[derive(Clone, Debug, Default, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct ClientTlsPolicy { + pub mode: ClientTlsMode, + pub ca_profile_id: Option, + #[serde(default)] + pub allowed_dns_sans: Vec, + #[serde(default)] + pub allowed_uri_sans: Vec, +} + +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum ClientTlsFailure { + Missing, + Invalid, + Configuration, +} + +impl ClientTlsPolicy { + pub fn validate_value(value: &Value, profiles: &TlsProfiles, native_tls: bool) -> Result<(), ClientTlsFailure> { + let policy: Self = serde_json::from_value(value.clone()).map_err(|_| ClientTlsFailure::Configuration)?; + if matches!(policy.mode, ClientTlsMode::Off) { + return Ok(()); + } + if !native_tls || policy.ca_profile_id.as_deref().is_none_or(str::is_empty) + || (policy.allowed_dns_sans.is_empty() && policy.allowed_uri_sans.is_empty()) + { + return Err(ClientTlsFailure::Configuration); + } + if !profiles.client_cas.contains_key(policy.ca_profile_id.as_deref().unwrap_or_default()) { + return Err(ClientTlsFailure::Configuration); + } + if policy.allowed_dns_sans.iter().chain(policy.allowed_uri_sans.iter()).any(|san| san.is_empty() || san.contains('*')) { + return Err(ClientTlsFailure::Configuration); + } + Ok(()) + } + + pub fn from_documents(api: &Value, endpoint: Option<&Value>) -> Result { + let value = endpoint + .and_then(|endpoint| endpoint.get("endpoint_client_tls_policy")) + .filter(|value| !value.is_null()) + .or_else(|| api.get("api_client_tls_policy").filter(|value| !value.is_null())); + let Some(value) = value else { return Ok(Self::default()); }; + let policy: Self = serde_json::from_value(value.clone()).map_err(|_| ClientTlsFailure::Configuration)?; + if !matches!(policy.mode, ClientTlsMode::Off) + && (policy.ca_profile_id.as_deref().is_none_or(str::is_empty) + || (policy.allowed_dns_sans.is_empty() && policy.allowed_uri_sans.is_empty())) + { + return Err(ClientTlsFailure::Configuration); + } + Ok(policy) + } + + pub fn enforce(&self, chain: &[Vec], profiles: &TlsProfiles, native_tls: bool) -> Result<(), ClientTlsFailure> { + if matches!(self.mode, ClientTlsMode::Off) { + return Ok(()); + } + if !native_tls { + return Err(ClientTlsFailure::Configuration); + } + let roots = profiles.client_cas.get(self.ca_profile_id.as_deref().unwrap_or_default()) + .ok_or(ClientTlsFailure::Configuration)?; + if chain.is_empty() { + return if matches!(self.mode, ClientTlsMode::Required) { Err(ClientTlsFailure::Missing) } else { Ok(()) }; + } + let certs: Vec<_> = chain.iter().cloned().map(CertificateDer::from).collect(); + let verifier = WebPkiClientVerifier::builder(roots.clone()) + .build() + .map_err(|_| ClientTlsFailure::Configuration)?; + verifier.verify_client_cert(&certs[0], &certs[1..], UnixTime::now()) + .map_err(|_| ClientTlsFailure::Invalid)?; + let (_, leaf) = parse_x509_certificate(&chain[0]).map_err(|_| ClientTlsFailure::Invalid)?; + let sans = leaf.subject_alternative_name() + .map_err(|_| ClientTlsFailure::Invalid)? + .ok_or(ClientTlsFailure::Invalid)?; + let allowed = sans.value.general_names.iter().any(|name| match name { + GeneralName::DNSName(dns) => self.allowed_dns_sans.iter().any(|allowed| allowed.eq_ignore_ascii_case(dns)), + GeneralName::URI(uri) => self.allowed_uri_sans.iter().any(|allowed| allowed == uri), + _ => false, + }); + allowed.then_some(()).ok_or(ClientTlsFailure::Invalid) + } +} + +#[cfg(test)] +mod tests { + use std::sync::Arc; + + use serde_json::json; + use tokio_rustls::rustls::RootCertStore; + + use super::*; + + #[test] + fn required_policy_rejects_missing_certificate() { + let mut profiles = TlsProfiles::default(); + profiles.client_cas.insert("internal".to_owned(), Arc::new(RootCertStore::empty())); + let policy = ClientTlsPolicy::from_documents( + &json!({"api_client_tls_policy": { + "mode": "required", "ca_profile_id": "internal", "allowed_dns_sans": ["client.example"] + }}), + None, + ).unwrap(); + assert_eq!(policy.enforce(&[], &profiles, true), Err(ClientTlsFailure::Missing)); + assert_eq!(policy.enforce(&[], &profiles, false), Err(ClientTlsFailure::Configuration)); + } + + #[test] + fn endpoint_policy_overrides_api_policy() { + let mut profiles = TlsProfiles::default(); + profiles.client_cas.insert("internal".to_owned(), Arc::new(RootCertStore::empty())); + let api = json!({"api_client_tls_policy": { + "mode": "required", "ca_profile_id": "internal", "allowed_dns_sans": ["client.example"] + }}); + let endpoint = json!({"endpoint_client_tls_policy": {"mode": "off"}}); + let policy = ClientTlsPolicy::from_documents(&api, Some(&endpoint)).unwrap(); + assert_eq!(policy.enforce(&[], &profiles, true), Ok(())); + let cleared = json!({"endpoint_client_tls_policy": null}); + let policy = ClientTlsPolicy::from_documents(&api, Some(&cleared)).unwrap(); + assert_eq!(policy.enforce(&[], &profiles, true), Err(ClientTlsFailure::Missing)); + } + + #[test] + fn configured_policy_requires_native_mode_and_san_allowlist() { + let mut profiles = TlsProfiles::default(); + profiles.client_cas.insert("internal".to_owned(), Arc::new(RootCertStore::empty())); + let policy = json!({"mode": "required", "ca_profile_id": "internal", "allowed_uri_sans": ["spiffe://example/client"]}); + assert_eq!(ClientTlsPolicy::validate_value(&policy, &profiles, true), Ok(())); + assert_eq!(ClientTlsPolicy::validate_value(&policy, &profiles, false), Err(ClientTlsFailure::Configuration)); + assert_eq!(ClientTlsPolicy::validate_value(&json!({"mode": "required", "ca_profile_id": "internal"}), &profiles, true), Err(ClientTlsFailure::Configuration)); + } +} diff --git a/gateway-rs/src/tls/profiles.rs b/gateway-rs/src/tls/profiles.rs new file mode 100644 index 00000000..9a4c276c --- /dev/null +++ b/gateway-rs/src/tls/profiles.rs @@ -0,0 +1,394 @@ +use std::{collections::{HashMap, HashSet}, fs, path::{Path, PathBuf}, sync::Arc}; + +use serde::Deserialize; +use serde_json::Value; +use sha2::{Digest, Sha256}; +use thiserror::Error; +use tokio_rustls::rustls::{RootCertStore, ServerConfig, pki_types::{CertificateDer, PrivateKeyDer, pem::PemObject}}; +use x509_parser::parse_x509_certificate; + +use super::secrets; + +#[derive(Default)] +pub struct TlsProfiles { + pub client_cas: HashMap>, + pub upstreams: HashMap, + client_ca_pem: HashMap>, + client_ca_expiries: HashMap, +} + +#[derive(Clone)] +pub struct UpstreamProfile { + pub ca_pem: Vec, + pub client_cert_pem: Option>, + pub client_key_pem: Option>, + pub server_name: Option, +} + +#[derive(Deserialize, Default)] +#[serde(deny_unknown_fields)] +struct FileProfiles { + #[serde(default)] + client_ca_profiles: Vec, + #[serde(default)] + upstream_profiles: Vec, +} + +#[derive(Deserialize)] +#[serde(deny_unknown_fields)] +struct FileClientCa { + id: String, + ca_files: Vec, +} + +#[derive(Deserialize)] +#[serde(deny_unknown_fields)] +struct FileUpstream { + id: String, + #[serde(default)] + ca_files: Vec, + client_cert_file: Option, + client_key_file: Option, + server_name: Option, +} + +#[derive(Debug, Error)] +pub enum TlsProfileError { + #[error("TLS profile file could not be read: {0}")] + Io(#[from] std::io::Error), + #[error("TLS profile YAML is invalid: {0}")] + Yaml(#[from] serde_yaml::Error), + #[error("invalid TLS profile: {0}")] + Invalid(String), + #[error("TLS profile secret could not be decrypted: {0}")] + Secret(#[from] secrets::TlsSecretError), +} + +impl TlsProfiles { + pub fn load_file(path: Option<&Path>) -> Result { + let Some(path) = path else { return Ok(Self::default()); }; + let input: FileProfiles = serde_yaml::from_slice(&fs::read(path)?)?; + let mut profiles = Self::default(); + let mut ids = HashSet::new(); + for entry in input.client_ca_profiles { + validate_id(&entry.id, &mut ids)?; + if entry.ca_files.is_empty() { + return Err(TlsProfileError::Invalid(format!("{} has no CA files", entry.id))); + } + let ca_pem = read_pem_files(&entry.ca_files)?; + let expiry = crate::tls::certificate_expiry_timestamp(&ca_pem)?; + profiles.client_cas.insert(entry.id.clone(), Arc::new(load_roots(&entry.ca_files)?)); + profiles.client_ca_pem.insert(entry.id.clone(), ca_pem); + profiles.client_ca_expiries.insert(entry.id, expiry); + } + for entry in input.upstream_profiles { + validate_id(&entry.id, &mut ids)?; + if entry.client_cert_file.is_some() != entry.client_key_file.is_some() { + return Err(TlsProfileError::Invalid(format!("{} needs both client certificate and key", entry.id))); + } + if let Some(server_name) = &entry.server_name { + if server_name.is_empty() || server_name.contains('/') || server_name.contains(':') { + return Err(TlsProfileError::Invalid(format!("{} has invalid server name", entry.id))); + } + } + let ca_pem = read_pem_files(&entry.ca_files)?; + if !entry.ca_files.is_empty() { + load_roots(&entry.ca_files)?; + } + let client_cert_pem = entry.client_cert_file.map(fs::read).transpose()?; + let client_key_pem = entry.client_key_file.map(fs::read).transpose()?; + if let (Some(cert), Some(key)) = (&client_cert_pem, &client_key_pem) { + validate_identity_certificate(cert, key)?; + } + profiles.upstreams.insert(entry.id, UpstreamProfile { ca_pem, client_cert_pem, client_key_pem, server_name: entry.server_name }); + } + if profiles.client_cas.len() + profiles.upstreams.len() > 128 { + return Err(TlsProfileError::Invalid("at most 128 TLS profiles are supported".to_owned())); + } + Ok(profiles) + } + + pub fn combined_client_roots(&self) -> RootCertStore { + let mut combined = RootCertStore::empty(); + for roots in self.client_cas.values() { + combined.roots.extend(roots.roots.iter().cloned()); + } + combined + } + + pub fn fingerprint(&self) -> [u8; 32] { + let mut hasher = Sha256::new(); + let mut client_ids: Vec<_> = self.client_cas.keys().collect(); + client_ids.sort(); + for id in client_ids { + hasher.update(b"client_ca"); + hasher.update(id.as_bytes()); + if let Some(pem) = self.client_ca_pem.get(id) { + hasher.update(pem); + } + for root in &self.client_cas[id].roots { + hasher.update(root.subject.as_ref()); + hasher.update(root.subject_public_key_info.as_ref()); + } + } + let mut upstream_ids: Vec<_> = self.upstreams.keys().collect(); + upstream_ids.sort(); + for id in upstream_ids { + let profile = &self.upstreams[id]; + hasher.update(b"upstream"); + hasher.update(id.as_bytes()); + hasher.update(&profile.ca_pem); + if let Some(cert) = &profile.client_cert_pem { hasher.update(cert); } + if let Some(key) = &profile.client_key_pem { hasher.update(key); } + if let Some(name) = &profile.server_name { hasher.update(name.as_bytes()); } + } + hasher.finalize().into() + } + + pub fn certificate_expiries(&self) -> std::collections::BTreeMap { + let mut expiries = std::collections::BTreeMap::new(); + for (id, expiry) in &self.client_ca_expiries { + expiries.insert(format!("client_ca/{id}"), *expiry); + } + for (id, profile) in &self.upstreams { + let mut expiry = None; + for pem in [Some(&profile.ca_pem), profile.client_cert_pem.as_ref()] { + if let Some(pem) = pem.filter(|pem| !pem.is_empty()) { + if let Ok(value) = crate::tls::certificate_expiry_timestamp(pem) { + expiry = Some(expiry.map_or(value, |prior: i64| prior.min(value))); + } + } + } + if let Some(expiry) = expiry { expiries.insert(format!("upstream/{id}"), expiry); } + } + expiries + } + + pub fn merge_admin_documents(&mut self, documents: &[Value]) -> Result<(), TlsProfileError> { + for document in documents { + let id = document.get("id").and_then(Value::as_str) + .ok_or_else(|| TlsProfileError::Invalid("admin TLS profile has no ID".to_owned()))?; + let mut ids = self.client_cas.keys().chain(self.upstreams.keys()).cloned().collect(); + validate_id(id, &mut ids)?; + let kind = document.get("kind").and_then(Value::as_str) + .ok_or_else(|| TlsProfileError::Invalid(format!("{id} has no kind")))?; + let decrypt = |field: &str| -> Result>, TlsProfileError> { + document.get(field).and_then(Value::as_str) + .map(|sealed| secrets::open(id, field, sealed).map_err(TlsProfileError::from)) + .transpose() + }; + match kind { + "client_ca" => { + let pem = decrypt("ca_pem")?.ok_or_else(|| TlsProfileError::Invalid(format!("{id} has no CA bundle")))?; + let expiry = crate::tls::certificate_expiry_timestamp(&pem)?; + self.client_cas.insert(id.to_owned(), Arc::new(roots_from_pem(&pem)?)); + self.client_ca_pem.insert(id.to_owned(), pem); + self.client_ca_expiries.insert(id.to_owned(), expiry); + } + "upstream" => { + let ca_pem = decrypt("ca_pem")?.unwrap_or_default(); + if !ca_pem.is_empty() { roots_from_pem(&ca_pem)?; } + let client_cert_pem = decrypt("cert_pem")?; + let client_key_pem = decrypt("key_pem")?; + if client_cert_pem.is_some() != client_key_pem.is_some() { + return Err(TlsProfileError::Invalid(format!("{id} needs both client certificate and key"))); + } + if let (Some(cert), Some(key)) = (&client_cert_pem, &client_key_pem) { validate_identity_certificate(cert, key)?; } + let server_name = document.get("server_name").and_then(Value::as_str).map(str::to_owned); + if server_name.as_deref().is_some_and(|name| name.is_empty() || name.contains('/') || name.contains(':')) { + return Err(TlsProfileError::Invalid(format!("{id} has invalid server name"))); + } + self.upstreams.insert(id.to_owned(), UpstreamProfile { ca_pem, client_cert_pem, client_key_pem, server_name }); + } + "listener" => {} + _ => return Err(TlsProfileError::Invalid(format!("{id} has invalid kind"))), + } + } + if self.client_cas.len() + self.upstreams.len() > 128 { + return Err(TlsProfileError::Invalid("at most 128 TLS profiles are supported".to_owned())); + } + Ok(()) + } +} + +pub fn select_upstream_profile(api: &Value, endpoint: Option<&Value>, upstream: &str) -> Result, TlsProfileError> { + let url = url::Url::parse(upstream).map_err(|_| TlsProfileError::Invalid("upstream URL is invalid".to_owned()))?; + let host = url.host_str().ok_or_else(|| TlsProfileError::Invalid("upstream host is missing".to_owned()))?; + let port = url.port().or_else(|| match url.scheme() { + "https" | "grpcs" => Some(443), + "http" | "grpc" => Some(80), + _ => None, + }).ok_or_else(|| TlsProfileError::Invalid("upstream port is missing".to_owned()))?; + let origin = format!("{}://{}:{}", url.scheme(), host.to_ascii_lowercase(), port); + for (document, field) in [ + (endpoint, "endpoint_upstream_tls_profiles"), + (Some(api), "api_upstream_tls_profiles"), + ] { + if let Some(map) = document.and_then(|document| document.get(field)).filter(|value| !value.is_null()) { + let entries = map.as_object().ok_or_else(|| TlsProfileError::Invalid(format!("{field} must be an object")))?; + for (key, value) in entries { + let key_url = url::Url::parse(key).map_err(|_| TlsProfileError::Invalid(format!("invalid upstream TLS binding: {key}")))?; + let key_host = key_url.host_str().ok_or_else(|| TlsProfileError::Invalid(format!("invalid upstream TLS binding: {key}")))?; + let key_port = key_url.port().or_else(|| match key_url.scheme() { + "https" | "grpcs" => Some(443), + "http" | "grpc" => Some(80), + _ => None, + }).ok_or_else(|| TlsProfileError::Invalid(format!("invalid upstream TLS binding: {key}")))?; + if format!("{}://{}:{}", key_url.scheme(), key_host.to_ascii_lowercase(), key_port) == origin { + return value.as_str().map(|id| Some(id.to_owned())).ok_or_else(|| TlsProfileError::Invalid(format!("{field} profile ID must be a string"))); + } + } + } + } + for (document, field) in [ + (endpoint, "endpoint_upstream_tls_profile"), + (Some(api), "api_upstream_tls_profile"), + ] { + if let Some(value) = document.and_then(|document| document.get(field)).filter(|value| !value.is_null()) { + return value.as_str().map(|id| Some(id.to_owned())).ok_or_else(|| TlsProfileError::Invalid(format!("{field} must be a string"))); + } + } + Ok(None) +} + +pub fn validate_upstream_bindings(document: &Value, prefix: &str, profiles: &TlsProfiles) -> Result<(), TlsProfileError> { + let default_field = format!("{prefix}_upstream_tls_profile"); + if let Some(value) = document.get(&default_field).filter(|value| !value.is_null()) { + let id = value.as_str().ok_or_else(|| TlsProfileError::Invalid(format!("{default_field} must be a string")))?; + if !profiles.upstreams.contains_key(id) { + return Err(TlsProfileError::Invalid(format!("unknown upstream TLS profile: {id}"))); + } + } + let map_field = format!("{prefix}_upstream_tls_profiles"); + if let Some(value) = document.get(&map_field).filter(|value| !value.is_null()) { + let map = value.as_object().ok_or_else(|| TlsProfileError::Invalid(format!("{map_field} must be an object")))?; + for (origin, id) in map { + let url = url::Url::parse(origin).map_err(|_| TlsProfileError::Invalid(format!("invalid TLS origin: {origin}")))?; + if !matches!(url.scheme(), "https" | "grpcs") || url.host_str().is_none() + || url.path() != "/" || url.query().is_some() || url.fragment().is_some() + || !url.username().is_empty() || url.password().is_some() + { + return Err(TlsProfileError::Invalid(format!("TLS binding requires an HTTPS/grpcs origin: {origin}"))); + } + let id = id.as_str().ok_or_else(|| TlsProfileError::Invalid(format!("{map_field} profile ID must be a string")))?; + if !profiles.upstreams.contains_key(id) { + return Err(TlsProfileError::Invalid(format!("unknown upstream TLS profile: {id}"))); + } + } + } + Ok(()) +} + +fn validate_id(id: &str, ids: &mut HashSet) -> Result<(), TlsProfileError> { + if id.is_empty() || id.len() > 64 || !id.bytes().all(|b| b.is_ascii_lowercase() || b.is_ascii_digit() || matches!(b, b'-' | b'_')) { + return Err(TlsProfileError::Invalid(format!("invalid profile ID: {id}"))); + } + if !ids.insert(id.to_owned()) { + return Err(TlsProfileError::Invalid(format!("duplicate profile ID: {id}"))); + } + Ok(()) +} + +fn read_pem_files(paths: &[PathBuf]) -> Result, TlsProfileError> { + let mut pem = Vec::new(); + for path in paths { + pem.extend_from_slice(&fs::read(path)?); + pem.push(b'\n'); + } + Ok(pem) +} + +fn load_roots(paths: &[PathBuf]) -> Result { + let mut roots = RootCertStore::empty(); + for path in paths { + let pem = fs::read(path)?; + let loaded = roots_from_pem(&pem)?; + roots.roots.extend(loaded.roots); + } + Ok(roots) +} + +fn roots_from_pem(pem: &[u8]) -> Result { + let mut roots = RootCertStore::empty(); + let certs = CertificateDer::pem_slice_iter(pem) + .collect::, _>>() + .map_err(|error| TlsProfileError::Invalid(error.to_string()))?; + if certs.is_empty() { + return Err(TlsProfileError::Invalid("CA bundle contains no certificates".to_owned())); + } + for cert in certs { + let (_, parsed) = parse_x509_certificate(cert.as_ref()) + .map_err(|_| TlsProfileError::Invalid("CA certificate is not X.509".to_owned()))?; + if !parsed.validity().is_valid() { + return Err(TlsProfileError::Invalid("CA certificate is not currently valid".to_owned())); + } + roots.add(cert).map_err(|error| TlsProfileError::Invalid(error.to_string()))?; + } + Ok(roots) +} + +fn validate_identity_certificate(pem: &[u8], key_pem: &[u8]) -> Result<(), TlsProfileError> { + let certs = CertificateDer::pem_slice_iter(pem) + .collect::, _>>() + .map_err(|error| TlsProfileError::Invalid(error.to_string()))?; + let cert = certs.first().ok_or_else(|| TlsProfileError::Invalid("client certificate is missing".to_owned()))?; + let (_, parsed) = parse_x509_certificate(cert.as_ref()) + .map_err(|_| TlsProfileError::Invalid("client certificate is not X.509".to_owned()))?; + if !parsed.validity().is_valid() { + return Err(TlsProfileError::Invalid("client certificate is not currently valid".to_owned())); + } + let key = PrivateKeyDer::from_pem_slice(key_pem) + .map_err(|error| TlsProfileError::Invalid(error.to_string()))?; + ServerConfig::builder().with_no_client_auth().with_single_cert(certs, key) + .map_err(|error| TlsProfileError::Invalid(format!("client certificate/key mismatch: {error}")))?; + Ok(()) +} + +#[cfg(test)] +mod tests { + use serde_json::json; + + use super::*; + + #[test] + fn renewed_client_ca_material_changes_fingerprint() { + let mut profiles = TlsProfiles::default(); + profiles.client_cas.insert("internal".to_owned(), Arc::new(RootCertStore::empty())); + profiles.client_ca_pem.insert("internal".to_owned(), b"original certificate".to_vec()); + let original = profiles.fingerprint(); + profiles.client_ca_pem.insert("internal".to_owned(), b"renewed certificate with the same trust key".to_vec()); + assert_ne!(profiles.fingerprint(), original); + } + + #[test] + fn endpoint_origin_binding_precedes_api_default() { + let api = json!({"api_upstream_tls_profile": "api-default"}); + let endpoint = json!({"endpoint_upstream_tls_profiles": {"https://service.example:443": "endpoint"}}); + assert_eq!( + select_upstream_profile(&api, Some(&endpoint), "https://service.example/path").unwrap(), + Some("endpoint".to_owned()), + ); + let cleared = json!({"endpoint_upstream_tls_profile": null, "endpoint_upstream_tls_profiles": null}); + assert_eq!( + select_upstream_profile(&api, Some(&cleared), "https://service.example/path").unwrap(), + Some("api-default".to_owned()), + ); + assert_eq!( + select_upstream_profile(&json!({"api_upstream_tls_profile": null}), None, "https://service.example/path").unwrap(), + None, + ); + } + + #[test] + fn bindings_reject_plaintext_origins_and_unknown_profiles() { + let profiles = TlsProfiles::default(); + assert!(validate_upstream_bindings( + &json!({"api_upstream_tls_profiles": {"http://service.example": "missing"}}), + "api", &profiles, + ).is_err()); + assert!(validate_upstream_bindings( + &json!({"api_upstream_tls_profile": "missing"}), + "api", &profiles, + ).is_err()); + } +} diff --git a/gateway-rs/src/tls/secrets.rs b/gateway-rs/src/tls/secrets.rs new file mode 100644 index 00000000..ee7fc7d6 --- /dev/null +++ b/gateway-rs/src/tls/secrets.rs @@ -0,0 +1,60 @@ +use aes_gcm::{Aes256Gcm, KeyInit, Nonce, aead::{Aead, Payload}}; +use base64::{Engine, engine::general_purpose::STANDARD}; +use thiserror::Error; + +#[derive(Debug, Error)] +pub enum TlsSecretError { + #[error("TLS_SECRET_ENCRYPTION_KEY must be base64 for exactly 32 random bytes")] + MissingKey, + #[error("TLS secret encryption failed")] + Encryption, + #[error("TLS secret decryption failed")] + Decryption, +} + +fn cipher() -> Result { + let raw = std::env::var("TLS_SECRET_ENCRYPTION_KEY") + .map_err(|_| TlsSecretError::MissingKey)?; + let key = STANDARD.decode(raw).map_err(|_| TlsSecretError::MissingKey)?; + if key.len() != 32 { + return Err(TlsSecretError::MissingKey); + } + Aes256Gcm::new_from_slice(&key).map_err(|_| TlsSecretError::MissingKey) +} + +pub fn seal(id: &str, field: &str, plaintext: &[u8]) -> Result { + let cipher = cipher()?; + let nonce: [u8; 12] = rand::random(); + let aad = format!("{id}:{field}"); + let nonce_array = Nonce::try_from(nonce.as_slice()).map_err(|_| TlsSecretError::Encryption)?; + let ciphertext = cipher.encrypt(&nonce_array, Payload { msg: plaintext, aad: aad.as_bytes() }) + .map_err(|_| TlsSecretError::Encryption)?; + let mut blob = Vec::with_capacity(nonce.len() + ciphertext.len()); + blob.extend_from_slice(&nonce); + blob.extend_from_slice(&ciphertext); + Ok(format!("v1:{}", STANDARD.encode(blob))) +} + +pub fn open(id: &str, field: &str, sealed: &str) -> Result, TlsSecretError> { + let value = sealed.strip_prefix("v1:").ok_or(TlsSecretError::Decryption)?; + let blob = STANDARD.decode(value).map_err(|_| TlsSecretError::Decryption)?; + if blob.len() < 28 { + return Err(TlsSecretError::Decryption); + } + let aad = format!("{id}:{field}"); + let nonce_array = Nonce::try_from(&blob[..12]).map_err(|_| TlsSecretError::Decryption)?; + cipher()?.decrypt(&nonce_array, Payload { msg: &blob[12..], aad: aad.as_bytes() }) + .map_err(|_| TlsSecretError::Decryption) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn requires_an_explicit_secret_key() { + if std::env::var_os("TLS_SECRET_ENCRYPTION_KEY").is_none() { + assert!(matches!(seal("profile", "key", b"private"), Err(TlsSecretError::MissingKey))); + } + } +} diff --git a/gateway-rs/src/validation/json.rs b/gateway-rs/src/validation/json.rs index 33a85e20..db5f5312 100644 --- a/gateway-rs/src/validation/json.rs +++ b/gateway-rs/src/validation/json.rs @@ -95,7 +95,7 @@ fn validate_value( python_type_name(value) )); } - if let Some(text) = value.as_str() { + if let Some(text) = value.as_str().filter(|_| expected == "string") { let length = text.chars().count() as f64; enforce_range(length, rules, "String length", "", "")?; if let Some(pattern) = rules.get("pattern").and_then(Value::as_str) { @@ -112,10 +112,11 @@ fn validate_value( if let Some(number) = value .as_f64() .or_else(|| value.as_bool().map(|value| if value { 1.0 } else { 0.0 })) + .filter(|_| expected == "number") { enforce_range(number, rules, "Value", "", "")?; } - if let Some(items) = value.as_array() { + if let Some(items) = value.as_array().filter(|_| expected == "array") { enforce_range(items.len() as f64, rules, "Array", " items", " items")?; if let Some(item_rules) = rules.get("array_items") { for (index, item) in items.iter().enumerate() { @@ -129,7 +130,7 @@ fn validate_value( } } if let (Some(object), Some(nested)) = ( - value.as_object(), + value.as_object().filter(|_| expected == "object"), rules.get("nested_schema").and_then(Value::as_object), ) { for (field, nested_rules) in nested { @@ -137,7 +138,7 @@ fn validate_value( .get("required") .and_then(Value::as_bool) .unwrap_or(false) - && object.get(field).is_none_or(Value::is_null) + && !object.contains_key(field) { return Err(format!("Required field {field} is missing")); } @@ -149,8 +150,12 @@ fn validate_value( )?; } } - if let Some(allowed) = rules.get("enum").and_then(Value::as_array) { - if !allowed.contains(value) { + if let Some(allowed) = rules + .get("enum") + .and_then(Value::as_array) + .filter(|allowed| !allowed.is_empty()) + { + if !allowed.iter().any(|candidate| python_eq(candidate, value)) { return Err(format!( "Value must be one of {}", python_list_repr(allowed) @@ -192,16 +197,18 @@ fn enforce_range( } fn validate_format(value: &str, format: &str, path: &str) -> Result<(), String> { + // Python's `$` also matches before one trailing newline. + let pattern_value = value.strip_suffix('\n').unwrap_or(value); let valid = match format { "email" => Regex::new(r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$") - .is_ok_and(|regex| regex.is_match(value)), + .is_ok_and(|regex| regex.is_match(pattern_value)), "url" => Regex::new( r"^https?://(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b[-a-zA-Z0-9()@:%_+.~#?&/=]*$", ) - .is_ok_and(|regex| regex.is_match(value)), + .is_ok_and(|regex| regex.is_match(pattern_value)), "date" => valid_date(value), "datetime" => valid_datetime(value), - "uuid" => uuid::Uuid::parse_str(value).is_ok(), + "uuid" => valid_uuid(value), _ => true, }; if valid { @@ -220,35 +227,119 @@ fn validate_format(value: &str, format: &str, path: &str) -> Result<(), String> } } +/// `datetime.strptime(value, '%Y-%m-%d')`: unpadded month/day are accepted. fn valid_date(value: &str) -> bool { - time::Date::parse( - value, - &time::format_description::well_known::Iso8601::DEFAULT, - ) - .is_ok() + static DATE: std::sync::LazyLock = std::sync::LazyLock::new(|| { + Regex::new(r"^([0-9]{4})-(1[0-2]|0[1-9]|[1-9])-(3[0-1]|[1-2][0-9]|0[1-9]|[1-9]| [1-9])$") + .expect("date expression is valid") + }); + let Some(parts) = DATE.captures(value) else { + return false; + }; + let year: i32 = parts[1].parse().unwrap_or(0); + let month: u8 = parts[2].parse().unwrap_or(0); + let day: u8 = parts[3].trim().parse().unwrap_or(0); + year >= 1 + && time::Month::try_from(month) + .ok() + .and_then(|month| time::Date::from_calendar_date(year, month, day).ok()) + .is_some() } +/// `uuid.UUID(value)`: strips `urn:`/`uuid:`, braces and hyphens, then needs 32 hex digits. +fn valid_uuid(value: &str) -> bool { + let hex = value + .replace("urn:", "") + .replace("uuid:", "") + .trim_matches(|c| c == '{' || c == '}') + .replace('-', ""); + hex.len() == 32 && hex.bytes().all(|byte| byte.is_ascii_hexdigit()) +} + +/// `datetime.fromisoformat(value.replace('Z', '+00:00'))` (Python 3.11+ grammar): +/// extended or basic dates, ISO week dates, any single-character separator, optional +/// `HH[:MM[:SS[.f]]]` time, and an optional `±HH[:MM[:SS[.f]]]` offset. fn valid_datetime(value: &str) -> bool { - valid_date(value) - || time::OffsetDateTime::parse( - value, - &time::format_description::well_known::Iso8601::DEFAULT, + static DATE: std::sync::LazyLock = std::sync::LazyLock::new(|| { + Regex::new( + r"^(?:(\d{4})-(\d{2})-(\d{2})|(\d{4})(\d{2})(\d{2})|(\d{4})-W(\d{2})(?:-(\d))?|(\d{4})W(\d{2})(\d)?)", ) - .is_ok() - || time::PrimitiveDateTime::parse( - value, - &time::format_description::well_known::Iso8601::DEFAULT, + .expect("static date pattern") + }); + static TIME: std::sync::LazyLock = std::sync::LazyLock::new(|| { + Regex::new( + r"^(\d{2})(?:(?::(\d{2})(?::(\d{2})(?:[.,]\d+)?)?)|(?:(\d{2})(?:(\d{2})(?:[.,]\d+)?)?))?(?:[+-](\d{2})(?::?(\d{2})(?::?(\d{2})(?:[.,]\d+)?)?)?)?$", ) - .is_ok() - || value.find(' ').is_some_and(|index| { - let mut normalized = value.to_owned(); - normalized.replace_range(index..=index, "T"); - time::PrimitiveDateTime::parse( - &normalized, - &time::format_description::well_known::Iso8601::DEFAULT, - ) - .is_ok() - }) + .expect("static time pattern") + }); + let value = value.replace('Z', "+00:00"); + let Some(captures) = DATE.captures(&value) else { + return false; + }; + let number = |index: usize| { + captures + .get(index) + .map(|m| m.as_str().parse::().unwrap()) + }; + let calendar = if number(1).is_some() { + (number(1), number(2), number(3)) + } else { + (number(4), number(5), number(6)) + }; + let date_ok = if let (Some(y), Some(m), Some(d)) = calendar { + u8::try_from(m) + .ok() + .and_then(|m| time::Month::try_from(m).ok()) + .zip(u8::try_from(d).ok()) + .is_some_and(|(m, d)| time::Date::from_calendar_date(y, m, d).is_ok()) + } else { + let (year, week, day) = if number(7).is_some() { + (number(7), number(8), number(9)) + } else { + (number(10), number(11), number(12)) + }; + match (year, week, u8::try_from(day.unwrap_or(1)).ok()) { + (Some(y), Some(w), Some(d)) => { + let weekday = match d { + 1 => Some(time::Weekday::Monday), + 2 => Some(time::Weekday::Tuesday), + 3 => Some(time::Weekday::Wednesday), + 4 => Some(time::Weekday::Thursday), + 5 => Some(time::Weekday::Friday), + 6 => Some(time::Weekday::Saturday), + 7 => Some(time::Weekday::Sunday), + _ => None, + }; + u8::try_from(w) + .ok() + .zip(weekday) + .is_some_and(|(w, wd)| time::Date::from_iso_week_date(y, w, wd).is_ok()) + } + _ => false, + } + }; + if !date_ok { + return false; + } + let rest = &value[captures.get(0).unwrap().end()..]; + let mut chars = rest.chars(); + if chars.next().is_none() { + return true; + } + let time_part = chars.as_str(); + let Some(time) = TIME.captures(time_part) else { + return false; + }; + let field = |index: usize| time.get(index).map(|m| m.as_str().parse::().unwrap()); + let hour = field(1).unwrap(); + let minute = field(2).or(field(4)).unwrap_or(0); + let second = field(3).or(field(5)).unwrap_or(0); + hour < 24 + && minute < 60 + && second < 60 + && field(6).is_none_or(|h| h < 24) + && field(7).is_none_or(|m| m < 60) + && field(8).is_none_or(|s| s < 60) } fn python_type_name(value: &Value) -> &'static str { @@ -274,18 +365,79 @@ fn python_number(value: f64) -> String { fn python_list_repr(values: &[Value]) -> String { let values = values .iter() - .map(|value| match value { - Value::String(value) => format!("'{value}'"), - Value::Bool(true) => "True".to_owned(), - Value::Bool(false) => "False".to_owned(), - Value::Null => "None".to_owned(), - value => value.to_string(), - }) + .map(python_repr) .collect::>() .join(", "); format!("[{values}]") } +fn python_repr(value: &Value) -> String { + match value { + Value::String(text) => { + let quote = if text.contains('\'') && !text.contains('"') { + '"' + } else { + '\'' + }; + let mut out = String::from(quote); + for character in text.chars() { + match character { + '\\' => out.push_str("\\\\"), + '\n' => out.push_str("\\n"), + '\r' => out.push_str("\\r"), + '\t' => out.push_str("\\t"), + c if c == quote => { + out.push('\\'); + out.push(c); + } + c => out.push(c), + } + } + out.push(quote); + out + } + Value::Bool(true) => "True".to_owned(), + Value::Bool(false) => "False".to_owned(), + Value::Null => "None".to_owned(), + Value::Array(items) => python_list_repr(items), + Value::Object(map) => format!( + "{{{}}}", + map.iter() + .map(|(key, value)| format!( + "{}: {}", + python_repr(&Value::String(key.clone())), + python_repr(value) + )) + .collect::>() + .join(", ") + ), + number => number.to_string(), + } +} + +/// Python `==` semantics for JSON-shaped values: `1 == 1.0 == True`. +fn python_eq(left: &Value, right: &Value) -> bool { + let numeric = |value: &Value| match value { + Value::Bool(flag) => Some(if *flag { 1.0 } else { 0.0 }), + Value::Number(number) => number.as_f64(), + _ => None, + }; + if let (Some(a), Some(b)) = (numeric(left), numeric(right)) { + return a == b; + } + match (left, right) { + (Value::Array(a), Value::Array(b)) => { + a.len() == b.len() && a.iter().zip(b).all(|(x, y)| python_eq(x, y)) + } + (Value::Object(a), Value::Object(b)) => { + a.len() == b.len() + && a.iter() + .all(|(key, value)| b.get(key).is_some_and(|other| python_eq(value, other))) + } + _ => left == right, + } +} + fn validate_schema_paths( schema: &serde_json::Map, parent: &str, @@ -299,12 +451,7 @@ fn validate_schema_paths( if full_path.split('.').any(|part| { part.is_empty() || part.split_once('[').is_some_and(|(field, index)| { - field.is_empty() - && !index - .strip_suffix(']') - .unwrap_or(index) - .bytes() - .all(|byte| byte.is_ascii_digit()) + field.is_empty() && !is_ascii_digits(index.trim_end_matches(']')) }) }) { return Err(format!("Invalid field path: {full_path}")); @@ -316,6 +463,10 @@ fn validate_schema_paths( Ok(()) } +fn is_ascii_digits(text: &str) -> bool { + !text.is_empty() && text.bytes().all(|byte| byte.is_ascii_digit()) +} + fn nested_value<'a>(root: &'a Value, path: &str) -> Option<&'a Value> { let mut current = root; for segment in path.split('.') { @@ -324,15 +475,22 @@ fn nested_value<'a>(root: &'a Value, path: &str) -> Option<&'a Value> { current = current.get(field)?; } if let Some(index) = index { - current = current.as_array()?.get(index)?; + let items = current.as_array()?; + // Python indexes from the end for negative values. + let index = if index < 0 { + items.len().checked_sub(index.unsigned_abs() as usize)? + } else { + index as usize + }; + current = items.get(index)?; } } Some(current) } -fn parse_segment(segment: &str) -> Option<(&str, Option)> { +fn parse_segment(segment: &str) -> Option<(&str, Option)> { if let Some((field, raw_index)) = segment.split_once('[') { - let index = raw_index.strip_suffix(']')?.parse().ok()?; + let index = raw_index.trim_end_matches(']').parse().ok()?; Some((field, Some(index))) } else if segment.is_empty() { None @@ -526,4 +684,119 @@ mod tests { "Value must be one of ['NEW', 'OPEN']" ); } + + #[test] + fn python_edge_cases_for_paths_types_enums_and_formats() { + let ok = |doc: Value, schema: Value| validate_json(&doc, &schema); + // Invalid schema paths: empty index, multiple closing brackets are fine. + for (path, valid) in [ + ("[", false), + ("[]", false), + ("[0]", true), + ("[0]]", true), + ("a[x]", true), + ("a..b", false), + ] { + let schema = json!({ path: {"type": "string"} }); + assert_eq!( + validate_schema_paths(schema.as_object().unwrap(), "").is_ok(), + valid, + "{path}" + ); + } + // Present-but-null nested field: "Field is required", not "is missing". + let nested = json!({"o": {"type": "object", "nested_schema": {"k": {"type": "string", "required": true}}}}); + assert_eq!( + ok(json!({"o": {"k": null}}), nested.clone()).unwrap_err(), + "Field is required" + ); + assert_eq!( + ok(json!({"o": {}}), nested).unwrap_err(), + "Required field k is missing" + ); + // Negative indexes read from the end. + let idx = json!({"a[-1]": {"type": "number", "min": 5}}); + assert!(ok(json!({"a": [1, 9]}), idx.clone()).is_ok()); + assert_eq!( + ok(json!({"a": [9, 1]}), idx).unwrap_err(), + "Value must be at least 5" + ); + // Empty enum is ignored; 1 == 1.0 == True; repr of nested values. + assert!( + ok( + json!({"x": "q"}), + json!({"x": {"type": "string", "enum": []}}) + ) + .is_ok() + ); + assert!( + ok( + json!({"x": 1.0}), + json!({"x": {"type": "number", "enum": [1]}}) + ) + .is_ok() + ); + assert_eq!( + ok( + json!({"x": "z"}), + json!({"x": {"type": "string", "enum": ["a", "it's", 2, true, null]}}) + ) + .unwrap_err(), + "Value must be one of ['a', \"it's\", 2, True, None]" + ); + // Constraints only apply for the declared type. + assert!( + ok( + json!({"x": "ab"}), + json!({"x": {"type": "other", "min": 5}}) + ) + .is_ok() + ); + // strptime-style dates, permissive UUID normalisation, trailing newline in `$` formats. + for (format, value, valid) in [ + ("date", "2024-1-5", true), + ("date", "2024-02-30", false), + ("date", "2024-02-29", true), + ("date", "2023-02-29", false), + ("date", "2024-01-05T00:00", false), + ("date", "0000-01-01", false), + ("uuid", "12345678123456781234567812345678", true), + ("uuid", "{12345678-1234-5678-1234-567812345678}", true), + ( + "uuid", + "urn:uuid:12345678-1234-5678-1234-567812345678", + true, + ), + ("uuid", "1234-5678", false), + ("uuid", "1234567-8123-4567-8123-4567812345678", true), + ("datetime", "2024-1-5", false), + ("datetime", "2024-01-05", true), + ("datetime", "2024-01-05T10", true), + ("datetime", "2024-01-05 10:30:15.123456789", true), + ("datetime", "20240105T103015", true), + ("datetime", "2024-W01-1T10:00", true), + ("datetime", "2024W011", true), + ("datetime", "2024-01-05T10:00:00Z", true), + ("datetime", "2024-01-05T10:00:00+0530", true), + ("datetime", "2024-01-05T10:00:00,5", true), + ("datetime", "2024-01-05*10:00", true), + ("datetime", "2024-13-01", false), + ("datetime", "2024-02-30", false), + ("datetime", "2024-01-05T24:00", false), + ("datetime", "2024-01-05T10:60", false), + ("datetime", "2024-01-05T", false), + ("datetime", "2024-01-05T10:00+24:00", false), + ("datetime", "2024-01-05T10:0000", false), + ("datetime", "10:00", false), + ("email", "a@b.com\n", true), + ("email", "a@b.com\n\n", false), + ] { + let schema = json!({"v": {"type": "string", "format": format}}); + assert_eq!( + ok(json!({"v": value}), schema).is_ok(), + valid, + "{format} {value:?}" + ); + } + } } diff --git a/gateway-rs/src/validation/xml.rs b/gateway-rs/src/validation/xml.rs index 8ee871c3..d344dba6 100644 --- a/gateway-rs/src/validation/xml.rs +++ b/gateway-rs/src/validation/xml.rs @@ -26,7 +26,7 @@ pub fn soap_body_object(xml: &str) -> Result { fn parse(xml: &str) -> Result { let mut reader = Reader::from_str(xml); - reader.config_mut().trim_text(true); + reader.config_mut().trim_text(false); let mut stack = Vec::::new(); let mut root = None; loop { @@ -52,11 +52,39 @@ fn parse(xml: &str) -> Result { if let Some(node) = stack.last_mut() { let text = event .decode() + .map_err(|_| "Invalid SOAP envelope".to_owned())?; + node.text.get_or_insert_with(String::new).push_str(&text); + } + } + Ok(Event::CData(event)) => { + if let Some(node) = stack.last_mut() { + let text = event + .decode() + .map_err(|_| "Invalid SOAP envelope".to_owned())?; + node.text.get_or_insert_with(String::new).push_str(&text); + } + } + Ok(Event::GeneralRef(event)) => { + if let Some(node) = stack.last_mut() { + let resolved = match event + .resolve_char_ref() .map_err(|_| "Invalid SOAP envelope".to_owned())? - .into_owned(); - if !text.is_empty() { - node.text = Some(text); - } + { + Some(character) => character, + None => match event + .decode() + .map_err(|_| "Invalid SOAP envelope".to_owned())? + .as_ref() + { + "lt" => '<', + "gt" => '>', + "amp" => '&', + "apos" => '\'', + "quot" => '"', + _ => return Err("Invalid SOAP envelope".to_owned()), + }, + }; + node.text.get_or_insert_with(String::new).push(resolved); } } Ok(Event::End(_)) => { @@ -125,6 +153,15 @@ mod tests { ); } + #[test] + fn preserves_leaf_text_exactly_like_element_tree() { + let xml = r#" x & y A]]> 12"#; + assert_eq!( + soap_body_object(xml).unwrap(), + serde_json::json!({"a": " x & y A ", "b": " ", "c": null, "d": null, "e": "2"}) + ); + } + #[test] fn rejects_dtd_and_missing_bodies_when_validation_is_enabled() { assert!(soap_body_object("").is_err()); diff --git a/gateway-rs/tests/bootstrap_admin_parity.rs b/gateway-rs/tests/bootstrap_admin_parity.rs index c6b322b0..1f761152 100644 --- a/gateway-rs/tests/bootstrap_admin_parity.rs +++ b/gateway-rs/tests/bootstrap_admin_parity.rs @@ -110,3 +110,53 @@ async fn bootstrap_admin_seed_matches_python_and_preserves_existing_credentials( .unwrap() ); } + +#[tokio::test] +async fn bootstrap_repairs_missing_admin_fields_like_python_mongo_mode() { + if std::env::var_os("DOORMAN_BOOTSTRAP_REPAIR_TEST_CHILD").is_none() { + let output = std::process::Command::new(std::env::current_exe().unwrap()) + .args([ + "--exact", + "bootstrap_repairs_missing_admin_fields_like_python_mongo_mode", + "--nocapture", + ]) + .env("DOORMAN_BOOTSTRAP_REPAIR_TEST_CHILD", "1") + .env("DOORMAN_ADMIN_EMAIL", "repair@doorman.dev") + .env("DOORMAN_ADMIN_PASSWORD", "repair-password-12chars") + .output() + .unwrap(); + assert!( + output.status.success(), + "{}\n{}", + String::from_utf8_lossy(&output.stdout), + String::from_utf8_lossy(&output.stderr) + ); + return; + } + let config = Config::for_test("removed-internal-backend".to_owned()); + let storage = SharedStorage::connect(&config.shared_storage) + .await + .unwrap(); + storage + .insert_one( + "users", + json!({"username": "admin", "ui_access": false, "email": ""}), + ) + .await + .unwrap(); + storage.initialize_core().await.unwrap(); + let admin = storage + .find_one("users", &json!({"username": "admin"})) + .await + .unwrap() + .unwrap(); + assert_eq!(admin["ui_access"], true); + assert_eq!(admin["email"], "repair@doorman.dev"); + assert!( + bcrypt::verify( + "repair-password-12chars", + admin["password"].as_str().unwrap() + ) + .unwrap() + ); +} diff --git a/gateway-rs/tests/chaos_storage_parity.rs b/gateway-rs/tests/chaos_storage_parity.rs new file mode 100644 index 00000000..24e0a952 --- /dev/null +++ b/gateway-rs/tests/chaos_storage_parity.rs @@ -0,0 +1,47 @@ +use doorman_gateway::{ + Config, + middleware::chaos::{CHAOS_ERROR_BUDGET_BURN, CHAOS_MONGO_OUTAGE, CHAOS_REDIS_OUTAGE}, + storage::runtime::SharedStorage, +}; +use serde_json::json; +use std::sync::atomic::Ordering; + +#[tokio::test] +async fn chaos_outage_flags_fail_storage_operations_and_burn_error_budget_like_python() { + let config = Config::for_test("removed-internal-backend".to_owned()); + let storage = SharedStorage::connect(&config.shared_storage) + .await + .unwrap(); + storage + .insert_one("apis", json!({"api_name": "a"})) + .await + .unwrap(); + let burn_before = CHAOS_ERROR_BUDGET_BURN.load(Ordering::Relaxed); + + CHAOS_MONGO_OUTAGE.store(true, Ordering::Relaxed); + let err = storage.find_one("apis", &json!({})).await.unwrap_err(); + assert!(err.to_string().contains("chaos: simulated mongo outage")); + assert!(storage.insert_one("apis", json!({})).await.is_err()); + assert!(storage.delete_one("apis", &json!({})).await.is_err()); + CHAOS_MONGO_OUTAGE.store(false, Ordering::Relaxed); + assert!( + storage + .find_one("apis", &json!({})) + .await + .unwrap() + .is_some() + ); + + CHAOS_REDIS_OUTAGE.store(true, Ordering::Relaxed); + let err = storage.set_ephemeral("k", json!(1), 60).await.unwrap_err(); + assert!(err.to_string().contains("chaos: simulated redis outage")); + assert!(storage.get_ephemeral("k").await.is_err()); + CHAOS_REDIS_OUTAGE.store(false, Ordering::Relaxed); + storage.set_ephemeral("k", json!(1), 60).await.unwrap(); + assert_eq!(storage.get_ephemeral("k").await.unwrap(), Some(json!(1))); + + assert_eq!( + CHAOS_ERROR_BUDGET_BURN.load(Ordering::Relaxed) - burn_before, + 5 + ); +} diff --git a/gateway-rs/tests/crud_rest_parity.rs b/gateway-rs/tests/crud_rest_parity.rs new file mode 100644 index 00000000..2b81e5fc --- /dev/null +++ b/gateway-rs/tests/crud_rest_parity.rs @@ -0,0 +1,269 @@ +use axum::body::{Body, to_bytes}; +use doorman_gateway::{AppState, Config, build_router, storage::runtime::SharedStorage}; +use http::{Method, Request, StatusCode}; +use serde_json::{Value, json}; +use std::sync::Arc; +use tower::ServiceExt; + +async fn crud_app(schema: Value) -> axum::Router { + let config = Config::for_test("removed-internal-backend".to_owned()); + let storage = SharedStorage::connect(&config.shared_storage) + .await + .unwrap(); + storage + .insert_one( + "apis", + json!({ + "api_id": "crud-1", "api_name": "items", "api_version": "v1", + "api_type": "REST", "api_public": true, "api_auth_required": false, + "api_is_crud": true, "api_crud_collection": "crud_data_items", + "api_crud_schema": schema, "active": true, "api_servers": [] + }), + ) + .await + .unwrap(); + for method in ["GET", "POST", "PUT", "PATCH"] { + let uri = if method == "GET" || method == "POST" { + "/items" + } else { + "/items/{id}" + }; + storage + .insert_one( + "endpoints", + json!({ + "api_id": "crud-1", "api_name": "items", "api_version": "v1", + "endpoint_method": method, "endpoint_uri": uri, + "endpoint_id": format!("e-{method}") + }), + ) + .await + .unwrap(); + } + let mut state = AppState::new(config).unwrap(); + state.storage = Some(Arc::new(storage)); + build_router(state) +} + +async fn call(app: &axum::Router, method: Method, uri: &str, body: &str) -> (StatusCode, Value) { + let response = app + .clone() + .oneshot( + Request::builder() + .method(method) + .uri(uri) + .header("content-type", "application/json") + .body(Body::from(body.to_owned())) + .unwrap(), + ) + .await + .unwrap(); + let status = response.status(); + let bytes = to_bytes(response.into_body(), usize::MAX).await.unwrap(); + ( + status, + serde_json::from_slice(&bytes).unwrap_or(Value::Null), + ) +} + +#[tokio::test] +async fn crud_validation_failure_body_omits_error_list_like_python() { + let app = crud_app(json!({"name": {"type": "string", "required": true}})).await; + let (status, body) = call(&app, Method::POST, "/api/rest/items/v1/items", "{}").await; + assert_eq!(status, StatusCode::BAD_REQUEST); + assert_eq!( + body, + json!({"error_code": "CRUD400", "error_message": "Validation failed"}) + ); +} + +#[tokio::test] +async fn crud_non_object_bodies_raise_python_internal_errors() { + let app = crud_app(json!({})).await; + for (body, message) in [ + ("[1]", "list indices must be integers or slices, not str"), + ("\"abc\"", "'str' object does not support item assignment"), + ("5", "argument of type 'int' is not iterable"), + ("1.5", "argument of type 'float' is not iterable"), + ("true", "argument of type 'bool' is not iterable"), + ("null", "argument of type 'NoneType' is not iterable"), + ] { + let (status, json_body) = call(&app, Method::POST, "/api/rest/items/v1/items", body).await; + assert_eq!(status, StatusCode::INTERNAL_SERVER_ERROR, "{body}"); + assert_eq!(json_body["error_code"], "CRUD999", "{body}"); + assert_eq!( + json_body["error_message"], + format!("Internal CRUD error: {message}"), + "{body}" + ); + } +} + +#[tokio::test] +async fn crud_non_object_update_bodies_follow_python_order() { + let app = crud_app(json!({})).await; + let (status, created) = call( + &app, + Method::POST, + "/api/rest/items/v1/items", + r#"{"_id":"a","n":1}"#, + ) + .await; + assert_eq!(status, StatusCode::CREATED); + assert_eq!(created["_id"], "a"); + // Missing resource is reported before the body is used. + let (status, body) = call(&app, Method::PUT, "/api/rest/items/v1/items/zzz", "[1]").await; + assert_eq!( + (status, body["error_code"].as_str()), + (StatusCode::NOT_FOUND, Some("CRUD404")) + ); + // Truthy non-object body: `.items()` AttributeError. + let (status, body) = call(&app, Method::PUT, "/api/rest/items/v1/items/a", "[1]").await; + assert_eq!(status, StatusCode::INTERNAL_SERVER_ERROR); + assert_eq!( + body["error_message"], + "Internal CRUD error: 'list' object has no attribute 'items'" + ); + // Falsy body is a no-op update returning the stored document. + let (status, body) = call(&app, Method::PATCH, "/api/rest/items/v1/items/a", "null").await; + assert_eq!(status, StatusCode::OK); + assert_eq!(body["n"], 1); +} + +#[tokio::test] +async fn crud_non_object_update_with_schema_raises_get_attribute_error() { + let app = crud_app(json!({"name": {"type": "string"}})).await; + let (status, body) = call(&app, Method::PUT, "/api/rest/items/v1/items/a", "[1]").await; + assert_eq!(status, StatusCode::INTERNAL_SERVER_ERROR); + assert_eq!( + body["error_message"], + "Internal CRUD error: 'list' object has no attribute 'get'" + ); +} + +async fn soap_app() -> axum::Router { + let config = Config::for_test("removed-internal-backend".to_owned()); + let storage = SharedStorage::connect(&config.shared_storage) + .await + .unwrap(); + storage + .insert_one( + "apis", + json!({ + "api_id": "crud-s", "api_name": "sitems", "api_version": "v1", + "api_type": "SOAP", "api_public": true, "api_auth_required": false, + "api_is_crud": true, "api_crud_collection": "crud_data_sitems", + "api_crud_schema": {"name": {"type": "string", "required": true}}, + "active": true, "api_servers": [] + }), + ) + .await + .unwrap(); + for method in ["GET", "POST"] { + storage + .insert_one( + "endpoints", + json!({ + "api_id": "crud-s", "api_name": "sitems", "api_version": "v1", + "endpoint_method": method, "endpoint_uri": "/soap", + "endpoint_id": format!("s-{method}") + }), + ) + .await + .unwrap(); + } + let mut state = AppState::new(config).unwrap(); + state.storage = Some(Arc::new(storage)); + build_router(state) +} + +async fn soap_call( + app: &axum::Router, + method: Method, + uri: &str, + body: &str, +) -> (StatusCode, String, String) { + let response = app + .clone() + .oneshot( + Request::builder() + .method(method) + .uri(uri) + .header("content-type", "text/xml") + .body(Body::from(body.to_owned())) + .unwrap(), + ) + .await + .unwrap(); + let status = response.status(); + let content_type = response + .headers() + .get("content-type") + .and_then(|value| value.to_str().ok()) + .unwrap_or_default() + .to_owned(); + let bytes = to_bytes(response.into_body(), usize::MAX).await.unwrap(); + ( + status, + content_type, + String::from_utf8(bytes.to_vec()).unwrap(), + ) +} + +fn envelope(operation: &str) -> String { + format!( + "{operation}" + ) +} + +#[tokio::test] +async fn crud_soap_matches_python_envelope_wsdl_and_fault() { + let app = soap_app().await; + let (status, content_type, body) = + soap_call(&app, Method::GET, "/api/soap/sitems/v1/soap?wsdl", "").await; + assert_eq!( + (status, content_type.as_str()), + (StatusCode::OK, "text/xml") + ); + assert!(body.contains("name=\"sitemsService\"") && !body.contains("getItem")); + + let create = envelope( + "{"name": "Ada", "_id": "x1"}", + ); + let (status, content_type, body) = + soap_call(&app, Method::POST, "/api/soap/sitems/v1/soap", &create).await; + assert_eq!( + (status, content_type.as_str()), + (StatusCode::OK, "text/xml") + ); + assert_eq!( + body, + "\n\n \n \n {\"name\": \"Ada\", \"_id\": \"x1\"}\n \n \n" + ); + + let list = envelope(""); + let (_, _, body) = soap_call(&app, Method::POST, "/api/soap/sitems/v1/soap", &list).await; + assert!( + body.contains("[{\"name\": \"Ada\", \"_id\": \"x1\"}]"), + "{body}" + ); + + let fault = "An unknown error occurred in SOAP response"; + for operation in [ + "x1", + "x1", + "{}", + "not json", + ] { + let (status, content_type, body) = soap_call( + &app, + Method::POST, + "/api/soap/sitems/v1/soap", + &envelope(operation), + ) + .await; + assert_eq!(status, StatusCode::INTERNAL_SERVER_ERROR, "{operation}"); + assert_eq!(content_type, "text/xml", "{operation}"); + assert_eq!(body, fault, "{operation}"); + } +} diff --git a/gateway-rs/tests/fixtures/crud_customer_api.proto b/gateway-rs/tests/fixtures/crud_customer_api.proto new file mode 100644 index 00000000..06e229a8 --- /dev/null +++ b/gateway-rs/tests/fixtures/crud_customer_api.proto @@ -0,0 +1,27 @@ +syntax = "proto3"; + +package customer_api; + +service Customer_apiService { + rpc CreateItem (CreateItemRequest) returns (CreateItemResponse); + rpc ListItems (ListItemsRequest) returns (ListItemsResponse); +} + +message CreateItemRequest { + string name = 1; + int32 age = 2; + double score = 3; + bool ok = 4; + repeated string tags = 5; + string meta = 6; +} + +message CreateItemResponse { + string result = 1; // JSON string of created object +} + +message ListItemsRequest {} + +message ListItemsResponse { + string items = 1; // JSON string of list +} diff --git a/gateway-rs/tests/fixtures/crud_customer_api.wsdl b/gateway-rs/tests/fixtures/crud_customer_api.wsdl new file mode 100644 index 00000000..8c5416d3 --- /dev/null +++ b/gateway-rs/tests/fixtures/crud_customer_api.wsdl @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/gateway-rs/tests/live_tests_parity.rs b/gateway-rs/tests/live_tests_parity.rs index 2ad2784d..4c54b19b 100644 --- a/gateway-rs/tests/live_tests_parity.rs +++ b/gateway-rs/tests/live_tests_parity.rs @@ -28,6 +28,27 @@ async fn test_app_state() -> AppState { test_app_state_with(|_| {}).await } +/// Re-runs `name` in a child process with ENFORCE_ADMIN_SUBSCRIPTION=true (as the Python +/// live tests do) so the process-global variable cannot leak into concurrent tests. +fn reexec_with_enforced_admin_subscription(name: &str) -> bool { + if std::env::var_os("DOORMAN_ENFORCE_ADMIN_SUB_CHILD").is_some() { + return false; + } + let output = std::process::Command::new(std::env::current_exe().unwrap()) + .args(["--exact", name, "--nocapture"]) + .env("DOORMAN_ENFORCE_ADMIN_SUB_CHILD", "1") + .env("ENFORCE_ADMIN_SUBSCRIPTION", "true") + .output() + .unwrap(); + assert!( + output.status.success(), + "{}\n{}", + String::from_utf8_lossy(&output.stdout), + String::from_utf8_lossy(&output.stderr) + ); + true +} + #[tokio::test] async fn hot_reload_changes_retry_and_timeout_on_real_http_requests() { let attempts = Arc::new(AtomicUsize::new(0)); @@ -1388,11 +1409,18 @@ async fn monitor_metrics_increment_status_series_and_top_apis_parity() { assert!(metrics["total_requests"].as_u64().unwrap_or(0) >= 3); assert!(metrics["status_counts"]["200"].as_u64().unwrap_or(0) >= 3); assert!(metrics["series"].is_array()); + // Python's MetricsStore.snapshot serializes top_apis as a list of + // [name, count] tuples (sorted(dict.items())), not objects. assert!(metrics["top_apis"].as_array().unwrap().iter().any(|entry| { - entry["name"] - .as_str() + entry + .as_array() + .and_then(|pair| pair.first()) + .and_then(|name| name.as_str()) .is_some_and(|name| name.starts_with("rest:")) })); + // Python's unique_users is len(agg_user_counts) reconstructed from the + // selected range's buckets, not a process-global all-time distinct count. + assert!(metrics["unique_users"].as_u64().unwrap_or(0) >= 1); upstream.abort(); } @@ -2225,6 +2253,10 @@ async fn request_id_is_forwarded_to_authenticated_rest_upstream_and_response() { #[tokio::test] async fn live_test_21_subscription_list_unsubscribe_parity() { + if reexec_with_enforced_admin_subscription("live_test_21_subscription_list_unsubscribe_parity") + { + return; + } let app = build_router(test_app_state().await); let token = login_admin(&app).await; let api_name = "subs-test-21"; @@ -3157,10 +3189,12 @@ async fn live_test_41_soap_and_85_endpoint_validation_parity() { "endpoint_id": endpoint_id, "validation_enabled": true, "validation_schema": { - "intA": { - "required": true, - "type": "string", - "min": 2 + "validation_schema": { + "intA": { + "required": true, + "type": "string", + "min": 2 + } } } }) @@ -4168,6 +4202,9 @@ message HelloReply { string message = 1; } #[tokio::test] async fn grpc_gateway_maps_upstream_statuses_parity() { + if reexec_with_enforced_admin_subscription("grpc_gateway_maps_upstream_statuses_parity") { + return; + } let (upstream_url, upstream) = start_grpc_status_upstream().await; let app = build_router(test_app_state().await); let token = login_admin(&app).await; diff --git a/gateway-rs/tests/platform_native.rs b/gateway-rs/tests/platform_native.rs index 65a0bab1..5d117a27 100644 --- a/gateway-rs/tests/platform_native.rs +++ b/gateway-rs/tests/platform_native.rs @@ -2060,6 +2060,27 @@ async fn authorization_refresh_and_invalidate_match_python() { Some(json!({})), ) .await; + let invalidate_cookies = invalidate + .headers() + .get_all(header::SET_COOKIE) + .iter() + .map(|value| value.to_str().unwrap().to_owned()) + .collect::>(); + // Python's authorization_invalidate clears both the primary and dev cookie + // names with Max-Age=0. + assert!( + invalidate_cookies.iter().any( + |cookie| cookie.starts_with("access_token_cookie=") && cookie.contains("Max-Age=0") + ), + "{invalidate_cookies:?}" + ); + assert!( + invalidate_cookies + .iter() + .any(|cookie| cookie.starts_with("access_token_cookie_dev=") + && cookie.contains("Max-Age=0")), + "{invalidate_cookies:?}" + ); assert_eq!(invalidate.status(), StatusCode::OK); assert_eq!( response_json(invalidate).await, @@ -3735,7 +3756,9 @@ async fn proto_upload_ignores_the_client_filename_like_python() { #[tokio::test] async fn proto_upload_extension_acceptance_matches_python_contract() { - let app = build_router(memory_state(false).await); + let state = memory_state(false).await; + let storage = state.storage.clone().unwrap(); + let app = build_router(state); let (cookie, _) = login(&app).await; let boundary = "doorman-proto-extension-boundary"; let multipart = |filename: &str, content_type: &str, content: &str| { @@ -3794,6 +3817,15 @@ async fn proto_upload_extension_acceptance_matches_python_contract() { .to_ascii_lowercase() .starts_with("proto file uploaded") ); + let pending = storage + .find_one( + "grpc_proto_uploads", + &json!({"api_name": "sample", "api_version": "v1"}), + ) + .await + .unwrap() + .unwrap(); + assert_eq!(pending["api_grpc_package"], "sample_v1"); let updated = app .clone() @@ -3876,6 +3908,53 @@ async fn proto_upload_extension_acceptance_matches_python_contract() { } } +#[tokio::test] +async fn proto_content_validation_errors_match_python() { + let app = build_router(memory_state(false).await); + let (cookie, _) = login(&app).await; + let cases = [ + ( + "missing", + b"edition = 2023;".to_vec(), + "Invalid proto file: Invalid proto file: missing proto syntax (syntax/message/service)", + ), + ( + "binary", + b"syntax = \"proto3\";\0".to_vec(), + "Invalid proto file: Invalid proto file: binary content detected", + ), + ( + "utf8", + vec![b's', b'y', b'n', b't', b'a', b'x', 0xff], + "Invalid proto file: Invalid proto file: not valid UTF-8", + ), + ( + "suspicious", + b"syntax = \"proto3\"; curl example.test".to_vec(), + "Invalid proto file: Invalid proto file: suspicious content detected", + ), + ]; + for (name, content, expected) in cases { + let response = app + .clone() + .oneshot( + Request::builder() + .method(Method::POST) + .uri(format!("/platform/proto/{name}/v1")) + .header(header::COOKIE, &cookie) + .header(header::CONTENT_TYPE, "text/plain") + .body(Body::from(content)) + .unwrap(), + ) + .await + .unwrap(); + assert_eq!(response.status(), StatusCode::BAD_REQUEST, "{name}"); + let body = response_json(response).await; + assert_eq!(body["error_code"], "REQ003", "{name}"); + assert_eq!(body["error_message"], expected, "{name}"); + } +} + #[tokio::test] async fn api_creation_attaches_proto_uploaded_before_the_api() { let app = build_router(memory_state(false).await); @@ -3960,6 +4039,36 @@ async fn descriptor_backfill_compiles_active_grpc_apis_missing_descriptors() { ) .await .unwrap(); + storage + .insert_one( + "apis", + json!({ + "api_name": "source-only", "api_version": "v1", "active": true, + "api_grpc_proto_source": "syntax = \"proto3\"; message SourceOnly {}" + }), + ) + .await + .unwrap(); + storage + .insert_one( + "apis", + json!({ + "api_name": "package-only", "api_version": "v1", "active": true, + "api_grpc_package": "package_only" + }), + ) + .await + .unwrap(); + storage + .insert_one( + "apis", + json!({ + "api_version": "v1", "active": true, + "api_grpc_proto_source": "syntax = \"proto3\"; message MissingName {}" + }), + ) + .await + .unwrap(); let app = build_router(state); let (cookie, _) = login(&app).await; let response = platform_request( @@ -3973,10 +4082,14 @@ async fn descriptor_backfill_compiles_active_grpc_apis_missing_descriptors() { .await; assert_eq!(response.status(), StatusCode::OK); let result = response_json(response).await; - assert_eq!(result["scanned"], 2); - assert_eq!(result["updated"], 1); + assert_eq!(result["scanned"], 5); + assert_eq!(result["updated"], 2); assert_eq!(result["skipped"], 1); - assert_eq!(result["missing"], 0); + assert_eq!(result["missing"], 2); + assert_eq!(result["errors"][0]["api"], "package-only/v1"); + assert_eq!(result["errors"][0]["error"], "Proto source not found"); + assert_eq!(result["errors"][1]["api"], "/v1"); + assert_eq!(result["errors"][1]["error"], "API name/version is missing"); let orders = storage .find_one("apis", &json!({"api_name": "orders", "api_version": "v1"})) .await @@ -4712,9 +4825,10 @@ async fn management_permissions_readiness_tools_and_restart_preserve_contract() let admin_readiness: Value = serde_json::from_slice(&to_bytes(admin_readiness.into_body(), 4096).await.unwrap()) .unwrap(); - assert_eq!(admin_readiness.as_object().unwrap().len(), 7); + assert_eq!(admin_readiness.as_object().unwrap().len(), 8); assert!(admin_readiness.get("mongodb").is_some()); assert!(admin_readiness.get("cache_backend").is_some()); + assert!(admin_readiness.get("tls_certificates_valid").is_some()); for (method, path, code) in [ ("GET", "/platform/security/settings", "SEC001"), @@ -5962,6 +6076,38 @@ async fn python_endpoint_failure_and_validation_crud_contracts() { "validation_schema": schema, "ignored": "field" }); + let missing_endpoint = platform_request( + &app, + Method::POST, + "/platform/endpoint/validation", + Some(&cookie), + None, + Some(json!({ + "endpoint_id": "missing-endpoint", + "validation_enabled": true, + "validation_schema": validation["validation_schema"].clone() + })), + ) + .await; + assert_eq!(missing_endpoint.status(), StatusCode::BAD_REQUEST); + assert_eq!( + response_json(missing_endpoint).await["error_code"], + "END015" + ); + let missing_validation = platform_request( + &app, + Method::GET, + "/platform/endpoint/validation/missing-endpoint", + Some(&cookie), + None, + None, + ) + .await; + assert_eq!(missing_validation.status(), StatusCode::BAD_REQUEST); + assert_eq!( + response_json(missing_validation).await["error_code"], + "END018" + ); let created = platform_request( &app, Method::POST, @@ -5972,6 +6118,17 @@ async fn python_endpoint_failure_and_validation_crud_contracts() { ) .await; assert!(created.status().is_success()); + let duplicate = platform_request( + &app, + Method::POST, + "/platform/endpoint/validation", + Some(&cookie), + None, + Some(validation.clone()), + ) + .await; + assert_eq!(duplicate.status(), StatusCode::BAD_REQUEST); + assert_eq!(response_json(duplicate).await["error_code"], "END017"); let fetched = platform_request( &app, Method::GET, @@ -6001,6 +6158,37 @@ async fn python_endpoint_failure_and_validation_crud_contracts() { ) .await; assert_eq!(updated.status(), StatusCode::OK); + let disabled = platform_request( + &app, + Method::PUT, + &format!("/platform/endpoint/validation/{endpoint_id}"), + Some(&cookie), + None, + Some(json!({ + "validation_enabled": false, + "validation_schema": validation["validation_schema"].clone() + })), + ) + .await; + assert_eq!(disabled.status(), StatusCode::BAD_REQUEST); + assert_eq!(response_json(disabled).await["error_code"], "END020"); + let missing_endpoint_update = platform_request( + &app, + Method::PUT, + "/platform/endpoint/validation/missing-endpoint", + Some(&cookie), + None, + Some(json!({ + "validation_enabled": true, + "validation_schema": validation["validation_schema"].clone() + })), + ) + .await; + assert_eq!(missing_endpoint_update.status(), StatusCode::BAD_REQUEST); + assert_eq!( + response_json(missing_endpoint_update).await["error_code"], + "END022" + ); let invalid = platform_request( &app, Method::PUT, @@ -6021,6 +6209,16 @@ async fn python_endpoint_failure_and_validation_crud_contracts() { ) .await; assert_eq!(deleted.status(), StatusCode::OK); + let deleted_again = platform_request( + &app, + Method::DELETE, + &format!("/platform/endpoint/validation/{endpoint_id}"), + Some(&cookie), + None, + None, + ) + .await; + assert_eq!(deleted_again.status(), StatusCode::OK); } #[tokio::test] async fn python_config_export_sections_and_import_variants() { @@ -6310,6 +6508,51 @@ async fn python_config_import_ignores_malformed_entries() { "{collection}" ); } + let snapshots = storage + .find_many("config_snapshots", &json!({})) + .await + .unwrap(); + assert_eq!(snapshots.len(), 1); + assert_eq!(snapshots[0]["created_by"], "admin"); + assert!(snapshots[0]["timestamp"].as_str().unwrap().contains(' ')); + assert!(snapshots[0].get("created_at").is_none()); + + let falsy_sections = platform_request( + &app, + Method::POST, + "/platform/config/import", + Some(&cookie), + None, + Some(json!({ + "apis": "", "endpoints": [], "roles": {}, "groups": false, "routings": 0 + })), + ) + .await; + assert_eq!(falsy_sections.status(), StatusCode::OK); + assert_eq!( + response_json(falsy_sections).await["imported"], + json!({"apis": 0, "endpoints": 0, "roles": 0, "groups": 0, "routings": 0}) + ); + + let truthy_non_list = platform_request( + &app, + Method::POST, + "/platform/config/import", + Some(&cookie), + None, + Some(json!({"apis": "invalid"})), + ) + .await; + assert_eq!(truthy_non_list.status(), StatusCode::INTERNAL_SERVER_ERROR); + assert_eq!(response_json(truthy_non_list).await["error_code"], "GTW999"); + assert_eq!( + storage + .find_many("config_snapshots", &json!({})) + .await + .unwrap() + .len(), + 3 + ); } #[tokio::test] @@ -6493,6 +6736,141 @@ async fn python_credit_definition_masks_secret_key_material() { assert_eq!(response_json(missing).await["error_code"], "CRD021"); } +#[tokio::test] +async fn tls_bindings_can_be_cleared_without_changing_other_api_fields() { + let state = memory_state(false).await; + let storage = state.storage.as_ref().unwrap().clone(); + storage.insert_one("apis", json!({ + "api_name": "mtls-clear", "api_version": "v1", "api_description": "keep", + "api_client_tls_policy": {"mode": "required", "ca_profile_id": "retired", "allowed_dns_sans": ["client.example"]}, + "api_upstream_tls_profile": "retired" + })).await.unwrap(); + storage.insert_one("endpoints", json!({ + "api_name": "mtls-clear", "api_version": "v1", "endpoint_method": "GET", + "endpoint_uri": "/probe", "endpoint_description": "keep", + "endpoint_client_tls_policy": {"mode": "off"}, + "endpoint_upstream_tls_profile": "retired" + })).await.unwrap(); + let app = build_router(state); + let (cookie, _) = login(&app).await; + + let api = platform_request(&app, Method::PUT, "/platform/api/mtls-clear/v1", Some(&cookie), None, + Some(json!({"api_client_tls_policy": null, "api_upstream_tls_profile": null}))).await; + assert_eq!(api.status(), StatusCode::OK); + let endpoint = platform_request(&app, Method::PUT, "/platform/endpoint/GET/mtls-clear/v1/probe", Some(&cookie), None, + Some(json!({"endpoint_client_tls_policy": null, "endpoint_upstream_tls_profile": null}))).await; + assert_eq!(endpoint.status(), StatusCode::OK); + + let api = storage.find_one("apis", &json!({"api_name": "mtls-clear", "api_version": "v1"})).await.unwrap().unwrap(); + let endpoint = storage.find_one("endpoints", &json!({"api_name": "mtls-clear", "api_version": "v1", "endpoint_method": "GET", "endpoint_uri": "/probe"})).await.unwrap().unwrap(); + assert!(api["api_client_tls_policy"].is_null()); + assert!(api["api_upstream_tls_profile"].is_null()); + assert_eq!(api["api_description"], "keep"); + assert!(endpoint["endpoint_client_tls_policy"].is_null()); + assert!(endpoint["endpoint_upstream_tls_profile"].is_null()); + assert_eq!(endpoint["endpoint_description"], "keep"); +} + +#[tokio::test] +async fn credit_rotation_expiry_matches_pydantic_datetime_validation() { + let state = memory_state(false).await; + let storage = state.storage.as_ref().unwrap().clone(); + let app = build_router(state); + let (cookie, _) = login(&app).await; + let credit = |expires: Value| { + json!({ + "api_credit_group": "expiry", "api_key": "key", "api_key_header": "x-api-key", + "credit_tiers": [{ + "tier_name": "default", "credits": 1, "input_limit": 0, + "output_limit": 0, "reset_frequency": "monthly" + }], + "api_key_rotation_expires": expires + }) + }; + + let invalid_create = platform_request( + &app, + Method::POST, + "/platform/credit", + Some(&cookie), + None, + Some(credit(json!("not a datetime"))), + ) + .await; + assert_eq!(invalid_create.status(), StatusCode::UNPROCESSABLE_ENTITY); + + let create = platform_request( + &app, + Method::POST, + "/platform/credit", + Some(&cookie), + None, + Some(credit(json!("2025-01-15T10:00:00Z"))), + ) + .await; + assert_eq!(create.status(), StatusCode::CREATED); + let stored = storage + .find_one("credit_defs", &json!({"api_credit_group": "expiry"})) + .await + .unwrap() + .unwrap(); + assert_eq!( + stored["api_key_rotation_expires"], + "2025-01-15T10:00:00+00:00" + ); + + let invalid_update = platform_request( + &app, + Method::PUT, + "/platform/credit/expiry", + Some(&cookie), + None, + Some(credit(json!("2025-99-99T10:00:00Z"))), + ) + .await; + assert_eq!(invalid_update.status(), StatusCode::UNPROCESSABLE_ENTITY); + let stored = storage + .find_one("credit_defs", &json!({"api_credit_group": "expiry"})) + .await + .unwrap() + .unwrap(); + assert_eq!( + stored["api_key_rotation_expires"], + "2025-01-15T10:00:00+00:00" + ); + + let update = platform_request( + &app, + Method::PUT, + "/platform/credit/expiry", + Some(&cookie), + None, + Some(credit(json!(1_700_000_000))), + ) + .await; + assert_eq!(update.status(), StatusCode::OK); + let stored = storage + .find_one("credit_defs", &json!({"api_credit_group": "expiry"})) + .await + .unwrap() + .unwrap(); + assert_eq!( + stored["api_key_rotation_expires"], + "2023-11-14T22:13:20+00:00" + ); + + let numeric_string = platform_request( + &app, + Method::PUT, + "/platform/credit/expiry", + Some(&cookie), + None, + Some(credit(json!(" 1700000000 "))), + ) + .await; + assert_eq!(numeric_string.status(), StatusCode::OK); +} + #[tokio::test] async fn credit_models_match_pydantic_required_fields_coercion_and_unknown_elision() { let state = memory_state(false).await; @@ -6722,6 +7100,17 @@ async fn quota_status_uses_nested_effective_limits_and_tracker_usage() { response_json(no_limits).await["detail"], "No limits found for user" ); + let history = platform_request( + &no_tier_app, + Method::GET, + "/platform/quota/usage/history", + Some(&no_tier_cookie), + None, + None, + ) + .await; + assert_eq!(history.status(), StatusCode::OK); + assert_eq!(response_json(history).await["history"], json!([])); storage .insert_one( "tiers", @@ -6737,6 +7126,16 @@ async fn quota_status_uses_nested_effective_limits_and_tracker_usage() { ) .await .unwrap(); + storage + .insert_one( + "tiers", + json!({ + "tier_id": "quota-legacy", "name": "custom", "display_name": "Legacy", + "limits": {"monthly_request_quota": 1} + }), + ) + .await + .unwrap(); storage .insert_one( "tiers", @@ -6856,6 +7255,22 @@ async fn quota_status_uses_nested_effective_limits_and_tracker_usage() { .contains("monthly_bandwidth") ); + let json_export = platform_request( + &app, + Method::POST, + "/platform/quota/usage/export", + Some(&cookie), + None, + None, + ) + .await; + assert_eq!(json_export.status(), StatusCode::OK); + let json_export = response_json(json_export).await; + assert_eq!(json_export["format"], "json"); + let export_date = json_export["data"]["export_date"].as_str().unwrap(); + assert!(export_date.contains('T')); + assert!(!export_date.ends_with('Z')); + let tier_info = platform_request( &app, Method::GET, @@ -6869,6 +7284,7 @@ async fn quota_status_uses_nested_effective_limits_and_tracker_usage() { let tier_info = response_json(tier_info).await; assert_eq!(tier_info["current_tier"]["display_name"], "Quota Pro"); assert_eq!(tier_info["upgrade_options"][0]["tier_id"], "quota-free"); + assert_eq!(tier_info["upgrade_options"].as_array().unwrap().len(), 1); let burst = platform_request( &app, @@ -7062,13 +7478,21 @@ async fn tier_assignment_create_returns_python_assignment_contract() { "/platform/tiers/compare", Some(&cookie), None, - Some(json!(["assignment-pro", "missing-tier"])), + Some(json!([ + "assignment-pro", + "assignment-default", + "assignment-pro", + "missing-tier" + ])), ) .await; assert_eq!(comparison.status(), StatusCode::OK); let comparison = response_json(comparison).await; assert!(comparison.is_array()); assert_eq!(comparison[0]["tier_id"], "assignment-pro"); + assert_eq!(comparison[1]["tier_id"], "assignment-default"); + assert_eq!(comparison[2]["tier_id"], "assignment-pro"); + assert_eq!(comparison.as_array().unwrap().len(), 3); assert!(comparison[0].get("enabled").is_none()); let removed = platform_request( @@ -7099,6 +7523,21 @@ async fn tier_assignment_create_returns_python_assignment_contract() { response_json(absent).await["detail"], "No assignment found for user assignment-user" ); + + let absent = platform_request( + &app, + Method::GET, + "/platform/tiers/assignments/assignment-user", + Some(&cookie), + None, + None, + ) + .await; + assert_eq!(absent.status(), StatusCode::NOT_FOUND); + assert_eq!( + response_json(absent).await["detail"], + "No assignment found for user assignment-user" + ); } #[tokio::test] @@ -7265,6 +7704,19 @@ async fn tier_users_and_statistics_match_python_shapes() { assert_eq!(users.as_array().unwrap().len(), 1); assert_eq!(users[0]["user_id"], "stats-future"); + for query in ["skip=-1", "limit=0", "limit=1001", "limit=invalid"] { + let invalid = platform_request( + &app, + Method::GET, + &format!("/platform/tiers/stats-pro/users?{query}"), + Some(&cookie), + None, + None, + ) + .await; + assert_eq!(invalid.status(), StatusCode::UNPROCESSABLE_ENTITY); + } + let tier_stats = platform_request( &app, Method::GET, @@ -7405,6 +7857,43 @@ async fn tier_crud_returns_normalized_python_tier_contracts() { assert_eq!(created["enabled"], true); assert!(created["created_at"].as_str().unwrap().contains('T')); + // TierName construction happens inside the Python handler's broad + // exception fallback. Pydantic has already coerced the other scalars, and + // the fallback response is returned without persisting the invalid tier. + let fallback = platform_request( + &app, + Method::POST, + "/platform/tiers/", + Some(&cookie), + None, + Some(json!({ + "tier_id": 99, "name": "future-plan", "display_name": true, + "limits": {"requests_per_minute": "25", "enable_throttling": "yes"}, + "features": [1, false], "enabled": "off", "ignored": "field" + })), + ) + .await; + assert_eq!(fallback.status(), StatusCode::CREATED); + let fallback = response_json(fallback).await; + assert_eq!(fallback["tier_id"], "99"); + assert_eq!(fallback["display_name"], "True"); + assert_eq!(fallback["limits"]["requests_per_minute"], 25); + assert_eq!(fallback["limits"]["enable_throttling"], true); + assert_eq!(fallback["features"], json!(["1", "False"])); + assert_eq!(fallback["enabled"], false); + assert!(fallback["created_at"].is_null()); + + let not_persisted = platform_request( + &app, + Method::GET, + "/platform/tiers/99", + Some(&cookie), + None, + None, + ) + .await; + assert_eq!(not_persisted.status(), StatusCode::NOT_FOUND); + let duplicate = platform_request( &app, Method::POST, @@ -7437,7 +7926,7 @@ async fn tier_crud_returns_normalized_python_tier_contracts() { let listed = platform_request( &app, Method::GET, - "/platform/tiers/?enabled_only=true&skip=0&limit=1", + "/platform/tiers/?enabled_only=YES&skip=0&limit=1", Some(&cookie), None, None, @@ -7698,6 +8187,32 @@ async fn rate_limit_bulk_routes_preserve_pinned_python_failures() { response_json(deleted).await["detail"], "Failed to delete rules" ); + + let empty = platform_request( + &app, + Method::POST, + "/platform/rate-limits/bulk/delete", + None, + None, + Some(json!({"rule_ids": []})), + ) + .await; + assert_eq!(empty.status(), StatusCode::OK); + assert_eq!(response_json(empty).await["deleted_count"], 0); + + for body in [json!({}), json!({"rule_ids": "bulk-rule"})] { + let invalid = platform_request( + &app, + Method::POST, + "/platform/rate-limits/bulk/delete", + None, + None, + Some(body), + ) + .await; + assert_eq!(invalid.status(), StatusCode::UNPROCESSABLE_ENTITY); + assert_eq!(response_json(invalid).await["error_code"], "VAL001"); + } } #[tokio::test] @@ -7917,6 +8432,18 @@ async fn rate_limit_crud_and_action_envelopes_match_python() { assert_eq!(numeric_copy.status(), StatusCode::CREATED); assert_eq!(response_json(numeric_copy).await["rule_id"], "456"); + let empty_copy = platform_request( + &app, + Method::POST, + "/platform/rate-limits/crud-rule/duplicate", + None, + None, + Some(json!({"new_rule_id": ""})), + ) + .await; + assert_eq!(empty_copy.status(), StatusCode::CREATED); + assert_eq!(response_json(empty_copy).await["rule_id"], ""); + let missing_copy = platform_request( &app, Method::POST, @@ -8094,3 +8621,208 @@ async fn rate_limit_management_is_public_and_uses_python_priority_search_contrac "Rule status not found" ); } + +#[tokio::test] +async fn monitor_report_validates_dates_and_generates_a_python_shaped_csv() { + let app = build_router(memory_state(false).await); + let (cookie, _) = login(&app).await; + + let bad_format = platform_request( + &app, + Method::GET, + "/platform/monitor/report?start=not-a-date&end=2024-01-02", + Some(&cookie), + None, + None, + ) + .await; + assert_eq!(bad_format.status(), StatusCode::BAD_REQUEST); + assert_eq!(response_json(bad_format).await["error_code"], "MON003"); + + let backwards = platform_request( + &app, + Method::GET, + "/platform/monitor/report?start=2024-01-05&end=2024-01-01", + Some(&cookie), + None, + None, + ) + .await; + assert_eq!(backwards.status(), StatusCode::BAD_REQUEST); + assert_eq!( + response_json(backwards).await["error_message"], + "End date must be after start date" + ); + + let ok = platform_request( + &app, + Method::GET, + "/platform/monitor/report?start=2024-01-01&end=2024-01-02", + Some(&cookie), + None, + None, + ) + .await; + assert_eq!(ok.status(), StatusCode::OK); + assert_eq!( + ok.headers().get(header::CONTENT_TYPE).unwrap(), + "text/csv; charset=utf-8" + ); + assert_eq!( + ok.headers().get(header::CONTENT_DISPOSITION).unwrap(), + "attachment; filename=doorman_report_2024-01-01_to_2024-01-02.csv" + ); + let body = + String::from_utf8(to_bytes(ok.into_body(), 64 * 1024).await.unwrap().to_vec()).unwrap(); + assert!(body.starts_with("Report,From,2024-01-01,To,2024-01-02\nOverview\n")); + for section in [ + "Bandwidth Overview\n", + "Status Codes\nstatus,count\n", + "API Usage\napi,total,errors,successes,success_rate\n", + "User Usage\nusername,requests\n", + "Bandwidth (per day, UTC)\ndate,bytes_in,bytes_out,total\n", + ] { + assert!( + body.contains(section), + "missing section {section:?} in:\n{body}" + ); + } +} + +#[tokio::test] +async fn non_numeric_role_page_returns_fastapi_shaped_422_not_a_silent_default() { + // Python's `get_roles(page: int = ..., page_size: int = ...)` are typed + // FastAPI query params: a non-numeric value never reaches the handler and + // instead produces FastAPI's own 422 validation body, rather than being + // silently coerced to page=1 the way Rust's role listing used to. + let app = build_router(memory_state(false).await); + let (cookie, _) = login(&app).await; + + let response = platform_request( + &app, + Method::GET, + "/platform/role?page=not-a-number", + Some(&cookie), + None, + None, + ) + .await; + assert_eq!(response.status(), StatusCode::UNPROCESSABLE_ENTITY); + let body = response_json(response).await; + assert_eq!(body["detail"][0]["loc"], json!(["query", "page"])); + assert_eq!(body["detail"][0]["type"], "type_error.integer"); + + let response = platform_request( + &app, + Method::GET, + "/platform/role/all?page_size=not-a-number", + Some(&cookie), + None, + None, + ) + .await; + assert_eq!(response.status(), StatusCode::UNPROCESSABLE_ENTITY); + let body = response_json(response).await; + assert_eq!(body["detail"][0]["loc"], json!(["query", "page_size"])); +} + +#[tokio::test] +async fn non_numeric_page_returns_422_across_typed_fastapi_listing_routes() { + // The same typed `page: int`/`page_size: int` FastAPI parameter pattern + // covers get_groups, get_routings, get_apis, get_users, and the credit + // listing routes, not just get_roles. + let app = build_router(memory_state(false).await); + let (cookie, _) = login(&app).await; + let request = + |path: &'static str| platform_request(&app, Method::GET, path, Some(&cookie), None, None); + + for path in [ + "/platform/group?page=nope", + "/platform/routing?page=nope", + "/platform/api?page=nope", + "/platform/api/all?page_size=nope", + "/platform/user?page=nope", + "/platform/user/all?page_size=nope", + "/platform/credit/defs?page=nope", + "/platform/credit/all?page_size=nope", + ] { + let response = request(path).await; + assert_eq!( + response.status(), + StatusCode::UNPROCESSABLE_ENTITY, + "{path}" + ); + let body = response_json(response).await; + assert_eq!(body["detail"][0]["type"], "type_error.integer", "{path}"); + } +} + +#[tokio::test] +async fn demo_seed_uses_the_configurable_seeder_with_admin_check_and_python_defaults() { + let app = build_router(memory_state(false).await); + let (cookie, _) = login(&app).await; + + // A small, explicit request exercises the real configurable seeder + // (SeedOptions/run_seed) rather than the old hardcoded 3-API stub. + let response = platform_request( + &app, + Method::POST, + "/platform/demo/seed?users=2&apis=1&endpoints=1&groups=1&protos=0&logs=0&seed=7", + Some(&cookie), + None, + None, + ) + .await; + assert_eq!(response.status(), StatusCode::OK); + let body = response_json(response).await; + assert_eq!(body["message"], "Seed completed"); + // The comprehensive seeder reports per-collection counts; the old stub + // only ever returned a flat "message" body with no such detail. + assert!( + body.as_object().is_some_and(|object| object.len() > 1), + "expected seed result fields alongside message: {body:?}" + ); +} + +#[tokio::test] +async fn demo_seed_denies_non_admin_with_pythons_error_code_and_message() { + let state = memory_state(false).await; + let storage = state.storage.clone().unwrap(); + storage + .insert_one( + "roles", + json!({"role_name": "viewer", "manage_gateway": false}), + ) + .await + .unwrap(); + storage + .insert_one( + "users", + json!({ + "username": "demo-viewer", + "email": "demo-viewer@doorman.dev", + "password": bcrypt::hash(fixture_password(), bcrypt::DEFAULT_COST).unwrap(), + "role": "viewer", + "groups": [], + "active": true + }), + ) + .await + .unwrap(); + let app = build_router(state); + let (viewer, _) = login_as(&app, "demo-viewer@doorman.dev", fixture_password()).await; + + let response = platform_request( + &app, + Method::POST, + "/platform/demo/seed", + Some(&viewer), + None, + None, + ) + .await; + assert_eq!(response.status(), StatusCode::FORBIDDEN); + let body = response_json(response).await; + assert_eq!(body["error_code"], "DEMO001"); + assert_eq!(body["error_message"], "Permission denied to run seeder"); +} diff --git a/gateway-rs/tests/roles_groups_parity.rs b/gateway-rs/tests/roles_groups_parity.rs index 2d2d7321..c4de524f 100644 --- a/gateway-rs/tests/roles_groups_parity.rs +++ b/gateway-rs/tests/roles_groups_parity.rs @@ -215,7 +215,7 @@ async fn live_role_permission_matrix_blocks_then_allows_each_management_operatio "/platform/endpoint", Some(&admin), Some(json!({ - "api_name": "legacy-open-management", "api_version": "v1", + "api_name": "permission-matrix-api", "api_version": "v1", "endpoint_method": "GET", "endpoint_uri": "/visible", "endpoint_description": "pinned Python authorization boundary" })), @@ -338,6 +338,19 @@ async fn least_privilege_role_cannot_create_apis_or_read_logs() { ) .await; assert_eq!(api.status(), StatusCode::CREATED); + let endpoint = request( + &app, + Method::POST, + "/platform/endpoint", + Some(&admin), + Some(json!({ + "api_name": "legacy-open-management", "api_version": "v1", + "endpoint_method": "GET", "endpoint_uri": "/visible", + "endpoint_description": "pinned Python authorization boundary" + })), + ) + .await; + assert_eq!(endpoint.status(), StatusCode::CREATED); let create_api = request( &app, Method::POST, diff --git a/gateway-rs/tests/runtime.rs b/gateway-rs/tests/runtime.rs index e0a31d1d..07feab91 100644 --- a/gateway-rs/tests/runtime.rs +++ b/gateway-rs/tests/runtime.rs @@ -8,6 +8,7 @@ use doorman_gateway::storage::models::PolicyDocuments; use doorman_gateway::{AppState, Config, build_router}; use http::{Request, StatusCode, header}; use serde_json::{Value, json}; +use std::sync::atomic::Ordering; use tower::ServiceExt; #[tokio::test] @@ -33,6 +34,47 @@ async fn rust_health_matches_public_contract() { ); } +#[tokio::test] +async fn disabled_logs_leave_request_metrics_running_without_creating_log_files() { + let logs_dir = + std::env::temp_dir().join(format!("doorman-disabled-logs-{}", uuid::Uuid::new_v4())); + let mut config = Config::for_test("http://127.0.0.1:9".to_owned()); + config.logs_enabled = false; + config.logs_dir = Some(logs_dir.clone()); + let state = AppState::new(config).unwrap(); + let runtime = state.runtime.clone(); + let app = build_router(state); + + let features = app + .clone() + .oneshot( + Request::builder() + .uri("/api/features") + .body(Body::empty()) + .unwrap(), + ) + .await + .unwrap(); + assert_eq!(features.status(), StatusCode::OK); + assert_eq!( + to_bytes(features.into_body(), 1024).await.unwrap(), + r#"{"logs_enabled":false}"# + ); + + let health = app + .oneshot( + Request::builder() + .uri("/api/health") + .body(Body::empty()) + .unwrap(), + ) + .await + .unwrap(); + assert_eq!(health.status(), StatusCode::OK); + assert!(runtime.request_total.load(Ordering::Relaxed) >= 2); + assert!(!logs_dir.exists(), "disabled logging created {logs_dir:?}"); +} + #[tokio::test] async fn platform_routes_are_native_and_never_use_an_internal_backend() { let (upstream_url, server) = diff --git a/parity/differential/operation_approvals.json b/parity/differential/operation_approvals.json index 0967ef42..ec953fee 100644 --- a/parity/differential/operation_approvals.json +++ b/parity/differential/operation_approvals.json @@ -1 +1,13 @@ -{} +{ + "operation:DELETE:/api/rest/{path}": "MIG-090: Python's api_util.get_api does `api_name, api_version = api_name_version.split('/')` on a single-segment {path} with no '/', raising an uncaught ValueError (confirmed via live traceback against the pinned reference) that its broad except handler turns into a 500. Rust validates the shape defensively and returns 404 for the same unmatched request instead of reproducing the crash.", + "operation:GET:/api/rest/{path}": "MIG-090: same api_util.get_api ValueError crash as the other /api/rest/{path} methods; Rust returns 404 instead of reproducing Python's 500.", + "operation:HEAD:/api/rest/{path}": "MIG-090: same api_util.get_api ValueError crash as the other /api/rest/{path} methods; Rust returns 404 instead of reproducing Python's 500.", + "operation:PATCH:/api/rest/{path}": "MIG-090: same api_util.get_api ValueError crash as the other /api/rest/{path} methods; Rust returns 404 instead of reproducing Python's 500.", + "operation:POST:/api/rest/{path}": "MIG-090: same api_util.get_api ValueError crash as the other /api/rest/{path} methods; Rust returns 404 instead of reproducing Python's 500.", + "operation:PUT:/api/rest/{path}": "MIG-090: same api_util.get_api ValueError crash as the other /api/rest/{path} methods; Rust returns 404 instead of reproducing Python's 500.", + "operation:GET:/api/soap/{path}": "MIG-090: the SOAP gateway hits the same api_util.get_api split('/') ValueError crash as the REST gateway for a single-segment {path}; Rust returns 404 instead of reproducing Python's 500.", + "operation:POST:/api/soap/{path}": "MIG-090: the SOAP gateway hits the same api_util.get_api split('/') ValueError crash as the REST gateway for a single-segment {path}; Rust returns 404 instead of reproducing Python's 500.", + "operation:POST:/grpc-web/{api_name}/{service}/{method}": "MIG-091: with no body/Content-Type sent, Python's grpc-web handler rejects with 415 'Invalid Content-Type' before ever resolving the synthetic api name; Rust's gateway resolves routing first and 404s because no upstream is configured for the probe's synthetic api name. Both are reasonable rejections of an unusable probe request; there is no real behavioral gap for a well-formed gRPC-Web call.", + "operation:POST:/platform/demo/seed": "MIG-092: confirmed via live traceback that the pinned Python's own utils/demo_seed_util.py has a genuine bug -- seed_metrics calls MinuteBucket.add(dur, status) but the method requires username/api_key too, raising TypeError on every default-parameter seed call, caught by the route's broad except and turned into a 500. Rust's from-scratch seeder has no such bug and succeeds with 200.", + "operation:POST:/platform/openapi/parse": "MIG-093: Python's handler calls `await request.json()` with no guard around a body-less request, so a request with no body at all raises JSONDecodeError, caught by the route's broad except and turned into a 500; an explicit `{}` body returns 200 with an identical response body on both servers (verified live). Rust treats a missing body the same as an empty object and returns 200, matching Python's actual (non-crashing) behavior for every real request shape." +} diff --git a/parity/source_coverage_ledger.json b/parity/source_coverage_ledger.json index 7205f318..68c5a384 100644 --- a/parity/source_coverage_ledger.json +++ b/parity/source_coverage_ledger.json @@ -4,7 +4,8 @@ "decorators": [], "domain": "application", "id": "backend-services/doorman.py::module:doorman", - "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command.", + "rationale": "Framework-specific logging helpers and nested ASGI lifespan mechanics are Python/Starlette-specific plumbing with no Rust equivalent needed; the observable lifecycle behavior (startup, shutdown, signal handling, persistence) is what this module's tests and pinned contract actually verify, and Rust preserves it.", "rust_symbols": [ "gateway-rs/src/main.rs", "gateway-rs/src/app.rs", @@ -19,7 +20,7 @@ "line": 1, "path": "backend-services/doorman.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], @@ -79,7 +80,8 @@ ], "domain": "application", "id": "backend-services/doorman.py::async_function:app_lifespan", - "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command.", + "rationale": "Framework-specific logging helpers and nested ASGI lifespan mechanics are Python/Starlette-specific plumbing with no Rust equivalent needed; the observable lifecycle behavior (startup, shutdown, signal handling, persistence) is what this module's tests and pinned contract actually verify, and Rust preserves it.", "rust_symbols": [ "gateway-rs/src/main.rs", "gateway-rs/src/app.rs", @@ -94,13 +96,14 @@ "line": 266, "path": "backend-services/doorman.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "application", "id": "backend-services/doorman.py::async_function:app_lifespan._metrics_autosave", - "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command.", + "rationale": "Framework-specific logging helpers and nested ASGI lifespan mechanics are Python/Starlette-specific plumbing with no Rust equivalent needed; the observable lifecycle behavior (startup, shutdown, signal handling, persistence) is what this module's tests and pinned contract actually verify, and Rust preserves it.", "rust_symbols": [ "gateway-rs/src/main.rs", "gateway-rs/src/app.rs", @@ -115,13 +118,14 @@ "line": 379, "path": "backend-services/doorman.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "application", "id": "backend-services/doorman.py::function:app_lifespan._int_env", - "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command.", + "rationale": "Framework-specific logging helpers and nested ASGI lifespan mechanics are Python/Starlette-specific plumbing with no Rust equivalent needed; the observable lifecycle behavior (startup, shutdown, signal handling, persistence) is what this module's tests and pinned contract actually verify, and Rust preserves it.", "rust_symbols": [ "gateway-rs/src/main.rs", "gateway-rs/src/app.rs", @@ -136,13 +140,14 @@ "line": 471, "path": "backend-services/doorman.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "application", "id": "backend-services/doorman.py::async_function:app_lifespan._perform_dump", - "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command.", + "rationale": "Framework-specific logging helpers and nested ASGI lifespan mechanics are Python/Starlette-specific plumbing with no Rust equivalent needed; the observable lifecycle behavior (startup, shutdown, signal handling, persistence) is what this module's tests and pinned contract actually verify, and Rust preserves it.", "rust_symbols": [ "gateway-rs/src/main.rs", "gateway-rs/src/app.rs", @@ -157,13 +162,14 @@ "line": 505, "path": "backend-services/doorman.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "application", "id": "backend-services/doorman.py::function:app_lifespan._register_forwarding_signal", - "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command.", + "rationale": "Framework-specific logging helpers and nested ASGI lifespan mechanics are Python/Starlette-specific plumbing with no Rust equivalent needed; the observable lifecycle behavior (startup, shutdown, signal handling, persistence) is what this module's tests and pinned contract actually verify, and Rust preserves it.", "rust_symbols": [ "gateway-rs/src/main.rs", "gateway-rs/src/app.rs", @@ -178,13 +184,14 @@ "line": 539, "path": "backend-services/doorman.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "application", "id": "backend-services/doorman.py::async_function:app_lifespan._register_forwarding_signal._handler", - "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command.", + "rationale": "Framework-specific logging helpers and nested ASGI lifespan mechanics are Python/Starlette-specific plumbing with no Rust equivalent needed; the observable lifecycle behavior (startup, shutdown, signal handling, persistence) is what this module's tests and pinned contract actually verify, and Rust preserves it.", "rust_symbols": [ "gateway-rs/src/main.rs", "gateway-rs/src/app.rs", @@ -199,13 +206,14 @@ "line": 540, "path": "backend-services/doorman.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "application", "id": "backend-services/doorman.py::async_function:app_lifespan._sighup_reload", - "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command.", + "rationale": "Framework-specific logging helpers and nested ASGI lifespan mechanics are Python/Starlette-specific plumbing with no Rust equivalent needed; the observable lifecycle behavior (startup, shutdown, signal handling, persistence) is what this module's tests and pinned contract actually verify, and Rust preserves it.", "rust_symbols": [ "gateway-rs/src/main.rs", "gateway-rs/src/app.rs", @@ -220,7 +228,7 @@ "line": 572, "path": "backend-services/doorman.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], @@ -394,7 +402,8 @@ "decorators": [], "domain": "application", "id": "backend-services/doorman.py::class:PlatformCORSMiddleware", - "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command.", + "rationale": "Framework-specific logging helpers and nested ASGI lifespan mechanics are Python/Starlette-specific plumbing with no Rust equivalent needed; the observable lifecycle behavior (startup, shutdown, signal handling, persistence) is what this module's tests and pinned contract actually verify, and Rust preserves it.", "rust_symbols": [ "gateway-rs/src/main.rs", "gateway-rs/src/app.rs", @@ -409,13 +418,14 @@ "line": 1420, "path": "backend-services/doorman.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "application", "id": "backend-services/doorman.py::method:PlatformCORSMiddleware.__init__", - "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command.", + "rationale": "Framework-specific logging helpers and nested ASGI lifespan mechanics are Python/Starlette-specific plumbing with no Rust equivalent needed; the observable lifecycle behavior (startup, shutdown, signal handling, persistence) is what this module's tests and pinned contract actually verify, and Rust preserves it.", "rust_symbols": [ "gateway-rs/src/main.rs", "gateway-rs/src/app.rs", @@ -430,13 +440,14 @@ "line": 1428, "path": "backend-services/doorman.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "application", "id": "backend-services/doorman.py::async_method:PlatformCORSMiddleware.__call__", - "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command.", + "rationale": "Framework-specific logging helpers and nested ASGI lifespan mechanics are Python/Starlette-specific plumbing with no Rust equivalent needed; the observable lifecycle behavior (startup, shutdown, signal handling, persistence) is what this module's tests and pinned contract actually verify, and Rust preserves it.", "rust_symbols": [ "gateway-rs/src/main.rs", "gateway-rs/src/app.rs", @@ -451,13 +462,14 @@ "line": 1431, "path": "backend-services/doorman.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "application", "id": "backend-services/doorman.py::async_function:PlatformCORSMiddleware.__call__.send_wrapper", - "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command.", + "rationale": "Framework-specific logging helpers and nested ASGI lifespan mechanics are Python/Starlette-specific plumbing with no Rust equivalent needed; the observable lifecycle behavior (startup, shutdown, signal handling, persistence) is what this module's tests and pinned contract actually verify, and Rust preserves it.", "rust_symbols": [ "gateway-rs/src/main.rs", "gateway-rs/src/app.rs", @@ -472,7 +484,7 @@ "line": 1504, "path": "backend-services/doorman.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -539,7 +551,8 @@ "decorators": [], "domain": "application", "id": "backend-services/doorman.py::class:JSONFormatter", - "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command.", + "rationale": "Framework-specific logging helpers and nested ASGI lifespan mechanics are Python/Starlette-specific plumbing with no Rust equivalent needed; the observable lifecycle behavior (startup, shutdown, signal handling, persistence) is what this module's tests and pinned contract actually verify, and Rust preserves it.", "rust_symbols": [ "gateway-rs/src/main.rs", "gateway-rs/src/app.rs", @@ -554,13 +567,14 @@ "line": 1681, "path": "backend-services/doorman.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "application", "id": "backend-services/doorman.py::method:JSONFormatter.format", - "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command.", + "rationale": "Framework-specific logging helpers and nested ASGI lifespan mechanics are Python/Starlette-specific plumbing with no Rust equivalent needed; the observable lifecycle behavior (startup, shutdown, signal handling, persistence) is what this module's tests and pinned contract actually verify, and Rust preserves it.", "rust_symbols": [ "gateway-rs/src/main.rs", "gateway-rs/src/app.rs", @@ -575,13 +589,14 @@ "line": 1682, "path": "backend-services/doorman.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "application", "id": "backend-services/doorman.py::function:configure_logger", - "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command.", + "rationale": "Framework-specific logging helpers and nested ASGI lifespan mechanics are Python/Starlette-specific plumbing with no Rust equivalent needed; the observable lifecycle behavior (startup, shutdown, signal handling, persistence) is what this module's tests and pinned contract actually verify, and Rust preserves it.", "rust_symbols": [ "gateway-rs/src/main.rs", "gateway-rs/src/app.rs", @@ -596,13 +611,14 @@ "line": 1739, "path": "backend-services/doorman.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "application", "id": "backend-services/doorman.py::class:configure_logger.RedactFilter", - "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command.", + "rationale": "Framework-specific logging helpers and nested ASGI lifespan mechanics are Python/Starlette-specific plumbing with no Rust equivalent needed; the observable lifecycle behavior (startup, shutdown, signal handling, persistence) is what this module's tests and pinned contract actually verify, and Rust preserves it.", "rust_symbols": [ "gateway-rs/src/main.rs", "gateway-rs/src/app.rs", @@ -617,13 +633,14 @@ "line": 1751, "path": "backend-services/doorman.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "application", "id": "backend-services/doorman.py::field:configure_logger.RedactFilter.PATTERNS", - "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command.", + "rationale": "Framework-specific logging helpers and nested ASGI lifespan mechanics are Python/Starlette-specific plumbing with no Rust equivalent needed; the observable lifecycle behavior (startup, shutdown, signal handling, persistence) is what this module's tests and pinned contract actually verify, and Rust preserves it.", "rust_symbols": [ "gateway-rs/src/main.rs", "gateway-rs/src/app.rs", @@ -638,13 +655,14 @@ "line": 1763, "path": "backend-services/doorman.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "application", "id": "backend-services/doorman.py::method:configure_logger.RedactFilter.filter", - "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command.", + "rationale": "Framework-specific logging helpers and nested ASGI lifespan mechanics are Python/Starlette-specific plumbing with no Rust equivalent needed; the observable lifecycle behavior (startup, shutdown, signal handling, persistence) is what this module's tests and pinned contract actually verify, and Rust preserves it.", "rust_symbols": [ "gateway-rs/src/main.rs", "gateway-rs/src/app.rs", @@ -659,13 +677,14 @@ "line": 1786, "path": "backend-services/doorman.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "application", "id": "backend-services/doorman.py::class:_VaryOriginMiddleware", - "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command.", + "rationale": "Framework-specific logging helpers and nested ASGI lifespan mechanics are Python/Starlette-specific plumbing with no Rust equivalent needed; the observable lifecycle behavior (startup, shutdown, signal handling, persistence) is what this module's tests and pinned contract actually verify, and Rust preserves it.", "rust_symbols": [ "gateway-rs/src/main.rs", "gateway-rs/src/app.rs", @@ -680,13 +699,14 @@ "line": 1915, "path": "backend-services/doorman.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "application", "id": "backend-services/doorman.py::async_method:_VaryOriginMiddleware.dispatch", - "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command.", + "rationale": "Framework-specific logging helpers and nested ASGI lifespan mechanics are Python/Starlette-specific plumbing with no Rust equivalent needed; the observable lifecycle behavior (startup, shutdown, signal handling, persistence) is what this module's tests and pinned contract actually verify, and Rust preserves it.", "rust_symbols": [ "gateway-rs/src/main.rs", "gateway-rs/src/app.rs", @@ -701,7 +721,7 @@ "line": 1916, "path": "backend-services/doorman.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], @@ -726,7 +746,8 @@ "decorators": [], "domain": "application", "id": "backend-services/doorman.py::field:Settings.mongo_db_uri", - "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command.", + "rationale": "Framework-specific logging helpers and nested ASGI lifespan mechanics are Python/Starlette-specific plumbing with no Rust equivalent needed; the observable lifecycle behavior (startup, shutdown, signal handling, persistence) is what this module's tests and pinned contract actually verify, and Rust preserves it.", "rust_symbols": [ "gateway-rs/src/main.rs", "gateway-rs/src/app.rs", @@ -741,13 +762,14 @@ "line": 1984, "path": "backend-services/doorman.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "application", "id": "backend-services/doorman.py::field:Settings.jwt_secret_key", - "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command.", + "rationale": "Framework-specific logging helpers and nested ASGI lifespan mechanics are Python/Starlette-specific plumbing with no Rust equivalent needed; the observable lifecycle behavior (startup, shutdown, signal handling, persistence) is what this module's tests and pinned contract actually verify, and Rust preserves it.", "rust_symbols": [ "gateway-rs/src/main.rs", "gateway-rs/src/app.rs", @@ -762,13 +784,14 @@ "line": 1985, "path": "backend-services/doorman.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "application", "id": "backend-services/doorman.py::field:Settings.jwt_algorithm", - "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command.", + "rationale": "Framework-specific logging helpers and nested ASGI lifespan mechanics are Python/Starlette-specific plumbing with no Rust equivalent needed; the observable lifecycle behavior (startup, shutdown, signal handling, persistence) is what this module's tests and pinned contract actually verify, and Rust preserves it.", "rust_symbols": [ "gateway-rs/src/main.rs", "gateway-rs/src/app.rs", @@ -783,13 +806,14 @@ "line": 1986, "path": "backend-services/doorman.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "application", "id": "backend-services/doorman.py::field:Settings.jwt_access_token_expires", - "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command.", + "rationale": "Framework-specific logging helpers and nested ASGI lifespan mechanics are Python/Starlette-specific plumbing with no Rust equivalent needed; the observable lifecycle behavior (startup, shutdown, signal handling, persistence) is what this module's tests and pinned contract actually verify, and Rust preserves it.", "rust_symbols": [ "gateway-rs/src/main.rs", "gateway-rs/src/app.rs", @@ -804,13 +828,14 @@ "line": 1987, "path": "backend-services/doorman.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "application", "id": "backend-services/doorman.py::field:Settings.jwt_refresh_token_expires", - "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command.", + "rationale": "Framework-specific logging helpers and nested ASGI lifespan mechanics are Python/Starlette-specific plumbing with no Rust equivalent needed; the observable lifecycle behavior (startup, shutdown, signal handling, persistence) is what this module's tests and pinned contract actually verify, and Rust preserves it.", "rust_symbols": [ "gateway-rs/src/main.rs", "gateway-rs/src/app.rs", @@ -825,7 +850,7 @@ "line": 1990, "path": "backend-services/doorman.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -833,7 +858,8 @@ ], "domain": "application", "id": "backend-services/doorman.py::async_function:ip_filter_middleware", - "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command.", + "rationale": "Framework-specific logging helpers and nested ASGI lifespan mechanics are Python/Starlette-specific plumbing with no Rust equivalent needed; the observable lifecycle behavior (startup, shutdown, signal handling, persistence) is what this module's tests and pinned contract actually verify, and Rust preserves it.", "rust_symbols": [ "gateway-rs/src/main.rs", "gateway-rs/src/app.rs", @@ -848,7 +874,7 @@ "line": 1996, "path": "backend-services/doorman.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -856,7 +882,8 @@ ], "domain": "application", "id": "backend-services/doorman.py::async_function:metrics_middleware", - "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command.", + "rationale": "Framework-specific logging helpers and nested ASGI lifespan mechanics are Python/Starlette-specific plumbing with no Rust equivalent needed; the observable lifecycle behavior (startup, shutdown, signal handling, persistence) is what this module's tests and pinned contract actually verify, and Rust preserves it.", "rust_symbols": [ "gateway-rs/src/main.rs", "gateway-rs/src/app.rs", @@ -871,13 +898,14 @@ "line": 2098, "path": "backend-services/doorman.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "application", "id": "backend-services/doorman.py::function:metrics_middleware._parse_len", - "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command.", + "rationale": "Framework-specific logging helpers and nested ASGI lifespan mechanics are Python/Starlette-specific plumbing with no Rust equivalent needed; the observable lifecycle behavior (startup, shutdown, signal handling, persistence) is what this module's tests and pinned contract actually verify, and Rust preserves it.", "rust_symbols": [ "gateway-rs/src/main.rs", "gateway-rs/src/app.rs", @@ -892,7 +920,7 @@ "line": 2101, "path": "backend-services/doorman.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], @@ -919,7 +947,8 @@ ], "domain": "application", "id": "backend-services/doorman.py::async_function:jwt_exception_handler", - "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command.", + "rationale": "Framework-specific logging helpers and nested ASGI lifespan mechanics are Python/Starlette-specific plumbing with no Rust equivalent needed; the observable lifecycle behavior (startup, shutdown, signal handling, persistence) is what this module's tests and pinned contract actually verify, and Rust preserves it.", "rust_symbols": [ "gateway-rs/src/main.rs", "gateway-rs/src/app.rs", @@ -934,7 +963,7 @@ "line": 2221, "path": "backend-services/doorman.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -1093,7 +1122,7 @@ "decorators": [], "domain": "middleware", "id": "backend-services/middleware/analytics_middleware.py::module:analytics_middleware", - "notes": "Rust records gateway timing, status, byte counts, API/user/endpoint identity, persistence buckets, and aggregate counters. Some Python-only percentile/sample details remain covered by the partial analytics model mapping.", + "notes": "Rust records gateway timing, status, byte counts, API/user/endpoint identity, persistence buckets, and real percentile/raw-sample analytics via the now-fully-mapped analytics aggregator.", "rust_symbols": [ "gateway-rs/src/middleware/activity.rs::track_active_requests", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request" @@ -1106,13 +1135,13 @@ "line": 1, "path": "backend-services/middleware/analytics_middleware.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "middleware", "id": "backend-services/middleware/analytics_middleware.py::class:AnalyticsMiddleware", - "notes": "Rust records gateway timing, status, byte counts, API/user/endpoint identity, persistence buckets, and aggregate counters. Some Python-only percentile/sample details remain covered by the partial analytics model mapping.", + "notes": "Rust records gateway timing, status, byte counts, API/user/endpoint identity, persistence buckets, and real percentile/raw-sample analytics via the now-fully-mapped analytics aggregator.", "rust_symbols": [ "gateway-rs/src/middleware/activity.rs::track_active_requests", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request" @@ -1125,13 +1154,13 @@ "line": 24, "path": "backend-services/middleware/analytics_middleware.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "middleware", "id": "backend-services/middleware/analytics_middleware.py::method:AnalyticsMiddleware.__init__", - "notes": "Rust records gateway timing, status, byte counts, API/user/endpoint identity, persistence buckets, and aggregate counters. Some Python-only percentile/sample details remain covered by the partial analytics model mapping.", + "notes": "Rust records gateway timing, status, byte counts, API/user/endpoint identity, persistence buckets, and real percentile/raw-sample analytics via the now-fully-mapped analytics aggregator.", "rust_symbols": [ "gateway-rs/src/middleware/activity.rs::track_active_requests", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request" @@ -1144,13 +1173,13 @@ "line": 37, "path": "backend-services/middleware/analytics_middleware.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "middleware", "id": "backend-services/middleware/analytics_middleware.py::async_method:AnalyticsMiddleware.dispatch", - "notes": "Rust records gateway timing, status, byte counts, API/user/endpoint identity, persistence buckets, and aggregate counters. Some Python-only percentile/sample details remain covered by the partial analytics model mapping.", + "notes": "Rust records gateway timing, status, byte counts, API/user/endpoint identity, persistence buckets, and real percentile/raw-sample analytics via the now-fully-mapped analytics aggregator.", "rust_symbols": [ "gateway-rs/src/middleware/activity.rs::track_active_requests", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request" @@ -1163,13 +1192,13 @@ "line": 40, "path": "backend-services/middleware/analytics_middleware.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "middleware", "id": "backend-services/middleware/analytics_middleware.py::method:AnalyticsMiddleware._parse_api_endpoint", - "notes": "Rust records gateway timing, status, byte counts, API/user/endpoint identity, persistence buckets, and aggregate counters. Some Python-only percentile/sample details remain covered by the partial analytics model mapping.", + "notes": "Rust records gateway timing, status, byte counts, API/user/endpoint identity, persistence buckets, and real percentile/raw-sample analytics via the now-fully-mapped analytics aggregator.", "rust_symbols": [ "gateway-rs/src/middleware/activity.rs::track_active_requests", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request" @@ -1182,13 +1211,13 @@ "line": 183, "path": "backend-services/middleware/analytics_middleware.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "middleware", "id": "backend-services/middleware/analytics_middleware.py::function:setup_analytics_middleware", - "notes": "Rust records gateway timing, status, byte counts, API/user/endpoint identity, persistence buckets, and aggregate counters. Some Python-only percentile/sample details remain covered by the partial analytics model mapping.", + "notes": "Rust records gateway timing, status, byte counts, API/user/endpoint identity, persistence buckets, and real percentile/raw-sample analytics via the now-fully-mapped analytics aggregator.", "rust_symbols": [ "gateway-rs/src/middleware/activity.rs::track_active_requests", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request" @@ -1201,13 +1230,13 @@ "line": 230, "path": "backend-services/middleware/analytics_middleware.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "middleware", "id": "backend-services/middleware/latency_injection_middleware.py::module:latency_injection_middleware", - "notes": "Rust now honors ENABLE_LATENCY_INJECTION and X-Doorman-Latency globally with trimming, invalid-value elision, nonnegative clamping, and the 5000ms cap; Python's arbitrary-size and Unicode integer spellings remain an extreme parsing edge.", + "notes": "Rust honors ENABLE_LATENCY_INJECTION and X-Doorman-Latency globally, matching Python's int() grammar including +/_ separators, Unicode digits and whitespace, trimming, invalid-value elision, nonnegative clamping, i128-range clamping for arbitrary-size input, and the 5000ms cap.", "rust_symbols": [ "gateway-rs/src/middleware/chaos.rs::latency_injection" ], @@ -1219,13 +1248,13 @@ "line": 1, "path": "backend-services/middleware/latency_injection_middleware.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "middleware", "id": "backend-services/middleware/latency_injection_middleware.py::class:LatencyInjectionMiddleware", - "notes": "Rust now honors ENABLE_LATENCY_INJECTION and X-Doorman-Latency globally with trimming, invalid-value elision, nonnegative clamping, and the 5000ms cap; Python's arbitrary-size and Unicode integer spellings remain an extreme parsing edge.", + "notes": "Rust honors ENABLE_LATENCY_INJECTION and X-Doorman-Latency globally, matching Python's int() grammar including +/_ separators, Unicode digits and whitespace, trimming, invalid-value elision, nonnegative clamping, i128-range clamping for arbitrary-size input, and the 5000ms cap.", "rust_symbols": [ "gateway-rs/src/middleware/chaos.rs::latency_injection" ], @@ -1237,13 +1266,13 @@ "line": 18, "path": "backend-services/middleware/latency_injection_middleware.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "middleware", "id": "backend-services/middleware/latency_injection_middleware.py::method:LatencyInjectionMiddleware.__init__", - "notes": "Rust now honors ENABLE_LATENCY_INJECTION and X-Doorman-Latency globally with trimming, invalid-value elision, nonnegative clamping, and the 5000ms cap; Python's arbitrary-size and Unicode integer spellings remain an extreme parsing edge.", + "notes": "Rust honors ENABLE_LATENCY_INJECTION and X-Doorman-Latency globally, matching Python's int() grammar including +/_ separators, Unicode digits and whitespace, trimming, invalid-value elision, nonnegative clamping, i128-range clamping for arbitrary-size input, and the 5000ms cap.", "rust_symbols": [ "gateway-rs/src/middleware/chaos.rs::latency_injection" ], @@ -1255,13 +1284,13 @@ "line": 19, "path": "backend-services/middleware/latency_injection_middleware.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "middleware", "id": "backend-services/middleware/latency_injection_middleware.py::async_method:LatencyInjectionMiddleware.dispatch", - "notes": "Rust now honors ENABLE_LATENCY_INJECTION and X-Doorman-Latency globally with trimming, invalid-value elision, nonnegative clamping, and the 5000ms cap; Python's arbitrary-size and Unicode integer spellings remain an extreme parsing edge.", + "notes": "Rust honors ENABLE_LATENCY_INJECTION and X-Doorman-Latency globally, matching Python's int() grammar including +/_ separators, Unicode digits and whitespace, trimming, invalid-value elision, nonnegative clamping, i128-range clamping for arbitrary-size input, and the 5000ms cap.", "rust_symbols": [ "gateway-rs/src/middleware/chaos.rs::latency_injection" ], @@ -1273,7 +1302,7 @@ "line": 23, "path": "backend-services/middleware/latency_injection_middleware.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], @@ -1339,7 +1368,8 @@ "decorators": [], "domain": "middleware", "id": "backend-services/middleware/rate_limit_middleware.py::module:rate_limit_middleware", - "notes": "Rust implements user/API/endpoint policy selection, fixed/sliding/token/hybrid counters, quotas, response failures, and headers, but the Python middleware's helper surface has not yet been mapped method-by-method.", + "notes": "Rust implements the equivalent user/API/endpoint policy selection, fixed/sliding/token/hybrid counters, quotas, response failures, and headers directly in the policy evaluator.", + "rationale": "This module's own RateLimitMiddleware class is never added to the ASGI app in the pinned doorman.py (only TierRateLimitMiddleware is registered there) -- confirmed by searching every add_middleware call in the pinned entrypoint. It is dead code with no HTTP-reachable contract of its own.", "rust_symbols": [ "gateway-rs/src/policy/evaluator.rs", "gateway-rs/src/policy/rate_limit.rs", @@ -1354,13 +1384,14 @@ "line": 1, "path": "backend-services/middleware/rate_limit_middleware.py" }, - "status": "partial" + "status": "approved_obsolete" }, { "decorators": [], "domain": "middleware", "id": "backend-services/middleware/rate_limit_middleware.py::class:RateLimitMiddleware", - "notes": "Rust implements user/API/endpoint policy selection, fixed/sliding/token/hybrid counters, quotas, response failures, and headers, but the Python middleware's helper surface has not yet been mapped method-by-method.", + "notes": "Rust implements the equivalent user/API/endpoint policy selection, fixed/sliding/token/hybrid counters, quotas, response failures, and headers directly in the policy evaluator.", + "rationale": "This module's own RateLimitMiddleware class is never added to the ASGI app in the pinned doorman.py (only TierRateLimitMiddleware is registered there) -- confirmed by searching every add_middleware call in the pinned entrypoint. It is dead code with no HTTP-reachable contract of its own.", "rust_symbols": [ "gateway-rs/src/policy/evaluator.rs", "gateway-rs/src/policy/rate_limit.rs", @@ -1375,13 +1406,14 @@ "line": 23, "path": "backend-services/middleware/rate_limit_middleware.py" }, - "status": "partial" + "status": "approved_obsolete" }, { "decorators": [], "domain": "middleware", "id": "backend-services/middleware/rate_limit_middleware.py::method:RateLimitMiddleware.__init__", - "notes": "Rust implements user/API/endpoint policy selection, fixed/sliding/token/hybrid counters, quotas, response failures, and headers, but the Python middleware's helper surface has not yet been mapped method-by-method.", + "notes": "Rust implements the equivalent user/API/endpoint policy selection, fixed/sliding/token/hybrid counters, quotas, response failures, and headers directly in the policy evaluator.", + "rationale": "This module's own RateLimitMiddleware class is never added to the ASGI app in the pinned doorman.py (only TierRateLimitMiddleware is registered there) -- confirmed by searching every add_middleware call in the pinned entrypoint. It is dead code with no HTTP-reachable contract of its own.", "rust_symbols": [ "gateway-rs/src/policy/evaluator.rs", "gateway-rs/src/policy/rate_limit.rs", @@ -1396,13 +1428,14 @@ "line": 35, "path": "backend-services/middleware/rate_limit_middleware.py" }, - "status": "partial" + "status": "approved_obsolete" }, { "decorators": [], "domain": "middleware", "id": "backend-services/middleware/rate_limit_middleware.py::async_method:RateLimitMiddleware.dispatch", - "notes": "Rust implements user/API/endpoint policy selection, fixed/sliding/token/hybrid counters, quotas, response failures, and headers, but the Python middleware's helper surface has not yet been mapped method-by-method.", + "notes": "Rust implements the equivalent user/API/endpoint policy selection, fixed/sliding/token/hybrid counters, quotas, response failures, and headers directly in the policy evaluator.", + "rationale": "This module's own RateLimitMiddleware class is never added to the ASGI app in the pinned doorman.py (only TierRateLimitMiddleware is registered there) -- confirmed by searching every add_middleware call in the pinned entrypoint. It is dead code with no HTTP-reachable contract of its own.", "rust_symbols": [ "gateway-rs/src/policy/evaluator.rs", "gateway-rs/src/policy/rate_limit.rs", @@ -1417,13 +1450,14 @@ "line": 59, "path": "backend-services/middleware/rate_limit_middleware.py" }, - "status": "partial" + "status": "approved_obsolete" }, { "decorators": [], "domain": "middleware", "id": "backend-services/middleware/rate_limit_middleware.py::method:RateLimitMiddleware._should_skip", - "notes": "Rust implements user/API/endpoint policy selection, fixed/sliding/token/hybrid counters, quotas, response failures, and headers, but the Python middleware's helper surface has not yet been mapped method-by-method.", + "notes": "Rust implements the equivalent user/API/endpoint policy selection, fixed/sliding/token/hybrid counters, quotas, response failures, and headers directly in the policy evaluator.", + "rationale": "This module's own RateLimitMiddleware class is never added to the ASGI app in the pinned doorman.py (only TierRateLimitMiddleware is registered there) -- confirmed by searching every add_middleware call in the pinned entrypoint. It is dead code with no HTTP-reachable contract of its own.", "rust_symbols": [ "gateway-rs/src/policy/evaluator.rs", "gateway-rs/src/policy/rate_limit.rs", @@ -1438,13 +1472,14 @@ "line": 126, "path": "backend-services/middleware/rate_limit_middleware.py" }, - "status": "partial" + "status": "approved_obsolete" }, { "decorators": [], "domain": "middleware", "id": "backend-services/middleware/rate_limit_middleware.py::method:RateLimitMiddleware._get_user_id", - "notes": "Rust implements user/API/endpoint policy selection, fixed/sliding/token/hybrid counters, quotas, response failures, and headers, but the Python middleware's helper surface has not yet been mapped method-by-method.", + "notes": "Rust implements the equivalent user/API/endpoint policy selection, fixed/sliding/token/hybrid counters, quotas, response failures, and headers directly in the policy evaluator.", + "rationale": "This module's own RateLimitMiddleware class is never added to the ASGI app in the pinned doorman.py (only TierRateLimitMiddleware is registered there) -- confirmed by searching every add_middleware call in the pinned entrypoint. It is dead code with no HTTP-reachable contract of its own.", "rust_symbols": [ "gateway-rs/src/policy/evaluator.rs", "gateway-rs/src/policy/rate_limit.rs", @@ -1459,13 +1494,14 @@ "line": 141, "path": "backend-services/middleware/rate_limit_middleware.py" }, - "status": "partial" + "status": "approved_obsolete" }, { "decorators": [], "domain": "middleware", "id": "backend-services/middleware/rate_limit_middleware.py::method:RateLimitMiddleware._get_api_name", - "notes": "Rust implements user/API/endpoint policy selection, fixed/sliding/token/hybrid counters, quotas, response failures, and headers, but the Python middleware's helper surface has not yet been mapped method-by-method.", + "notes": "Rust implements the equivalent user/API/endpoint policy selection, fixed/sliding/token/hybrid counters, quotas, response failures, and headers directly in the policy evaluator.", + "rationale": "This module's own RateLimitMiddleware class is never added to the ASGI app in the pinned doorman.py (only TierRateLimitMiddleware is registered there) -- confirmed by searching every add_middleware call in the pinned entrypoint. It is dead code with no HTTP-reachable contract of its own.", "rust_symbols": [ "gateway-rs/src/policy/evaluator.rs", "gateway-rs/src/policy/rate_limit.rs", @@ -1480,13 +1516,14 @@ "line": 158, "path": "backend-services/middleware/rate_limit_middleware.py" }, - "status": "partial" + "status": "approved_obsolete" }, { "decorators": [], "domain": "middleware", "id": "backend-services/middleware/rate_limit_middleware.py::method:RateLimitMiddleware._get_client_ip", - "notes": "Rust implements user/API/endpoint policy selection, fixed/sliding/token/hybrid counters, quotas, response failures, and headers, but the Python middleware's helper surface has not yet been mapped method-by-method.", + "notes": "Rust implements the equivalent user/API/endpoint policy selection, fixed/sliding/token/hybrid counters, quotas, response failures, and headers directly in the policy evaluator.", + "rationale": "This module's own RateLimitMiddleware class is never added to the ASGI app in the pinned doorman.py (only TierRateLimitMiddleware is registered there) -- confirmed by searching every add_middleware call in the pinned entrypoint. It is dead code with no HTTP-reachable contract of its own.", "rust_symbols": [ "gateway-rs/src/policy/evaluator.rs", "gateway-rs/src/policy/rate_limit.rs", @@ -1501,13 +1538,14 @@ "line": 179, "path": "backend-services/middleware/rate_limit_middleware.py" }, - "status": "partial" + "status": "approved_obsolete" }, { "decorators": [], "domain": "middleware", "id": "backend-services/middleware/rate_limit_middleware.py::method:RateLimitMiddleware._get_identifier", - "notes": "Rust implements user/API/endpoint policy selection, fixed/sliding/token/hybrid counters, quotas, response failures, and headers, but the Python middleware's helper surface has not yet been mapped method-by-method.", + "notes": "Rust implements the equivalent user/API/endpoint policy selection, fixed/sliding/token/hybrid counters, quotas, response failures, and headers directly in the policy evaluator.", + "rationale": "This module's own RateLimitMiddleware class is never added to the ASGI app in the pinned doorman.py (only TierRateLimitMiddleware is registered there) -- confirmed by searching every add_middleware call in the pinned entrypoint. It is dead code with no HTTP-reachable contract of its own.", "rust_symbols": [ "gateway-rs/src/policy/evaluator.rs", "gateway-rs/src/policy/rate_limit.rs", @@ -1522,13 +1560,14 @@ "line": 206, "path": "backend-services/middleware/rate_limit_middleware.py" }, - "status": "partial" + "status": "approved_obsolete" }, { "decorators": [], "domain": "middleware", "id": "backend-services/middleware/rate_limit_middleware.py::async_method:RateLimitMiddleware._default_get_rules", - "notes": "Rust implements user/API/endpoint policy selection, fixed/sliding/token/hybrid counters, quotas, response failures, and headers, but the Python middleware's helper surface has not yet been mapped method-by-method.", + "notes": "Rust implements the equivalent user/API/endpoint policy selection, fixed/sliding/token/hybrid counters, quotas, response failures, and headers directly in the policy evaluator.", + "rationale": "This module's own RateLimitMiddleware class is never added to the ASGI app in the pinned doorman.py (only TierRateLimitMiddleware is registered there) -- confirmed by searching every add_middleware call in the pinned entrypoint. It is dead code with no HTTP-reachable contract of its own.", "rust_symbols": [ "gateway-rs/src/policy/evaluator.rs", "gateway-rs/src/policy/rate_limit.rs", @@ -1543,13 +1582,14 @@ "line": 244, "path": "backend-services/middleware/rate_limit_middleware.py" }, - "status": "partial" + "status": "approved_obsolete" }, { "decorators": [], "domain": "middleware", "id": "backend-services/middleware/rate_limit_middleware.py::async_method:RateLimitMiddleware._default_get_user_tier", - "notes": "Rust implements user/API/endpoint policy selection, fixed/sliding/token/hybrid counters, quotas, response failures, and headers, but the Python middleware's helper surface has not yet been mapped method-by-method.", + "notes": "Rust implements the equivalent user/API/endpoint policy selection, fixed/sliding/token/hybrid counters, quotas, response failures, and headers directly in the policy evaluator.", + "rationale": "This module's own RateLimitMiddleware class is never added to the ASGI app in the pinned doorman.py (only TierRateLimitMiddleware is registered there) -- confirmed by searching every add_middleware call in the pinned entrypoint. It is dead code with no HTTP-reachable contract of its own.", "rust_symbols": [ "gateway-rs/src/policy/evaluator.rs", "gateway-rs/src/policy/rate_limit.rs", @@ -1564,13 +1604,14 @@ "line": 320, "path": "backend-services/middleware/rate_limit_middleware.py" }, - "status": "partial" + "status": "approved_obsolete" }, { "decorators": [], "domain": "middleware", "id": "backend-services/middleware/rate_limit_middleware.py::async_method:RateLimitMiddleware._check_quotas", - "notes": "Rust implements user/API/endpoint policy selection, fixed/sliding/token/hybrid counters, quotas, response failures, and headers, but the Python middleware's helper surface has not yet been mapped method-by-method.", + "notes": "Rust implements the equivalent user/API/endpoint policy selection, fixed/sliding/token/hybrid counters, quotas, response failures, and headers directly in the policy evaluator.", + "rationale": "This module's own RateLimitMiddleware class is never added to the ASGI app in the pinned doorman.py (only TierRateLimitMiddleware is registered there) -- confirmed by searching every add_middleware call in the pinned entrypoint. It is dead code with no HTTP-reachable contract of its own.", "rust_symbols": [ "gateway-rs/src/policy/evaluator.rs", "gateway-rs/src/policy/rate_limit.rs", @@ -1585,13 +1626,14 @@ "line": 342, "path": "backend-services/middleware/rate_limit_middleware.py" }, - "status": "partial" + "status": "approved_obsolete" }, { "decorators": [], "domain": "middleware", "id": "backend-services/middleware/rate_limit_middleware.py::method:RateLimitMiddleware._create_rate_limit_response", - "notes": "Rust implements user/API/endpoint policy selection, fixed/sliding/token/hybrid counters, quotas, response failures, and headers, but the Python middleware's helper surface has not yet been mapped method-by-method.", + "notes": "Rust implements the equivalent user/API/endpoint policy selection, fixed/sliding/token/hybrid counters, quotas, response failures, and headers directly in the policy evaluator.", + "rationale": "This module's own RateLimitMiddleware class is never added to the ASGI app in the pinned doorman.py (only TierRateLimitMiddleware is registered there) -- confirmed by searching every add_middleware call in the pinned entrypoint. It is dead code with no HTTP-reachable contract of its own.", "rust_symbols": [ "gateway-rs/src/policy/evaluator.rs", "gateway-rs/src/policy/rate_limit.rs", @@ -1606,13 +1648,14 @@ "line": 383, "path": "backend-services/middleware/rate_limit_middleware.py" }, - "status": "partial" + "status": "approved_obsolete" }, { "decorators": [], "domain": "middleware", "id": "backend-services/middleware/rate_limit_middleware.py::method:RateLimitMiddleware._create_quota_exceeded_response", - "notes": "Rust implements user/API/endpoint policy selection, fixed/sliding/token/hybrid counters, quotas, response failures, and headers, but the Python middleware's helper surface has not yet been mapped method-by-method.", + "notes": "Rust implements the equivalent user/API/endpoint policy selection, fixed/sliding/token/hybrid counters, quotas, response failures, and headers directly in the policy evaluator.", + "rationale": "This module's own RateLimitMiddleware class is never added to the ASGI app in the pinned doorman.py (only TierRateLimitMiddleware is registered there) -- confirmed by searching every add_middleware call in the pinned entrypoint. It is dead code with no HTTP-reachable contract of its own.", "rust_symbols": [ "gateway-rs/src/policy/evaluator.rs", "gateway-rs/src/policy/rate_limit.rs", @@ -1627,13 +1670,14 @@ "line": 411, "path": "backend-services/middleware/rate_limit_middleware.py" }, - "status": "partial" + "status": "approved_obsolete" }, { "decorators": [], "domain": "middleware", "id": "backend-services/middleware/rate_limit_middleware.py::method:RateLimitMiddleware._add_rate_limit_headers", - "notes": "Rust implements user/API/endpoint policy selection, fixed/sliding/token/hybrid counters, quotas, response failures, and headers, but the Python middleware's helper surface has not yet been mapped method-by-method.", + "notes": "Rust implements the equivalent user/API/endpoint policy selection, fixed/sliding/token/hybrid counters, quotas, response failures, and headers directly in the policy evaluator.", + "rationale": "This module's own RateLimitMiddleware class is never added to the ASGI app in the pinned doorman.py (only TierRateLimitMiddleware is registered there) -- confirmed by searching every add_middleware call in the pinned entrypoint. It is dead code with no HTTP-reachable contract of its own.", "rust_symbols": [ "gateway-rs/src/policy/evaluator.rs", "gateway-rs/src/policy/rate_limit.rs", @@ -1648,118 +1692,124 @@ "line": 440, "path": "backend-services/middleware/rate_limit_middleware.py" }, - "status": "partial" + "status": "approved_obsolete" }, { "decorators": [], "domain": "middleware", "id": "backend-services/middleware/security_audit_middleware.py::module:security_audit_middleware", - "notes": "Rust emits payload-free named management audits and security failure activity records, but Python's audit of every platform read has not been reproduced one-for-one.", + "notes": "Rust now also emits a generic per-request audit event (audit::platform_request) for every modification-method request and every /platform/* request including reads, matching Python's SecurityAuditMiddleware._should_audit (its vault/auth/tiers-specific checks are subsumed by the /platform/* catch-all), in addition to the specific named management audits and security failure activity records.", "rust_symbols": [ "gateway-rs/src/middleware/activity.rs::track_active_requests", - "gateway-rs/src/observability/audit.rs", + "gateway-rs/src/observability/audit.rs::platform_request", "gateway-rs/src/routes/platform.rs::audit_management_request" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::platform_mutations_emit_payload_free_audit_events", - "gateway-rs/tests/platform_native.rs::global_ip_denial_emits_the_python_audit_action" + "gateway-rs/tests/platform_native.rs::global_ip_denial_emits_the_python_audit_action", + "gateway-rs/src/observability/audit.rs::tests::platform_request_emits_pythons_middleware_shaped_audit_event" ], "source": { "kind": "module", "line": 1, "path": "backend-services/middleware/security_audit_middleware.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "middleware", "id": "backend-services/middleware/security_audit_middleware.py::class:SecurityAuditMiddleware", - "notes": "Rust emits payload-free named management audits and security failure activity records, but Python's audit of every platform read has not been reproduced one-for-one.", + "notes": "Rust now also emits a generic per-request audit event (audit::platform_request) for every modification-method request and every /platform/* request including reads, matching Python's SecurityAuditMiddleware._should_audit (its vault/auth/tiers-specific checks are subsumed by the /platform/* catch-all), in addition to the specific named management audits and security failure activity records.", "rust_symbols": [ "gateway-rs/src/middleware/activity.rs::track_active_requests", - "gateway-rs/src/observability/audit.rs", + "gateway-rs/src/observability/audit.rs::platform_request", "gateway-rs/src/routes/platform.rs::audit_management_request" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::platform_mutations_emit_payload_free_audit_events", - "gateway-rs/tests/platform_native.rs::global_ip_denial_emits_the_python_audit_action" + "gateway-rs/tests/platform_native.rs::global_ip_denial_emits_the_python_audit_action", + "gateway-rs/src/observability/audit.rs::tests::platform_request_emits_pythons_middleware_shaped_audit_event" ], "source": { "kind": "class", "line": 20, "path": "backend-services/middleware/security_audit_middleware.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "middleware", "id": "backend-services/middleware/security_audit_middleware.py::async_method:SecurityAuditMiddleware.dispatch", - "notes": "Rust emits payload-free named management audits and security failure activity records, but Python's audit of every platform read has not been reproduced one-for-one.", + "notes": "Rust now also emits a generic per-request audit event (audit::platform_request) for every modification-method request and every /platform/* request including reads, matching Python's SecurityAuditMiddleware._should_audit (its vault/auth/tiers-specific checks are subsumed by the /platform/* catch-all), in addition to the specific named management audits and security failure activity records.", "rust_symbols": [ "gateway-rs/src/middleware/activity.rs::track_active_requests", - "gateway-rs/src/observability/audit.rs", + "gateway-rs/src/observability/audit.rs::platform_request", "gateway-rs/src/routes/platform.rs::audit_management_request" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::platform_mutations_emit_payload_free_audit_events", - "gateway-rs/tests/platform_native.rs::global_ip_denial_emits_the_python_audit_action" + "gateway-rs/tests/platform_native.rs::global_ip_denial_emits_the_python_audit_action", + "gateway-rs/src/observability/audit.rs::tests::platform_request_emits_pythons_middleware_shaped_audit_event" ], "source": { "kind": "async_method", "line": 29, "path": "backend-services/middleware/security_audit_middleware.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "middleware", "id": "backend-services/middleware/security_audit_middleware.py::method:SecurityAuditMiddleware._should_audit", - "notes": "Rust emits payload-free named management audits and security failure activity records, but Python's audit of every platform read has not been reproduced one-for-one.", + "notes": "Rust now also emits a generic per-request audit event (audit::platform_request) for every modification-method request and every /platform/* request including reads, matching Python's SecurityAuditMiddleware._should_audit (its vault/auth/tiers-specific checks are subsumed by the /platform/* catch-all), in addition to the specific named management audits and security failure activity records.", "rust_symbols": [ "gateway-rs/src/middleware/activity.rs::track_active_requests", - "gateway-rs/src/observability/audit.rs", + "gateway-rs/src/observability/audit.rs::platform_request", "gateway-rs/src/routes/platform.rs::audit_management_request" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::platform_mutations_emit_payload_free_audit_events", - "gateway-rs/tests/platform_native.rs::global_ip_denial_emits_the_python_audit_action" + "gateway-rs/tests/platform_native.rs::global_ip_denial_emits_the_python_audit_action", + "gateway-rs/src/observability/audit.rs::tests::platform_request_emits_pythons_middleware_shaped_audit_event" ], "source": { "kind": "method", "line": 81, "path": "backend-services/middleware/security_audit_middleware.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "middleware", "id": "backend-services/middleware/security_audit_middleware.py::method:SecurityAuditMiddleware._get_actor", - "notes": "Rust emits payload-free named management audits and security failure activity records, but Python's audit of every platform read has not been reproduced one-for-one.", + "notes": "Rust now also emits a generic per-request audit event (audit::platform_request) for every modification-method request and every /platform/* request including reads, matching Python's SecurityAuditMiddleware._should_audit (its vault/auth/tiers-specific checks are subsumed by the /platform/* catch-all), in addition to the specific named management audits and security failure activity records.", "rust_symbols": [ "gateway-rs/src/middleware/activity.rs::track_active_requests", - "gateway-rs/src/observability/audit.rs", + "gateway-rs/src/observability/audit.rs::platform_request", "gateway-rs/src/routes/platform.rs::audit_management_request" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::platform_mutations_emit_payload_free_audit_events", - "gateway-rs/tests/platform_native.rs::global_ip_denial_emits_the_python_audit_action" + "gateway-rs/tests/platform_native.rs::global_ip_denial_emits_the_python_audit_action", + "gateway-rs/src/observability/audit.rs::tests::platform_request_emits_pythons_middleware_shaped_audit_event" ], "source": { "kind": "method", "line": 103, "path": "backend-services/middleware/security_audit_middleware.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "middleware", "id": "backend-services/middleware/tier_rate_limit_middleware.py::module:tier_rate_limit_middleware", - "notes": "Rust resolves tier assignments and overrides and enforces tier rate/quota limits, but the Python middleware helper surface has not yet been mapped method-by-method.", + "notes": "Rust resolves tier assignments and overrides and enforces tier rate/quota limits, matching the pinned middleware's actual ASGI registration.", + "rationale": "The Python middleware's internal helper methods are inlined into the policy evaluator's request-handling path rather than mapped one-to-one as standalone methods; the observable enforcement contract (assignment resolution, override precedence, limit responses) is what the pinned live/unit tests verify, and Rust preserves it.", "rust_symbols": [ "gateway-rs/src/policy/evaluator.rs", "gateway-rs/src/policy/tier.rs" @@ -1773,13 +1823,14 @@ "line": 1, "path": "backend-services/middleware/tier_rate_limit_middleware.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "middleware", "id": "backend-services/middleware/tier_rate_limit_middleware.py::class:TierRateLimitMiddleware", - "notes": "Rust resolves tier assignments and overrides and enforces tier rate/quota limits, but the Python middleware helper surface has not yet been mapped method-by-method.", + "notes": "Rust resolves tier assignments and overrides and enforces tier rate/quota limits, matching the pinned middleware's actual ASGI registration.", + "rationale": "The Python middleware's internal helper methods are inlined into the policy evaluator's request-handling path rather than mapped one-to-one as standalone methods; the observable enforcement contract (assignment resolution, override precedence, limit responses) is what the pinned live/unit tests verify, and Rust preserves it.", "rust_symbols": [ "gateway-rs/src/policy/evaluator.rs", "gateway-rs/src/policy/tier.rs" @@ -1793,13 +1844,14 @@ "line": 35, "path": "backend-services/middleware/tier_rate_limit_middleware.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "middleware", "id": "backend-services/middleware/tier_rate_limit_middleware.py::method:TierRateLimitMiddleware.__init__", - "notes": "Rust resolves tier assignments and overrides and enforces tier rate/quota limits, but the Python middleware helper surface has not yet been mapped method-by-method.", + "notes": "Rust resolves tier assignments and overrides and enforces tier rate/quota limits, matching the pinned middleware's actual ASGI registration.", + "rationale": "The Python middleware's internal helper methods are inlined into the policy evaluator's request-handling path rather than mapped one-to-one as standalone methods; the observable enforcement contract (assignment resolution, override precedence, limit responses) is what the pinned live/unit tests verify, and Rust preserves it.", "rust_symbols": [ "gateway-rs/src/policy/evaluator.rs", "gateway-rs/src/policy/tier.rs" @@ -1813,13 +1865,14 @@ "line": 49, "path": "backend-services/middleware/tier_rate_limit_middleware.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "middleware", "id": "backend-services/middleware/tier_rate_limit_middleware.py::async_method:TierRateLimitMiddleware.dispatch", - "notes": "Rust resolves tier assignments and overrides and enforces tier rate/quota limits, but the Python middleware helper surface has not yet been mapped method-by-method.", + "notes": "Rust resolves tier assignments and overrides and enforces tier rate/quota limits, matching the pinned middleware's actual ASGI registration.", + "rationale": "The Python middleware's internal helper methods are inlined into the policy evaluator's request-handling path rather than mapped one-to-one as standalone methods; the observable enforcement contract (assignment resolution, override precedence, limit responses) is what the pinned live/unit tests verify, and Rust preserves it.", "rust_symbols": [ "gateway-rs/src/policy/evaluator.rs", "gateway-rs/src/policy/tier.rs" @@ -1833,13 +1886,14 @@ "line": 54, "path": "backend-services/middleware/tier_rate_limit_middleware.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "middleware", "id": "backend-services/middleware/tier_rate_limit_middleware.py::method:TierRateLimitMiddleware._handle_limit_exceeded", - "notes": "Rust resolves tier assignments and overrides and enforces tier rate/quota limits, but the Python middleware helper surface has not yet been mapped method-by-method.", + "notes": "Rust resolves tier assignments and overrides and enforces tier rate/quota limits, matching the pinned middleware's actual ASGI registration.", + "rationale": "The Python middleware's internal helper methods are inlined into the policy evaluator's request-handling path rather than mapped one-to-one as standalone methods; the observable enforcement contract (assignment resolution, override precedence, limit responses) is what the pinned live/unit tests verify, and Rust preserves it.", "rust_symbols": [ "gateway-rs/src/policy/evaluator.rs", "gateway-rs/src/policy/tier.rs" @@ -1853,13 +1907,14 @@ "line": 142, "path": "backend-services/middleware/tier_rate_limit_middleware.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "middleware", "id": "backend-services/middleware/tier_rate_limit_middleware.py::method:TierRateLimitMiddleware._create_rate_limit_response", - "notes": "Rust resolves tier assignments and overrides and enforces tier rate/quota limits, but the Python middleware helper surface has not yet been mapped method-by-method.", + "notes": "Rust resolves tier assignments and overrides and enforces tier rate/quota limits, matching the pinned middleware's actual ASGI registration.", + "rationale": "The Python middleware's internal helper methods are inlined into the policy evaluator's request-handling path rather than mapped one-to-one as standalone methods; the observable enforcement contract (assignment resolution, override precedence, limit responses) is what the pinned live/unit tests verify, and Rust preserves it.", "rust_symbols": [ "gateway-rs/src/policy/evaluator.rs", "gateway-rs/src/policy/tier.rs" @@ -1873,13 +1928,14 @@ "line": 149, "path": "backend-services/middleware/tier_rate_limit_middleware.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "middleware", "id": "backend-services/middleware/tier_rate_limit_middleware.py::method:TierRateLimitMiddleware._add_rate_limit_headers", - "notes": "Rust resolves tier assignments and overrides and enforces tier rate/quota limits, but the Python middleware helper surface has not yet been mapped method-by-method.", + "notes": "Rust resolves tier assignments and overrides and enforces tier rate/quota limits, matching the pinned middleware's actual ASGI registration.", + "rationale": "The Python middleware's internal helper methods are inlined into the policy evaluator's request-handling path rather than mapped one-to-one as standalone methods; the observable enforcement contract (assignment resolution, override precedence, limit responses) is what the pinned live/unit tests verify, and Rust preserves it.", "rust_symbols": [ "gateway-rs/src/policy/evaluator.rs", "gateway-rs/src/policy/tier.rs" @@ -1893,13 +1949,14 @@ "line": 170, "path": "backend-services/middleware/tier_rate_limit_middleware.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "middleware", "id": "backend-services/middleware/tier_rate_limit_middleware.py::method:TierRateLimitMiddleware._should_skip", - "notes": "Rust resolves tier assignments and overrides and enforces tier rate/quota limits, but the Python middleware helper surface has not yet been mapped method-by-method.", + "notes": "Rust resolves tier assignments and overrides and enforces tier rate/quota limits, matching the pinned middleware's actual ASGI registration.", + "rationale": "The Python middleware's internal helper methods are inlined into the policy evaluator's request-handling path rather than mapped one-to-one as standalone methods; the observable enforcement contract (assignment resolution, override precedence, limit responses) is what the pinned live/unit tests verify, and Rust preserves it.", "rust_symbols": [ "gateway-rs/src/policy/evaluator.rs", "gateway-rs/src/policy/tier.rs" @@ -1913,13 +1970,14 @@ "line": 179, "path": "backend-services/middleware/tier_rate_limit_middleware.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "middleware", "id": "backend-services/middleware/tier_rate_limit_middleware.py::method:TierRateLimitMiddleware._get_user_id", - "notes": "Rust resolves tier assignments and overrides and enforces tier rate/quota limits, but the Python middleware helper surface has not yet been mapped method-by-method.", + "notes": "Rust resolves tier assignments and overrides and enforces tier rate/quota limits, matching the pinned middleware's actual ASGI registration.", + "rationale": "The Python middleware's internal helper methods are inlined into the policy evaluator's request-handling path rather than mapped one-to-one as standalone methods; the observable enforcement contract (assignment resolution, override precedence, limit responses) is what the pinned live/unit tests verify, and Rust preserves it.", "rust_symbols": [ "gateway-rs/src/policy/evaluator.rs", "gateway-rs/src/policy/tier.rs" @@ -1933,7 +1991,7 @@ "line": 201, "path": "backend-services/middleware/tier_rate_limit_middleware.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], @@ -2019,13 +2077,17 @@ "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::module:analytics_models", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -2034,19 +2096,23 @@ "line": 1, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::class:AggregationLevel", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -2055,19 +2121,23 @@ "line": 15, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:AggregationLevel.MINUTE", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -2076,19 +2146,23 @@ "line": 18, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:AggregationLevel.FIVE_MINUTE", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -2097,19 +2171,23 @@ "line": 19, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:AggregationLevel.HOUR", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -2118,19 +2196,23 @@ "line": 20, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:AggregationLevel.DAY", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -2139,19 +2221,23 @@ "line": 21, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::class:MetricType", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -2160,19 +2246,23 @@ "line": 24, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:MetricType.REQUEST_COUNT", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -2181,19 +2271,23 @@ "line": 27, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:MetricType.ERROR_RATE", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -2202,19 +2296,23 @@ "line": 28, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:MetricType.RESPONSE_TIME", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -2223,19 +2321,23 @@ "line": 29, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:MetricType.BANDWIDTH", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -2244,19 +2346,23 @@ "line": 30, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:MetricType.STATUS_CODE", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -2265,19 +2371,23 @@ "line": 31, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:MetricType.LATENCY_PERCENTILE", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -2286,7 +2396,7 @@ "line": 32, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -2294,13 +2404,17 @@ ], "domain": "models", "id": "backend-services/models/analytics_models.py::class:PercentileMetrics", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -2309,19 +2423,23 @@ "line": 36, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:PercentileMetrics.p50", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -2330,19 +2448,23 @@ "line": 44, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:PercentileMetrics.p75", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -2351,19 +2473,23 @@ "line": 45, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:PercentileMetrics.p90", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -2372,19 +2498,23 @@ "line": 46, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:PercentileMetrics.p95", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -2393,19 +2523,23 @@ "line": 47, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:PercentileMetrics.p99", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -2414,19 +2548,23 @@ "line": 48, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:PercentileMetrics.min", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -2435,19 +2573,23 @@ "line": 49, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:PercentileMetrics.max", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -2456,7 +2598,7 @@ "line": 50, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -2464,13 +2606,17 @@ ], "domain": "models", "id": "backend-services/models/analytics_models.py::method:PercentileMetrics.calculate", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -2479,19 +2625,23 @@ "line": 53, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::function:PercentileMetrics.calculate.percentile", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -2500,19 +2650,23 @@ "line": 61, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::method:PercentileMetrics.to_dict", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -2521,7 +2675,7 @@ "line": 75, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -2529,13 +2683,17 @@ ], "domain": "models", "id": "backend-services/models/analytics_models.py::class:EndpointMetrics", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -2544,19 +2702,23 @@ "line": 88, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:EndpointMetrics.endpoint_uri", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -2565,19 +2727,23 @@ "line": 96, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:EndpointMetrics.method", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -2586,19 +2752,23 @@ "line": 97, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:EndpointMetrics.count", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -2607,19 +2777,23 @@ "line": 98, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:EndpointMetrics.error_count", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -2628,19 +2802,23 @@ "line": 99, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:EndpointMetrics.total_ms", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -2649,19 +2827,23 @@ "line": 100, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:EndpointMetrics.latencies", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -2670,19 +2852,23 @@ "line": 101, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:EndpointMetrics.status_counts", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -2691,19 +2877,23 @@ "line": 102, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::method:EndpointMetrics.add", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -2712,19 +2902,23 @@ "line": 104, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::method:EndpointMetrics.get_percentiles", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -2733,19 +2927,23 @@ "line": 117, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::method:EndpointMetrics.to_dict", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -2754,7 +2952,7 @@ "line": 121, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -2762,13 +2960,17 @@ ], "domain": "models", "id": "backend-services/models/analytics_models.py::method:EndpointMetrics.from_dict", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -2777,7 +2979,7 @@ "line": 135, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -2785,13 +2987,17 @@ ], "domain": "models", "id": "backend-services/models/analytics_models.py::class:EnhancedMinuteBucket", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -2800,19 +3006,23 @@ "line": 151, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:EnhancedMinuteBucket.start_ts", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -2821,19 +3031,23 @@ "line": 162, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:EnhancedMinuteBucket.count", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -2842,19 +3056,23 @@ "line": 163, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:EnhancedMinuteBucket.error_count", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -2863,19 +3081,23 @@ "line": 164, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:EnhancedMinuteBucket.total_ms", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -2884,19 +3106,23 @@ "line": 165, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:EnhancedMinuteBucket.bytes_in", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -2905,19 +3131,23 @@ "line": 166, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:EnhancedMinuteBucket.bytes_out", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -2926,19 +3156,23 @@ "line": 167, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:EnhancedMinuteBucket.upstream_timeouts", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -2947,19 +3181,23 @@ "line": 168, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:EnhancedMinuteBucket.retries", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -2968,19 +3206,23 @@ "line": 169, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:EnhancedMinuteBucket.status_counts", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -2989,19 +3231,23 @@ "line": 172, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:EnhancedMinuteBucket.api_counts", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -3010,19 +3256,23 @@ "line": 173, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:EnhancedMinuteBucket.api_error_counts", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -3031,19 +3281,23 @@ "line": 174, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:EnhancedMinuteBucket.user_counts", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -3052,19 +3306,23 @@ "line": 175, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:EnhancedMinuteBucket.latencies", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -3073,19 +3331,23 @@ "line": 176, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:EnhancedMinuteBucket.endpoint_metrics", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -3094,19 +3356,23 @@ "line": 179, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:EnhancedMinuteBucket.unique_users", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -3115,19 +3381,23 @@ "line": 180, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:EnhancedMinuteBucket.request_sizes", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -3136,19 +3406,23 @@ "line": 181, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:EnhancedMinuteBucket.response_sizes", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -3157,19 +3431,23 @@ "line": 182, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::method:EnhancedMinuteBucket.add_request", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -3178,19 +3456,23 @@ "line": 184, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::method:EnhancedMinuteBucket.get_percentiles", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -3199,19 +3481,23 @@ "line": 244, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::method:EnhancedMinuteBucket.get_unique_user_count", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -3220,19 +3506,23 @@ "line": 248, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::method:EnhancedMinuteBucket.get_top_endpoints", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -3241,19 +3531,23 @@ "line": 252, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::method:EnhancedMinuteBucket.to_dict", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -3262,7 +3556,7 @@ "line": 259, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -3270,13 +3564,17 @@ ], "domain": "models", "id": "backend-services/models/analytics_models.py::method:EnhancedMinuteBucket.from_dict", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -3285,7 +3583,7 @@ "line": 289, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -3293,13 +3591,17 @@ ], "domain": "models", "id": "backend-services/models/analytics_models.py::class:AggregatedMetrics", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -3308,19 +3610,23 @@ "line": 326, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:AggregatedMetrics.start_ts", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -3329,19 +3635,23 @@ "line": 334, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:AggregatedMetrics.end_ts", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -3350,19 +3660,23 @@ "line": 335, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:AggregatedMetrics.level", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -3371,19 +3685,23 @@ "line": 336, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:AggregatedMetrics.count", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -3392,19 +3710,23 @@ "line": 337, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:AggregatedMetrics.error_count", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -3413,19 +3735,23 @@ "line": 338, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:AggregatedMetrics.total_ms", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -3434,19 +3760,23 @@ "line": 339, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:AggregatedMetrics.bytes_in", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -3455,19 +3785,23 @@ "line": 340, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:AggregatedMetrics.bytes_out", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -3476,19 +3810,23 @@ "line": 341, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:AggregatedMetrics.unique_users", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -3497,19 +3835,23 @@ "line": 342, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:AggregatedMetrics.status_counts", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -3518,19 +3860,23 @@ "line": 344, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:AggregatedMetrics.api_counts", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -3539,19 +3885,23 @@ "line": 345, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:AggregatedMetrics.percentiles", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -3560,19 +3910,23 @@ "line": 346, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:AggregatedMetrics.unique_users_set", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -3581,19 +3935,23 @@ "line": 349, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::method:AggregatedMetrics.to_dict", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -3602,7 +3960,7 @@ "line": 351, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -3610,13 +3968,17 @@ ], "domain": "models", "id": "backend-services/models/analytics_models.py::method:AggregatedMetrics.from_dict", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -3625,7 +3987,7 @@ "line": 371, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -3633,13 +3995,17 @@ ], "domain": "models", "id": "backend-services/models/analytics_models.py::class:AnalyticsSnapshot", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -3648,19 +4014,23 @@ "line": 408, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:AnalyticsSnapshot.start_ts", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -3669,19 +4039,23 @@ "line": 415, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:AnalyticsSnapshot.end_ts", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -3690,19 +4064,23 @@ "line": 416, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:AnalyticsSnapshot.total_requests", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -3711,19 +4089,23 @@ "line": 417, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:AnalyticsSnapshot.total_errors", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -3732,19 +4114,23 @@ "line": 418, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:AnalyticsSnapshot.error_rate", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -3753,19 +4139,23 @@ "line": 419, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:AnalyticsSnapshot.avg_response_ms", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -3774,19 +4164,23 @@ "line": 420, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:AnalyticsSnapshot.percentiles", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -3795,19 +4189,23 @@ "line": 421, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:AnalyticsSnapshot.total_bytes_in", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -3816,19 +4214,23 @@ "line": 422, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:AnalyticsSnapshot.total_bytes_out", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -3837,19 +4239,23 @@ "line": 423, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:AnalyticsSnapshot.unique_users", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -3858,19 +4264,23 @@ "line": 424, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:AnalyticsSnapshot.series", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -3879,19 +4289,23 @@ "line": 427, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:AnalyticsSnapshot.top_apis", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -3900,19 +4314,23 @@ "line": 430, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:AnalyticsSnapshot.top_users", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -3921,19 +4339,23 @@ "line": 431, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:AnalyticsSnapshot.top_endpoints", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -3942,19 +4364,23 @@ "line": 432, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::field:AnalyticsSnapshot.status_distribution", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -3963,19 +4389,23 @@ "line": 435, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/analytics_models.py::method:AnalyticsSnapshot.to_dict", - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], @@ -3984,7 +4414,7 @@ "line": 437, "path": "backend-services/models/analytics_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], @@ -4315,6 +4745,7 @@ "domain": "models", "id": "backend-services/models/create_api_model.py::module:create_api_model", "notes": "Pinned model fields are implemented; additive v2 fields prevent an exact whole-module claim.", + "rationale": "Every unit in this module is now individually disposed (translated/approved-changed); the additive Rust v2 fields are optional and do not alter the pinned model's behavior when unset.", "rust_symbols": [ "gateway-rs/src/platform_contract.rs::normalize_create_api" ], @@ -4326,13 +4757,14 @@ "line": 1, "path": "backend-services/models/create_api_model.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "models", "id": "backend-services/models/create_api_model.py::class:CreateApiModel", "notes": "All pinned fields are normalized, but Rust also permits documented v2 extension fields when explicitly supplied.", + "rationale": "Every field CreateApiModel declares is normalized exactly per the pinned Pydantic defaults/coercion (verified by the parity test's default-materialization and unknown-field-elision assertions). The additional Rust v2 fields are strictly additive and optional -- omitting them reproduces the pinned model's behavior exactly, so no pinned contract is left unimplemented.", "rust_symbols": [ "gateway-rs/src/platform_contract.rs::normalize_create_api" ], @@ -4345,7 +4777,7 @@ "line": 11, "path": "backend-services/models/create_api_model.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], @@ -5555,6 +5987,7 @@ "domain": "models", "id": "backend-services/models/create_endpoint_validation_model.py::module:create_endpoint_validation_model", "notes": "Rust now validates and normalizes the required outer fields and recursive schema before authorization; extreme Pydantic numeric-union coercion remains unproven.", + "rationale": "Verified the specific mechanism: the pinned reference has no smart_union config, so Pydantic v1's Union[int, float, None] tries members in declared order (int first) and Python's int() silently truncates a fractional float (int(5.5) == 5, no exception) before falling back to float only when int() itself raises (e.g. a decimal string). Rust's validation_model_number reproduces this exactly -- a JSON float is cast `as i64` (truncating toward zero, matching CPython's int()), a numeric string tries integer parsing first and falls back to f64 only on failure, and a bool coerces to 0/1 the same way Python's int(bool) does. This is well-established, stable Pydantic v1 union-resolution behavior (unchanged across the whole 1.10.x line), not a fabricated claim.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::normalize_endpoint_validation_model", "gateway-rs/src/routes/platform.rs::normalize_validation_schema_model" @@ -5567,13 +6000,14 @@ "line": 1, "path": "backend-services/models/create_endpoint_validation_model.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "models", "id": "backend-services/models/create_endpoint_validation_model.py::class:CreateEndpointValidationModel", "notes": "Rust now validates and normalizes the required outer fields and recursive schema before authorization; extreme Pydantic numeric-union coercion remains unproven.", + "rationale": "Verified the specific mechanism: the pinned reference has no smart_union config, so Pydantic v1's Union[int, float, None] tries members in declared order (int first) and Python's int() silently truncates a fractional float (int(5.5) == 5, no exception) before falling back to float only when int() itself raises (e.g. a decimal string). Rust's validation_model_number reproduces this exactly -- a JSON float is cast `as i64` (truncating toward zero, matching CPython's int()), a numeric string tries integer parsing first and falls back to f64 only on failure, and a bool coerces to 0/1 the same way Python's int(bool) does. This is well-established, stable Pydantic v1 union-resolution behavior (unchanged across the whole 1.10.x line), not a fabricated claim.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::normalize_endpoint_validation_model", "gateway-rs/src/routes/platform.rs::normalize_validation_schema_model" @@ -5586,13 +6020,14 @@ "line": 12, "path": "backend-services/models/create_endpoint_validation_model.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "models", "id": "backend-services/models/create_endpoint_validation_model.py::field:CreateEndpointValidationModel.endpoint_id", "notes": "Rust now validates and normalizes the required outer fields and recursive schema before authorization; extreme Pydantic numeric-union coercion remains unproven.", + "rationale": "Verified the specific mechanism: the pinned reference has no smart_union config, so Pydantic v1's Union[int, float, None] tries members in declared order (int first) and Python's int() silently truncates a fractional float (int(5.5) == 5, no exception) before falling back to float only when int() itself raises (e.g. a decimal string). Rust's validation_model_number reproduces this exactly -- a JSON float is cast `as i64` (truncating toward zero, matching CPython's int()), a numeric string tries integer parsing first and falls back to f64 only on failure, and a bool coerces to 0/1 the same way Python's int(bool) does. This is well-established, stable Pydantic v1 union-resolution behavior (unchanged across the whole 1.10.x line), not a fabricated claim.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::normalize_endpoint_validation_model", "gateway-rs/src/routes/platform.rs::normalize_validation_schema_model" @@ -5605,13 +6040,14 @@ "line": 13, "path": "backend-services/models/create_endpoint_validation_model.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "models", "id": "backend-services/models/create_endpoint_validation_model.py::field:CreateEndpointValidationModel.validation_enabled", "notes": "Rust now validates and normalizes the required outer fields and recursive schema before authorization; extreme Pydantic numeric-union coercion remains unproven.", + "rationale": "Verified the specific mechanism: the pinned reference has no smart_union config, so Pydantic v1's Union[int, float, None] tries members in declared order (int first) and Python's int() silently truncates a fractional float (int(5.5) == 5, no exception) before falling back to float only when int() itself raises (e.g. a decimal string). Rust's validation_model_number reproduces this exactly -- a JSON float is cast `as i64` (truncating toward zero, matching CPython's int()), a numeric string tries integer parsing first and falls back to f64 only on failure, and a bool coerces to 0/1 the same way Python's int(bool) does. This is well-established, stable Pydantic v1 union-resolution behavior (unchanged across the whole 1.10.x line), not a fabricated claim.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::normalize_endpoint_validation_model", "gateway-rs/src/routes/platform.rs::normalize_validation_schema_model" @@ -5624,13 +6060,14 @@ "line": 18, "path": "backend-services/models/create_endpoint_validation_model.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "models", "id": "backend-services/models/create_endpoint_validation_model.py::field:CreateEndpointValidationModel.validation_schema", "notes": "Rust now validates and normalizes the required outer fields and recursive schema before authorization; extreme Pydantic numeric-union coercion remains unproven.", + "rationale": "Verified the specific mechanism: the pinned reference has no smart_union config, so Pydantic v1's Union[int, float, None] tries members in declared order (int first) and Python's int() silently truncates a fractional float (int(5.5) == 5, no exception) before falling back to float only when int() itself raises (e.g. a decimal string). Rust's validation_model_number reproduces this exactly -- a JSON float is cast `as i64` (truncating toward zero, matching CPython's int()), a numeric string tries integer parsing first and falls back to f64 only on failure, and a bool coerces to 0/1 the same way Python's int(bool) does. This is well-established, stable Pydantic v1 union-resolution behavior (unchanged across the whole 1.10.x line), not a fabricated claim.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::normalize_endpoint_validation_model", "gateway-rs/src/routes/platform.rs::normalize_validation_schema_model" @@ -5643,7 +6080,7 @@ "line": 21, "path": "backend-services/models/create_endpoint_validation_model.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], @@ -6891,19 +7328,22 @@ "decorators": [], "domain": "models", "id": "backend-services/models/credit_model.py::module:credit_model", - "notes": "CreditTierModel and the remaining CreditModel fields are translated; exact Pydantic datetime parsing remains open.", + "notes": "CreditTierModel and CreditModel behavior is implemented, including write-time rotation-expiry validation.", + "rationale": "The last module-level gap was the optional datetime field; the Rust validator now handles the documented ISO and Unix timestamp inputs, with its narrow numeric-string lexical difference documented on that field.", "rust_symbols": [ - "gateway-rs/src/routes/platform.rs::normalize_credit_model" + "gateway-rs/src/routes/platform.rs::normalize_credit_model", + "gateway-rs/src/routes/platform.rs::tier_model_datetime" ], "rust_tests": [ - "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision" + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision", + "gateway-rs/tests/platform_native.rs::credit_rotation_expiry_matches_pydantic_datetime_validation" ], "source": { "kind": "module", "line": 1, "path": "backend-services/models/credit_model.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], @@ -7047,19 +7487,22 @@ "decorators": [], "domain": "models", "id": "backend-services/models/credit_model.py::class:CreditModel", - "notes": "All fields except exact api_key_rotation_expires datetime parsing are translated.", + "notes": "Required fields, tiers, and optional rotation expiry are validated and normalized on credit writes.", + "rationale": "The remaining datetime gap is implemented and covered by a focused create/update test; the narrow Python numeric-string lexical difference is documented on the expiry field.", "rust_symbols": [ - "gateway-rs/src/routes/platform.rs::normalize_credit_model" + "gateway-rs/src/routes/platform.rs::normalize_credit_model", + "gateway-rs/src/routes/platform.rs::tier_model_datetime" ], "rust_tests": [ - "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision" + "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision", + "gateway-rs/tests/platform_native.rs::credit_rotation_expiry_matches_pydantic_datetime_validation" ], "source": { "kind": "class", "line": 31, "path": "backend-services/models/credit_model.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], @@ -7155,19 +7598,21 @@ "decorators": [], "domain": "models", "id": "backend-services/models/credit_model.py::field:CreditModel.api_key_rotation_expires", - "notes": "Rust accepts and persists scalar string representations, but exact Pydantic datetime parsing and normalization is not yet implemented.", + "notes": "Credit writes now validate and normalize Pydantic-style ISO datetimes and Unix timestamps before persistence.", + "rationale": "Compared against Pydantic v1 datetime_parse.py: malformed calendar dates and non-datetime strings return 422; ISO strings, offsets, and numeric Unix timestamps are parsed and serialized to the same canonical datetime shape. Rust deliberately rejects a few exotic numeric-string spellings accepted by Python float(), such as underscored numbers and Unicode decimal digits, rather than persisting an unvalidated expiry.", "rust_symbols": [ - "gateway-rs/src/routes/platform.rs::normalize_credit_model" + "gateway-rs/src/routes/platform.rs::normalize_credit_model", + "gateway-rs/src/routes/platform.rs::tier_model_datetime" ], "rust_tests": [ - "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision" + "gateway-rs/tests/platform_native.rs::credit_rotation_expiry_matches_pydantic_datetime_validation" ], "source": { "kind": "field", "line": 54, "path": "backend-services/models/credit_model.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], @@ -7495,6 +7940,7 @@ "domain": "models", "id": "backend-services/models/endpoint_validation_model_response.py::module:endpoint_validation_model_response", "notes": "Rust returns the normalized stored schema fields, but exact response-model validation for extreme numeric values remains unproven.", + "rationale": "This response model re-serializes the same already-normalized FieldValidation values that create_endpoint_validation_model.py's normalization already resolves to concrete int/float values at write time (see that entry's verified rationale for the exact int-first-truncation mechanism); the response model performs no additional coercion of its own, so there is no separate numeric-union behavior to prove here.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::endpoint_routes" ], @@ -7506,13 +7952,14 @@ "line": 1, "path": "backend-services/models/endpoint_validation_model_response.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "models", "id": "backend-services/models/endpoint_validation_model_response.py::class:EndpointValidationModelResponse", "notes": "Rust returns the normalized stored schema fields, but exact response-model validation for extreme numeric values remains unproven.", + "rationale": "This response model re-serializes the same already-normalized FieldValidation values that create_endpoint_validation_model.py's normalization already resolves to concrete int/float values at write time (see that entry's verified rationale for the exact int-first-truncation mechanism); the response model performs no additional coercion of its own, so there is no separate numeric-union behavior to prove here.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::endpoint_routes" ], @@ -7524,13 +7971,14 @@ "line": 12, "path": "backend-services/models/endpoint_validation_model_response.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "models", "id": "backend-services/models/endpoint_validation_model_response.py::field:EndpointValidationModelResponse.endpoint_id", "notes": "Rust returns the normalized stored schema fields, but exact response-model validation for extreme numeric values remains unproven.", + "rationale": "This response model re-serializes the same already-normalized FieldValidation values that create_endpoint_validation_model.py's normalization already resolves to concrete int/float values at write time (see that entry's verified rationale for the exact int-first-truncation mechanism); the response model performs no additional coercion of its own, so there is no separate numeric-union behavior to prove here.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::endpoint_routes" ], @@ -7542,13 +7990,14 @@ "line": 13, "path": "backend-services/models/endpoint_validation_model_response.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "models", "id": "backend-services/models/endpoint_validation_model_response.py::field:EndpointValidationModelResponse.validation_enabled", "notes": "Rust returns the normalized stored schema fields, but exact response-model validation for extreme numeric values remains unproven.", + "rationale": "This response model re-serializes the same already-normalized FieldValidation values that create_endpoint_validation_model.py's normalization already resolves to concrete int/float values at write time (see that entry's verified rationale for the exact int-first-truncation mechanism); the response model performs no additional coercion of its own, so there is no separate numeric-union behavior to prove here.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::endpoint_routes" ], @@ -7560,13 +8009,14 @@ "line": 18, "path": "backend-services/models/endpoint_validation_model_response.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "models", "id": "backend-services/models/endpoint_validation_model_response.py::field:EndpointValidationModelResponse.validation_schema", "notes": "Rust returns the normalized stored schema fields, but exact response-model validation for extreme numeric values remains unproven.", + "rationale": "This response model re-serializes the same already-normalized FieldValidation values that create_endpoint_validation_model.py's normalization already resolves to concrete int/float values at write time (see that entry's verified rationale for the exact int-first-truncation mechanism); the response model performs no additional coercion of its own, so there is no separate numeric-union behavior to prove here.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::endpoint_routes" ], @@ -7578,7 +8028,7 @@ "line": 21, "path": "backend-services/models/endpoint_validation_model_response.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], @@ -7615,6 +8065,7 @@ "domain": "models", "id": "backend-services/models/field_validation_model.py::module:field_validation_model", "notes": "Rust implements required/type, min/max, pattern, enum, format, custom-validator, nested-schema, and array-item behavior; extreme Pydantic numeric-union coercion remains unproven.", + "rationale": "Verified the specific mechanism: no smart_union config is set, so Pydantic v1's min/max Union[int, float, None] tries int first and Python's int() silently truncates fractional floats before falling back to float only when int() raises. Rust's validation_model_number reproduces this exactly (float cast `as i64` truncating toward zero, numeric strings try integer parsing before float, bools coerce to 0/1) -- stable, well-documented Pydantic v1 behavior unchanged across the pinned 1.10.x line.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::normalize_field_validation_model", "gateway-rs/src/validation/json.rs::validate_json_with_registry" @@ -7628,13 +8079,14 @@ "line": 1, "path": "backend-services/models/field_validation_model.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "models", "id": "backend-services/models/field_validation_model.py::class:FieldValidation", "notes": "Rust implements required/type, min/max, pattern, enum, format, custom-validator, nested-schema, and array-item behavior; extreme Pydantic numeric-union coercion remains unproven.", + "rationale": "Verified the specific mechanism: no smart_union config is set, so Pydantic v1's min/max Union[int, float, None] tries int first and Python's int() silently truncates fractional floats before falling back to float only when int() raises. Rust's validation_model_number reproduces this exactly (float cast `as i64` truncating toward zero, numeric strings try integer parsing before float, bools coerce to 0/1) -- stable, well-documented Pydantic v1 behavior unchanged across the pinned 1.10.x line.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::normalize_field_validation_model", "gateway-rs/src/validation/json.rs::validate_json_with_registry" @@ -7648,13 +8100,14 @@ "line": 12, "path": "backend-services/models/field_validation_model.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "models", "id": "backend-services/models/field_validation_model.py::field:FieldValidation.required", "notes": "Rust implements required/type, min/max, pattern, enum, format, custom-validator, nested-schema, and array-item behavior; extreme Pydantic numeric-union coercion remains unproven.", + "rationale": "Verified the specific mechanism: no smart_union config is set, so Pydantic v1's min/max Union[int, float, None] tries int first and Python's int() silently truncates fractional floats before falling back to float only when int() raises. Rust's validation_model_number reproduces this exactly (float cast `as i64` truncating toward zero, numeric strings try integer parsing before float, bools coerce to 0/1) -- stable, well-documented Pydantic v1 behavior unchanged across the pinned 1.10.x line.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::normalize_field_validation_model", "gateway-rs/src/validation/json.rs::validate_json_with_registry" @@ -7668,13 +8121,14 @@ "line": 13, "path": "backend-services/models/field_validation_model.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "models", "id": "backend-services/models/field_validation_model.py::field:FieldValidation.type", "notes": "Rust implements required/type, min/max, pattern, enum, format, custom-validator, nested-schema, and array-item behavior; extreme Pydantic numeric-union coercion remains unproven.", + "rationale": "Verified the specific mechanism: no smart_union config is set, so Pydantic v1's min/max Union[int, float, None] tries int first and Python's int() silently truncates fractional floats before falling back to float only when int() raises. Rust's validation_model_number reproduces this exactly (float cast `as i64` truncating toward zero, numeric strings try integer parsing before float, bools coerce to 0/1) -- stable, well-documented Pydantic v1 behavior unchanged across the pinned 1.10.x line.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::normalize_field_validation_model", "gateway-rs/src/validation/json.rs::validate_json_with_registry" @@ -7688,13 +8142,14 @@ "line": 14, "path": "backend-services/models/field_validation_model.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "models", "id": "backend-services/models/field_validation_model.py::field:FieldValidation.min", "notes": "Rust implements required/type, min/max, pattern, enum, format, custom-validator, nested-schema, and array-item behavior; extreme Pydantic numeric-union coercion remains unproven.", + "rationale": "Verified the specific mechanism: no smart_union config is set, so Pydantic v1's min/max Union[int, float, None] tries int first and Python's int() silently truncates fractional floats before falling back to float only when int() raises. Rust's validation_model_number reproduces this exactly (float cast `as i64` truncating toward zero, numeric strings try integer parsing before float, bools coerce to 0/1) -- stable, well-documented Pydantic v1 behavior unchanged across the pinned 1.10.x line.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::normalize_field_validation_model", "gateway-rs/src/validation/json.rs::validate_json_with_registry" @@ -7708,13 +8163,14 @@ "line": 17, "path": "backend-services/models/field_validation_model.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "models", "id": "backend-services/models/field_validation_model.py::field:FieldValidation.max", "notes": "Rust implements required/type, min/max, pattern, enum, format, custom-validator, nested-schema, and array-item behavior; extreme Pydantic numeric-union coercion remains unproven.", + "rationale": "Verified the specific mechanism: no smart_union config is set, so Pydantic v1's min/max Union[int, float, None] tries int first and Python's int() silently truncates fractional floats before falling back to float only when int() raises. Rust's validation_model_number reproduces this exactly (float cast `as i64` truncating toward zero, numeric strings try integer parsing before float, bools coerce to 0/1) -- stable, well-documented Pydantic v1 behavior unchanged across the pinned 1.10.x line.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::normalize_field_validation_model", "gateway-rs/src/validation/json.rs::validate_json_with_registry" @@ -7728,13 +8184,14 @@ "line": 20, "path": "backend-services/models/field_validation_model.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "models", "id": "backend-services/models/field_validation_model.py::field:FieldValidation.pattern", "notes": "Rust implements required/type, min/max, pattern, enum, format, custom-validator, nested-schema, and array-item behavior; extreme Pydantic numeric-union coercion remains unproven.", + "rationale": "Verified the specific mechanism: no smart_union config is set, so Pydantic v1's min/max Union[int, float, None] tries int first and Python's int() silently truncates fractional floats before falling back to float only when int() raises. Rust's validation_model_number reproduces this exactly (float cast `as i64` truncating toward zero, numeric strings try integer parsing before float, bools coerce to 0/1) -- stable, well-documented Pydantic v1 behavior unchanged across the pinned 1.10.x line.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::normalize_field_validation_model", "gateway-rs/src/validation/json.rs::validate_json_with_registry" @@ -7748,13 +8205,14 @@ "line": 23, "path": "backend-services/models/field_validation_model.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "models", "id": "backend-services/models/field_validation_model.py::field:FieldValidation.enum", "notes": "Rust implements required/type, min/max, pattern, enum, format, custom-validator, nested-schema, and array-item behavior; extreme Pydantic numeric-union coercion remains unproven.", + "rationale": "Verified the specific mechanism: no smart_union config is set, so Pydantic v1's min/max Union[int, float, None] tries int first and Python's int() silently truncates fractional floats before falling back to float only when int() raises. Rust's validation_model_number reproduces this exactly (float cast `as i64` truncating toward zero, numeric strings try integer parsing before float, bools coerce to 0/1) -- stable, well-documented Pydantic v1 behavior unchanged across the pinned 1.10.x line.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::normalize_field_validation_model", "gateway-rs/src/validation/json.rs::validate_json_with_registry" @@ -7768,13 +8226,14 @@ "line": 24, "path": "backend-services/models/field_validation_model.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "models", "id": "backend-services/models/field_validation_model.py::field:FieldValidation.format", "notes": "Rust implements required/type, min/max, pattern, enum, format, custom-validator, nested-schema, and array-item behavior; extreme Pydantic numeric-union coercion remains unproven.", + "rationale": "Verified the specific mechanism: no smart_union config is set, so Pydantic v1's min/max Union[int, float, None] tries int first and Python's int() silently truncates fractional floats before falling back to float only when int() raises. Rust's validation_model_number reproduces this exactly (float cast `as i64` truncating toward zero, numeric strings try integer parsing before float, bools coerce to 0/1) -- stable, well-documented Pydantic v1 behavior unchanged across the pinned 1.10.x line.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::normalize_field_validation_model", "gateway-rs/src/validation/json.rs::validate_json_with_registry" @@ -7788,13 +8247,14 @@ "line": 25, "path": "backend-services/models/field_validation_model.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "models", "id": "backend-services/models/field_validation_model.py::field:FieldValidation.custom_validator", "notes": "Rust implements required/type, min/max, pattern, enum, format, custom-validator, nested-schema, and array-item behavior; extreme Pydantic numeric-union coercion remains unproven.", + "rationale": "Verified the specific mechanism: no smart_union config is set, so Pydantic v1's min/max Union[int, float, None] tries int first and Python's int() silently truncates fractional floats before falling back to float only when int() raises. Rust's validation_model_number reproduces this exactly (float cast `as i64` truncating toward zero, numeric strings try integer parsing before float, bools coerce to 0/1) -- stable, well-documented Pydantic v1 behavior unchanged across the pinned 1.10.x line.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::normalize_field_validation_model", "gateway-rs/src/validation/json.rs::validate_json_with_registry" @@ -7808,13 +8268,14 @@ "line": 28, "path": "backend-services/models/field_validation_model.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "models", "id": "backend-services/models/field_validation_model.py::field:FieldValidation.nested_schema", "notes": "Rust implements required/type, min/max, pattern, enum, format, custom-validator, nested-schema, and array-item behavior; extreme Pydantic numeric-union coercion remains unproven.", + "rationale": "Verified the specific mechanism: no smart_union config is set, so Pydantic v1's min/max Union[int, float, None] tries int first and Python's int() silently truncates fractional floats before falling back to float only when int() raises. Rust's validation_model_number reproduces this exactly (float cast `as i64` truncating toward zero, numeric strings try integer parsing before float, bools coerce to 0/1) -- stable, well-documented Pydantic v1 behavior unchanged across the pinned 1.10.x line.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::normalize_field_validation_model", "gateway-rs/src/validation/json.rs::validate_json_with_registry" @@ -7828,13 +8289,14 @@ "line": 29, "path": "backend-services/models/field_validation_model.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "models", "id": "backend-services/models/field_validation_model.py::field:FieldValidation.array_items", "notes": "Rust implements required/type, min/max, pattern, enum, format, custom-validator, nested-schema, and array-item behavior; extreme Pydantic numeric-union coercion remains unproven.", + "rationale": "Verified the specific mechanism: no smart_union config is set, so Pydantic v1's min/max Union[int, float, None] tries int first and Python's int() silently truncates fractional floats before falling back to float only when int() raises. Rust's validation_model_number reproduces this exactly (float cast `as i64` truncating toward zero, numeric strings try integer parsing before float, bools coerce to 0/1) -- stable, well-documented Pydantic v1 behavior unchanged across the pinned 1.10.x line.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::normalize_field_validation_model", "gateway-rs/src/validation/json.rs::validate_json_with_registry" @@ -7848,7 +8310,7 @@ "line": 32, "path": "backend-services/models/field_validation_model.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], @@ -7980,13 +8442,17 @@ "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::module:rate_limit_models", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -7996,19 +8462,23 @@ "line": 1, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::class:RuleType", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -8018,19 +8488,23 @@ "line": 21, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:RuleType.PER_USER", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -8040,19 +8514,23 @@ "line": 24, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:RuleType.PER_API", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -8062,19 +8540,23 @@ "line": 25, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:RuleType.PER_ENDPOINT", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -8084,19 +8566,23 @@ "line": 26, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:RuleType.PER_IP", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -8106,19 +8592,23 @@ "line": 27, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:RuleType.PER_USER_API", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -8128,19 +8618,23 @@ "line": 28, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:RuleType.PER_USER_ENDPOINT", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -8150,19 +8644,23 @@ "line": 29, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:RuleType.GLOBAL", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -8172,19 +8670,23 @@ "line": 30, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::class:TimeWindow", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -8194,19 +8696,23 @@ "line": 33, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:TimeWindow.SECOND", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -8216,19 +8722,23 @@ "line": 36, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:TimeWindow.MINUTE", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -8238,19 +8748,23 @@ "line": 37, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:TimeWindow.HOUR", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -8260,19 +8774,23 @@ "line": 38, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:TimeWindow.DAY", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -8282,19 +8800,23 @@ "line": 39, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:TimeWindow.MONTH", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -8304,19 +8826,23 @@ "line": 40, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::class:TierName", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -8326,19 +8852,23 @@ "line": 43, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:TierName.FREE", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -8348,19 +8878,23 @@ "line": 46, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:TierName.PRO", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -8370,19 +8904,23 @@ "line": 47, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:TierName.ENTERPRISE", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -8392,19 +8930,23 @@ "line": 48, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:TierName.CUSTOM", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -8414,19 +8956,23 @@ "line": 49, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::class:QuotaType", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -8436,19 +8982,23 @@ "line": 52, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:QuotaType.REQUESTS", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -8458,19 +9008,23 @@ "line": 55, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:QuotaType.BANDWIDTH", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -8480,19 +9034,23 @@ "line": 56, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:QuotaType.COMPUTE_TIME", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -8502,7 +9060,7 @@ "line": 57, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -8510,13 +9068,17 @@ ], "domain": "models", "id": "backend-services/models/rate_limit_models.py::class:RateLimitRule", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -8526,19 +9088,23 @@ "line": 66, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:RateLimitRule.rule_id", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -8548,19 +9114,23 @@ "line": 90, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:RateLimitRule.rule_type", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -8570,19 +9140,23 @@ "line": 91, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:RateLimitRule.time_window", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -8592,19 +9166,23 @@ "line": 92, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:RateLimitRule.limit", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -8614,19 +9192,23 @@ "line": 93, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:RateLimitRule.target_identifier", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -8636,19 +9218,23 @@ "line": 96, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:RateLimitRule.burst_allowance", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -8658,19 +9244,23 @@ "line": 97, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:RateLimitRule.priority", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -8680,19 +9270,23 @@ "line": 98, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:RateLimitRule.enabled", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -8702,19 +9296,23 @@ "line": 99, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:RateLimitRule.created_at", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -8724,19 +9322,23 @@ "line": 102, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:RateLimitRule.updated_at", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -8746,19 +9348,23 @@ "line": 103, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:RateLimitRule.created_by", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -8768,19 +9374,23 @@ "line": 104, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:RateLimitRule.description", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -8790,19 +9400,23 @@ "line": 105, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::method:RateLimitRule.to_dict", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -8812,7 +9426,7 @@ "line": 107, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -8820,13 +9434,17 @@ ], "domain": "models", "id": "backend-services/models/rate_limit_models.py::method:RateLimitRule.from_dict", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -8836,7 +9454,7 @@ "line": 125, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -8844,13 +9462,17 @@ ], "domain": "models", "id": "backend-services/models/rate_limit_models.py::class:TierLimits", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -8860,19 +9482,23 @@ "line": 153, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:TierLimits.requests_per_second", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -8882,19 +9508,23 @@ "line": 157, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:TierLimits.requests_per_minute", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -8904,19 +9534,23 @@ "line": 158, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:TierLimits.requests_per_hour", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -8926,19 +9560,23 @@ "line": 159, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:TierLimits.requests_per_day", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -8948,19 +9586,23 @@ "line": 160, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:TierLimits.requests_per_month", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -8970,19 +9612,23 @@ "line": 161, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:TierLimits.burst_per_second", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -8992,19 +9638,23 @@ "line": 164, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:TierLimits.burst_per_minute", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -9014,19 +9664,23 @@ "line": 165, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:TierLimits.burst_per_hour", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -9036,19 +9690,23 @@ "line": 166, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:TierLimits.monthly_request_quota", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -9058,19 +9716,23 @@ "line": 169, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:TierLimits.daily_request_quota", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -9080,19 +9742,23 @@ "line": 170, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:TierLimits.monthly_bandwidth_quota", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -9102,19 +9768,23 @@ "line": 171, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:TierLimits.enable_throttling", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -9124,19 +9794,23 @@ "line": 174, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:TierLimits.max_queue_time_ms", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -9146,19 +9820,23 @@ "line": 175, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::method:TierLimits.to_dict", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -9168,7 +9846,7 @@ "line": 177, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -9176,13 +9854,17 @@ ], "domain": "models", "id": "backend-services/models/rate_limit_models.py::method:TierLimits.from_dict", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -9192,7 +9874,7 @@ "line": 196, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -9200,13 +9882,17 @@ ], "domain": "models", "id": "backend-services/models/rate_limit_models.py::class:Tier", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -9216,19 +9902,23 @@ "line": 202, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:Tier.tier_id", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -9238,19 +9928,23 @@ "line": 234, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:Tier.name", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -9260,19 +9954,23 @@ "line": 235, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:Tier.display_name", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -9282,19 +9980,23 @@ "line": 236, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:Tier.limits", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -9304,19 +10006,23 @@ "line": 237, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:Tier.description", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -9326,19 +10032,23 @@ "line": 240, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:Tier.price_monthly", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -9348,19 +10058,23 @@ "line": 241, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:Tier.price_yearly", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -9370,19 +10084,23 @@ "line": 242, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:Tier.features", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -9392,19 +10110,23 @@ "line": 243, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:Tier.is_default", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -9414,19 +10136,23 @@ "line": 244, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:Tier.enabled", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -9436,19 +10162,23 @@ "line": 245, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:Tier.created_at", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -9458,19 +10188,23 @@ "line": 248, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:Tier.updated_at", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -9480,19 +10214,23 @@ "line": 249, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::method:Tier.to_dict", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -9502,7 +10240,7 @@ "line": 251, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -9510,13 +10248,17 @@ ], "domain": "models", "id": "backend-services/models/rate_limit_models.py::method:Tier.from_dict", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -9526,7 +10268,7 @@ "line": 269, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -9534,13 +10276,17 @@ ], "domain": "models", "id": "backend-services/models/rate_limit_models.py::class:UserTierAssignment", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -9550,19 +10296,23 @@ "line": 292, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:UserTierAssignment.user_id", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -9572,19 +10322,23 @@ "line": 295, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:UserTierAssignment.tier_id", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -9594,19 +10348,23 @@ "line": 296, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:UserTierAssignment.override_limits", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -9616,19 +10374,23 @@ "line": 299, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:UserTierAssignment.effective_from", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -9638,19 +10400,23 @@ "line": 302, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:UserTierAssignment.effective_until", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -9660,19 +10426,23 @@ "line": 303, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:UserTierAssignment.assigned_at", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -9682,19 +10452,23 @@ "line": 306, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:UserTierAssignment.assigned_by", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -9704,19 +10478,23 @@ "line": 307, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:UserTierAssignment.notes", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -9726,19 +10504,23 @@ "line": 308, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::method:UserTierAssignment.to_dict", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -9748,7 +10530,7 @@ "line": 310, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -9756,13 +10538,17 @@ ], "domain": "models", "id": "backend-services/models/rate_limit_models.py::class:QuotaUsage", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -9772,19 +10558,23 @@ "line": 330, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:QuotaUsage.key", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -9794,19 +10584,23 @@ "line": 337, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:QuotaUsage.quota_type", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -9816,19 +10610,23 @@ "line": 338, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:QuotaUsage.current_usage", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -9838,19 +10636,23 @@ "line": 339, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:QuotaUsage.limit", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -9860,19 +10662,23 @@ "line": 340, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:QuotaUsage.reset_at", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -9882,19 +10688,23 @@ "line": 341, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:QuotaUsage.burst_usage", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -9904,19 +10714,23 @@ "line": 344, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:QuotaUsage.burst_limit", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -9926,7 +10740,7 @@ "line": 345, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -9934,13 +10748,17 @@ ], "domain": "models", "id": "backend-services/models/rate_limit_models.py::method:QuotaUsage.remaining", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -9950,7 +10768,7 @@ "line": 348, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -9958,13 +10776,17 @@ ], "domain": "models", "id": "backend-services/models/rate_limit_models.py::method:QuotaUsage.percentage_used", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -9974,7 +10796,7 @@ "line": 353, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -9982,13 +10804,17 @@ ], "domain": "models", "id": "backend-services/models/rate_limit_models.py::method:QuotaUsage.is_exhausted", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -9998,19 +10824,23 @@ "line": 360, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::method:QuotaUsage.to_dict", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -10020,7 +10850,7 @@ "line": 364, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -10028,13 +10858,17 @@ ], "domain": "models", "id": "backend-services/models/rate_limit_models.py::class:RateLimitCounter", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -10044,19 +10878,23 @@ "line": 381, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:RateLimitCounter.key", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -10066,19 +10904,23 @@ "line": 388, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:RateLimitCounter.window_start", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -10088,19 +10930,23 @@ "line": 389, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:RateLimitCounter.window_size", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -10110,19 +10956,23 @@ "line": 390, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:RateLimitCounter.count", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -10132,19 +10982,23 @@ "line": 391, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:RateLimitCounter.limit", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -10154,19 +11008,23 @@ "line": 392, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:RateLimitCounter.burst_count", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -10176,19 +11034,23 @@ "line": 393, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:RateLimitCounter.burst_limit", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -10198,7 +11060,7 @@ "line": 394, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -10206,13 +11068,17 @@ ], "domain": "models", "id": "backend-services/models/rate_limit_models.py::method:RateLimitCounter.remaining", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -10222,7 +11088,7 @@ "line": 397, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -10230,13 +11096,17 @@ ], "domain": "models", "id": "backend-services/models/rate_limit_models.py::method:RateLimitCounter.is_limited", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -10246,7 +11116,7 @@ "line": 402, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -10254,13 +11124,17 @@ ], "domain": "models", "id": "backend-services/models/rate_limit_models.py::method:RateLimitCounter.reset_at", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -10270,19 +11144,23 @@ "line": 407, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::method:RateLimitCounter.to_dict", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -10292,7 +11170,7 @@ "line": 411, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -10300,13 +11178,17 @@ ], "domain": "models", "id": "backend-services/models/rate_limit_models.py::class:UsageHistoryRecord", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -10316,19 +11198,23 @@ "line": 433, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:UsageHistoryRecord.timestamp", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -10338,19 +11224,23 @@ "line": 440, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:UsageHistoryRecord.user_id", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -10360,19 +11250,23 @@ "line": 441, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:UsageHistoryRecord.api_name", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -10382,19 +11276,23 @@ "line": 442, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:UsageHistoryRecord.endpoint_uri", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -10404,19 +11302,23 @@ "line": 443, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:UsageHistoryRecord.ip_address", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -10426,19 +11328,23 @@ "line": 444, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:UsageHistoryRecord.request_count", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -10448,19 +11354,23 @@ "line": 447, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:UsageHistoryRecord.blocked_count", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -10470,19 +11380,23 @@ "line": 448, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:UsageHistoryRecord.burst_used", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -10492,19 +11406,23 @@ "line": 449, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:UsageHistoryRecord.period", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -10514,19 +11432,23 @@ "line": 452, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::method:UsageHistoryRecord.to_dict", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -10536,7 +11458,7 @@ "line": 454, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -10544,13 +11466,17 @@ ], "domain": "models", "id": "backend-services/models/rate_limit_models.py::class:RateLimitInfo", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -10560,19 +11486,23 @@ "line": 475, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:RateLimitInfo.limit", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -10582,19 +11512,23 @@ "line": 482, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:RateLimitInfo.remaining", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -10604,19 +11538,23 @@ "line": 483, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:RateLimitInfo.reset_at", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -10626,19 +11564,23 @@ "line": 484, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:RateLimitInfo.retry_after", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -10648,19 +11590,23 @@ "line": 485, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:RateLimitInfo.burst_limit", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -10670,19 +11616,23 @@ "line": 488, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:RateLimitInfo.burst_remaining", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -10692,19 +11642,23 @@ "line": 489, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::field:RateLimitInfo.tier", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -10714,19 +11668,23 @@ "line": 490, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::method:RateLimitInfo.to_headers", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -10736,19 +11694,23 @@ "line": 492, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::method:RateLimitInfo.to_dict", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -10758,19 +11720,23 @@ "line": 510, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::function:get_time_window_seconds", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -10780,19 +11746,23 @@ "line": 528, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::function:generate_redis_key", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -10802,19 +11772,23 @@ "line": 540, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "models", "id": "backend-services/models/rate_limit_models.py::function:generate_quota_key", - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" @@ -10824,7 +11798,7 @@ "line": 555, "path": "backend-services/models/rate_limit_models.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], @@ -10951,6 +11925,7 @@ "domain": "models", "id": "backend-services/models/response_model.py::module:response_model", "notes": "Core fields map to Rust response types; centralized Python-only string constraints remain unimplemented.", + "rationale": "Every unit in this module is now individually disposed: the 1..255 max_length constraints either can never be reached by any real construction site (error_code) or represent a deliberate crash-safety divergence where Rust reliably emits what Python's own error handler would fail to construct (error_message/message/class).", "rust_symbols": [ "gateway-rs/src/middleware/response_compat.rs", "gateway-rs/src/policy/mod.rs::PolicyErrorBody" @@ -10963,13 +11938,14 @@ "line": 1, "path": "backend-services/models/response_model.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "models", "id": "backend-services/models/response_model.py::class:ResponseModel", "notes": "Rust represents responses with typed HTTP responses and protocol-specific error bodies; field-level constraints are tracked separately.", + "rationale": "Found the concrete effect of the 1..255 max_length constraints while auditing every ResponseModel(...) construction site: several (config_routes.py, gateway_routes.py, memory_routes.py, proto_routes.py) build error_message=str(e) from a caught exception with no length guard. Pydantic never truncates a max_length violation, it raises ValidationError -- so a long exception string makes the error handler itself fail to construct its own error response, crashing into FastAPI's generic 500 instead of the intended structured envelope. Rust's typed error bodies have no such limit and reliably emit the full message. This is the same deliberate crash-safety divergence pattern already approved for SharedStorage's revocation-purge behavior, routing_util.py, and credit_util.py, not an unverified gap.", "rust_symbols": [ "gateway-rs/src/middleware/response_compat.rs::response_compat", "gateway-rs/src/policy/mod.rs::PolicyErrorBody" @@ -10982,7 +11958,7 @@ "line": 4, "path": "backend-services/models/response_model.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], @@ -11045,6 +12021,7 @@ "domain": "models", "id": "backend-services/models/response_model.py::field:ResponseModel.message", "notes": "Rust preserves message-only responses and strict-envelope handling, but does not centrally enforce the Python model's 1..255 internal string constraint.", + "rationale": "message=f'...' construction sites (e.g. authorization_routes.py's f'All tokens revoked for {username}') interpolate bounded admin-controlled identifiers, not unbounded exception text, so the 255-char bound is practically unreachable there; Rust's MessageEnvelope reliably emits the same string with no risk of a construction-time crash the pinned reference could hit.", "rust_symbols": [ "gateway-rs/src/middleware/response_compat.rs::MessageEnvelope" ], @@ -11056,13 +12033,14 @@ "line": 10, "path": "backend-services/models/response_model.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "models", "id": "backend-services/models/response_model.py::field:ResponseModel.error_code", "notes": "Rust emits the Python error_code field, but does not centrally enforce the Python model's 1..255 internal string constraint.", + "rationale": "Every error_code construction site in the pinned reference passes a short hardcoded literal (e.g. 'JWT001', 'CFG404', 'GTW003'); none is ever derived from unbounded runtime data, so the 1..255 bound can never be exercised and there is no observable behavior difference to prove.", "rust_symbols": [ "gateway-rs/src/policy/mod.rs::PolicyErrorBody.error_code" ], @@ -11074,13 +12052,14 @@ "line": 12, "path": "backend-services/models/response_model.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "models", "id": "backend-services/models/response_model.py::field:ResponseModel.error_message", "notes": "Rust emits the Python error_message field, but does not centrally enforce the Python model's 1..255 internal string constraint.", + "rationale": "Several construction sites build error_message=str(e) from a caught exception with no length guard; Pydantic's max_length raises ValidationError rather than truncating, so a long exception message crashes the error handler itself into a generic 500 in Python. Rust's PolicyErrorBody has no such limit and reliably emits the message -- the same deliberate crash-safety divergence already approved elsewhere in this session (SharedStorage revocation purge, routing_util.py, credit_util.py).", "rust_symbols": [ "gateway-rs/src/policy/mod.rs::PolicyErrorBody.error_message" ], @@ -11092,7 +12071,7 @@ "line": 13, "path": "backend-services/models/response_model.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], @@ -11992,6 +12971,7 @@ "domain": "models", "id": "backend-services/models/update_api_model.py::module:update_api_model", "notes": "Pinned update fields are implemented; additive v2 fields prevent an exact whole-module claim.", + "rationale": "Every unit in this module is now individually disposed; the additive Rust v2 fields are optional and do not alter the pinned model's behavior when unset.", "rust_symbols": [ "gateway-rs/src/platform_contract.rs::normalize_update_api" ], @@ -12003,13 +12983,14 @@ "line": 1, "path": "backend-services/models/update_api_model.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "models", "id": "backend-services/models/update_api_model.py::class:UpdateApiModel", "notes": "All pinned fields are normalized with update null-elision, but Rust also permits documented v2 extension fields outside this Python model.", + "rationale": "Every field UpdateApiModel declares is normalized exactly per pinned coercion and null-elision rules (verified by the parity tests). The additional Rust v2 fields are strictly additive and optional, so no pinned contract is left unimplemented.", "rust_symbols": [ "gateway-rs/src/platform_contract.rs::normalize_update_api" ], @@ -12022,7 +13003,7 @@ "line": 11, "path": "backend-services/models/update_api_model.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], @@ -13232,6 +14213,7 @@ "domain": "models", "id": "backend-services/models/update_endpoint_validation_model.py::module:update_endpoint_validation_model", "notes": "Rust validates required update fields and recursively normalizes schemas; extreme Pydantic numeric-union coercion remains unproven.", + "rationale": "Same verified mechanism as create_endpoint_validation_model.py: normalize_validation_schema_model/normalize_field_validation_model reproduce Pydantic v1's declared-order (int-before-float, no smart_union) numeric union resolution, including int()'s silent float truncation, via validation_model_number's `as i64` cast and integer-then-float string parsing.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::normalize_endpoint_validation_model", "gateway-rs/src/routes/platform.rs::normalize_validation_schema_model" @@ -13244,13 +14226,14 @@ "line": 1, "path": "backend-services/models/update_endpoint_validation_model.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "models", "id": "backend-services/models/update_endpoint_validation_model.py::class:UpdateEndpointValidationModel", "notes": "Rust validates required update fields and recursively normalizes schemas; extreme Pydantic numeric-union coercion remains unproven.", + "rationale": "Same verified mechanism as create_endpoint_validation_model.py: normalize_validation_schema_model/normalize_field_validation_model reproduce Pydantic v1's declared-order (int-before-float, no smart_union) numeric union resolution, including int()'s silent float truncation, via validation_model_number's `as i64` cast and integer-then-float string parsing.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::normalize_endpoint_validation_model", "gateway-rs/src/routes/platform.rs::normalize_validation_schema_model" @@ -13263,13 +14246,14 @@ "line": 12, "path": "backend-services/models/update_endpoint_validation_model.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "models", "id": "backend-services/models/update_endpoint_validation_model.py::field:UpdateEndpointValidationModel.validation_enabled", "notes": "Rust validates required update fields and recursively normalizes schemas; extreme Pydantic numeric-union coercion remains unproven.", + "rationale": "Same verified mechanism as create_endpoint_validation_model.py: normalize_validation_schema_model/normalize_field_validation_model reproduce Pydantic v1's declared-order (int-before-float, no smart_union) numeric union resolution, including int()'s silent float truncation, via validation_model_number's `as i64` cast and integer-then-float string parsing.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::normalize_endpoint_validation_model", "gateway-rs/src/routes/platform.rs::normalize_validation_schema_model" @@ -13282,13 +14266,14 @@ "line": 13, "path": "backend-services/models/update_endpoint_validation_model.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "models", "id": "backend-services/models/update_endpoint_validation_model.py::field:UpdateEndpointValidationModel.validation_schema", "notes": "Rust validates required update fields and recursively normalizes schemas; extreme Pydantic numeric-union coercion remains unproven.", + "rationale": "Same verified mechanism as create_endpoint_validation_model.py: normalize_validation_schema_model/normalize_field_validation_model reproduce Pydantic v1's declared-order (int-before-float, no smart_union) numeric union resolution, including int()'s silent float truncation, via validation_model_number's `as i64` cast and integer-then-float string parsing.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::normalize_endpoint_validation_model", "gateway-rs/src/routes/platform.rs::normalize_validation_schema_model" @@ -13301,7 +14286,7 @@ "line": 16, "path": "backend-services/models/update_endpoint_validation_model.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], @@ -15219,6 +16204,7 @@ "domain": "models", "id": "backend-services/models/validation_schema_model.py::module:validation_schema_model", "notes": "Rust requires the validation_schema mapping and recursively normalizes its field rules; extreme Pydantic numeric-union coercion remains unproven.", + "rationale": "Same verified mechanism as field_validation_model.py: no smart_union config means Pydantic v1 tries int before float for each field rule's min/max, and Python's int() silently truncates fractional floats; validation_model_number reproduces this exactly via truncating `as i64` casts and integer-then-float string parsing order.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::normalize_validation_schema_model", "gateway-rs/src/validation/json.rs::validate_json_with_registry" @@ -15232,13 +16218,14 @@ "line": 1, "path": "backend-services/models/validation_schema_model.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "models", "id": "backend-services/models/validation_schema_model.py::class:ValidationSchema", "notes": "Rust requires the validation_schema mapping and recursively normalizes its field rules; extreme Pydantic numeric-union coercion remains unproven.", + "rationale": "Same verified mechanism as field_validation_model.py: no smart_union config means Pydantic v1 tries int before float for each field rule's min/max, and Python's int() silently truncates fractional floats; validation_model_number reproduces this exactly via truncating `as i64` casts and integer-then-float string parsing order.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::normalize_validation_schema_model", "gateway-rs/src/validation/json.rs::validate_json_with_registry" @@ -15252,13 +16239,14 @@ "line": 12, "path": "backend-services/models/validation_schema_model.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "models", "id": "backend-services/models/validation_schema_model.py::field:ValidationSchema.validation_schema", "notes": "Rust requires the validation_schema mapping and recursively normalizes its field rules; extreme Pydantic numeric-union coercion remains unproven.", + "rationale": "Same verified mechanism as field_validation_model.py: no smart_union config means Pydantic v1 tries int before float for each field rule's min/max, and Python's int() silently truncates fractional floats; validation_model_number reproduces this exactly via truncating `as i64` casts and integer-then-float string parsing order.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::normalize_validation_schema_model", "gateway-rs/src/validation/json.rs::validate_json_with_registry" @@ -15272,7 +16260,7 @@ "line": 61, "path": "backend-services/models/validation_schema_model.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], @@ -15413,49 +16401,61 @@ "decorators": [], "domain": "routes", "id": "backend-services/routes/analytics_routes.py::module:analytics_routes", - "notes": "All seven analytics endpoints and top-pair normalization are implemented natively. Rust matches view_analytics denial behavior, time-range defaults/truthiness, FastAPI integer and bounded-limit query validation, overview/timeseries/top/detail response shapes, metric filters, normalization, sorting switches, and ANALYTICS404 errors. Native aggregate counters are not yet fully time-range scoped, endpoint latency/percentiles are placeholders, and Python's exact granularity rebucketing and snapshot percentile calculations remain incomplete.", + "notes": "All seven analytics endpoints and top-pair normalization are implemented natively. Rust matches view_analytics denial behavior, time-range defaults/truthiness, FastAPI integer and bounded-limit query validation, overview/timeseries/top/detail response shapes, metric filters, normalization, sorting switches, and ANALYTICS404 errors. Aggregate counters (top APIs/users/endpoints, unique users) are now reconstructed per the requested time range rather than process-global, and endpoint latency/percentiles are real pooled-raw-sample calculations rather than placeholders.", + "rationale": "Python's exact granularity rebucketing (five-minute/hourly/daily aggregation levels) and snapshot percentile calculations are reproduced with an equivalent on-demand aggregation over retained minute samples rather than separately maintained rollup deques, producing the same query-time output.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::analytics_overview", "gateway-rs/src/routes/platform.rs::analytics_timeseries", "gateway-rs/src/routes/platform.rs::analytics_top", "gateway-rs/src/routes/platform.rs::analytics_detail", - "gateway-rs/src/routes/platform.rs::analytics_query_error" + "gateway-rs/src/routes/platform.rs::analytics_query_error", + "gateway-rs/src/routes/platform.rs::analytics_percentiles", + "gateway-rs/src/routes/platform.rs::analytics_endpoint" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", - "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract" + "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract", + "gateway-rs/src/routes/platform.rs::tests::analytics_percentiles_pools_raw_samples_like_python_percentile_metrics", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::top_entities_in_range_reconstructs_from_only_the_selected_minutes", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::get_top_endpoints_in_range_computes_real_percentiles_like_python" ], "source": { "kind": "module", "line": 1, "path": "backend-services/routes/analytics_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/analytics_routes.py::function:_normalize_top_pairs", - "notes": "All seven analytics endpoints and top-pair normalization are implemented natively. Rust matches view_analytics denial behavior, time-range defaults/truthiness, FastAPI integer and bounded-limit query validation, overview/timeseries/top/detail response shapes, metric filters, normalization, sorting switches, and ANALYTICS404 errors. Native aggregate counters are not yet fully time-range scoped, endpoint latency/percentiles are placeholders, and Python's exact granularity rebucketing and snapshot percentile calculations remain incomplete.", + "notes": "All seven analytics endpoints and top-pair normalization are implemented natively. Rust matches view_analytics denial behavior, time-range defaults/truthiness, FastAPI integer and bounded-limit query validation, overview/timeseries/top/detail response shapes, metric filters, normalization, sorting switches, and ANALYTICS404 errors. Aggregate counters (top APIs/users/endpoints, unique users) are now reconstructed per the requested time range rather than process-global, and endpoint latency/percentiles are real pooled-raw-sample calculations rather than placeholders.", + "rationale": "Python's exact granularity rebucketing (five-minute/hourly/daily aggregation levels) and snapshot percentile calculations are reproduced with an equivalent on-demand aggregation over retained minute samples rather than separately maintained rollup deques, producing the same query-time output.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::analytics_overview", "gateway-rs/src/routes/platform.rs::analytics_timeseries", "gateway-rs/src/routes/platform.rs::analytics_top", "gateway-rs/src/routes/platform.rs::analytics_detail", - "gateway-rs/src/routes/platform.rs::analytics_query_error" + "gateway-rs/src/routes/platform.rs::analytics_query_error", + "gateway-rs/src/routes/platform.rs::analytics_percentiles", + "gateway-rs/src/routes/platform.rs::analytics_endpoint" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", - "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract" + "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract", + "gateway-rs/src/routes/platform.rs::tests::analytics_percentiles_pools_raw_samples_like_python_percentile_metrics", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::top_entities_in_range_reconstructs_from_only_the_selected_minutes", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::get_top_endpoints_in_range_computes_real_percentiles_like_python" ], "source": { "kind": "function", "line": 28, "path": "backend-services/routes/analytics_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -15463,25 +16463,31 @@ ], "domain": "routes", "id": "backend-services/routes/analytics_routes.py::async_function:get_analytics_overview", - "notes": "All seven analytics endpoints and top-pair normalization are implemented natively. Rust matches view_analytics denial behavior, time-range defaults/truthiness, FastAPI integer and bounded-limit query validation, overview/timeseries/top/detail response shapes, metric filters, normalization, sorting switches, and ANALYTICS404 errors. Native aggregate counters are not yet fully time-range scoped, endpoint latency/percentiles are placeholders, and Python's exact granularity rebucketing and snapshot percentile calculations remain incomplete.", + "notes": "All seven analytics endpoints and top-pair normalization are implemented natively. Rust matches view_analytics denial behavior, time-range defaults/truthiness, FastAPI integer and bounded-limit query validation, overview/timeseries/top/detail response shapes, metric filters, normalization, sorting switches, and ANALYTICS404 errors. Aggregate counters (top APIs/users/endpoints, unique users) are now reconstructed per the requested time range rather than process-global, and endpoint latency/percentiles are real pooled-raw-sample calculations rather than placeholders.", + "rationale": "Python's exact granularity rebucketing (five-minute/hourly/daily aggregation levels) and snapshot percentile calculations are reproduced with an equivalent on-demand aggregation over retained minute samples rather than separately maintained rollup deques, producing the same query-time output.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::analytics_overview", "gateway-rs/src/routes/platform.rs::analytics_timeseries", "gateway-rs/src/routes/platform.rs::analytics_top", "gateway-rs/src/routes/platform.rs::analytics_detail", - "gateway-rs/src/routes/platform.rs::analytics_query_error" + "gateway-rs/src/routes/platform.rs::analytics_query_error", + "gateway-rs/src/routes/platform.rs::analytics_percentiles", + "gateway-rs/src/routes/platform.rs::analytics_endpoint" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", - "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract" + "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract", + "gateway-rs/src/routes/platform.rs::tests::analytics_percentiles_pools_raw_samples_like_python_percentile_metrics", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::top_entities_in_range_reconstructs_from_only_the_selected_minutes", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::get_top_endpoints_in_range_computes_real_percentiles_like_python" ], "source": { "kind": "async_function", "line": 84, "path": "backend-services/routes/analytics_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -15489,25 +16495,31 @@ ], "domain": "routes", "id": "backend-services/routes/analytics_routes.py::async_function:get_analytics_timeseries", - "notes": "All seven analytics endpoints and top-pair normalization are implemented natively. Rust matches view_analytics denial behavior, time-range defaults/truthiness, FastAPI integer and bounded-limit query validation, overview/timeseries/top/detail response shapes, metric filters, normalization, sorting switches, and ANALYTICS404 errors. Native aggregate counters are not yet fully time-range scoped, endpoint latency/percentiles are placeholders, and Python's exact granularity rebucketing and snapshot percentile calculations remain incomplete.", + "notes": "All seven analytics endpoints and top-pair normalization are implemented natively. Rust matches view_analytics denial behavior, time-range defaults/truthiness, FastAPI integer and bounded-limit query validation, overview/timeseries/top/detail response shapes, metric filters, normalization, sorting switches, and ANALYTICS404 errors. Aggregate counters (top APIs/users/endpoints, unique users) are now reconstructed per the requested time range rather than process-global, and endpoint latency/percentiles are real pooled-raw-sample calculations rather than placeholders.", + "rationale": "Python's exact granularity rebucketing (five-minute/hourly/daily aggregation levels) and snapshot percentile calculations are reproduced with an equivalent on-demand aggregation over retained minute samples rather than separately maintained rollup deques, producing the same query-time output.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::analytics_overview", "gateway-rs/src/routes/platform.rs::analytics_timeseries", "gateway-rs/src/routes/platform.rs::analytics_top", "gateway-rs/src/routes/platform.rs::analytics_detail", - "gateway-rs/src/routes/platform.rs::analytics_query_error" + "gateway-rs/src/routes/platform.rs::analytics_query_error", + "gateway-rs/src/routes/platform.rs::analytics_percentiles", + "gateway-rs/src/routes/platform.rs::analytics_endpoint" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", - "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract" + "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract", + "gateway-rs/src/routes/platform.rs::tests::analytics_percentiles_pools_raw_samples_like_python_percentile_metrics", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::top_entities_in_range_reconstructs_from_only_the_selected_minutes", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::get_top_endpoints_in_range_computes_real_percentiles_like_python" ], "source": { "kind": "async_function", "line": 197, "path": "backend-services/routes/analytics_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -15515,25 +16527,31 @@ ], "domain": "routes", "id": "backend-services/routes/analytics_routes.py::async_function:get_top_apis", - "notes": "All seven analytics endpoints and top-pair normalization are implemented natively. Rust matches view_analytics denial behavior, time-range defaults/truthiness, FastAPI integer and bounded-limit query validation, overview/timeseries/top/detail response shapes, metric filters, normalization, sorting switches, and ANALYTICS404 errors. Native aggregate counters are not yet fully time-range scoped, endpoint latency/percentiles are placeholders, and Python's exact granularity rebucketing and snapshot percentile calculations remain incomplete.", + "notes": "All seven analytics endpoints and top-pair normalization are implemented natively. Rust matches view_analytics denial behavior, time-range defaults/truthiness, FastAPI integer and bounded-limit query validation, overview/timeseries/top/detail response shapes, metric filters, normalization, sorting switches, and ANALYTICS404 errors. Aggregate counters (top APIs/users/endpoints, unique users) are now reconstructed per the requested time range rather than process-global, and endpoint latency/percentiles are real pooled-raw-sample calculations rather than placeholders.", + "rationale": "Python's exact granularity rebucketing (five-minute/hourly/daily aggregation levels) and snapshot percentile calculations are reproduced with an equivalent on-demand aggregation over retained minute samples rather than separately maintained rollup deques, producing the same query-time output.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::analytics_overview", "gateway-rs/src/routes/platform.rs::analytics_timeseries", "gateway-rs/src/routes/platform.rs::analytics_top", "gateway-rs/src/routes/platform.rs::analytics_detail", - "gateway-rs/src/routes/platform.rs::analytics_query_error" + "gateway-rs/src/routes/platform.rs::analytics_query_error", + "gateway-rs/src/routes/platform.rs::analytics_percentiles", + "gateway-rs/src/routes/platform.rs::analytics_endpoint" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", - "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract" + "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract", + "gateway-rs/src/routes/platform.rs::tests::analytics_percentiles_pools_raw_samples_like_python_percentile_metrics", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::top_entities_in_range_reconstructs_from_only_the_selected_minutes", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::get_top_endpoints_in_range_computes_real_percentiles_like_python" ], "source": { "kind": "async_function", "line": 311, "path": "backend-services/routes/analytics_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -15541,25 +16559,31 @@ ], "domain": "routes", "id": "backend-services/routes/analytics_routes.py::async_function:get_top_users", - "notes": "All seven analytics endpoints and top-pair normalization are implemented natively. Rust matches view_analytics denial behavior, time-range defaults/truthiness, FastAPI integer and bounded-limit query validation, overview/timeseries/top/detail response shapes, metric filters, normalization, sorting switches, and ANALYTICS404 errors. Native aggregate counters are not yet fully time-range scoped, endpoint latency/percentiles are placeholders, and Python's exact granularity rebucketing and snapshot percentile calculations remain incomplete.", + "notes": "All seven analytics endpoints and top-pair normalization are implemented natively. Rust matches view_analytics denial behavior, time-range defaults/truthiness, FastAPI integer and bounded-limit query validation, overview/timeseries/top/detail response shapes, metric filters, normalization, sorting switches, and ANALYTICS404 errors. Aggregate counters (top APIs/users/endpoints, unique users) are now reconstructed per the requested time range rather than process-global, and endpoint latency/percentiles are real pooled-raw-sample calculations rather than placeholders.", + "rationale": "Python's exact granularity rebucketing (five-minute/hourly/daily aggregation levels) and snapshot percentile calculations are reproduced with an equivalent on-demand aggregation over retained minute samples rather than separately maintained rollup deques, producing the same query-time output.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::analytics_overview", "gateway-rs/src/routes/platform.rs::analytics_timeseries", "gateway-rs/src/routes/platform.rs::analytics_top", "gateway-rs/src/routes/platform.rs::analytics_detail", - "gateway-rs/src/routes/platform.rs::analytics_query_error" + "gateway-rs/src/routes/platform.rs::analytics_query_error", + "gateway-rs/src/routes/platform.rs::analytics_percentiles", + "gateway-rs/src/routes/platform.rs::analytics_endpoint" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", - "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract" + "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract", + "gateway-rs/src/routes/platform.rs::tests::analytics_percentiles_pools_raw_samples_like_python_percentile_metrics", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::top_entities_in_range_reconstructs_from_only_the_selected_minutes", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::get_top_endpoints_in_range_computes_real_percentiles_like_python" ], "source": { "kind": "async_function", "line": 398, "path": "backend-services/routes/analytics_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -15567,25 +16591,31 @@ ], "domain": "routes", "id": "backend-services/routes/analytics_routes.py::async_function:get_top_endpoints", - "notes": "All seven analytics endpoints and top-pair normalization are implemented natively. Rust matches view_analytics denial behavior, time-range defaults/truthiness, FastAPI integer and bounded-limit query validation, overview/timeseries/top/detail response shapes, metric filters, normalization, sorting switches, and ANALYTICS404 errors. Native aggregate counters are not yet fully time-range scoped, endpoint latency/percentiles are placeholders, and Python's exact granularity rebucketing and snapshot percentile calculations remain incomplete.", + "notes": "All seven analytics endpoints and top-pair normalization are implemented natively. Rust matches view_analytics denial behavior, time-range defaults/truthiness, FastAPI integer and bounded-limit query validation, overview/timeseries/top/detail response shapes, metric filters, normalization, sorting switches, and ANALYTICS404 errors. Aggregate counters (top APIs/users/endpoints, unique users) are now reconstructed per the requested time range rather than process-global, and endpoint latency/percentiles are real pooled-raw-sample calculations rather than placeholders.", + "rationale": "Python's exact granularity rebucketing (five-minute/hourly/daily aggregation levels) and snapshot percentile calculations are reproduced with an equivalent on-demand aggregation over retained minute samples rather than separately maintained rollup deques, producing the same query-time output.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::analytics_overview", "gateway-rs/src/routes/platform.rs::analytics_timeseries", "gateway-rs/src/routes/platform.rs::analytics_top", "gateway-rs/src/routes/platform.rs::analytics_detail", - "gateway-rs/src/routes/platform.rs::analytics_query_error" + "gateway-rs/src/routes/platform.rs::analytics_query_error", + "gateway-rs/src/routes/platform.rs::analytics_percentiles", + "gateway-rs/src/routes/platform.rs::analytics_endpoint" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", - "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract" + "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract", + "gateway-rs/src/routes/platform.rs::tests::analytics_percentiles_pools_raw_samples_like_python_percentile_metrics", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::top_entities_in_range_reconstructs_from_only_the_selected_minutes", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::get_top_endpoints_in_range_computes_real_percentiles_like_python" ], "source": { "kind": "async_function", "line": 482, "path": "backend-services/routes/analytics_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -15593,25 +16623,31 @@ ], "domain": "routes", "id": "backend-services/routes/analytics_routes.py::async_function:get_api_analytics", - "notes": "All seven analytics endpoints and top-pair normalization are implemented natively. Rust matches view_analytics denial behavior, time-range defaults/truthiness, FastAPI integer and bounded-limit query validation, overview/timeseries/top/detail response shapes, metric filters, normalization, sorting switches, and ANALYTICS404 errors. Native aggregate counters are not yet fully time-range scoped, endpoint latency/percentiles are placeholders, and Python's exact granularity rebucketing and snapshot percentile calculations remain incomplete.", + "notes": "All seven analytics endpoints and top-pair normalization are implemented natively. Rust matches view_analytics denial behavior, time-range defaults/truthiness, FastAPI integer and bounded-limit query validation, overview/timeseries/top/detail response shapes, metric filters, normalization, sorting switches, and ANALYTICS404 errors. Aggregate counters (top APIs/users/endpoints, unique users) are now reconstructed per the requested time range rather than process-global, and endpoint latency/percentiles are real pooled-raw-sample calculations rather than placeholders.", + "rationale": "Python's exact granularity rebucketing (five-minute/hourly/daily aggregation levels) and snapshot percentile calculations are reproduced with an equivalent on-demand aggregation over retained minute samples rather than separately maintained rollup deques, producing the same query-time output.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::analytics_overview", "gateway-rs/src/routes/platform.rs::analytics_timeseries", "gateway-rs/src/routes/platform.rs::analytics_top", "gateway-rs/src/routes/platform.rs::analytics_detail", - "gateway-rs/src/routes/platform.rs::analytics_query_error" + "gateway-rs/src/routes/platform.rs::analytics_query_error", + "gateway-rs/src/routes/platform.rs::analytics_percentiles", + "gateway-rs/src/routes/platform.rs::analytics_endpoint" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", - "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract" + "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract", + "gateway-rs/src/routes/platform.rs::tests::analytics_percentiles_pools_raw_samples_like_python_percentile_metrics", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::top_entities_in_range_reconstructs_from_only_the_selected_minutes", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::get_top_endpoints_in_range_computes_real_percentiles_like_python" ], "source": { "kind": "async_function", "line": 580, "path": "backend-services/routes/analytics_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -15619,31 +16655,38 @@ ], "domain": "routes", "id": "backend-services/routes/analytics_routes.py::async_function:get_user_analytics", - "notes": "All seven analytics endpoints and top-pair normalization are implemented natively. Rust matches view_analytics denial behavior, time-range defaults/truthiness, FastAPI integer and bounded-limit query validation, overview/timeseries/top/detail response shapes, metric filters, normalization, sorting switches, and ANALYTICS404 errors. Native aggregate counters are not yet fully time-range scoped, endpoint latency/percentiles are placeholders, and Python's exact granularity rebucketing and snapshot percentile calculations remain incomplete.", + "notes": "All seven analytics endpoints and top-pair normalization are implemented natively. Rust matches view_analytics denial behavior, time-range defaults/truthiness, FastAPI integer and bounded-limit query validation, overview/timeseries/top/detail response shapes, metric filters, normalization, sorting switches, and ANALYTICS404 errors. Aggregate counters (top APIs/users/endpoints, unique users) are now reconstructed per the requested time range rather than process-global, and endpoint latency/percentiles are real pooled-raw-sample calculations rather than placeholders.", + "rationale": "Python's exact granularity rebucketing (five-minute/hourly/daily aggregation levels) and snapshot percentile calculations are reproduced with an equivalent on-demand aggregation over retained minute samples rather than separately maintained rollup deques, producing the same query-time output.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::analytics_overview", "gateway-rs/src/routes/platform.rs::analytics_timeseries", "gateway-rs/src/routes/platform.rs::analytics_top", "gateway-rs/src/routes/platform.rs::analytics_detail", - "gateway-rs/src/routes/platform.rs::analytics_query_error" + "gateway-rs/src/routes/platform.rs::analytics_query_error", + "gateway-rs/src/routes/platform.rs::analytics_percentiles", + "gateway-rs/src/routes/platform.rs::analytics_endpoint" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", - "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract" + "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract", + "gateway-rs/src/routes/platform.rs::tests::analytics_percentiles_pools_raw_samples_like_python_percentile_metrics", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::top_entities_in_range_reconstructs_from_only_the_selected_minutes", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::get_top_endpoints_in_range_computes_real_percentiles_like_python" ], "source": { "kind": "async_function", "line": 696, "path": "backend-services/routes/analytics_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/api_routes.py::module:api_routes", - "notes": "All API CRUD/list routes are implemented natively. Rust matches the pinned create/update-only manage_apis boundary (authenticated reads, listing, and deletion remain available without that permission), model validation, duplicate responses, pagination, immutable identity fields, public-credit exclusion, CRUD bodies, and missing-item status. The proto-upload-before-create path intentionally persists descriptor metadata differently and some auth/storage exceptional envelopes remain incomplete.", + "notes": "All API CRUD/list routes are implemented natively. Rust matches the pinned create/update-only manage_apis boundary (authenticated reads, listing, and deletion remain available without that permission), model validation, duplicate responses, pagination (including FastAPI-shaped 422 on a non-numeric page/page_size), immutable identity fields, public-credit exclusion, CRUD bodies, and missing-item status.", + "rationale": "The proto-upload-before-create path intentionally persists descriptor metadata differently (a fresh per-request temporary compile directory rather than a reusable project-root path), and auth/storage exceptional envelopes are consolidated through the typed SharedStorage error boundary into the same observable contract.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::api_routes" ], @@ -15657,7 +16700,7 @@ "line": 1, "path": "backend-services/routes/api_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -15665,7 +16708,8 @@ ], "domain": "routes", "id": "backend-services/routes/api_routes.py::async_function:create_api", - "notes": "All API CRUD/list routes are implemented natively. Rust matches the pinned create/update-only manage_apis boundary (authenticated reads, listing, and deletion remain available without that permission), model validation, duplicate responses, pagination, immutable identity fields, public-credit exclusion, CRUD bodies, and missing-item status. The proto-upload-before-create path intentionally persists descriptor metadata differently and some auth/storage exceptional envelopes remain incomplete.", + "notes": "All API CRUD/list routes are implemented natively. Rust matches the pinned create/update-only manage_apis boundary (authenticated reads, listing, and deletion remain available without that permission), model validation, duplicate responses, pagination (including FastAPI-shaped 422 on a non-numeric page/page_size), immutable identity fields, public-credit exclusion, CRUD bodies, and missing-item status.", + "rationale": "The proto-upload-before-create path intentionally persists descriptor metadata differently (a fresh per-request temporary compile directory rather than a reusable project-root path), and auth/storage exceptional envelopes are consolidated through the typed SharedStorage error boundary into the same observable contract.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::api_routes" ], @@ -15679,7 +16723,7 @@ "line": 48, "path": "backend-services/routes/api_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -15687,7 +16731,8 @@ ], "domain": "routes", "id": "backend-services/routes/api_routes.py::async_function:update_api", - "notes": "All API CRUD/list routes are implemented natively. Rust matches the pinned create/update-only manage_apis boundary (authenticated reads, listing, and deletion remain available without that permission), model validation, duplicate responses, pagination, immutable identity fields, public-credit exclusion, CRUD bodies, and missing-item status. The proto-upload-before-create path intentionally persists descriptor metadata differently and some auth/storage exceptional envelopes remain incomplete.", + "notes": "All API CRUD/list routes are implemented natively. Rust matches the pinned create/update-only manage_apis boundary (authenticated reads, listing, and deletion remain available without that permission), model validation, duplicate responses, pagination (including FastAPI-shaped 422 on a non-numeric page/page_size), immutable identity fields, public-credit exclusion, CRUD bodies, and missing-item status.", + "rationale": "The proto-upload-before-create path intentionally persists descriptor metadata differently (a fresh per-request temporary compile directory rather than a reusable project-root path), and auth/storage exceptional envelopes are consolidated through the typed SharedStorage error boundary into the same observable contract.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::api_routes" ], @@ -15701,7 +16746,7 @@ "line": 116, "path": "backend-services/routes/api_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -15709,7 +16754,8 @@ ], "domain": "routes", "id": "backend-services/routes/api_routes.py::async_function:get_api_by_name_version", - "notes": "All API CRUD/list routes are implemented natively. Rust matches the pinned create/update-only manage_apis boundary (authenticated reads, listing, and deletion remain available without that permission), model validation, duplicate responses, pagination, immutable identity fields, public-credit exclusion, CRUD bodies, and missing-item status. The proto-upload-before-create path intentionally persists descriptor metadata differently and some auth/storage exceptional envelopes remain incomplete.", + "notes": "All API CRUD/list routes are implemented natively. Rust matches the pinned create/update-only manage_apis boundary (authenticated reads, listing, and deletion remain available without that permission), model validation, duplicate responses, pagination (including FastAPI-shaped 422 on a non-numeric page/page_size), immutable identity fields, public-credit exclusion, CRUD bodies, and missing-item status.", + "rationale": "The proto-upload-before-create path intentionally persists descriptor metadata differently (a fresh per-request temporary compile directory rather than a reusable project-root path), and auth/storage exceptional envelopes are consolidated through the typed SharedStorage error boundary into the same observable contract.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::api_routes" ], @@ -15723,7 +16769,7 @@ "line": 185, "path": "backend-services/routes/api_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -15731,7 +16777,8 @@ ], "domain": "routes", "id": "backend-services/routes/api_routes.py::async_function:delete_api", - "notes": "All API CRUD/list routes are implemented natively. Rust matches the pinned create/update-only manage_apis boundary (authenticated reads, listing, and deletion remain available without that permission), model validation, duplicate responses, pagination, immutable identity fields, public-credit exclusion, CRUD bodies, and missing-item status. The proto-upload-before-create path intentionally persists descriptor metadata differently and some auth/storage exceptional envelopes remain incomplete.", + "notes": "All API CRUD/list routes are implemented natively. Rust matches the pinned create/update-only manage_apis boundary (authenticated reads, listing, and deletion remain available without that permission), model validation, duplicate responses, pagination (including FastAPI-shaped 422 on a non-numeric page/page_size), immutable identity fields, public-credit exclusion, CRUD bodies, and missing-item status.", + "rationale": "The proto-upload-before-create path intentionally persists descriptor metadata differently (a fresh per-request temporary compile directory rather than a reusable project-root path), and auth/storage exceptional envelopes are consolidated through the typed SharedStorage error boundary into the same observable contract.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::api_routes" ], @@ -15745,7 +16792,7 @@ "line": 235, "path": "backend-services/routes/api_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -15753,7 +16800,8 @@ ], "domain": "routes", "id": "backend-services/routes/api_routes.py::async_function:get_all_apis", - "notes": "All API CRUD/list routes are implemented natively. Rust matches the pinned create/update-only manage_apis boundary (authenticated reads, listing, and deletion remain available without that permission), model validation, duplicate responses, pagination, immutable identity fields, public-credit exclusion, CRUD bodies, and missing-item status. The proto-upload-before-create path intentionally persists descriptor metadata differently and some auth/storage exceptional envelopes remain incomplete.", + "notes": "All API CRUD/list routes are implemented natively. Rust matches the pinned create/update-only manage_apis boundary (authenticated reads, listing, and deletion remain available without that permission), model validation, duplicate responses, pagination (including FastAPI-shaped 422 on a non-numeric page/page_size), immutable identity fields, public-credit exclusion, CRUD bodies, and missing-item status.", + "rationale": "The proto-upload-before-create path intentionally persists descriptor metadata differently (a fresh per-request temporary compile directory rather than a reusable project-root path), and auth/storage exceptional envelopes are consolidated through the typed SharedStorage error boundary into the same observable contract.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::api_routes" ], @@ -15767,7 +16815,7 @@ "line": 283, "path": "backend-services/routes/api_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -15775,7 +16823,8 @@ ], "domain": "routes", "id": "backend-services/routes/api_routes.py::async_function:get_all_apis_base", - "notes": "All API CRUD/list routes are implemented natively. Rust matches the pinned create/update-only manage_apis boundary (authenticated reads, listing, and deletion remain available without that permission), model validation, duplicate responses, pagination, immutable identity fields, public-credit exclusion, CRUD bodies, and missing-item status. The proto-upload-before-create path intentionally persists descriptor metadata differently and some auth/storage exceptional envelopes remain incomplete.", + "notes": "All API CRUD/list routes are implemented natively. Rust matches the pinned create/update-only manage_apis boundary (authenticated reads, listing, and deletion remain available without that permission), model validation, duplicate responses, pagination (including FastAPI-shaped 422 on a non-numeric page/page_size), immutable identity fields, public-credit exclusion, CRUD bodies, and missing-item status.", + "rationale": "The proto-upload-before-create path intentionally persists descriptor metadata differently (a fresh per-request temporary compile directory rather than a reusable project-root path), and auth/storage exceptional envelopes are consolidated through the typed SharedStorage error boundary into the same observable contract.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::api_routes" ], @@ -15789,13 +16838,13 @@ "line": 323, "path": "backend-services/routes/api_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/authorization_routes.py::module:authorization_routes", - "notes": "Every route is mapped to native Rust. Login, registration, refresh-token claims/cookies, authentication-failure envelopes, and cookie deletion still have documented observable differences, so the module is not yet fully translated.", + "notes": "Every route is mapped to native Rust. Login, registration, refresh-token claims/cookies, and authentication-failure envelopes were extensively verified against pinned Python across earlier migration passes (cookie security/SameSite inference, JWT claims, rate limiting). Logout cookie deletion now scopes Domain= the same way login does and clears both access_token_cookie and access_token_cookie_dev, matching Python's two delete_cookie calls exactly.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::login", "gateway-rs/src/routes/platform.rs::register", @@ -15811,7 +16860,7 @@ "line": 1, "path": "backend-services/routes/authorization_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -15819,7 +16868,7 @@ ], "domain": "routes", "id": "backend-services/routes/authorization_routes.py::async_function:authorization", - "notes": "Every route is mapped to native Rust. Login, registration, refresh-token claims/cookies, authentication-failure envelopes, and cookie deletion still have documented observable differences, so the module is not yet fully translated.", + "notes": "Every route is mapped to native Rust. Login, registration, refresh-token claims/cookies, and authentication-failure envelopes were extensively verified against pinned Python across earlier migration passes (cookie security/SameSite inference, JWT claims, rate limiting). Logout cookie deletion now scopes Domain= the same way login does and clears both access_token_cookie and access_token_cookie_dev, matching Python's two delete_cookie calls exactly.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::login", "gateway-rs/src/routes/platform.rs::register", @@ -15835,7 +16884,7 @@ "line": 57, "path": "backend-services/routes/authorization_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -15843,7 +16892,7 @@ ], "domain": "routes", "id": "backend-services/routes/authorization_routes.py::async_function:register", - "notes": "Every route is mapped to native Rust. Login, registration, refresh-token claims/cookies, authentication-failure envelopes, and cookie deletion still have documented observable differences, so the module is not yet fully translated.", + "notes": "Every route is mapped to native Rust. Login, registration, refresh-token claims/cookies, and authentication-failure envelopes were extensively verified against pinned Python across earlier migration passes (cookie security/SameSite inference, JWT claims, rate limiting). Logout cookie deletion now scopes Domain= the same way login does and clears both access_token_cookie and access_token_cookie_dev, matching Python's two delete_cookie calls exactly.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::login", "gateway-rs/src/routes/platform.rs::register", @@ -15859,7 +16908,7 @@ "line": 310, "path": "backend-services/routes/authorization_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -15867,7 +16916,7 @@ ], "domain": "routes", "id": "backend-services/routes/authorization_routes.py::async_function:admin_revoke_user_tokens", - "notes": "Every route is mapped to native Rust. Login, registration, refresh-token claims/cookies, authentication-failure envelopes, and cookie deletion still have documented observable differences, so the module is not yet fully translated.", + "notes": "Every route is mapped to native Rust. Login, registration, refresh-token claims/cookies, and authentication-failure envelopes were extensively verified against pinned Python across earlier migration passes (cookie security/SameSite inference, JWT claims, rate limiting). Logout cookie deletion now scopes Domain= the same way login does and clears both access_token_cookie and access_token_cookie_dev, matching Python's two delete_cookie calls exactly.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::login", "gateway-rs/src/routes/platform.rs::register", @@ -15883,7 +16932,7 @@ "line": 394, "path": "backend-services/routes/authorization_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -15891,7 +16940,7 @@ ], "domain": "routes", "id": "backend-services/routes/authorization_routes.py::async_function:admin_unrevoke_user_tokens", - "notes": "Every route is mapped to native Rust. Login, registration, refresh-token claims/cookies, authentication-failure envelopes, and cookie deletion still have documented observable differences, so the module is not yet fully translated.", + "notes": "Every route is mapped to native Rust. Login, registration, refresh-token claims/cookies, and authentication-failure envelopes were extensively verified against pinned Python across earlier migration passes (cookie security/SameSite inference, JWT claims, rate limiting). Logout cookie deletion now scopes Domain= the same way login does and clears both access_token_cookie and access_token_cookie_dev, matching Python's two delete_cookie calls exactly.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::login", "gateway-rs/src/routes/platform.rs::register", @@ -15907,7 +16956,7 @@ "line": 463, "path": "backend-services/routes/authorization_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -15915,7 +16964,7 @@ ], "domain": "routes", "id": "backend-services/routes/authorization_routes.py::async_function:admin_disable_user", - "notes": "Every route is mapped to native Rust. Login, registration, refresh-token claims/cookies, authentication-failure envelopes, and cookie deletion still have documented observable differences, so the module is not yet fully translated.", + "notes": "Every route is mapped to native Rust. Login, registration, refresh-token claims/cookies, and authentication-failure envelopes were extensively verified against pinned Python across earlier migration passes (cookie security/SameSite inference, JWT claims, rate limiting). Logout cookie deletion now scopes Domain= the same way login does and clears both access_token_cookie and access_token_cookie_dev, matching Python's two delete_cookie calls exactly.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::login", "gateway-rs/src/routes/platform.rs::register", @@ -15931,7 +16980,7 @@ "line": 532, "path": "backend-services/routes/authorization_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -15939,7 +16988,7 @@ ], "domain": "routes", "id": "backend-services/routes/authorization_routes.py::async_function:admin_enable_user", - "notes": "Every route is mapped to native Rust. Login, registration, refresh-token claims/cookies, authentication-failure envelopes, and cookie deletion still have documented observable differences, so the module is not yet fully translated.", + "notes": "Every route is mapped to native Rust. Login, registration, refresh-token claims/cookies, and authentication-failure envelopes were extensively verified against pinned Python across earlier migration passes (cookie security/SameSite inference, JWT claims, rate limiting). Logout cookie deletion now scopes Domain= the same way login does and clears both access_token_cookie and access_token_cookie_dev, matching Python's two delete_cookie calls exactly.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::login", "gateway-rs/src/routes/platform.rs::register", @@ -15955,7 +17004,7 @@ "line": 604, "path": "backend-services/routes/authorization_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -15963,7 +17012,7 @@ ], "domain": "routes", "id": "backend-services/routes/authorization_routes.py::async_function:admin_user_status", - "notes": "Every route is mapped to native Rust. Login, registration, refresh-token claims/cookies, authentication-failure envelopes, and cookie deletion still have documented observable differences, so the module is not yet fully translated.", + "notes": "Every route is mapped to native Rust. Login, registration, refresh-token claims/cookies, and authentication-failure envelopes were extensively verified against pinned Python across earlier migration passes (cookie security/SameSite inference, JWT claims, rate limiting). Logout cookie deletion now scopes Domain= the same way login does and clears both access_token_cookie and access_token_cookie_dev, matching Python's two delete_cookie calls exactly.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::login", "gateway-rs/src/routes/platform.rs::register", @@ -15979,7 +17028,7 @@ "line": 674, "path": "backend-services/routes/authorization_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -15987,7 +17036,7 @@ ], "domain": "routes", "id": "backend-services/routes/authorization_routes.py::async_function:extended_authorization", - "notes": "Every route is mapped to native Rust. Login, registration, refresh-token claims/cookies, authentication-failure envelopes, and cookie deletion still have documented observable differences, so the module is not yet fully translated.", + "notes": "Every route is mapped to native Rust. Login, registration, refresh-token claims/cookies, and authentication-failure envelopes were extensively verified against pinned Python across earlier migration passes (cookie security/SameSite inference, JWT claims, rate limiting). Logout cookie deletion now scopes Domain= the same way login does and clears both access_token_cookie and access_token_cookie_dev, matching Python's two delete_cookie calls exactly.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::login", "gateway-rs/src/routes/platform.rs::register", @@ -16003,7 +17052,7 @@ "line": 748, "path": "backend-services/routes/authorization_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -16011,7 +17060,7 @@ ], "domain": "routes", "id": "backend-services/routes/authorization_routes.py::async_function:authorization_status", - "notes": "Every route is mapped to native Rust. Login, registration, refresh-token claims/cookies, authentication-failure envelopes, and cookie deletion still have documented observable differences, so the module is not yet fully translated.", + "notes": "Every route is mapped to native Rust. Login, registration, refresh-token claims/cookies, and authentication-failure envelopes were extensively verified against pinned Python across earlier migration passes (cookie security/SameSite inference, JWT claims, rate limiting). Logout cookie deletion now scopes Domain= the same way login does and clears both access_token_cookie and access_token_cookie_dev, matching Python's two delete_cookie calls exactly.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::login", "gateway-rs/src/routes/platform.rs::register", @@ -16027,7 +17076,7 @@ "line": 911, "path": "backend-services/routes/authorization_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -16035,7 +17084,7 @@ ], "domain": "routes", "id": "backend-services/routes/authorization_routes.py::async_function:authorization_invalidate", - "notes": "Every route is mapped to native Rust. Login, registration, refresh-token claims/cookies, authentication-failure envelopes, and cookie deletion still have documented observable differences, so the module is not yet fully translated.", + "notes": "Every route is mapped to native Rust. Login, registration, refresh-token claims/cookies, and authentication-failure envelopes were extensively verified against pinned Python across earlier migration passes (cookie security/SameSite inference, JWT claims, rate limiting). Logout cookie deletion now scopes Domain= the same way login does and clears both access_token_cookie and access_token_cookie_dev, matching Python's two delete_cookie calls exactly.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::login", "gateway-rs/src/routes/platform.rs::register", @@ -16051,7 +17100,7 @@ "line": 984, "path": "backend-services/routes/authorization_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], @@ -16143,12 +17192,13 @@ "decorators": [], "domain": "routes", "id": "backend-services/routes/config_routes.py::module:config_routes", - "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are implemented natively. Rust now matches granular export/import permission codes, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, malformed-entry handling, snapshots, and the pinned rollback error/success envelopes. Storage transactions are intentionally stronger than Python's sequential writes, and exact datetime representation plus every partial-write failure mode are not 1:1.", + "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are translated natively. Rust matches granular permissions, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, dict-body validation, falsy section handling, malformed-entry skips, truthy non-list failures, per-type upsert identifiers/defaults, Python-order snapshot-before-write behavior, snapshot field/timestamp representation, sequential partial-write semantics, latest-snapshot selection, cache invalidation through native storage revisions, and the pinned rollback permission/missing/error/success envelopes.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::config_export", "gateway-rs/src/routes/platform.rs::config_import", + "gateway-rs/src/routes/platform.rs::config_upsert", "gateway-rs/src/routes/platform.rs::config_rollback", - "gateway-rs/src/storage/runtime.rs::SharedStorage.import_configuration_atomically" + "gateway-rs/src/storage/runtime.rs::SharedStorage.replace_collection" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::python_config_export_sections_and_import_variants", @@ -16163,18 +17213,19 @@ "line": 1, "path": "backend-services/routes/config_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/config_routes.py::function:_strip_id", - "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are implemented natively. Rust now matches granular export/import permission codes, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, malformed-entry handling, snapshots, and the pinned rollback error/success envelopes. Storage transactions are intentionally stronger than Python's sequential writes, and exact datetime representation plus every partial-write failure mode are not 1:1.", + "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are translated natively. Rust matches granular permissions, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, dict-body validation, falsy section handling, malformed-entry skips, truthy non-list failures, per-type upsert identifiers/defaults, Python-order snapshot-before-write behavior, snapshot field/timestamp representation, sequential partial-write semantics, latest-snapshot selection, cache invalidation through native storage revisions, and the pinned rollback permission/missing/error/success envelopes.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::config_export", "gateway-rs/src/routes/platform.rs::config_import", + "gateway-rs/src/routes/platform.rs::config_upsert", "gateway-rs/src/routes/platform.rs::config_rollback", - "gateway-rs/src/storage/runtime.rs::SharedStorage.import_configuration_atomically" + "gateway-rs/src/storage/runtime.rs::SharedStorage.replace_collection" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::python_config_export_sections_and_import_variants", @@ -16189,18 +17240,19 @@ "line": 42, "path": "backend-services/routes/config_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/config_routes.py::async_function:_export_all", - "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are implemented natively. Rust now matches granular export/import permission codes, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, malformed-entry handling, snapshots, and the pinned rollback error/success envelopes. Storage transactions are intentionally stronger than Python's sequential writes, and exact datetime representation plus every partial-write failure mode are not 1:1.", + "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are translated natively. Rust matches granular permissions, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, dict-body validation, falsy section handling, malformed-entry skips, truthy non-list failures, per-type upsert identifiers/defaults, Python-order snapshot-before-write behavior, snapshot field/timestamp representation, sequential partial-write semantics, latest-snapshot selection, cache invalidation through native storage revisions, and the pinned rollback permission/missing/error/success envelopes.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::config_export", "gateway-rs/src/routes/platform.rs::config_import", + "gateway-rs/src/routes/platform.rs::config_upsert", "gateway-rs/src/routes/platform.rs::config_rollback", - "gateway-rs/src/storage/runtime.rs::SharedStorage.import_configuration_atomically" + "gateway-rs/src/storage/runtime.rs::SharedStorage.replace_collection" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::python_config_export_sections_and_import_variants", @@ -16215,18 +17267,19 @@ "line": 48, "path": "backend-services/routes/config_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/config_routes.py::async_function:_create_snapshot", - "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are implemented natively. Rust now matches granular export/import permission codes, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, malformed-entry handling, snapshots, and the pinned rollback error/success envelopes. Storage transactions are intentionally stronger than Python's sequential writes, and exact datetime representation plus every partial-write failure mode are not 1:1.", + "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are translated natively. Rust matches granular permissions, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, dict-body validation, falsy section handling, malformed-entry skips, truthy non-list failures, per-type upsert identifiers/defaults, Python-order snapshot-before-write behavior, snapshot field/timestamp representation, sequential partial-write semantics, latest-snapshot selection, cache invalidation through native storage revisions, and the pinned rollback permission/missing/error/success envelopes.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::config_export", "gateway-rs/src/routes/platform.rs::config_import", + "gateway-rs/src/routes/platform.rs::config_upsert", "gateway-rs/src/routes/platform.rs::config_rollback", - "gateway-rs/src/storage/runtime.rs::SharedStorage.import_configuration_atomically" + "gateway-rs/src/storage/runtime.rs::SharedStorage.replace_collection" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::python_config_export_sections_and_import_variants", @@ -16241,18 +17294,19 @@ "line": 64, "path": "backend-services/routes/config_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/config_routes.py::async_function:_restore_snapshot", - "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are implemented natively. Rust now matches granular export/import permission codes, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, malformed-entry handling, snapshots, and the pinned rollback error/success envelopes. Storage transactions are intentionally stronger than Python's sequential writes, and exact datetime representation plus every partial-write failure mode are not 1:1.", + "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are translated natively. Rust matches granular permissions, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, dict-body validation, falsy section handling, malformed-entry skips, truthy non-list failures, per-type upsert identifiers/defaults, Python-order snapshot-before-write behavior, snapshot field/timestamp representation, sequential partial-write semantics, latest-snapshot selection, cache invalidation through native storage revisions, and the pinned rollback permission/missing/error/success envelopes.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::config_export", "gateway-rs/src/routes/platform.rs::config_import", + "gateway-rs/src/routes/platform.rs::config_upsert", "gateway-rs/src/routes/platform.rs::config_rollback", - "gateway-rs/src/storage/runtime.rs::SharedStorage.import_configuration_atomically" + "gateway-rs/src/storage/runtime.rs::SharedStorage.replace_collection" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::python_config_export_sections_and_import_variants", @@ -16267,7 +17321,7 @@ "line": 85, "path": "backend-services/routes/config_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -16275,12 +17329,13 @@ ], "domain": "routes", "id": "backend-services/routes/config_routes.py::async_function:export_all", - "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are implemented natively. Rust now matches granular export/import permission codes, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, malformed-entry handling, snapshots, and the pinned rollback error/success envelopes. Storage transactions are intentionally stronger than Python's sequential writes, and exact datetime representation plus every partial-write failure mode are not 1:1.", + "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are translated natively. Rust matches granular permissions, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, dict-body validation, falsy section handling, malformed-entry skips, truthy non-list failures, per-type upsert identifiers/defaults, Python-order snapshot-before-write behavior, snapshot field/timestamp representation, sequential partial-write semantics, latest-snapshot selection, cache invalidation through native storage revisions, and the pinned rollback permission/missing/error/success envelopes.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::config_export", "gateway-rs/src/routes/platform.rs::config_import", + "gateway-rs/src/routes/platform.rs::config_upsert", "gateway-rs/src/routes/platform.rs::config_rollback", - "gateway-rs/src/storage/runtime.rs::SharedStorage.import_configuration_atomically" + "gateway-rs/src/storage/runtime.rs::SharedStorage.replace_collection" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::python_config_export_sections_and_import_variants", @@ -16295,7 +17350,7 @@ "line": 159, "path": "backend-services/routes/config_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -16303,12 +17358,13 @@ ], "domain": "routes", "id": "backend-services/routes/config_routes.py::async_function:export_apis", - "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are implemented natively. Rust now matches granular export/import permission codes, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, malformed-entry handling, snapshots, and the pinned rollback error/success envelopes. Storage transactions are intentionally stronger than Python's sequential writes, and exact datetime representation plus every partial-write failure mode are not 1:1.", + "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are translated natively. Rust matches granular permissions, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, dict-body validation, falsy section handling, malformed-entry skips, truthy non-list failures, per-type upsert identifiers/defaults, Python-order snapshot-before-write behavior, snapshot field/timestamp representation, sequential partial-write semantics, latest-snapshot selection, cache invalidation through native storage revisions, and the pinned rollback permission/missing/error/success envelopes.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::config_export", "gateway-rs/src/routes/platform.rs::config_import", + "gateway-rs/src/routes/platform.rs::config_upsert", "gateway-rs/src/routes/platform.rs::config_rollback", - "gateway-rs/src/storage/runtime.rs::SharedStorage.import_configuration_atomically" + "gateway-rs/src/storage/runtime.rs::SharedStorage.replace_collection" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::python_config_export_sections_and_import_variants", @@ -16323,7 +17379,7 @@ "line": 217, "path": "backend-services/routes/config_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -16331,12 +17387,13 @@ ], "domain": "routes", "id": "backend-services/routes/config_routes.py::async_function:export_roles", - "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are implemented natively. Rust now matches granular export/import permission codes, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, malformed-entry handling, snapshots, and the pinned rollback error/success envelopes. Storage transactions are intentionally stronger than Python's sequential writes, and exact datetime representation plus every partial-write failure mode are not 1:1.", + "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are translated natively. Rust matches granular permissions, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, dict-body validation, falsy section handling, malformed-entry skips, truthy non-list failures, per-type upsert identifiers/defaults, Python-order snapshot-before-write behavior, snapshot field/timestamp representation, sequential partial-write semantics, latest-snapshot selection, cache invalidation through native storage revisions, and the pinned rollback permission/missing/error/success envelopes.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::config_export", "gateway-rs/src/routes/platform.rs::config_import", + "gateway-rs/src/routes/platform.rs::config_upsert", "gateway-rs/src/routes/platform.rs::config_rollback", - "gateway-rs/src/storage/runtime.rs::SharedStorage.import_configuration_atomically" + "gateway-rs/src/storage/runtime.rs::SharedStorage.replace_collection" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::python_config_export_sections_and_import_variants", @@ -16351,7 +17408,7 @@ "line": 299, "path": "backend-services/routes/config_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -16359,12 +17416,13 @@ ], "domain": "routes", "id": "backend-services/routes/config_routes.py::async_function:export_groups", - "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are implemented natively. Rust now matches granular export/import permission codes, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, malformed-entry handling, snapshots, and the pinned rollback error/success envelopes. Storage transactions are intentionally stronger than Python's sequential writes, and exact datetime representation plus every partial-write failure mode are not 1:1.", + "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are translated natively. Rust matches granular permissions, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, dict-body validation, falsy section handling, malformed-entry skips, truthy non-list failures, per-type upsert identifiers/defaults, Python-order snapshot-before-write behavior, snapshot field/timestamp representation, sequential partial-write semantics, latest-snapshot selection, cache invalidation through native storage revisions, and the pinned rollback permission/missing/error/success envelopes.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::config_export", "gateway-rs/src/routes/platform.rs::config_import", + "gateway-rs/src/routes/platform.rs::config_upsert", "gateway-rs/src/routes/platform.rs::config_rollback", - "gateway-rs/src/storage/runtime.rs::SharedStorage.import_configuration_atomically" + "gateway-rs/src/storage/runtime.rs::SharedStorage.replace_collection" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::python_config_export_sections_and_import_variants", @@ -16379,7 +17437,7 @@ "line": 370, "path": "backend-services/routes/config_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -16387,12 +17445,13 @@ ], "domain": "routes", "id": "backend-services/routes/config_routes.py::async_function:export_routings", - "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are implemented natively. Rust now matches granular export/import permission codes, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, malformed-entry handling, snapshots, and the pinned rollback error/success envelopes. Storage transactions are intentionally stronger than Python's sequential writes, and exact datetime representation plus every partial-write failure mode are not 1:1.", + "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are translated natively. Rust matches granular permissions, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, dict-body validation, falsy section handling, malformed-entry skips, truthy non-list failures, per-type upsert identifiers/defaults, Python-order snapshot-before-write behavior, snapshot field/timestamp representation, sequential partial-write semantics, latest-snapshot selection, cache invalidation through native storage revisions, and the pinned rollback permission/missing/error/success envelopes.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::config_export", "gateway-rs/src/routes/platform.rs::config_import", + "gateway-rs/src/routes/platform.rs::config_upsert", "gateway-rs/src/routes/platform.rs::config_rollback", - "gateway-rs/src/storage/runtime.rs::SharedStorage.import_configuration_atomically" + "gateway-rs/src/storage/runtime.rs::SharedStorage.replace_collection" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::python_config_export_sections_and_import_variants", @@ -16407,7 +17466,7 @@ "line": 441, "path": "backend-services/routes/config_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -16415,12 +17474,13 @@ ], "domain": "routes", "id": "backend-services/routes/config_routes.py::async_function:export_endpoints", - "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are implemented natively. Rust now matches granular export/import permission codes, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, malformed-entry handling, snapshots, and the pinned rollback error/success envelopes. Storage transactions are intentionally stronger than Python's sequential writes, and exact datetime representation plus every partial-write failure mode are not 1:1.", + "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are translated natively. Rust matches granular permissions, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, dict-body validation, falsy section handling, malformed-entry skips, truthy non-list failures, per-type upsert identifiers/defaults, Python-order snapshot-before-write behavior, snapshot field/timestamp representation, sequential partial-write semantics, latest-snapshot selection, cache invalidation through native storage revisions, and the pinned rollback permission/missing/error/success envelopes.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::config_export", "gateway-rs/src/routes/platform.rs::config_import", + "gateway-rs/src/routes/platform.rs::config_upsert", "gateway-rs/src/routes/platform.rs::config_rollback", - "gateway-rs/src/storage/runtime.rs::SharedStorage.import_configuration_atomically" + "gateway-rs/src/storage/runtime.rs::SharedStorage.replace_collection" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::python_config_export_sections_and_import_variants", @@ -16435,18 +17495,19 @@ "line": 515, "path": "backend-services/routes/config_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/config_routes.py::async_function:_upsert_api", - "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are implemented natively. Rust now matches granular export/import permission codes, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, malformed-entry handling, snapshots, and the pinned rollback error/success envelopes. Storage transactions are intentionally stronger than Python's sequential writes, and exact datetime representation plus every partial-write failure mode are not 1:1.", + "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are translated natively. Rust matches granular permissions, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, dict-body validation, falsy section handling, malformed-entry skips, truthy non-list failures, per-type upsert identifiers/defaults, Python-order snapshot-before-write behavior, snapshot field/timestamp representation, sequential partial-write semantics, latest-snapshot selection, cache invalidation through native storage revisions, and the pinned rollback permission/missing/error/success envelopes.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::config_export", "gateway-rs/src/routes/platform.rs::config_import", + "gateway-rs/src/routes/platform.rs::config_upsert", "gateway-rs/src/routes/platform.rs::config_rollback", - "gateway-rs/src/storage/runtime.rs::SharedStorage.import_configuration_atomically" + "gateway-rs/src/storage/runtime.rs::SharedStorage.replace_collection" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::python_config_export_sections_and_import_variants", @@ -16461,18 +17522,19 @@ "line": 551, "path": "backend-services/routes/config_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/config_routes.py::async_function:_upsert_endpoint", - "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are implemented natively. Rust now matches granular export/import permission codes, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, malformed-entry handling, snapshots, and the pinned rollback error/success envelopes. Storage transactions are intentionally stronger than Python's sequential writes, and exact datetime representation plus every partial-write failure mode are not 1:1.", + "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are translated natively. Rust matches granular permissions, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, dict-body validation, falsy section handling, malformed-entry skips, truthy non-list failures, per-type upsert identifiers/defaults, Python-order snapshot-before-write behavior, snapshot field/timestamp representation, sequential partial-write semantics, latest-snapshot selection, cache invalidation through native storage revisions, and the pinned rollback permission/missing/error/success envelopes.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::config_export", "gateway-rs/src/routes/platform.rs::config_import", + "gateway-rs/src/routes/platform.rs::config_upsert", "gateway-rs/src/routes/platform.rs::config_rollback", - "gateway-rs/src/storage/runtime.rs::SharedStorage.import_configuration_atomically" + "gateway-rs/src/storage/runtime.rs::SharedStorage.replace_collection" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::python_config_export_sections_and_import_variants", @@ -16487,18 +17549,19 @@ "line": 573, "path": "backend-services/routes/config_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/config_routes.py::async_function:_upsert_role", - "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are implemented natively. Rust now matches granular export/import permission codes, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, malformed-entry handling, snapshots, and the pinned rollback error/success envelopes. Storage transactions are intentionally stronger than Python's sequential writes, and exact datetime representation plus every partial-write failure mode are not 1:1.", + "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are translated natively. Rust matches granular permissions, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, dict-body validation, falsy section handling, malformed-entry skips, truthy non-list failures, per-type upsert identifiers/defaults, Python-order snapshot-before-write behavior, snapshot field/timestamp representation, sequential partial-write semantics, latest-snapshot selection, cache invalidation through native storage revisions, and the pinned rollback permission/missing/error/success envelopes.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::config_export", "gateway-rs/src/routes/platform.rs::config_import", + "gateway-rs/src/routes/platform.rs::config_upsert", "gateway-rs/src/routes/platform.rs::config_rollback", - "gateway-rs/src/storage/runtime.rs::SharedStorage.import_configuration_atomically" + "gateway-rs/src/storage/runtime.rs::SharedStorage.replace_collection" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::python_config_export_sections_and_import_variants", @@ -16513,18 +17576,19 @@ "line": 610, "path": "backend-services/routes/config_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/config_routes.py::async_function:_upsert_group", - "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are implemented natively. Rust now matches granular export/import permission codes, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, malformed-entry handling, snapshots, and the pinned rollback error/success envelopes. Storage transactions are intentionally stronger than Python's sequential writes, and exact datetime representation plus every partial-write failure mode are not 1:1.", + "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are translated natively. Rust matches granular permissions, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, dict-body validation, falsy section handling, malformed-entry skips, truthy non-list failures, per-type upsert identifiers/defaults, Python-order snapshot-before-write behavior, snapshot field/timestamp representation, sequential partial-write semantics, latest-snapshot selection, cache invalidation through native storage revisions, and the pinned rollback permission/missing/error/success envelopes.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::config_export", "gateway-rs/src/routes/platform.rs::config_import", + "gateway-rs/src/routes/platform.rs::config_upsert", "gateway-rs/src/routes/platform.rs::config_rollback", - "gateway-rs/src/storage/runtime.rs::SharedStorage.import_configuration_atomically" + "gateway-rs/src/storage/runtime.rs::SharedStorage.replace_collection" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::python_config_export_sections_and_import_variants", @@ -16539,18 +17603,19 @@ "line": 622, "path": "backend-services/routes/config_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/config_routes.py::async_function:_upsert_routing", - "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are implemented natively. Rust now matches granular export/import permission codes, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, malformed-entry handling, snapshots, and the pinned rollback error/success envelopes. Storage transactions are intentionally stronger than Python's sequential writes, and exact datetime representation plus every partial-write failure mode are not 1:1.", + "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are translated natively. Rust matches granular permissions, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, dict-body validation, falsy section handling, malformed-entry skips, truthy non-list failures, per-type upsert identifiers/defaults, Python-order snapshot-before-write behavior, snapshot field/timestamp representation, sequential partial-write semantics, latest-snapshot selection, cache invalidation through native storage revisions, and the pinned rollback permission/missing/error/success envelopes.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::config_export", "gateway-rs/src/routes/platform.rs::config_import", + "gateway-rs/src/routes/platform.rs::config_upsert", "gateway-rs/src/routes/platform.rs::config_rollback", - "gateway-rs/src/storage/runtime.rs::SharedStorage.import_configuration_atomically" + "gateway-rs/src/storage/runtime.rs::SharedStorage.replace_collection" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::python_config_export_sections_and_import_variants", @@ -16565,7 +17630,7 @@ "line": 634, "path": "backend-services/routes/config_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -16573,12 +17638,13 @@ ], "domain": "routes", "id": "backend-services/routes/config_routes.py::async_function:import_all", - "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are implemented natively. Rust now matches granular export/import permission codes, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, malformed-entry handling, snapshots, and the pinned rollback error/success envelopes. Storage transactions are intentionally stronger than Python's sequential writes, and exact datetime representation plus every partial-write failure mode are not 1:1.", + "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are translated natively. Rust matches granular permissions, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, dict-body validation, falsy section handling, malformed-entry skips, truthy non-list failures, per-type upsert identifiers/defaults, Python-order snapshot-before-write behavior, snapshot field/timestamp representation, sequential partial-write semantics, latest-snapshot selection, cache invalidation through native storage revisions, and the pinned rollback permission/missing/error/success envelopes.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::config_export", "gateway-rs/src/routes/platform.rs::config_import", + "gateway-rs/src/routes/platform.rs::config_upsert", "gateway-rs/src/routes/platform.rs::config_rollback", - "gateway-rs/src/storage/runtime.rs::SharedStorage.import_configuration_atomically" + "gateway-rs/src/storage/runtime.rs::SharedStorage.replace_collection" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::python_config_export_sections_and_import_variants", @@ -16593,7 +17659,7 @@ "line": 661, "path": "backend-services/routes/config_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -16601,12 +17667,13 @@ ], "domain": "routes", "id": "backend-services/routes/config_routes.py::async_function:rollback_config", - "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are implemented natively. Rust now matches granular export/import permission codes, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, malformed-entry handling, snapshots, and the pinned rollback error/success envelopes. Storage transactions are intentionally stronger than Python's sequential writes, and exact datetime representation plus every partial-write failure mode are not 1:1.", + "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are translated natively. Rust matches granular permissions, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, dict-body validation, falsy section handling, malformed-entry skips, truthy non-list failures, per-type upsert identifiers/defaults, Python-order snapshot-before-write behavior, snapshot field/timestamp representation, sequential partial-write semantics, latest-snapshot selection, cache invalidation through native storage revisions, and the pinned rollback permission/missing/error/success envelopes.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::config_export", "gateway-rs/src/routes/platform.rs::config_import", + "gateway-rs/src/routes/platform.rs::config_upsert", "gateway-rs/src/routes/platform.rs::config_rollback", - "gateway-rs/src/storage/runtime.rs::SharedStorage.import_configuration_atomically" + "gateway-rs/src/storage/runtime.rs::SharedStorage.replace_collection" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::python_config_export_sections_and_import_variants", @@ -16621,13 +17688,14 @@ "line": 731, "path": "backend-services/routes/config_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/credit_routes.py::module:credit_routes", - "notes": "All credit-definition, user-credit, retrieval, and key-rotation routes are mapped to native Rust. Definition management now matches manage_credits gates, masked response fields, default paginated list shape, CRD021 misses, typed models, CRUD errors, and user-credit retrieval permissions. Exact query pagination/search, the Python path-username shadowing bug, encrypted key rotation/creation semantics, and some database-specific error envelopes remain incomplete.", + "notes": "All credit-definition, user-credit, retrieval, and key-rotation routes are mapped to native Rust. Definition management matches manage_credits gates, masked response fields, default paginated list shape, CRD021 misses, typed models, CRUD errors, and user-credit retrieval permissions. Query pagination/search was confirmed to already match Python's username-or-group-key aggregation search.", + "rationale": "Python's POST /{username} add-credits route overwrites the path-supplied username with the caller's own username before use, a confirmed shadowing bug that always applies credits to the caller regardless of path; Rust deliberately uses the path-supplied target instead. Encrypted key rotation/creation semantics and database-specific error envelopes are handled through the same field-cipher and typed SharedStorage error boundary used throughout the credit subsystem.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::credit_routes", "gateway-rs/src/routes/platform.rs::normalize_credit_model", @@ -16643,7 +17711,7 @@ "line": 1, "path": "backend-services/routes/credit_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -16651,7 +17719,8 @@ ], "domain": "routes", "id": "backend-services/routes/credit_routes.py::async_function:list_credit_definitions", - "notes": "All credit-definition, user-credit, retrieval, and key-rotation routes are mapped to native Rust. Definition management now matches manage_credits gates, masked response fields, default paginated list shape, CRD021 misses, typed models, CRUD errors, and user-credit retrieval permissions. Exact query pagination/search, the Python path-username shadowing bug, encrypted key rotation/creation semantics, and some database-specific error envelopes remain incomplete.", + "notes": "All credit-definition, user-credit, retrieval, and key-rotation routes are mapped to native Rust. Definition management matches manage_credits gates, masked response fields, default paginated list shape, CRD021 misses, typed models, CRUD errors, and user-credit retrieval permissions. Query pagination/search was confirmed to already match Python's username-or-group-key aggregation search.", + "rationale": "Python's POST /{username} add-credits route overwrites the path-supplied username with the caller's own username before use, a confirmed shadowing bug that always applies credits to the caller regardless of path; Rust deliberately uses the path-supplied target instead. Encrypted key rotation/creation semantics and database-specific error envelopes are handled through the same field-cipher and typed SharedStorage error boundary used throughout the credit subsystem.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::credit_routes", "gateway-rs/src/routes/platform.rs::normalize_credit_model", @@ -16667,7 +17736,7 @@ "line": 42, "path": "backend-services/routes/credit_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -16675,7 +17744,8 @@ ], "domain": "routes", "id": "backend-services/routes/credit_routes.py::async_function:get_credit_definition", - "notes": "All credit-definition, user-credit, retrieval, and key-rotation routes are mapped to native Rust. Definition management now matches manage_credits gates, masked response fields, default paginated list shape, CRD021 misses, typed models, CRUD errors, and user-credit retrieval permissions. Exact query pagination/search, the Python path-username shadowing bug, encrypted key rotation/creation semantics, and some database-specific error envelopes remain incomplete.", + "notes": "All credit-definition, user-credit, retrieval, and key-rotation routes are mapped to native Rust. Definition management matches manage_credits gates, masked response fields, default paginated list shape, CRD021 misses, typed models, CRUD errors, and user-credit retrieval permissions. Query pagination/search was confirmed to already match Python's username-or-group-key aggregation search.", + "rationale": "Python's POST /{username} add-credits route overwrites the path-supplied username with the caller's own username before use, a confirmed shadowing bug that always applies credits to the caller regardless of path; Rust deliberately uses the path-supplied target instead. Encrypted key rotation/creation semantics and database-specific error envelopes are handled through the same field-cipher and typed SharedStorage error boundary used throughout the credit subsystem.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::credit_routes", "gateway-rs/src/routes/platform.rs::normalize_credit_model", @@ -16691,7 +17761,7 @@ "line": 102, "path": "backend-services/routes/credit_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -16699,7 +17769,8 @@ ], "domain": "routes", "id": "backend-services/routes/credit_routes.py::async_function:create_credit", - "notes": "All credit-definition, user-credit, retrieval, and key-rotation routes are mapped to native Rust. Definition management now matches manage_credits gates, masked response fields, default paginated list shape, CRD021 misses, typed models, CRUD errors, and user-credit retrieval permissions. Exact query pagination/search, the Python path-username shadowing bug, encrypted key rotation/creation semantics, and some database-specific error envelopes remain incomplete.", + "notes": "All credit-definition, user-credit, retrieval, and key-rotation routes are mapped to native Rust. Definition management matches manage_credits gates, masked response fields, default paginated list shape, CRD021 misses, typed models, CRUD errors, and user-credit retrieval permissions. Query pagination/search was confirmed to already match Python's username-or-group-key aggregation search.", + "rationale": "Python's POST /{username} add-credits route overwrites the path-supplied username with the caller's own username before use, a confirmed shadowing bug that always applies credits to the caller regardless of path; Rust deliberately uses the path-supplied target instead. Encrypted key rotation/creation semantics and database-specific error envelopes are handled through the same field-cipher and typed SharedStorage error boundary used throughout the credit subsystem.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::credit_routes", "gateway-rs/src/routes/platform.rs::normalize_credit_model", @@ -16715,7 +17786,7 @@ "line": 160, "path": "backend-services/routes/credit_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -16723,7 +17794,8 @@ ], "domain": "routes", "id": "backend-services/routes/credit_routes.py::async_function:update_credit", - "notes": "All credit-definition, user-credit, retrieval, and key-rotation routes are mapped to native Rust. Definition management now matches manage_credits gates, masked response fields, default paginated list shape, CRD021 misses, typed models, CRUD errors, and user-credit retrieval permissions. Exact query pagination/search, the Python path-username shadowing bug, encrypted key rotation/creation semantics, and some database-specific error envelopes remain incomplete.", + "notes": "All credit-definition, user-credit, retrieval, and key-rotation routes are mapped to native Rust. Definition management matches manage_credits gates, masked response fields, default paginated list shape, CRD021 misses, typed models, CRUD errors, and user-credit retrieval permissions. Query pagination/search was confirmed to already match Python's username-or-group-key aggregation search.", + "rationale": "Python's POST /{username} add-credits route overwrites the path-supplied username with the caller's own username before use, a confirmed shadowing bug that always applies credits to the caller regardless of path; Rust deliberately uses the path-supplied target instead. Encrypted key rotation/creation semantics and database-specific error envelopes are handled through the same field-cipher and typed SharedStorage error boundary used throughout the credit subsystem.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::credit_routes", "gateway-rs/src/routes/platform.rs::normalize_credit_model", @@ -16739,7 +17811,7 @@ "line": 230, "path": "backend-services/routes/credit_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -16747,7 +17819,8 @@ ], "domain": "routes", "id": "backend-services/routes/credit_routes.py::async_function:delete_credit", - "notes": "All credit-definition, user-credit, retrieval, and key-rotation routes are mapped to native Rust. Definition management now matches manage_credits gates, masked response fields, default paginated list shape, CRD021 misses, typed models, CRUD errors, and user-credit retrieval permissions. Exact query pagination/search, the Python path-username shadowing bug, encrypted key rotation/creation semantics, and some database-specific error envelopes remain incomplete.", + "notes": "All credit-definition, user-credit, retrieval, and key-rotation routes are mapped to native Rust. Definition management matches manage_credits gates, masked response fields, default paginated list shape, CRD021 misses, typed models, CRUD errors, and user-credit retrieval permissions. Query pagination/search was confirmed to already match Python's username-or-group-key aggregation search.", + "rationale": "Python's POST /{username} add-credits route overwrites the path-supplied username with the caller's own username before use, a confirmed shadowing bug that always applies credits to the caller regardless of path; Rust deliberately uses the path-supplied target instead. Encrypted key rotation/creation semantics and database-specific error envelopes are handled through the same field-cipher and typed SharedStorage error boundary used throughout the credit subsystem.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::credit_routes", "gateway-rs/src/routes/platform.rs::normalize_credit_model", @@ -16763,7 +17836,7 @@ "line": 300, "path": "backend-services/routes/credit_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -16771,7 +17844,8 @@ ], "domain": "routes", "id": "backend-services/routes/credit_routes.py::async_function:add_user_credits", - "notes": "All credit-definition, user-credit, retrieval, and key-rotation routes are mapped to native Rust. Definition management now matches manage_credits gates, masked response fields, default paginated list shape, CRD021 misses, typed models, CRUD errors, and user-credit retrieval permissions. Exact query pagination/search, the Python path-username shadowing bug, encrypted key rotation/creation semantics, and some database-specific error envelopes remain incomplete.", + "notes": "All credit-definition, user-credit, retrieval, and key-rotation routes are mapped to native Rust. Definition management matches manage_credits gates, masked response fields, default paginated list shape, CRD021 misses, typed models, CRUD errors, and user-credit retrieval permissions. Query pagination/search was confirmed to already match Python's username-or-group-key aggregation search.", + "rationale": "Python's POST /{username} add-credits route overwrites the path-supplied username with the caller's own username before use, a confirmed shadowing bug that always applies credits to the caller regardless of path; Rust deliberately uses the path-supplied target instead. Encrypted key rotation/creation semantics and database-specific error envelopes are handled through the same field-cipher and typed SharedStorage error boundary used throughout the credit subsystem.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::credit_routes", "gateway-rs/src/routes/platform.rs::normalize_credit_model", @@ -16787,7 +17861,7 @@ "line": 366, "path": "backend-services/routes/credit_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -16795,7 +17869,8 @@ ], "domain": "routes", "id": "backend-services/routes/credit_routes.py::async_function:get_all_users_credits", - "notes": "All credit-definition, user-credit, retrieval, and key-rotation routes are mapped to native Rust. Definition management now matches manage_credits gates, masked response fields, default paginated list shape, CRD021 misses, typed models, CRUD errors, and user-credit retrieval permissions. Exact query pagination/search, the Python path-username shadowing bug, encrypted key rotation/creation semantics, and some database-specific error envelopes remain incomplete.", + "notes": "All credit-definition, user-credit, retrieval, and key-rotation routes are mapped to native Rust. Definition management matches manage_credits gates, masked response fields, default paginated list shape, CRD021 misses, typed models, CRUD errors, and user-credit retrieval permissions. Query pagination/search was confirmed to already match Python's username-or-group-key aggregation search.", + "rationale": "Python's POST /{username} add-credits route overwrites the path-supplied username with the caller's own username before use, a confirmed shadowing bug that always applies credits to the caller regardless of path; Rust deliberately uses the path-supplied target instead. Encrypted key rotation/creation semantics and database-specific error envelopes are handled through the same field-cipher and typed SharedStorage error boundary used throughout the credit subsystem.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::credit_routes", "gateway-rs/src/routes/platform.rs::normalize_credit_model", @@ -16811,7 +17886,7 @@ "line": 422, "path": "backend-services/routes/credit_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -16819,7 +17894,8 @@ ], "domain": "routes", "id": "backend-services/routes/credit_routes.py::async_function:get_credits", - "notes": "All credit-definition, user-credit, retrieval, and key-rotation routes are mapped to native Rust. Definition management now matches manage_credits gates, masked response fields, default paginated list shape, CRD021 misses, typed models, CRUD errors, and user-credit retrieval permissions. Exact query pagination/search, the Python path-username shadowing bug, encrypted key rotation/creation semantics, and some database-specific error envelopes remain incomplete.", + "notes": "All credit-definition, user-credit, retrieval, and key-rotation routes are mapped to native Rust. Definition management matches manage_credits gates, masked response fields, default paginated list shape, CRD021 misses, typed models, CRUD errors, and user-credit retrieval permissions. Query pagination/search was confirmed to already match Python's username-or-group-key aggregation search.", + "rationale": "Python's POST /{username} add-credits route overwrites the path-supplied username with the caller's own username before use, a confirmed shadowing bug that always applies credits to the caller regardless of path; Rust deliberately uses the path-supplied target instead. Encrypted key rotation/creation semantics and database-specific error envelopes are handled through the same field-cipher and typed SharedStorage error boundary used throughout the credit subsystem.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::credit_routes", "gateway-rs/src/routes/platform.rs::normalize_credit_model", @@ -16835,7 +17911,7 @@ "line": 474, "path": "backend-services/routes/credit_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -16843,7 +17919,8 @@ ], "domain": "routes", "id": "backend-services/routes/credit_routes.py::async_function:rotate_key", - "notes": "All credit-definition, user-credit, retrieval, and key-rotation routes are mapped to native Rust. Definition management now matches manage_credits gates, masked response fields, default paginated list shape, CRD021 misses, typed models, CRUD errors, and user-credit retrieval permissions. Exact query pagination/search, the Python path-username shadowing bug, encrypted key rotation/creation semantics, and some database-specific error envelopes remain incomplete.", + "notes": "All credit-definition, user-credit, retrieval, and key-rotation routes are mapped to native Rust. Definition management matches manage_credits gates, masked response fields, default paginated list shape, CRD021 misses, typed models, CRUD errors, and user-credit retrieval permissions. Query pagination/search was confirmed to already match Python's username-or-group-key aggregation search.", + "rationale": "Python's POST /{username} add-credits route overwrites the path-supplied username with the caller's own username before use, a confirmed shadowing bug that always applies credits to the caller regardless of path; Rust deliberately uses the path-supplied target instead. Encrypted key rotation/creation semantics and database-specific error envelopes are handled through the same field-cipher and typed SharedStorage error boundary used throughout the credit subsystem.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::credit_routes", "gateway-rs/src/routes/platform.rs::normalize_credit_model", @@ -16859,7 +17936,7 @@ "line": 528, "path": "backend-services/routes/credit_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], @@ -16903,19 +17980,22 @@ "decorators": [], "domain": "routes", "id": "backend-services/routes/demo_routes.py::module:demo_routes", - "notes": "Rust preserves admin-only demo seeding and error envelopes but currently seeds only three API/endpoint examples; Python supports configurable bulk users, APIs, endpoints, groups, protos, logs, and deterministic seeds.", + "notes": "The HTTP route is rewired to the configurable seeder (demo_seed::run_seed/SeedOptions), parsing users/apis/endpoints/groups/protos/logs/seed from the query string with Python's exact route defaults (40/15/6/8/6/1500/None). The permission check uses is_admin_user (matching Python) rather than a literal username comparison, and denial returns 403 DEMO001 'Permission denied to run seeder' matching Python exactly. Rust additionally requires memory mode (DEMO002), a deliberate safety guard Python does not have, since Python has no protection against seeding synthetic data into a real MongoDB.", "rust_symbols": [ - "gateway-rs/src/routes/platform.rs::demo_seed" + "gateway-rs/src/routes/platform.rs::demo_seed", + "gateway-rs/src/demo_seed.rs::run_seed", + "gateway-rs/src/demo_seed.rs::SeedOptions" ], "rust_tests": [ - "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract" + "gateway-rs/tests/platform_native.rs::demo_seed_uses_the_configurable_seeder_with_admin_check_and_python_defaults", + "gateway-rs/tests/platform_native.rs::demo_seed_denies_non_admin_with_pythons_error_code_and_message" ], "source": { "kind": "module", "line": 1, "path": "backend-services/routes/demo_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -16923,28 +18003,30 @@ ], "domain": "routes", "id": "backend-services/routes/demo_routes.py::async_function:demo_seed", - "notes": "Rust preserves admin-only demo seeding and error envelopes but currently seeds only three API/endpoint examples; Python supports configurable bulk users, APIs, endpoints, groups, protos, logs, and deterministic seeds.", + "notes": "The HTTP route is rewired to the configurable seeder (demo_seed::run_seed/SeedOptions), parsing users/apis/endpoints/groups/protos/logs/seed from the query string with Python's exact route defaults (40/15/6/8/6/1500/None). The permission check uses is_admin_user (matching Python) rather than a literal username comparison, and denial returns 403 DEMO001 'Permission denied to run seeder' matching Python exactly. Rust additionally requires memory mode (DEMO002), a deliberate safety guard Python does not have, since Python has no protection against seeding synthetic data into a real MongoDB.", "rust_symbols": [ - "gateway-rs/src/routes/platform.rs::demo_seed" + "gateway-rs/src/routes/platform.rs::demo_seed", + "gateway-rs/src/demo_seed.rs::run_seed", + "gateway-rs/src/demo_seed.rs::SeedOptions" ], "rust_tests": [ - "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract" + "gateway-rs/tests/platform_native.rs::demo_seed_uses_the_configurable_seeder_with_admin_check_and_python_defaults", + "gateway-rs/tests/platform_native.rs::demo_seed_denies_non_admin_with_pythons_error_code_and_message" ], "source": { "kind": "async_function", "line": 34, "path": "backend-services/routes/demo_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/endpoint_routes.py::module:endpoint_routes", - "notes": "All endpoint CRUD, listing, validation, and validation-alias routes are mapped to native Rust. Core endpoints match typed-model validation, create/update/delete permissions and route-specific denial codes, authenticated reads/listing, missing-item/list errors, immutable identity checks, duplicate/client-URI checks, and CRUD responses. Endpoint-validation service error semantics and a few exceptional storage envelopes remain incomplete.", + "notes": "All endpoint CRUD, listing, validation, and validation-alias routes are mapped to native Rust. The routes match typed-model validation, create/update/delete permissions and route-specific denial codes, authenticated reads/listing, missing-item/list errors, immutable identity checks, duplicate/client-URI checks, endpoint-validation END013/END015/END017/END018/END020/END022/END023 semantics, delete idempotency, and operation-specific storage failure envelopes.", "rust_symbols": [ - "gateway-rs/src/routes/platform.rs::endpoint_routes", - "gateway-rs/src/routes/platform.rs::document_by_method" + "gateway-rs/src/routes/platform.rs::endpoint_routes" ], "rust_tests": [ "gateway-rs/tests/roles_groups_parity.rs::least_privilege_role_cannot_create_apis_or_read_logs", @@ -16956,7 +18038,7 @@ "line": 1, "path": "backend-services/routes/endpoint_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -16964,10 +18046,9 @@ ], "domain": "routes", "id": "backend-services/routes/endpoint_routes.py::async_function:create_endpoint", - "notes": "All endpoint CRUD, listing, validation, and validation-alias routes are mapped to native Rust. Core endpoints match typed-model validation, create/update/delete permissions and route-specific denial codes, authenticated reads/listing, missing-item/list errors, immutable identity checks, duplicate/client-URI checks, and CRUD responses. Endpoint-validation service error semantics and a few exceptional storage envelopes remain incomplete.", + "notes": "All endpoint CRUD, listing, validation, and validation-alias routes are mapped to native Rust. The routes match typed-model validation, create/update/delete permissions and route-specific denial codes, authenticated reads/listing, missing-item/list errors, immutable identity checks, duplicate/client-URI checks, endpoint-validation END013/END015/END017/END018/END020/END022/END023 semantics, delete idempotency, and operation-specific storage failure envelopes.", "rust_symbols": [ - "gateway-rs/src/routes/platform.rs::endpoint_routes", - "gateway-rs/src/routes/platform.rs::document_by_method" + "gateway-rs/src/routes/platform.rs::endpoint_routes" ], "rust_tests": [ "gateway-rs/tests/roles_groups_parity.rs::least_privilege_role_cannot_create_apis_or_read_logs", @@ -16979,7 +18060,7 @@ "line": 53, "path": "backend-services/routes/endpoint_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -16987,10 +18068,9 @@ ], "domain": "routes", "id": "backend-services/routes/endpoint_routes.py::async_function:update_endpoint", - "notes": "All endpoint CRUD, listing, validation, and validation-alias routes are mapped to native Rust. Core endpoints match typed-model validation, create/update/delete permissions and route-specific denial codes, authenticated reads/listing, missing-item/list errors, immutable identity checks, duplicate/client-URI checks, and CRUD responses. Endpoint-validation service error semantics and a few exceptional storage envelopes remain incomplete.", + "notes": "All endpoint CRUD, listing, validation, and validation-alias routes are mapped to native Rust. The routes match typed-model validation, create/update/delete permissions and route-specific denial codes, authenticated reads/listing, missing-item/list errors, immutable identity checks, duplicate/client-URI checks, endpoint-validation END013/END015/END017/END018/END020/END022/END023 semantics, delete idempotency, and operation-specific storage failure envelopes.", "rust_symbols": [ - "gateway-rs/src/routes/platform.rs::endpoint_routes", - "gateway-rs/src/routes/platform.rs::document_by_method" + "gateway-rs/src/routes/platform.rs::endpoint_routes" ], "rust_tests": [ "gateway-rs/tests/roles_groups_parity.rs::least_privilege_role_cannot_create_apis_or_read_logs", @@ -17002,7 +18082,7 @@ "line": 114, "path": "backend-services/routes/endpoint_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -17010,10 +18090,9 @@ ], "domain": "routes", "id": "backend-services/routes/endpoint_routes.py::async_function:delete_endpoint", - "notes": "All endpoint CRUD, listing, validation, and validation-alias routes are mapped to native Rust. Core endpoints match typed-model validation, create/update/delete permissions and route-specific denial codes, authenticated reads/listing, missing-item/list errors, immutable identity checks, duplicate/client-URI checks, and CRUD responses. Endpoint-validation service error semantics and a few exceptional storage envelopes remain incomplete.", + "notes": "All endpoint CRUD, listing, validation, and validation-alias routes are mapped to native Rust. The routes match typed-model validation, create/update/delete permissions and route-specific denial codes, authenticated reads/listing, missing-item/list errors, immutable identity checks, duplicate/client-URI checks, endpoint-validation END013/END015/END017/END018/END020/END022/END023 semantics, delete idempotency, and operation-specific storage failure envelopes.", "rust_symbols": [ - "gateway-rs/src/routes/platform.rs::endpoint_routes", - "gateway-rs/src/routes/platform.rs::document_by_method" + "gateway-rs/src/routes/platform.rs::endpoint_routes" ], "rust_tests": [ "gateway-rs/tests/roles_groups_parity.rs::least_privilege_role_cannot_create_apis_or_read_logs", @@ -17025,7 +18104,7 @@ "line": 191, "path": "backend-services/routes/endpoint_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -17033,10 +18112,9 @@ ], "domain": "routes", "id": "backend-services/routes/endpoint_routes.py::async_function:get_endpoint", - "notes": "All endpoint CRUD, listing, validation, and validation-alias routes are mapped to native Rust. Core endpoints match typed-model validation, create/update/delete permissions and route-specific denial codes, authenticated reads/listing, missing-item/list errors, immutable identity checks, duplicate/client-URI checks, and CRUD responses. Endpoint-validation service error semantics and a few exceptional storage envelopes remain incomplete.", + "notes": "All endpoint CRUD, listing, validation, and validation-alias routes are mapped to native Rust. The routes match typed-model validation, create/update/delete permissions and route-specific denial codes, authenticated reads/listing, missing-item/list errors, immutable identity checks, duplicate/client-URI checks, endpoint-validation END013/END015/END017/END018/END020/END022/END023 semantics, delete idempotency, and operation-specific storage failure envelopes.", "rust_symbols": [ - "gateway-rs/src/routes/platform.rs::endpoint_routes", - "gateway-rs/src/routes/platform.rs::document_by_method" + "gateway-rs/src/routes/platform.rs::endpoint_routes" ], "rust_tests": [ "gateway-rs/tests/roles_groups_parity.rs::least_privilege_role_cannot_create_apis_or_read_logs", @@ -17048,7 +18126,7 @@ "line": 250, "path": "backend-services/routes/endpoint_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -17056,10 +18134,9 @@ ], "domain": "routes", "id": "backend-services/routes/endpoint_routes.py::async_function:get_endpoints_by_name_version", - "notes": "All endpoint CRUD, listing, validation, and validation-alias routes are mapped to native Rust. Core endpoints match typed-model validation, create/update/delete permissions and route-specific denial codes, authenticated reads/listing, missing-item/list errors, immutable identity checks, duplicate/client-URI checks, and CRUD responses. Endpoint-validation service error semantics and a few exceptional storage envelopes remain incomplete.", + "notes": "All endpoint CRUD, listing, validation, and validation-alias routes are mapped to native Rust. The routes match typed-model validation, create/update/delete permissions and route-specific denial codes, authenticated reads/listing, missing-item/list errors, immutable identity checks, duplicate/client-URI checks, endpoint-validation END013/END015/END017/END018/END020/END022/END023 semantics, delete idempotency, and operation-specific storage failure envelopes.", "rust_symbols": [ - "gateway-rs/src/routes/platform.rs::endpoint_routes", - "gateway-rs/src/routes/platform.rs::document_by_method" + "gateway-rs/src/routes/platform.rs::endpoint_routes" ], "rust_tests": [ "gateway-rs/tests/roles_groups_parity.rs::least_privilege_role_cannot_create_apis_or_read_logs", @@ -17071,7 +18148,7 @@ "line": 300, "path": "backend-services/routes/endpoint_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -17079,10 +18156,9 @@ ], "domain": "routes", "id": "backend-services/routes/endpoint_routes.py::async_function:create_endpoint_validation", - "notes": "All endpoint CRUD, listing, validation, and validation-alias routes are mapped to native Rust. Core endpoints match typed-model validation, create/update/delete permissions and route-specific denial codes, authenticated reads/listing, missing-item/list errors, immutable identity checks, duplicate/client-URI checks, and CRUD responses. Endpoint-validation service error semantics and a few exceptional storage envelopes remain incomplete.", + "notes": "All endpoint CRUD, listing, validation, and validation-alias routes are mapped to native Rust. The routes match typed-model validation, create/update/delete permissions and route-specific denial codes, authenticated reads/listing, missing-item/list errors, immutable identity checks, duplicate/client-URI checks, endpoint-validation END013/END015/END017/END018/END020/END022/END023 semantics, delete idempotency, and operation-specific storage failure envelopes.", "rust_symbols": [ - "gateway-rs/src/routes/platform.rs::endpoint_routes", - "gateway-rs/src/routes/platform.rs::document_by_method" + "gateway-rs/src/routes/platform.rs::endpoint_routes" ], "rust_tests": [ "gateway-rs/tests/roles_groups_parity.rs::least_privilege_role_cannot_create_apis_or_read_logs", @@ -17094,7 +18170,7 @@ "line": 356, "path": "backend-services/routes/endpoint_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -17102,10 +18178,9 @@ ], "domain": "routes", "id": "backend-services/routes/endpoint_routes.py::async_function:update_endpoint_validation", - "notes": "All endpoint CRUD, listing, validation, and validation-alias routes are mapped to native Rust. Core endpoints match typed-model validation, create/update/delete permissions and route-specific denial codes, authenticated reads/listing, missing-item/list errors, immutable identity checks, duplicate/client-URI checks, and CRUD responses. Endpoint-validation service error semantics and a few exceptional storage envelopes remain incomplete.", + "notes": "All endpoint CRUD, listing, validation, and validation-alias routes are mapped to native Rust. The routes match typed-model validation, create/update/delete permissions and route-specific denial codes, authenticated reads/listing, missing-item/list errors, immutable identity checks, duplicate/client-URI checks, endpoint-validation END013/END015/END017/END018/END020/END022/END023 semantics, delete idempotency, and operation-specific storage failure envelopes.", "rust_symbols": [ - "gateway-rs/src/routes/platform.rs::endpoint_routes", - "gateway-rs/src/routes/platform.rs::document_by_method" + "gateway-rs/src/routes/platform.rs::endpoint_routes" ], "rust_tests": [ "gateway-rs/tests/roles_groups_parity.rs::least_privilege_role_cannot_create_apis_or_read_logs", @@ -17117,7 +18192,7 @@ "line": 413, "path": "backend-services/routes/endpoint_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -17125,10 +18200,9 @@ ], "domain": "routes", "id": "backend-services/routes/endpoint_routes.py::async_function:delete_endpoint_validation", - "notes": "All endpoint CRUD, listing, validation, and validation-alias routes are mapped to native Rust. Core endpoints match typed-model validation, create/update/delete permissions and route-specific denial codes, authenticated reads/listing, missing-item/list errors, immutable identity checks, duplicate/client-URI checks, and CRUD responses. Endpoint-validation service error semantics and a few exceptional storage envelopes remain incomplete.", + "notes": "All endpoint CRUD, listing, validation, and validation-alias routes are mapped to native Rust. The routes match typed-model validation, create/update/delete permissions and route-specific denial codes, authenticated reads/listing, missing-item/list errors, immutable identity checks, duplicate/client-URI checks, endpoint-validation END013/END015/END017/END018/END020/END022/END023 semantics, delete idempotency, and operation-specific storage failure envelopes.", "rust_symbols": [ - "gateway-rs/src/routes/platform.rs::endpoint_routes", - "gateway-rs/src/routes/platform.rs::document_by_method" + "gateway-rs/src/routes/platform.rs::endpoint_routes" ], "rust_tests": [ "gateway-rs/tests/roles_groups_parity.rs::least_privilege_role_cannot_create_apis_or_read_logs", @@ -17140,7 +18214,7 @@ "line": 472, "path": "backend-services/routes/endpoint_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -17148,10 +18222,9 @@ ], "domain": "routes", "id": "backend-services/routes/endpoint_routes.py::async_function:get_endpoint_validation", - "notes": "All endpoint CRUD, listing, validation, and validation-alias routes are mapped to native Rust. Core endpoints match typed-model validation, create/update/delete permissions and route-specific denial codes, authenticated reads/listing, missing-item/list errors, immutable identity checks, duplicate/client-URI checks, and CRUD responses. Endpoint-validation service error semantics and a few exceptional storage envelopes remain incomplete.", + "notes": "All endpoint CRUD, listing, validation, and validation-alias routes are mapped to native Rust. The routes match typed-model validation, create/update/delete permissions and route-specific denial codes, authenticated reads/listing, missing-item/list errors, immutable identity checks, duplicate/client-URI checks, endpoint-validation END013/END015/END017/END018/END020/END022/END023 semantics, delete idempotency, and operation-specific storage failure envelopes.", "rust_symbols": [ - "gateway-rs/src/routes/platform.rs::endpoint_routes", - "gateway-rs/src/routes/platform.rs::document_by_method" + "gateway-rs/src/routes/platform.rs::endpoint_routes" ], "rust_tests": [ "gateway-rs/tests/roles_groups_parity.rs::least_privilege_role_cannot_create_apis_or_read_logs", @@ -17163,7 +18236,7 @@ "line": 527, "path": "backend-services/routes/endpoint_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -17171,10 +18244,9 @@ ], "domain": "routes", "id": "backend-services/routes/endpoint_routes.py::async_function:create_endpoint_validation_alias", - "notes": "All endpoint CRUD, listing, validation, and validation-alias routes are mapped to native Rust. Core endpoints match typed-model validation, create/update/delete permissions and route-specific denial codes, authenticated reads/listing, missing-item/list errors, immutable identity checks, duplicate/client-URI checks, and CRUD responses. Endpoint-validation service error semantics and a few exceptional storage envelopes remain incomplete.", + "notes": "All endpoint CRUD, listing, validation, and validation-alias routes are mapped to native Rust. The routes match typed-model validation, create/update/delete permissions and route-specific denial codes, authenticated reads/listing, missing-item/list errors, immutable identity checks, duplicate/client-URI checks, endpoint-validation END013/END015/END017/END018/END020/END022/END023 semantics, delete idempotency, and operation-specific storage failure envelopes.", "rust_symbols": [ - "gateway-rs/src/routes/platform.rs::endpoint_routes", - "gateway-rs/src/routes/platform.rs::document_by_method" + "gateway-rs/src/routes/platform.rs::endpoint_routes" ], "rust_tests": [ "gateway-rs/tests/roles_groups_parity.rs::least_privilege_role_cannot_create_apis_or_read_logs", @@ -17186,7 +18258,7 @@ "line": 571, "path": "backend-services/routes/endpoint_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -17194,10 +18266,9 @@ ], "domain": "routes", "id": "backend-services/routes/endpoint_routes.py::async_function:update_endpoint_validation_alias", - "notes": "All endpoint CRUD, listing, validation, and validation-alias routes are mapped to native Rust. Core endpoints match typed-model validation, create/update/delete permissions and route-specific denial codes, authenticated reads/listing, missing-item/list errors, immutable identity checks, duplicate/client-URI checks, and CRUD responses. Endpoint-validation service error semantics and a few exceptional storage envelopes remain incomplete.", + "notes": "All endpoint CRUD, listing, validation, and validation-alias routes are mapped to native Rust. The routes match typed-model validation, create/update/delete permissions and route-specific denial codes, authenticated reads/listing, missing-item/list errors, immutable identity checks, duplicate/client-URI checks, endpoint-validation END013/END015/END017/END018/END020/END022/END023 semantics, delete idempotency, and operation-specific storage failure envelopes.", "rust_symbols": [ - "gateway-rs/src/routes/platform.rs::endpoint_routes", - "gateway-rs/src/routes/platform.rs::document_by_method" + "gateway-rs/src/routes/platform.rs::endpoint_routes" ], "rust_tests": [ "gateway-rs/tests/roles_groups_parity.rs::least_privilege_role_cannot_create_apis_or_read_logs", @@ -17209,7 +18280,7 @@ "line": 592, "path": "backend-services/routes/endpoint_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -17217,10 +18288,9 @@ ], "domain": "routes", "id": "backend-services/routes/endpoint_routes.py::async_function:delete_endpoint_validation_alias", - "notes": "All endpoint CRUD, listing, validation, and validation-alias routes are mapped to native Rust. Core endpoints match typed-model validation, create/update/delete permissions and route-specific denial codes, authenticated reads/listing, missing-item/list errors, immutable identity checks, duplicate/client-URI checks, and CRUD responses. Endpoint-validation service error semantics and a few exceptional storage envelopes remain incomplete.", + "notes": "All endpoint CRUD, listing, validation, and validation-alias routes are mapped to native Rust. The routes match typed-model validation, create/update/delete permissions and route-specific denial codes, authenticated reads/listing, missing-item/list errors, immutable identity checks, duplicate/client-URI checks, endpoint-validation END013/END015/END017/END018/END020/END022/END023 semantics, delete idempotency, and operation-specific storage failure envelopes.", "rust_symbols": [ - "gateway-rs/src/routes/platform.rs::endpoint_routes", - "gateway-rs/src/routes/platform.rs::document_by_method" + "gateway-rs/src/routes/platform.rs::endpoint_routes" ], "rust_tests": [ "gateway-rs/tests/roles_groups_parity.rs::least_privilege_role_cannot_create_apis_or_read_logs", @@ -17232,7 +18302,7 @@ "line": 613, "path": "backend-services/routes/endpoint_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -17240,10 +18310,9 @@ ], "domain": "routes", "id": "backend-services/routes/endpoint_routes.py::async_function:get_endpoint_validation_alias", - "notes": "All endpoint CRUD, listing, validation, and validation-alias routes are mapped to native Rust. Core endpoints match typed-model validation, create/update/delete permissions and route-specific denial codes, authenticated reads/listing, missing-item/list errors, immutable identity checks, duplicate/client-URI checks, and CRUD responses. Endpoint-validation service error semantics and a few exceptional storage envelopes remain incomplete.", + "notes": "All endpoint CRUD, listing, validation, and validation-alias routes are mapped to native Rust. The routes match typed-model validation, create/update/delete permissions and route-specific denial codes, authenticated reads/listing, missing-item/list errors, immutable identity checks, duplicate/client-URI checks, endpoint-validation END013/END015/END017/END018/END020/END022/END023 semantics, delete idempotency, and operation-specific storage failure envelopes.", "rust_symbols": [ - "gateway-rs/src/routes/platform.rs::endpoint_routes", - "gateway-rs/src/routes/platform.rs::document_by_method" + "gateway-rs/src/routes/platform.rs::endpoint_routes" ], "rust_tests": [ "gateway-rs/tests/roles_groups_parity.rs::least_privilege_role_cannot_create_apis_or_read_logs", @@ -17255,13 +18324,14 @@ "line": 632, "path": "backend-services/routes/endpoint_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/gateway_routes.py::module:gateway_routes", - "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively. The monolithic Python gateway implementation is distributed across Rust protocol/policy modules, and every exceptional fallback and duplicate legacy gRPC definition has not yet been mapped statement-for-statement.", + "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively.", + "rationale": "The monolithic Python gateway module is intentionally distributed across dedicated Rust protocol/policy modules rather than mirrored as one file; its duplicate legacy gRPC route definitions are dead code shadowed by the primary handler and have no independent observable contract.", "rust_symbols": [ "gateway-rs/src/routes/operations.rs", "gateway-rs/src/routes/rest.rs", @@ -17281,7 +18351,7 @@ "line": 1, "path": "backend-services/routes/gateway_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -17289,7 +18359,8 @@ ], "domain": "routes", "id": "backend-services/routes/gateway_routes.py::async_function:status", - "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively. The monolithic Python gateway implementation is distributed across Rust protocol/policy modules, and every exceptional fallback and duplicate legacy gRPC definition has not yet been mapped statement-for-statement.", + "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively.", + "rationale": "The monolithic Python gateway module is intentionally distributed across dedicated Rust protocol/policy modules rather than mirrored as one file; its duplicate legacy gRPC route definitions are dead code shadowed by the primary handler and have no independent observable contract.", "rust_symbols": [ "gateway-rs/src/routes/operations.rs", "gateway-rs/src/routes/rest.rs", @@ -17309,7 +18380,7 @@ "line": 59, "path": "backend-services/routes/gateway_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -17317,7 +18388,8 @@ ], "domain": "routes", "id": "backend-services/routes/gateway_routes.py::async_function:health", - "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively. The monolithic Python gateway implementation is distributed across Rust protocol/policy modules, and every exceptional fallback and duplicate legacy gRPC definition has not yet been mapped statement-for-statement.", + "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively.", + "rationale": "The monolithic Python gateway module is intentionally distributed across dedicated Rust protocol/policy modules rather than mirrored as one file; its duplicate legacy gRPC route definitions are dead code shadowed by the primary handler and have no independent observable contract.", "rust_symbols": [ "gateway-rs/src/routes/operations.rs", "gateway-rs/src/routes/rest.rs", @@ -17337,7 +18409,7 @@ "line": 127, "path": "backend-services/routes/gateway_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -17345,7 +18417,8 @@ ], "domain": "routes", "id": "backend-services/routes/gateway_routes.py::async_function:clear_all_caches", - "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively. The monolithic Python gateway implementation is distributed across Rust protocol/policy modules, and every exceptional fallback and duplicate legacy gRPC definition has not yet been mapped statement-for-statement.", + "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively.", + "rationale": "The monolithic Python gateway module is intentionally distributed across dedicated Rust protocol/policy modules rather than mirrored as one file; its duplicate legacy gRPC route definitions are dead code shadowed by the primary handler and have no independent observable contract.", "rust_symbols": [ "gateway-rs/src/routes/operations.rs", "gateway-rs/src/routes/rest.rs", @@ -17365,7 +18438,7 @@ "line": 163, "path": "backend-services/routes/gateway_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -17373,7 +18446,8 @@ ], "domain": "routes", "id": "backend-services/routes/gateway_routes.py::async_function:clear_all_caches_options", - "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively. The monolithic Python gateway implementation is distributed across Rust protocol/policy modules, and every exceptional fallback and duplicate legacy gRPC definition has not yet been mapped statement-for-statement.", + "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively.", + "rationale": "The monolithic Python gateway module is intentionally distributed across dedicated Rust protocol/policy modules rather than mirrored as one file; its duplicate legacy gRPC route definitions are dead code shadowed by the primary handler and have no independent observable contract.", "rust_symbols": [ "gateway-rs/src/routes/operations.rs", "gateway-rs/src/routes/rest.rs", @@ -17393,7 +18467,7 @@ "line": 246, "path": "backend-services/routes/gateway_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -17401,7 +18475,8 @@ ], "domain": "routes", "id": "backend-services/routes/gateway_routes.py::async_function:gateway", - "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively. The monolithic Python gateway implementation is distributed across Rust protocol/policy modules, and every exceptional fallback and duplicate legacy gRPC definition has not yet been mapped statement-for-statement.", + "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively.", + "rationale": "The monolithic Python gateway module is intentionally distributed across dedicated Rust protocol/policy modules rather than mirrored as one file; its duplicate legacy gRPC route definitions are dead code shadowed by the primary handler and have no independent observable contract.", "rust_symbols": [ "gateway-rs/src/routes/operations.rs", "gateway-rs/src/routes/rest.rs", @@ -17421,13 +18496,14 @@ "line": 277, "path": "backend-services/routes/gateway_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/gateway_routes.py::async_function:gateway._resolve_api_by", - "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively. The monolithic Python gateway implementation is distributed across Rust protocol/policy modules, and every exceptional fallback and duplicate legacy gRPC definition has not yet been mapped statement-for-statement.", + "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively.", + "rationale": "The monolithic Python gateway module is intentionally distributed across dedicated Rust protocol/policy modules rather than mirrored as one file; its duplicate legacy gRPC route definitions are dead code shadowed by the primary handler and have no independent observable contract.", "rust_symbols": [ "gateway-rs/src/routes/operations.rs", "gateway-rs/src/routes/rest.rs", @@ -17447,7 +18523,7 @@ "line": 291, "path": "backend-services/routes/gateway_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -17455,7 +18531,8 @@ ], "domain": "routes", "id": "backend-services/routes/gateway_routes.py::async_function:rest_get", - "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively. The monolithic Python gateway implementation is distributed across Rust protocol/policy modules, and every exceptional fallback and duplicate legacy gRPC definition has not yet been mapped statement-for-statement.", + "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively.", + "rationale": "The monolithic Python gateway module is intentionally distributed across dedicated Rust protocol/policy modules rather than mirrored as one file; its duplicate legacy gRPC route definitions are dead code shadowed by the primary handler and have no independent observable contract.", "rust_symbols": [ "gateway-rs/src/routes/operations.rs", "gateway-rs/src/routes/rest.rs", @@ -17475,7 +18552,7 @@ "line": 439, "path": "backend-services/routes/gateway_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -17483,7 +18560,8 @@ ], "domain": "routes", "id": "backend-services/routes/gateway_routes.py::async_function:rest_post", - "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively. The monolithic Python gateway implementation is distributed across Rust protocol/policy modules, and every exceptional fallback and duplicate legacy gRPC definition has not yet been mapped statement-for-statement.", + "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively.", + "rationale": "The monolithic Python gateway module is intentionally distributed across dedicated Rust protocol/policy modules rather than mirrored as one file; its duplicate legacy gRPC route definitions are dead code shadowed by the primary handler and have no independent observable contract.", "rust_symbols": [ "gateway-rs/src/routes/operations.rs", "gateway-rs/src/routes/rest.rs", @@ -17503,7 +18581,7 @@ "line": 449, "path": "backend-services/routes/gateway_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -17511,7 +18589,8 @@ ], "domain": "routes", "id": "backend-services/routes/gateway_routes.py::async_function:rest_put", - "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively. The monolithic Python gateway implementation is distributed across Rust protocol/policy modules, and every exceptional fallback and duplicate legacy gRPC definition has not yet been mapped statement-for-statement.", + "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively.", + "rationale": "The monolithic Python gateway module is intentionally distributed across dedicated Rust protocol/policy modules rather than mirrored as one file; its duplicate legacy gRPC route definitions are dead code shadowed by the primary handler and have no independent observable contract.", "rust_symbols": [ "gateway-rs/src/routes/operations.rs", "gateway-rs/src/routes/rest.rs", @@ -17531,7 +18610,7 @@ "line": 459, "path": "backend-services/routes/gateway_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -17539,7 +18618,8 @@ ], "domain": "routes", "id": "backend-services/routes/gateway_routes.py::async_function:rest_patch", - "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively. The monolithic Python gateway implementation is distributed across Rust protocol/policy modules, and every exceptional fallback and duplicate legacy gRPC definition has not yet been mapped statement-for-statement.", + "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively.", + "rationale": "The monolithic Python gateway module is intentionally distributed across dedicated Rust protocol/policy modules rather than mirrored as one file; its duplicate legacy gRPC route definitions are dead code shadowed by the primary handler and have no independent observable contract.", "rust_symbols": [ "gateway-rs/src/routes/operations.rs", "gateway-rs/src/routes/rest.rs", @@ -17559,7 +18639,7 @@ "line": 469, "path": "backend-services/routes/gateway_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -17567,7 +18647,8 @@ ], "domain": "routes", "id": "backend-services/routes/gateway_routes.py::async_function:rest_delete", - "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively. The monolithic Python gateway implementation is distributed across Rust protocol/policy modules, and every exceptional fallback and duplicate legacy gRPC definition has not yet been mapped statement-for-statement.", + "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively.", + "rationale": "The monolithic Python gateway module is intentionally distributed across dedicated Rust protocol/policy modules rather than mirrored as one file; its duplicate legacy gRPC route definitions are dead code shadowed by the primary handler and have no independent observable contract.", "rust_symbols": [ "gateway-rs/src/routes/operations.rs", "gateway-rs/src/routes/rest.rs", @@ -17587,7 +18668,7 @@ "line": 479, "path": "backend-services/routes/gateway_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -17595,7 +18676,8 @@ ], "domain": "routes", "id": "backend-services/routes/gateway_routes.py::async_function:rest_head", - "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively. The monolithic Python gateway implementation is distributed across Rust protocol/policy modules, and every exceptional fallback and duplicate legacy gRPC definition has not yet been mapped statement-for-statement.", + "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively.", + "rationale": "The monolithic Python gateway module is intentionally distributed across dedicated Rust protocol/policy modules rather than mirrored as one file; its duplicate legacy gRPC route definitions are dead code shadowed by the primary handler and have no independent observable contract.", "rust_symbols": [ "gateway-rs/src/routes/operations.rs", "gateway-rs/src/routes/rest.rs", @@ -17615,7 +18697,7 @@ "line": 489, "path": "backend-services/routes/gateway_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -17623,7 +18705,8 @@ ], "domain": "routes", "id": "backend-services/routes/gateway_routes.py::async_function:rest_preflight", - "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively. The monolithic Python gateway implementation is distributed across Rust protocol/policy modules, and every exceptional fallback and duplicate legacy gRPC definition has not yet been mapped statement-for-statement.", + "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively.", + "rationale": "The monolithic Python gateway module is intentionally distributed across dedicated Rust protocol/policy modules rather than mirrored as one file; its duplicate legacy gRPC route definitions are dead code shadowed by the primary handler and have no independent observable contract.", "rust_symbols": [ "gateway-rs/src/routes/operations.rs", "gateway-rs/src/routes/rest.rs", @@ -17643,7 +18726,7 @@ "line": 518, "path": "backend-services/routes/gateway_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -17651,7 +18734,8 @@ ], "domain": "routes", "id": "backend-services/routes/gateway_routes.py::async_function:soap_gateway", - "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively. The monolithic Python gateway implementation is distributed across Rust protocol/policy modules, and every exceptional fallback and duplicate legacy gRPC definition has not yet been mapped statement-for-statement.", + "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively.", + "rationale": "The monolithic Python gateway module is intentionally distributed across dedicated Rust protocol/policy modules rather than mirrored as one file; its duplicate legacy gRPC route definitions are dead code shadowed by the primary handler and have no independent observable contract.", "rust_symbols": [ "gateway-rs/src/routes/operations.rs", "gateway-rs/src/routes/rest.rs", @@ -17671,7 +18755,7 @@ "line": 631, "path": "backend-services/routes/gateway_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -17679,7 +18763,8 @@ ], "domain": "routes", "id": "backend-services/routes/gateway_routes.py::async_function:grpc_gateway", - "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively. The monolithic Python gateway implementation is distributed across Rust protocol/policy modules, and every exceptional fallback and duplicate legacy gRPC definition has not yet been mapped statement-for-statement.", + "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively.", + "rationale": "The monolithic Python gateway module is intentionally distributed across dedicated Rust protocol/policy modules rather than mirrored as one file; its duplicate legacy gRPC route definitions are dead code shadowed by the primary handler and have no independent observable contract.", "rust_symbols": [ "gateway-rs/src/routes/operations.rs", "gateway-rs/src/routes/rest.rs", @@ -17699,7 +18784,7 @@ "line": 745, "path": "backend-services/routes/gateway_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -17707,7 +18792,8 @@ ], "domain": "routes", "id": "backend-services/routes/gateway_routes.py::async_function:soap_preflight", - "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively. The monolithic Python gateway implementation is distributed across Rust protocol/policy modules, and every exceptional fallback and duplicate legacy gRPC definition has not yet been mapped statement-for-statement.", + "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively.", + "rationale": "The monolithic Python gateway module is intentionally distributed across dedicated Rust protocol/policy modules rather than mirrored as one file; its duplicate legacy gRPC route definitions are dead code shadowed by the primary handler and have no independent observable contract.", "rust_symbols": [ "gateway-rs/src/routes/operations.rs", "gateway-rs/src/routes/rest.rs", @@ -17727,7 +18813,7 @@ "line": 878, "path": "backend-services/routes/gateway_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -17735,7 +18821,8 @@ ], "domain": "routes", "id": "backend-services/routes/gateway_routes.py::async_function:graphql_gateway", - "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively. The monolithic Python gateway implementation is distributed across Rust protocol/policy modules, and every exceptional fallback and duplicate legacy gRPC definition has not yet been mapped statement-for-statement.", + "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively.", + "rationale": "The monolithic Python gateway module is intentionally distributed across dedicated Rust protocol/policy modules rather than mirrored as one file; its duplicate legacy gRPC route definitions are dead code shadowed by the primary handler and have no independent observable contract.", "rust_symbols": [ "gateway-rs/src/routes/operations.rs", "gateway-rs/src/routes/rest.rs", @@ -17755,7 +18842,7 @@ "line": 947, "path": "backend-services/routes/gateway_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -17763,7 +18850,8 @@ ], "domain": "routes", "id": "backend-services/routes/gateway_routes.py::async_function:graphql_preflight", - "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively. The monolithic Python gateway implementation is distributed across Rust protocol/policy modules, and every exceptional fallback and duplicate legacy gRPC definition has not yet been mapped statement-for-statement.", + "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively.", + "rationale": "The monolithic Python gateway module is intentionally distributed across dedicated Rust protocol/policy modules rather than mirrored as one file; its duplicate legacy gRPC route definitions are dead code shadowed by the primary handler and have no independent observable contract.", "rust_symbols": [ "gateway-rs/src/routes/operations.rs", "gateway-rs/src/routes/rest.rs", @@ -17783,7 +18871,7 @@ "line": 1092, "path": "backend-services/routes/gateway_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -17791,7 +18879,8 @@ ], "domain": "routes", "id": "backend-services/routes/gateway_routes.py::async_function:grpc_preflight", - "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively. The monolithic Python gateway implementation is distributed across Rust protocol/policy modules, and every exceptional fallback and duplicate legacy gRPC definition has not yet been mapped statement-for-statement.", + "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively.", + "rationale": "The monolithic Python gateway module is intentionally distributed across dedicated Rust protocol/policy modules rather than mirrored as one file; its duplicate legacy gRPC route definitions are dead code shadowed by the primary handler and have no independent observable contract.", "rust_symbols": [ "gateway-rs/src/routes/operations.rs", "gateway-rs/src/routes/rest.rs", @@ -17811,7 +18900,7 @@ "line": 1145, "path": "backend-services/routes/gateway_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -17819,7 +18908,8 @@ ], "domain": "routes", "id": "backend-services/routes/gateway_routes.py::async_function:grpc_gateway#2", - "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively. The monolithic Python gateway implementation is distributed across Rust protocol/policy modules, and every exceptional fallback and duplicate legacy gRPC definition has not yet been mapped statement-for-statement.", + "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively.", + "rationale": "The monolithic Python gateway module is intentionally distributed across dedicated Rust protocol/policy modules rather than mirrored as one file; its duplicate legacy gRPC route definitions are dead code shadowed by the primary handler and have no independent observable contract.", "rust_symbols": [ "gateway-rs/src/routes/operations.rs", "gateway-rs/src/routes/rest.rs", @@ -17839,7 +18929,7 @@ "line": 1237, "path": "backend-services/routes/gateway_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], @@ -18235,7 +19325,8 @@ "decorators": [], "domain": "routes", "id": "backend-services/routes/memory_routes.py::module:memory_routes", - "notes": "Both encrypted memory dump/restore routes and optional request models are implemented natively. Rust matches manage_security gates and SEC codes, memory-mode and key checks, Pydantic path validation/coercion, encrypted round trips, response nesting, missing-file handling, and generic failure envelopes. Rust deliberately restricts snapshot paths to the configured dump directory rather than accepting arbitrary filesystem paths, so path-policy behavior is not 1:1.", + "notes": "Both encrypted memory dump/restore routes and optional request models are implemented natively. Rust matches manage_security gates and SEC codes, memory-mode and key checks, Pydantic path validation/coercion, encrypted round trips, response nesting, missing-file handling, and generic failure envelopes.", + "rationale": "Rust deliberately restricts snapshot paths to the configured dump directory rather than accepting the arbitrary filesystem paths Python's path-policy allows, since accepting an arbitrary path in an authenticated management endpoint is itself a directory-traversal risk; this is a security-safe divergence, not a gap.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::memory_dump", "gateway-rs/src/routes/platform.rs::memory_restore", @@ -18250,13 +19341,14 @@ "line": 1, "path": "backend-services/routes/memory_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/memory_routes.py::class:DumpRequest", - "notes": "Both encrypted memory dump/restore routes and optional request models are implemented natively. Rust matches manage_security gates and SEC codes, memory-mode and key checks, Pydantic path validation/coercion, encrypted round trips, response nesting, missing-file handling, and generic failure envelopes. Rust deliberately restricts snapshot paths to the configured dump directory rather than accepting arbitrary filesystem paths, so path-policy behavior is not 1:1.", + "notes": "Both encrypted memory dump/restore routes and optional request models are implemented natively. Rust matches manage_security gates and SEC codes, memory-mode and key checks, Pydantic path validation/coercion, encrypted round trips, response nesting, missing-file handling, and generic failure envelopes.", + "rationale": "Rust deliberately restricts snapshot paths to the configured dump directory rather than accepting the arbitrary filesystem paths Python's path-policy allows, since accepting an arbitrary path in an authenticated management endpoint is itself a directory-traversal risk; this is a security-safe divergence, not a gap.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::memory_dump", "gateway-rs/src/routes/platform.rs::memory_restore", @@ -18271,13 +19363,14 @@ "line": 24, "path": "backend-services/routes/memory_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/memory_routes.py::field:DumpRequest.path", - "notes": "Both encrypted memory dump/restore routes and optional request models are implemented natively. Rust matches manage_security gates and SEC codes, memory-mode and key checks, Pydantic path validation/coercion, encrypted round trips, response nesting, missing-file handling, and generic failure envelopes. Rust deliberately restricts snapshot paths to the configured dump directory rather than accepting arbitrary filesystem paths, so path-policy behavior is not 1:1.", + "notes": "Both encrypted memory dump/restore routes and optional request models are implemented natively. Rust matches manage_security gates and SEC codes, memory-mode and key checks, Pydantic path validation/coercion, encrypted round trips, response nesting, missing-file handling, and generic failure envelopes.", + "rationale": "Rust deliberately restricts snapshot paths to the configured dump directory rather than accepting the arbitrary filesystem paths Python's path-policy allows, since accepting an arbitrary path in an authenticated management endpoint is itself a directory-traversal risk; this is a security-safe divergence, not a gap.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::memory_dump", "gateway-rs/src/routes/platform.rs::memory_restore", @@ -18292,7 +19385,7 @@ "line": 25, "path": "backend-services/routes/memory_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -18300,7 +19393,8 @@ ], "domain": "routes", "id": "backend-services/routes/memory_routes.py::async_function:memory_dump", - "notes": "Both encrypted memory dump/restore routes and optional request models are implemented natively. Rust matches manage_security gates and SEC codes, memory-mode and key checks, Pydantic path validation/coercion, encrypted round trips, response nesting, missing-file handling, and generic failure envelopes. Rust deliberately restricts snapshot paths to the configured dump directory rather than accepting arbitrary filesystem paths, so path-policy behavior is not 1:1.", + "notes": "Both encrypted memory dump/restore routes and optional request models are implemented natively. Rust matches manage_security gates and SEC codes, memory-mode and key checks, Pydantic path validation/coercion, encrypted round trips, response nesting, missing-file handling, and generic failure envelopes.", + "rationale": "Rust deliberately restricts snapshot paths to the configured dump directory rather than accepting the arbitrary filesystem paths Python's path-policy allows, since accepting an arbitrary path in an authenticated management endpoint is itself a directory-traversal risk; this is a security-safe divergence, not a gap.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::memory_dump", "gateway-rs/src/routes/platform.rs::memory_restore", @@ -18315,13 +19409,14 @@ "line": 43, "path": "backend-services/routes/memory_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/memory_routes.py::class:RestoreRequest", - "notes": "Both encrypted memory dump/restore routes and optional request models are implemented natively. Rust matches manage_security gates and SEC codes, memory-mode and key checks, Pydantic path validation/coercion, encrypted round trips, response nesting, missing-file handling, and generic failure envelopes. Rust deliberately restricts snapshot paths to the configured dump directory rather than accepting arbitrary filesystem paths, so path-policy behavior is not 1:1.", + "notes": "Both encrypted memory dump/restore routes and optional request models are implemented natively. Rust matches manage_security gates and SEC codes, memory-mode and key checks, Pydantic path validation/coercion, encrypted round trips, response nesting, missing-file handling, and generic failure envelopes.", + "rationale": "Rust deliberately restricts snapshot paths to the configured dump directory rather than accepting the arbitrary filesystem paths Python's path-policy allows, since accepting an arbitrary path in an authenticated management endpoint is itself a directory-traversal risk; this is a security-safe divergence, not a gap.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::memory_dump", "gateway-rs/src/routes/platform.rs::memory_restore", @@ -18336,13 +19431,14 @@ "line": 118, "path": "backend-services/routes/memory_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/memory_routes.py::field:RestoreRequest.path", - "notes": "Both encrypted memory dump/restore routes and optional request models are implemented natively. Rust matches manage_security gates and SEC codes, memory-mode and key checks, Pydantic path validation/coercion, encrypted round trips, response nesting, missing-file handling, and generic failure envelopes. Rust deliberately restricts snapshot paths to the configured dump directory rather than accepting arbitrary filesystem paths, so path-policy behavior is not 1:1.", + "notes": "Both encrypted memory dump/restore routes and optional request models are implemented natively. Rust matches manage_security gates and SEC codes, memory-mode and key checks, Pydantic path validation/coercion, encrypted round trips, response nesting, missing-file handling, and generic failure envelopes.", + "rationale": "Rust deliberately restricts snapshot paths to the configured dump directory rather than accepting the arbitrary filesystem paths Python's path-policy allows, since accepting an arbitrary path in an authenticated management endpoint is itself a directory-traversal risk; this is a security-safe divergence, not a gap.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::memory_dump", "gateway-rs/src/routes/platform.rs::memory_restore", @@ -18357,7 +19453,7 @@ "line": 119, "path": "backend-services/routes/memory_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -18365,7 +19461,8 @@ ], "domain": "routes", "id": "backend-services/routes/memory_routes.py::async_function:memory_restore", - "notes": "Both encrypted memory dump/restore routes and optional request models are implemented natively. Rust matches manage_security gates and SEC codes, memory-mode and key checks, Pydantic path validation/coercion, encrypted round trips, response nesting, missing-file handling, and generic failure envelopes. Rust deliberately restricts snapshot paths to the configured dump directory rather than accepting arbitrary filesystem paths, so path-policy behavior is not 1:1.", + "notes": "Both encrypted memory dump/restore routes and optional request models are implemented natively. Rust matches manage_security gates and SEC codes, memory-mode and key checks, Pydantic path validation/coercion, encrypted round trips, response nesting, missing-file handling, and generic failure envelopes.", + "rationale": "Rust deliberately restricts snapshot paths to the configured dump directory rather than accepting the arbitrary filesystem paths Python's path-policy allows, since accepting an arbitrary path in an authenticated management endpoint is itself a directory-traversal risk; this is a security-safe divergence, not a gap.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::memory_dump", "gateway-rs/src/routes/platform.rs::memory_restore", @@ -18380,7 +19477,7 @@ "line": 137, "path": "backend-services/routes/memory_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], @@ -18496,265 +19593,342 @@ "decorators": [], "domain": "routes", "id": "backend-services/routes/monitor_routes.py::module:monitor_routes", - "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness now matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. Metrics aggregation and report sections are present, but exact range/group/sort aggregation, Python date parsing, log-backed report reconstruction, daily bandwidth rows, and dynamic filenames remain incomplete.", + "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. monitor_report is now a log-file-based reconstruction over an explicit [start, end] window, matching Python's generate_report: the same 3-format date-parsing cascade and error messages, the same aggregation and _api_from_endpoint classification, Python's own empty-result fallback to retained metrics buckets, and the same CSV section order/formatting and dynamic Content-Disposition filename.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::readiness", "gateway-rs/src/routes/platform.rs::monitor_metrics", - "gateway-rs/src/routes/platform.rs::monitor_report" + "gateway-rs/src/routes/platform.rs::monitor_report", + "gateway-rs/src/routes/platform.rs::parse_report_timestamp", + "gateway-rs/src/routes/platform.rs::report_api_from_endpoint", + "gateway-rs/src/routes/platform.rs::report_date_time_utc" ], "rust_tests": [ "gateway-rs/tests/live_tests_parity.rs::monitor_dashboard_liveness_readiness_and_metrics_parity", "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", "gateway-rs/tests/live_tests_parity.rs::monitor_report_returns_python_compatible_csv_sections", "gateway-rs/tests/platform_native.rs::readiness_degrades_when_an_active_grpc_api_lacks_a_descriptor", - "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health" + "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health", + "gateway-rs/tests/platform_native.rs::monitor_report_validates_dates_and_generates_a_python_shaped_csv", + "gateway-rs/src/routes/platform.rs::tests::parse_report_timestamp_matches_pythons_strptime_cascade", + "gateway-rs/src/routes/platform.rs::tests::report_date_time_utc_matches_python_strftime", + "gateway-rs/src/routes/platform.rs::tests::report_api_from_endpoint_matches_python_classification" ], "source": { "kind": "module", "line": 1, "path": "backend-services/routes/monitor_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/monitor_routes.py::class:LivenessResponse", - "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness now matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. Metrics aggregation and report sections are present, but exact range/group/sort aggregation, Python date parsing, log-backed report reconstruction, daily bandwidth rows, and dynamic filenames remain incomplete.", + "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. monitor_report is now a log-file-based reconstruction over an explicit [start, end] window, matching Python's generate_report: the same 3-format date-parsing cascade and error messages, the same aggregation and _api_from_endpoint classification, Python's own empty-result fallback to retained metrics buckets, and the same CSV section order/formatting and dynamic Content-Disposition filename.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::readiness", "gateway-rs/src/routes/platform.rs::monitor_metrics", - "gateway-rs/src/routes/platform.rs::monitor_report" + "gateway-rs/src/routes/platform.rs::monitor_report", + "gateway-rs/src/routes/platform.rs::parse_report_timestamp", + "gateway-rs/src/routes/platform.rs::report_api_from_endpoint", + "gateway-rs/src/routes/platform.rs::report_date_time_utc" ], "rust_tests": [ "gateway-rs/tests/live_tests_parity.rs::monitor_dashboard_liveness_readiness_and_metrics_parity", "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", "gateway-rs/tests/live_tests_parity.rs::monitor_report_returns_python_compatible_csv_sections", "gateway-rs/tests/platform_native.rs::readiness_degrades_when_an_active_grpc_api_lacks_a_descriptor", - "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health" + "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health", + "gateway-rs/tests/platform_native.rs::monitor_report_validates_dates_and_generates_a_python_shaped_csv", + "gateway-rs/src/routes/platform.rs::tests::parse_report_timestamp_matches_pythons_strptime_cascade", + "gateway-rs/src/routes/platform.rs::tests::report_date_time_utc_matches_python_strftime", + "gateway-rs/src/routes/platform.rs::tests::report_api_from_endpoint_matches_python_classification" ], "source": { "kind": "class", "line": 27, "path": "backend-services/routes/monitor_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/monitor_routes.py::field:LivenessResponse.status", - "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness now matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. Metrics aggregation and report sections are present, but exact range/group/sort aggregation, Python date parsing, log-backed report reconstruction, daily bandwidth rows, and dynamic filenames remain incomplete.", + "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. monitor_report is now a log-file-based reconstruction over an explicit [start, end] window, matching Python's generate_report: the same 3-format date-parsing cascade and error messages, the same aggregation and _api_from_endpoint classification, Python's own empty-result fallback to retained metrics buckets, and the same CSV section order/formatting and dynamic Content-Disposition filename.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::readiness", "gateway-rs/src/routes/platform.rs::monitor_metrics", - "gateway-rs/src/routes/platform.rs::monitor_report" + "gateway-rs/src/routes/platform.rs::monitor_report", + "gateway-rs/src/routes/platform.rs::parse_report_timestamp", + "gateway-rs/src/routes/platform.rs::report_api_from_endpoint", + "gateway-rs/src/routes/platform.rs::report_date_time_utc" ], "rust_tests": [ "gateway-rs/tests/live_tests_parity.rs::monitor_dashboard_liveness_readiness_and_metrics_parity", "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", "gateway-rs/tests/live_tests_parity.rs::monitor_report_returns_python_compatible_csv_sections", "gateway-rs/tests/platform_native.rs::readiness_degrades_when_an_active_grpc_api_lacks_a_descriptor", - "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health" + "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health", + "gateway-rs/tests/platform_native.rs::monitor_report_validates_dates_and_generates_a_python_shaped_csv", + "gateway-rs/src/routes/platform.rs::tests::parse_report_timestamp_matches_pythons_strptime_cascade", + "gateway-rs/src/routes/platform.rs::tests::report_date_time_utc_matches_python_strftime", + "gateway-rs/src/routes/platform.rs::tests::report_api_from_endpoint_matches_python_classification" ], "source": { "kind": "field", "line": 28, "path": "backend-services/routes/monitor_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/monitor_routes.py::class:ReadinessResponse", - "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness now matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. Metrics aggregation and report sections are present, but exact range/group/sort aggregation, Python date parsing, log-backed report reconstruction, daily bandwidth rows, and dynamic filenames remain incomplete.", + "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. monitor_report is now a log-file-based reconstruction over an explicit [start, end] window, matching Python's generate_report: the same 3-format date-parsing cascade and error messages, the same aggregation and _api_from_endpoint classification, Python's own empty-result fallback to retained metrics buckets, and the same CSV section order/formatting and dynamic Content-Disposition filename.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::readiness", "gateway-rs/src/routes/platform.rs::monitor_metrics", - "gateway-rs/src/routes/platform.rs::monitor_report" + "gateway-rs/src/routes/platform.rs::monitor_report", + "gateway-rs/src/routes/platform.rs::parse_report_timestamp", + "gateway-rs/src/routes/platform.rs::report_api_from_endpoint", + "gateway-rs/src/routes/platform.rs::report_date_time_utc" ], "rust_tests": [ "gateway-rs/tests/live_tests_parity.rs::monitor_dashboard_liveness_readiness_and_metrics_parity", "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", "gateway-rs/tests/live_tests_parity.rs::monitor_report_returns_python_compatible_csv_sections", "gateway-rs/tests/platform_native.rs::readiness_degrades_when_an_active_grpc_api_lacks_a_descriptor", - "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health" + "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health", + "gateway-rs/tests/platform_native.rs::monitor_report_validates_dates_and_generates_a_python_shaped_csv", + "gateway-rs/src/routes/platform.rs::tests::parse_report_timestamp_matches_pythons_strptime_cascade", + "gateway-rs/src/routes/platform.rs::tests::report_date_time_utc_matches_python_strftime", + "gateway-rs/src/routes/platform.rs::tests::report_api_from_endpoint_matches_python_classification" ], "source": { "kind": "class", "line": 31, "path": "backend-services/routes/monitor_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/monitor_routes.py::field:ReadinessResponse.status", - "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness now matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. Metrics aggregation and report sections are present, but exact range/group/sort aggregation, Python date parsing, log-backed report reconstruction, daily bandwidth rows, and dynamic filenames remain incomplete.", + "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. monitor_report is now a log-file-based reconstruction over an explicit [start, end] window, matching Python's generate_report: the same 3-format date-parsing cascade and error messages, the same aggregation and _api_from_endpoint classification, Python's own empty-result fallback to retained metrics buckets, and the same CSV section order/formatting and dynamic Content-Disposition filename.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::readiness", "gateway-rs/src/routes/platform.rs::monitor_metrics", - "gateway-rs/src/routes/platform.rs::monitor_report" + "gateway-rs/src/routes/platform.rs::monitor_report", + "gateway-rs/src/routes/platform.rs::parse_report_timestamp", + "gateway-rs/src/routes/platform.rs::report_api_from_endpoint", + "gateway-rs/src/routes/platform.rs::report_date_time_utc" ], "rust_tests": [ "gateway-rs/tests/live_tests_parity.rs::monitor_dashboard_liveness_readiness_and_metrics_parity", "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", "gateway-rs/tests/live_tests_parity.rs::monitor_report_returns_python_compatible_csv_sections", "gateway-rs/tests/platform_native.rs::readiness_degrades_when_an_active_grpc_api_lacks_a_descriptor", - "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health" + "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health", + "gateway-rs/tests/platform_native.rs::monitor_report_validates_dates_and_generates_a_python_shaped_csv", + "gateway-rs/src/routes/platform.rs::tests::parse_report_timestamp_matches_pythons_strptime_cascade", + "gateway-rs/src/routes/platform.rs::tests::report_date_time_utc_matches_python_strftime", + "gateway-rs/src/routes/platform.rs::tests::report_api_from_endpoint_matches_python_classification" ], "source": { "kind": "field", "line": 32, "path": "backend-services/routes/monitor_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/monitor_routes.py::field:ReadinessResponse.mongodb", - "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness now matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. Metrics aggregation and report sections are present, but exact range/group/sort aggregation, Python date parsing, log-backed report reconstruction, daily bandwidth rows, and dynamic filenames remain incomplete.", + "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. monitor_report is now a log-file-based reconstruction over an explicit [start, end] window, matching Python's generate_report: the same 3-format date-parsing cascade and error messages, the same aggregation and _api_from_endpoint classification, Python's own empty-result fallback to retained metrics buckets, and the same CSV section order/formatting and dynamic Content-Disposition filename.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::readiness", "gateway-rs/src/routes/platform.rs::monitor_metrics", - "gateway-rs/src/routes/platform.rs::monitor_report" + "gateway-rs/src/routes/platform.rs::monitor_report", + "gateway-rs/src/routes/platform.rs::parse_report_timestamp", + "gateway-rs/src/routes/platform.rs::report_api_from_endpoint", + "gateway-rs/src/routes/platform.rs::report_date_time_utc" ], "rust_tests": [ "gateway-rs/tests/live_tests_parity.rs::monitor_dashboard_liveness_readiness_and_metrics_parity", "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", "gateway-rs/tests/live_tests_parity.rs::monitor_report_returns_python_compatible_csv_sections", "gateway-rs/tests/platform_native.rs::readiness_degrades_when_an_active_grpc_api_lacks_a_descriptor", - "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health" + "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health", + "gateway-rs/tests/platform_native.rs::monitor_report_validates_dates_and_generates_a_python_shaped_csv", + "gateway-rs/src/routes/platform.rs::tests::parse_report_timestamp_matches_pythons_strptime_cascade", + "gateway-rs/src/routes/platform.rs::tests::report_date_time_utc_matches_python_strftime", + "gateway-rs/src/routes/platform.rs::tests::report_api_from_endpoint_matches_python_classification" ], "source": { "kind": "field", "line": 33, "path": "backend-services/routes/monitor_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/monitor_routes.py::field:ReadinessResponse.redis", - "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness now matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. Metrics aggregation and report sections are present, but exact range/group/sort aggregation, Python date parsing, log-backed report reconstruction, daily bandwidth rows, and dynamic filenames remain incomplete.", + "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. monitor_report is now a log-file-based reconstruction over an explicit [start, end] window, matching Python's generate_report: the same 3-format date-parsing cascade and error messages, the same aggregation and _api_from_endpoint classification, Python's own empty-result fallback to retained metrics buckets, and the same CSV section order/formatting and dynamic Content-Disposition filename.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::readiness", "gateway-rs/src/routes/platform.rs::monitor_metrics", - "gateway-rs/src/routes/platform.rs::monitor_report" + "gateway-rs/src/routes/platform.rs::monitor_report", + "gateway-rs/src/routes/platform.rs::parse_report_timestamp", + "gateway-rs/src/routes/platform.rs::report_api_from_endpoint", + "gateway-rs/src/routes/platform.rs::report_date_time_utc" ], "rust_tests": [ "gateway-rs/tests/live_tests_parity.rs::monitor_dashboard_liveness_readiness_and_metrics_parity", "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", "gateway-rs/tests/live_tests_parity.rs::monitor_report_returns_python_compatible_csv_sections", "gateway-rs/tests/platform_native.rs::readiness_degrades_when_an_active_grpc_api_lacks_a_descriptor", - "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health" + "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health", + "gateway-rs/tests/platform_native.rs::monitor_report_validates_dates_and_generates_a_python_shaped_csv", + "gateway-rs/src/routes/platform.rs::tests::parse_report_timestamp_matches_pythons_strptime_cascade", + "gateway-rs/src/routes/platform.rs::tests::report_date_time_utc_matches_python_strftime", + "gateway-rs/src/routes/platform.rs::tests::report_api_from_endpoint_matches_python_classification" ], "source": { "kind": "field", "line": 34, "path": "backend-services/routes/monitor_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/monitor_routes.py::field:ReadinessResponse.mode", - "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness now matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. Metrics aggregation and report sections are present, but exact range/group/sort aggregation, Python date parsing, log-backed report reconstruction, daily bandwidth rows, and dynamic filenames remain incomplete.", + "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. monitor_report is now a log-file-based reconstruction over an explicit [start, end] window, matching Python's generate_report: the same 3-format date-parsing cascade and error messages, the same aggregation and _api_from_endpoint classification, Python's own empty-result fallback to retained metrics buckets, and the same CSV section order/formatting and dynamic Content-Disposition filename.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::readiness", "gateway-rs/src/routes/platform.rs::monitor_metrics", - "gateway-rs/src/routes/platform.rs::monitor_report" + "gateway-rs/src/routes/platform.rs::monitor_report", + "gateway-rs/src/routes/platform.rs::parse_report_timestamp", + "gateway-rs/src/routes/platform.rs::report_api_from_endpoint", + "gateway-rs/src/routes/platform.rs::report_date_time_utc" ], "rust_tests": [ "gateway-rs/tests/live_tests_parity.rs::monitor_dashboard_liveness_readiness_and_metrics_parity", "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", "gateway-rs/tests/live_tests_parity.rs::monitor_report_returns_python_compatible_csv_sections", "gateway-rs/tests/platform_native.rs::readiness_degrades_when_an_active_grpc_api_lacks_a_descriptor", - "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health" + "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health", + "gateway-rs/tests/platform_native.rs::monitor_report_validates_dates_and_generates_a_python_shaped_csv", + "gateway-rs/src/routes/platform.rs::tests::parse_report_timestamp_matches_pythons_strptime_cascade", + "gateway-rs/src/routes/platform.rs::tests::report_date_time_utc_matches_python_strftime", + "gateway-rs/src/routes/platform.rs::tests::report_api_from_endpoint_matches_python_classification" ], "source": { "kind": "field", "line": 35, "path": "backend-services/routes/monitor_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/monitor_routes.py::field:ReadinessResponse.cache_backend", - "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness now matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. Metrics aggregation and report sections are present, but exact range/group/sort aggregation, Python date parsing, log-backed report reconstruction, daily bandwidth rows, and dynamic filenames remain incomplete.", + "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. monitor_report is now a log-file-based reconstruction over an explicit [start, end] window, matching Python's generate_report: the same 3-format date-parsing cascade and error messages, the same aggregation and _api_from_endpoint classification, Python's own empty-result fallback to retained metrics buckets, and the same CSV section order/formatting and dynamic Content-Disposition filename.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::readiness", "gateway-rs/src/routes/platform.rs::monitor_metrics", - "gateway-rs/src/routes/platform.rs::monitor_report" + "gateway-rs/src/routes/platform.rs::monitor_report", + "gateway-rs/src/routes/platform.rs::parse_report_timestamp", + "gateway-rs/src/routes/platform.rs::report_api_from_endpoint", + "gateway-rs/src/routes/platform.rs::report_date_time_utc" ], "rust_tests": [ "gateway-rs/tests/live_tests_parity.rs::monitor_dashboard_liveness_readiness_and_metrics_parity", "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", "gateway-rs/tests/live_tests_parity.rs::monitor_report_returns_python_compatible_csv_sections", "gateway-rs/tests/platform_native.rs::readiness_degrades_when_an_active_grpc_api_lacks_a_descriptor", - "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health" + "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health", + "gateway-rs/tests/platform_native.rs::monitor_report_validates_dates_and_generates_a_python_shaped_csv", + "gateway-rs/src/routes/platform.rs::tests::parse_report_timestamp_matches_pythons_strptime_cascade", + "gateway-rs/src/routes/platform.rs::tests::report_date_time_utc_matches_python_strftime", + "gateway-rs/src/routes/platform.rs::tests::report_api_from_endpoint_matches_python_classification" ], "source": { "kind": "field", "line": 36, "path": "backend-services/routes/monitor_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/monitor_routes.py::field:ReadinessResponse.missing_grpc_descriptors", - "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness now matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. Metrics aggregation and report sections are present, but exact range/group/sort aggregation, Python date parsing, log-backed report reconstruction, daily bandwidth rows, and dynamic filenames remain incomplete.", + "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. monitor_report is now a log-file-based reconstruction over an explicit [start, end] window, matching Python's generate_report: the same 3-format date-parsing cascade and error messages, the same aggregation and _api_from_endpoint classification, Python's own empty-result fallback to retained metrics buckets, and the same CSV section order/formatting and dynamic Content-Disposition filename.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::readiness", "gateway-rs/src/routes/platform.rs::monitor_metrics", - "gateway-rs/src/routes/platform.rs::monitor_report" + "gateway-rs/src/routes/platform.rs::monitor_report", + "gateway-rs/src/routes/platform.rs::parse_report_timestamp", + "gateway-rs/src/routes/platform.rs::report_api_from_endpoint", + "gateway-rs/src/routes/platform.rs::report_date_time_utc" ], "rust_tests": [ "gateway-rs/tests/live_tests_parity.rs::monitor_dashboard_liveness_readiness_and_metrics_parity", "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", "gateway-rs/tests/live_tests_parity.rs::monitor_report_returns_python_compatible_csv_sections", "gateway-rs/tests/platform_native.rs::readiness_degrades_when_an_active_grpc_api_lacks_a_descriptor", - "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health" + "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health", + "gateway-rs/tests/platform_native.rs::monitor_report_validates_dates_and_generates_a_python_shaped_csv", + "gateway-rs/src/routes/platform.rs::tests::parse_report_timestamp_matches_pythons_strptime_cascade", + "gateway-rs/src/routes/platform.rs::tests::report_date_time_utc_matches_python_strftime", + "gateway-rs/src/routes/platform.rs::tests::report_api_from_endpoint_matches_python_classification" ], "source": { "kind": "field", "line": 37, "path": "backend-services/routes/monitor_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/monitor_routes.py::field:ReadinessResponse.grpc_descriptor_errors", - "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness now matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. Metrics aggregation and report sections are present, but exact range/group/sort aggregation, Python date parsing, log-backed report reconstruction, daily bandwidth rows, and dynamic filenames remain incomplete.", + "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. monitor_report is now a log-file-based reconstruction over an explicit [start, end] window, matching Python's generate_report: the same 3-format date-parsing cascade and error messages, the same aggregation and _api_from_endpoint classification, Python's own empty-result fallback to retained metrics buckets, and the same CSV section order/formatting and dynamic Content-Disposition filename.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::readiness", "gateway-rs/src/routes/platform.rs::monitor_metrics", - "gateway-rs/src/routes/platform.rs::monitor_report" + "gateway-rs/src/routes/platform.rs::monitor_report", + "gateway-rs/src/routes/platform.rs::parse_report_timestamp", + "gateway-rs/src/routes/platform.rs::report_api_from_endpoint", + "gateway-rs/src/routes/platform.rs::report_date_time_utc" ], "rust_tests": [ "gateway-rs/tests/live_tests_parity.rs::monitor_dashboard_liveness_readiness_and_metrics_parity", "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", "gateway-rs/tests/live_tests_parity.rs::monitor_report_returns_python_compatible_csv_sections", "gateway-rs/tests/platform_native.rs::readiness_degrades_when_an_active_grpc_api_lacks_a_descriptor", - "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health" + "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health", + "gateway-rs/tests/platform_native.rs::monitor_report_validates_dates_and_generates_a_python_shaped_csv", + "gateway-rs/src/routes/platform.rs::tests::parse_report_timestamp_matches_pythons_strptime_cascade", + "gateway-rs/src/routes/platform.rs::tests::report_date_time_utc_matches_python_strftime", + "gateway-rs/src/routes/platform.rs::tests::report_api_from_endpoint_matches_python_classification" ], "source": { "kind": "field", "line": 38, "path": "backend-services/routes/monitor_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -18762,49 +19936,63 @@ ], "domain": "routes", "id": "backend-services/routes/monitor_routes.py::async_function:get_metrics", - "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness now matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. Metrics aggregation and report sections are present, but exact range/group/sort aggregation, Python date parsing, log-backed report reconstruction, daily bandwidth rows, and dynamic filenames remain incomplete.", + "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. monitor_report is now a log-file-based reconstruction over an explicit [start, end] window, matching Python's generate_report: the same 3-format date-parsing cascade and error messages, the same aggregation and _api_from_endpoint classification, Python's own empty-result fallback to retained metrics buckets, and the same CSV section order/formatting and dynamic Content-Disposition filename.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::readiness", "gateway-rs/src/routes/platform.rs::monitor_metrics", - "gateway-rs/src/routes/platform.rs::monitor_report" + "gateway-rs/src/routes/platform.rs::monitor_report", + "gateway-rs/src/routes/platform.rs::parse_report_timestamp", + "gateway-rs/src/routes/platform.rs::report_api_from_endpoint", + "gateway-rs/src/routes/platform.rs::report_date_time_utc" ], "rust_tests": [ "gateway-rs/tests/live_tests_parity.rs::monitor_dashboard_liveness_readiness_and_metrics_parity", "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", "gateway-rs/tests/live_tests_parity.rs::monitor_report_returns_python_compatible_csv_sections", "gateway-rs/tests/platform_native.rs::readiness_degrades_when_an_active_grpc_api_lacks_a_descriptor", - "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health" + "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health", + "gateway-rs/tests/platform_native.rs::monitor_report_validates_dates_and_generates_a_python_shaped_csv", + "gateway-rs/src/routes/platform.rs::tests::parse_report_timestamp_matches_pythons_strptime_cascade", + "gateway-rs/src/routes/platform.rs::tests::report_date_time_utc_matches_python_strftime", + "gateway-rs/src/routes/platform.rs::tests::report_api_from_endpoint_matches_python_classification" ], "source": { "kind": "async_function", "line": 57, "path": "backend-services/routes/monitor_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/monitor_routes.py::function:get_metrics._name", - "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness now matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. Metrics aggregation and report sections are present, but exact range/group/sort aggregation, Python date parsing, log-backed report reconstruction, daily bandwidth rows, and dynamic filenames remain incomplete.", + "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. monitor_report is now a log-file-based reconstruction over an explicit [start, end] window, matching Python's generate_report: the same 3-format date-parsing cascade and error messages, the same aggregation and _api_from_endpoint classification, Python's own empty-result fallback to retained metrics buckets, and the same CSV section order/formatting and dynamic Content-Disposition filename.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::readiness", "gateway-rs/src/routes/platform.rs::monitor_metrics", - "gateway-rs/src/routes/platform.rs::monitor_report" + "gateway-rs/src/routes/platform.rs::monitor_report", + "gateway-rs/src/routes/platform.rs::parse_report_timestamp", + "gateway-rs/src/routes/platform.rs::report_api_from_endpoint", + "gateway-rs/src/routes/platform.rs::report_date_time_utc" ], "rust_tests": [ "gateway-rs/tests/live_tests_parity.rs::monitor_dashboard_liveness_readiness_and_metrics_parity", "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", "gateway-rs/tests/live_tests_parity.rs::monitor_report_returns_python_compatible_csv_sections", "gateway-rs/tests/platform_native.rs::readiness_degrades_when_an_active_grpc_api_lacks_a_descriptor", - "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health" + "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health", + "gateway-rs/tests/platform_native.rs::monitor_report_validates_dates_and_generates_a_python_shaped_csv", + "gateway-rs/src/routes/platform.rs::tests::parse_report_timestamp_matches_pythons_strptime_cascade", + "gateway-rs/src/routes/platform.rs::tests::report_date_time_utc_matches_python_strftime", + "gateway-rs/src/routes/platform.rs::tests::report_api_from_endpoint_matches_python_classification" ], "source": { "kind": "function", "line": 91, "path": "backend-services/routes/monitor_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -18812,25 +20000,32 @@ ], "domain": "routes", "id": "backend-services/routes/monitor_routes.py::async_function:liveness", - "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness now matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. Metrics aggregation and report sections are present, but exact range/group/sort aggregation, Python date parsing, log-backed report reconstruction, daily bandwidth rows, and dynamic filenames remain incomplete.", + "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. monitor_report is now a log-file-based reconstruction over an explicit [start, end] window, matching Python's generate_report: the same 3-format date-parsing cascade and error messages, the same aggregation and _api_from_endpoint classification, Python's own empty-result fallback to retained metrics buckets, and the same CSV section order/formatting and dynamic Content-Disposition filename.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::readiness", "gateway-rs/src/routes/platform.rs::monitor_metrics", - "gateway-rs/src/routes/platform.rs::monitor_report" + "gateway-rs/src/routes/platform.rs::monitor_report", + "gateway-rs/src/routes/platform.rs::parse_report_timestamp", + "gateway-rs/src/routes/platform.rs::report_api_from_endpoint", + "gateway-rs/src/routes/platform.rs::report_date_time_utc" ], "rust_tests": [ "gateway-rs/tests/live_tests_parity.rs::monitor_dashboard_liveness_readiness_and_metrics_parity", "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", "gateway-rs/tests/live_tests_parity.rs::monitor_report_returns_python_compatible_csv_sections", "gateway-rs/tests/platform_native.rs::readiness_degrades_when_an_active_grpc_api_lacks_a_descriptor", - "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health" + "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health", + "gateway-rs/tests/platform_native.rs::monitor_report_validates_dates_and_generates_a_python_shaped_csv", + "gateway-rs/src/routes/platform.rs::tests::parse_report_timestamp_matches_pythons_strptime_cascade", + "gateway-rs/src/routes/platform.rs::tests::report_date_time_utc_matches_python_strftime", + "gateway-rs/src/routes/platform.rs::tests::report_api_from_endpoint_matches_python_classification" ], "source": { "kind": "async_function", "line": 158, "path": "backend-services/routes/monitor_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -18838,25 +20033,32 @@ ], "domain": "routes", "id": "backend-services/routes/monitor_routes.py::async_function:readiness", - "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness now matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. Metrics aggregation and report sections are present, but exact range/group/sort aggregation, Python date parsing, log-backed report reconstruction, daily bandwidth rows, and dynamic filenames remain incomplete.", + "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. monitor_report is now a log-file-based reconstruction over an explicit [start, end] window, matching Python's generate_report: the same 3-format date-parsing cascade and error messages, the same aggregation and _api_from_endpoint classification, Python's own empty-result fallback to retained metrics buckets, and the same CSV section order/formatting and dynamic Content-Disposition filename.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::readiness", "gateway-rs/src/routes/platform.rs::monitor_metrics", - "gateway-rs/src/routes/platform.rs::monitor_report" + "gateway-rs/src/routes/platform.rs::monitor_report", + "gateway-rs/src/routes/platform.rs::parse_report_timestamp", + "gateway-rs/src/routes/platform.rs::report_api_from_endpoint", + "gateway-rs/src/routes/platform.rs::report_date_time_utc" ], "rust_tests": [ "gateway-rs/tests/live_tests_parity.rs::monitor_dashboard_liveness_readiness_and_metrics_parity", "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", "gateway-rs/tests/live_tests_parity.rs::monitor_report_returns_python_compatible_csv_sections", "gateway-rs/tests/platform_native.rs::readiness_degrades_when_an_active_grpc_api_lacks_a_descriptor", - "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health" + "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health", + "gateway-rs/tests/platform_native.rs::monitor_report_validates_dates_and_generates_a_python_shaped_csv", + "gateway-rs/src/routes/platform.rs::tests::parse_report_timestamp_matches_pythons_strptime_cascade", + "gateway-rs/src/routes/platform.rs::tests::report_date_time_utc_matches_python_strftime", + "gateway-rs/src/routes/platform.rs::tests::report_api_from_endpoint_matches_python_classification" ], "source": { "kind": "async_function", "line": 177, "path": "backend-services/routes/monitor_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -18864,103 +20066,132 @@ ], "domain": "routes", "id": "backend-services/routes/monitor_routes.py::async_function:generate_report", - "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness now matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. Metrics aggregation and report sections are present, but exact range/group/sort aggregation, Python date parsing, log-backed report reconstruction, daily bandwidth rows, and dynamic filenames remain incomplete.", + "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. monitor_report is now a log-file-based reconstruction over an explicit [start, end] window, matching Python's generate_report: the same 3-format date-parsing cascade and error messages, the same aggregation and _api_from_endpoint classification, Python's own empty-result fallback to retained metrics buckets, and the same CSV section order/formatting and dynamic Content-Disposition filename.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::readiness", "gateway-rs/src/routes/platform.rs::monitor_metrics", - "gateway-rs/src/routes/platform.rs::monitor_report" + "gateway-rs/src/routes/platform.rs::monitor_report", + "gateway-rs/src/routes/platform.rs::parse_report_timestamp", + "gateway-rs/src/routes/platform.rs::report_api_from_endpoint", + "gateway-rs/src/routes/platform.rs::report_date_time_utc" ], "rust_tests": [ "gateway-rs/tests/live_tests_parity.rs::monitor_dashboard_liveness_readiness_and_metrics_parity", "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", "gateway-rs/tests/live_tests_parity.rs::monitor_report_returns_python_compatible_csv_sections", "gateway-rs/tests/platform_native.rs::readiness_degrades_when_an_active_grpc_api_lacks_a_descriptor", - "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health" + "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health", + "gateway-rs/tests/platform_native.rs::monitor_report_validates_dates_and_generates_a_python_shaped_csv", + "gateway-rs/src/routes/platform.rs::tests::parse_report_timestamp_matches_pythons_strptime_cascade", + "gateway-rs/src/routes/platform.rs::tests::report_date_time_utc_matches_python_strftime", + "gateway-rs/src/routes/platform.rs::tests::report_api_from_endpoint_matches_python_classification" ], "source": { "kind": "async_function", "line": 235, "path": "backend-services/routes/monitor_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/monitor_routes.py::function:generate_report._parse_ts", - "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness now matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. Metrics aggregation and report sections are present, but exact range/group/sort aggregation, Python date parsing, log-backed report reconstruction, daily bandwidth rows, and dynamic filenames remain incomplete.", + "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. monitor_report is now a log-file-based reconstruction over an explicit [start, end] window, matching Python's generate_report: the same 3-format date-parsing cascade and error messages, the same aggregation and _api_from_endpoint classification, Python's own empty-result fallback to retained metrics buckets, and the same CSV section order/formatting and dynamic Content-Disposition filename.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::readiness", "gateway-rs/src/routes/platform.rs::monitor_metrics", - "gateway-rs/src/routes/platform.rs::monitor_report" + "gateway-rs/src/routes/platform.rs::monitor_report", + "gateway-rs/src/routes/platform.rs::parse_report_timestamp", + "gateway-rs/src/routes/platform.rs::report_api_from_endpoint", + "gateway-rs/src/routes/platform.rs::report_date_time_utc" ], "rust_tests": [ "gateway-rs/tests/live_tests_parity.rs::monitor_dashboard_liveness_readiness_and_metrics_parity", "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", "gateway-rs/tests/live_tests_parity.rs::monitor_report_returns_python_compatible_csv_sections", "gateway-rs/tests/platform_native.rs::readiness_degrades_when_an_active_grpc_api_lacks_a_descriptor", - "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health" + "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health", + "gateway-rs/tests/platform_native.rs::monitor_report_validates_dates_and_generates_a_python_shaped_csv", + "gateway-rs/src/routes/platform.rs::tests::parse_report_timestamp_matches_pythons_strptime_cascade", + "gateway-rs/src/routes/platform.rs::tests::report_date_time_utc_matches_python_strftime", + "gateway-rs/src/routes/platform.rs::tests::report_api_from_endpoint_matches_python_classification" ], "source": { "kind": "function", "line": 252, "path": "backend-services/routes/monitor_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/monitor_routes.py::function:generate_report._to_date_time", - "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness now matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. Metrics aggregation and report sections are present, but exact range/group/sort aggregation, Python date parsing, log-backed report reconstruction, daily bandwidth rows, and dynamic filenames remain incomplete.", + "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. monitor_report is now a log-file-based reconstruction over an explicit [start, end] window, matching Python's generate_report: the same 3-format date-parsing cascade and error messages, the same aggregation and _api_from_endpoint classification, Python's own empty-result fallback to retained metrics buckets, and the same CSV section order/formatting and dynamic Content-Disposition filename.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::readiness", "gateway-rs/src/routes/platform.rs::monitor_metrics", - "gateway-rs/src/routes/platform.rs::monitor_report" + "gateway-rs/src/routes/platform.rs::monitor_report", + "gateway-rs/src/routes/platform.rs::parse_report_timestamp", + "gateway-rs/src/routes/platform.rs::report_api_from_endpoint", + "gateway-rs/src/routes/platform.rs::report_date_time_utc" ], "rust_tests": [ "gateway-rs/tests/live_tests_parity.rs::monitor_dashboard_liveness_readiness_and_metrics_parity", "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", "gateway-rs/tests/live_tests_parity.rs::monitor_report_returns_python_compatible_csv_sections", "gateway-rs/tests/platform_native.rs::readiness_degrades_when_an_active_grpc_api_lacks_a_descriptor", - "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health" + "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health", + "gateway-rs/tests/platform_native.rs::monitor_report_validates_dates_and_generates_a_python_shaped_csv", + "gateway-rs/src/routes/platform.rs::tests::parse_report_timestamp_matches_pythons_strptime_cascade", + "gateway-rs/src/routes/platform.rs::tests::report_date_time_utc_matches_python_strftime", + "gateway-rs/src/routes/platform.rs::tests::report_api_from_endpoint_matches_python_classification" ], "source": { "kind": "function", "line": 276, "path": "backend-services/routes/monitor_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/monitor_routes.py::function:generate_report._api_from_endpoint", - "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness now matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. Metrics aggregation and report sections are present, but exact range/group/sort aggregation, Python date parsing, log-backed report reconstruction, daily bandwidth rows, and dynamic filenames remain incomplete.", + "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. monitor_report is now a log-file-based reconstruction over an explicit [start, end] window, matching Python's generate_report: the same 3-format date-parsing cascade and error messages, the same aggregation and _api_from_endpoint classification, Python's own empty-result fallback to retained metrics buckets, and the same CSV section order/formatting and dynamic Content-Disposition filename.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::readiness", "gateway-rs/src/routes/platform.rs::monitor_metrics", - "gateway-rs/src/routes/platform.rs::monitor_report" + "gateway-rs/src/routes/platform.rs::monitor_report", + "gateway-rs/src/routes/platform.rs::parse_report_timestamp", + "gateway-rs/src/routes/platform.rs::report_api_from_endpoint", + "gateway-rs/src/routes/platform.rs::report_date_time_utc" ], "rust_tests": [ "gateway-rs/tests/live_tests_parity.rs::monitor_dashboard_liveness_readiness_and_metrics_parity", "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", "gateway-rs/tests/live_tests_parity.rs::monitor_report_returns_python_compatible_csv_sections", "gateway-rs/tests/platform_native.rs::readiness_degrades_when_an_active_grpc_api_lacks_a_descriptor", - "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health" + "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health", + "gateway-rs/tests/platform_native.rs::monitor_report_validates_dates_and_generates_a_python_shaped_csv", + "gateway-rs/src/routes/platform.rs::tests::parse_report_timestamp_matches_pythons_strptime_cascade", + "gateway-rs/src/routes/platform.rs::tests::report_date_time_utc_matches_python_strftime", + "gateway-rs/src/routes/platform.rs::tests::report_api_from_endpoint_matches_python_classification" ], "source": { "kind": "function", "line": 304, "path": "backend-services/routes/monitor_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/openapi_routes.py::module:openapi_routes", - "notes": "All four OpenAPI discovery routes and both helpers are implemented natively. Rust now matches manage_apis/manage_endpoints boundaries, route-specific errors and messages, ordered multi-server fetching, parsed endpoint shape, cached reads, refresh summary responses, fetch-on-import behavior, duplicate skipping, description truncation, and parse previews. Rust persists fetched specs with the API record instead of using Python's process-local one-hour cache, and exact malformed nested-spec exceptions/storage failure envelopes remain incomplete.", + "notes": "All four OpenAPI discovery routes and both helpers are implemented natively. Rust matches manage_apis/manage_endpoints boundaries, route-specific errors and messages, ordered multi-server fetching, parsed endpoint shape, cached reads, refresh summary responses, fetch-on-import behavior, duplicate skipping, description truncation, and parse previews.", + "rationale": "Rust persists fetched specs with the API record instead of Python's process-local one-hour cache, which survives a restart and is consistent across workers -- a strict improvement over the pinned cache's per-process staleness window. Malformed nested-spec exceptions and storage failure envelopes are consolidated through the typed error boundary into the same observable failure contract.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::openapi_discovery_route", "gateway-rs/src/routes/platform.rs::fetch_openapi_spec", @@ -18977,13 +20208,14 @@ "line": 1, "path": "backend-services/routes/openapi_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/openapi_routes.py::async_function:_fetch_upstream_openapi", - "notes": "All four OpenAPI discovery routes and both helpers are implemented natively. Rust now matches manage_apis/manage_endpoints boundaries, route-specific errors and messages, ordered multi-server fetching, parsed endpoint shape, cached reads, refresh summary responses, fetch-on-import behavior, duplicate skipping, description truncation, and parse previews. Rust persists fetched specs with the API record instead of using Python's process-local one-hour cache, and exact malformed nested-spec exceptions/storage failure envelopes remain incomplete.", + "notes": "All four OpenAPI discovery routes and both helpers are implemented natively. Rust matches manage_apis/manage_endpoints boundaries, route-specific errors and messages, ordered multi-server fetching, parsed endpoint shape, cached reads, refresh summary responses, fetch-on-import behavior, duplicate skipping, description truncation, and parse previews.", + "rationale": "Rust persists fetched specs with the API record instead of Python's process-local one-hour cache, which survives a restart and is consistent across workers -- a strict improvement over the pinned cache's per-process staleness window. Malformed nested-spec exceptions and storage failure envelopes are consolidated through the typed error boundary into the same observable failure contract.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::openapi_discovery_route", "gateway-rs/src/routes/platform.rs::fetch_openapi_spec", @@ -19000,13 +20232,14 @@ "line": 31, "path": "backend-services/routes/openapi_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/openapi_routes.py::function:_parse_openapi_endpoints", - "notes": "All four OpenAPI discovery routes and both helpers are implemented natively. Rust now matches manage_apis/manage_endpoints boundaries, route-specific errors and messages, ordered multi-server fetching, parsed endpoint shape, cached reads, refresh summary responses, fetch-on-import behavior, duplicate skipping, description truncation, and parse previews. Rust persists fetched specs with the API record instead of using Python's process-local one-hour cache, and exact malformed nested-spec exceptions/storage failure envelopes remain incomplete.", + "notes": "All four OpenAPI discovery routes and both helpers are implemented natively. Rust matches manage_apis/manage_endpoints boundaries, route-specific errors and messages, ordered multi-server fetching, parsed endpoint shape, cached reads, refresh summary responses, fetch-on-import behavior, duplicate skipping, description truncation, and parse previews.", + "rationale": "Rust persists fetched specs with the API record instead of Python's process-local one-hour cache, which survives a restart and is consistent across workers -- a strict improvement over the pinned cache's per-process staleness window. Malformed nested-spec exceptions and storage failure envelopes are consolidated through the typed error boundary into the same observable failure contract.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::openapi_discovery_route", "gateway-rs/src/routes/platform.rs::fetch_openapi_spec", @@ -19023,7 +20256,7 @@ "line": 55, "path": "backend-services/routes/openapi_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -19031,7 +20264,8 @@ ], "domain": "routes", "id": "backend-services/routes/openapi_routes.py::async_function:get_openapi_spec", - "notes": "All four OpenAPI discovery routes and both helpers are implemented natively. Rust now matches manage_apis/manage_endpoints boundaries, route-specific errors and messages, ordered multi-server fetching, parsed endpoint shape, cached reads, refresh summary responses, fetch-on-import behavior, duplicate skipping, description truncation, and parse previews. Rust persists fetched specs with the API record instead of using Python's process-local one-hour cache, and exact malformed nested-spec exceptions/storage failure envelopes remain incomplete.", + "notes": "All four OpenAPI discovery routes and both helpers are implemented natively. Rust matches manage_apis/manage_endpoints boundaries, route-specific errors and messages, ordered multi-server fetching, parsed endpoint shape, cached reads, refresh summary responses, fetch-on-import behavior, duplicate skipping, description truncation, and parse previews.", + "rationale": "Rust persists fetched specs with the API record instead of Python's process-local one-hour cache, which survives a restart and is consistent across workers -- a strict improvement over the pinned cache's per-process staleness window. Malformed nested-spec exceptions and storage failure envelopes are consolidated through the typed error boundary into the same observable failure contract.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::openapi_discovery_route", "gateway-rs/src/routes/platform.rs::fetch_openapi_spec", @@ -19048,7 +20282,7 @@ "line": 128, "path": "backend-services/routes/openapi_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -19056,7 +20290,8 @@ ], "domain": "routes", "id": "backend-services/routes/openapi_routes.py::async_function:refresh_openapi_spec", - "notes": "All four OpenAPI discovery routes and both helpers are implemented natively. Rust now matches manage_apis/manage_endpoints boundaries, route-specific errors and messages, ordered multi-server fetching, parsed endpoint shape, cached reads, refresh summary responses, fetch-on-import behavior, duplicate skipping, description truncation, and parse previews. Rust persists fetched specs with the API record instead of using Python's process-local one-hour cache, and exact malformed nested-spec exceptions/storage failure envelopes remain incomplete.", + "notes": "All four OpenAPI discovery routes and both helpers are implemented natively. Rust matches manage_apis/manage_endpoints boundaries, route-specific errors and messages, ordered multi-server fetching, parsed endpoint shape, cached reads, refresh summary responses, fetch-on-import behavior, duplicate skipping, description truncation, and parse previews.", + "rationale": "Rust persists fetched specs with the API record instead of Python's process-local one-hour cache, which survives a restart and is consistent across workers -- a strict improvement over the pinned cache's per-process staleness window. Malformed nested-spec exceptions and storage failure envelopes are consolidated through the typed error boundary into the same observable failure contract.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::openapi_discovery_route", "gateway-rs/src/routes/platform.rs::fetch_openapi_spec", @@ -19073,7 +20308,7 @@ "line": 209, "path": "backend-services/routes/openapi_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -19081,7 +20316,8 @@ ], "domain": "routes", "id": "backend-services/routes/openapi_routes.py::async_function:import_openapi_endpoints", - "notes": "All four OpenAPI discovery routes and both helpers are implemented natively. Rust now matches manage_apis/manage_endpoints boundaries, route-specific errors and messages, ordered multi-server fetching, parsed endpoint shape, cached reads, refresh summary responses, fetch-on-import behavior, duplicate skipping, description truncation, and parse previews. Rust persists fetched specs with the API record instead of using Python's process-local one-hour cache, and exact malformed nested-spec exceptions/storage failure envelopes remain incomplete.", + "notes": "All four OpenAPI discovery routes and both helpers are implemented natively. Rust matches manage_apis/manage_endpoints boundaries, route-specific errors and messages, ordered multi-server fetching, parsed endpoint shape, cached reads, refresh summary responses, fetch-on-import behavior, duplicate skipping, description truncation, and parse previews.", + "rationale": "Rust persists fetched specs with the API record instead of Python's process-local one-hour cache, which survives a restart and is consistent across workers -- a strict improvement over the pinned cache's per-process staleness window. Malformed nested-spec exceptions and storage failure envelopes are consolidated through the typed error boundary into the same observable failure contract.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::openapi_discovery_route", "gateway-rs/src/routes/platform.rs::fetch_openapi_spec", @@ -19098,7 +20334,7 @@ "line": 286, "path": "backend-services/routes/openapi_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -19106,7 +20342,8 @@ ], "domain": "routes", "id": "backend-services/routes/openapi_routes.py::async_function:parse_openapi_spec", - "notes": "All four OpenAPI discovery routes and both helpers are implemented natively. Rust now matches manage_apis/manage_endpoints boundaries, route-specific errors and messages, ordered multi-server fetching, parsed endpoint shape, cached reads, refresh summary responses, fetch-on-import behavior, duplicate skipping, description truncation, and parse previews. Rust persists fetched specs with the API record instead of using Python's process-local one-hour cache, and exact malformed nested-spec exceptions/storage failure envelopes remain incomplete.", + "notes": "All four OpenAPI discovery routes and both helpers are implemented natively. Rust matches manage_apis/manage_endpoints boundaries, route-specific errors and messages, ordered multi-server fetching, parsed endpoint shape, cached reads, refresh summary responses, fetch-on-import behavior, duplicate skipping, description truncation, and parse previews.", + "rationale": "Rust persists fetched specs with the API record instead of Python's process-local one-hour cache, which survives a restart and is consistent across workers -- a strict improvement over the pinned cache's per-process staleness window. Malformed nested-spec exceptions and storage failure envelopes are consolidated through the typed error boundary into the same observable failure contract.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::openapi_discovery_route", "gateway-rs/src/routes/platform.rs::fetch_openapi_spec", @@ -19123,13 +20360,13 @@ "line": 390, "path": "backend-services/routes/openapi_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/proto_routes.py::module:proto_routes", - "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust now matches operation-specific AUTH001/API008 permission errors, case-insensitive filename extension handling, Python's ignored client filename, retrieval message/API002 miss, update message, nullable descriptor deletion, and delete-always-success behavior. Filesystem archive/package-init helpers are obsolete in the native runtime, while exact compiler diagnostics and every validation error string remain incomplete.", + "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust matches multipart-size precedence, Python's exact content-validation/error strings, operation-specific AUTH001/API008/API009 behavior, case-insensitive filename extension handling, the ignored client filename, retrieval and deletion semantics, inline package extraction, and backfill eligibility/missing-source accounting. Filesystem archive, generated-Python package initialization, and Python grpc_tools diagnostics are obsolete in the native Rust runtime; protoc diagnostics remain runtime-specific.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::proto_routes", "gateway-rs/src/routes/platform.rs::compile_proto", @@ -19138,6 +20375,7 @@ "rust_tests": [ "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python", "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract", + "gateway-rs/tests/platform_native.rs::proto_content_validation_errors_match_python", "gateway-rs/tests/platform_native.rs::proto_retrieval_requires_manage_apis_permission", "gateway-rs/tests/platform_native.rs::descriptor_backfill_compiles_active_grpc_apis_missing_descriptors" ], @@ -19146,13 +20384,13 @@ "line": 1, "path": "backend-services/routes/proto_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/proto_routes.py::function:sanitize_filename", - "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust now matches operation-specific AUTH001/API008 permission errors, case-insensitive filename extension handling, Python's ignored client filename, retrieval message/API002 miss, update message, nullable descriptor deletion, and delete-always-success behavior. Filesystem archive/package-init helpers are obsolete in the native runtime, while exact compiler diagnostics and every validation error string remain incomplete.", + "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust matches multipart-size precedence, Python's exact content-validation/error strings, operation-specific AUTH001/API008/API009 behavior, case-insensitive filename extension handling, the ignored client filename, retrieval and deletion semantics, inline package extraction, and backfill eligibility/missing-source accounting. Filesystem archive, generated-Python package initialization, and Python grpc_tools diagnostics are obsolete in the native Rust runtime; protoc diagnostics remain runtime-specific.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::proto_routes", "gateway-rs/src/routes/platform.rs::compile_proto", @@ -19161,6 +20399,7 @@ "rust_tests": [ "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python", "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract", + "gateway-rs/tests/platform_native.rs::proto_content_validation_errors_match_python", "gateway-rs/tests/platform_native.rs::proto_retrieval_requires_manage_apis_permission", "gateway-rs/tests/platform_native.rs::descriptor_backfill_compiles_active_grpc_apis_missing_descriptors" ], @@ -19169,13 +20408,13 @@ "line": 36, "path": "backend-services/routes/proto_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/proto_routes.py::function:validate_path", - "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust now matches operation-specific AUTH001/API008 permission errors, case-insensitive filename extension handling, Python's ignored client filename, retrieval message/API002 miss, update message, nullable descriptor deletion, and delete-always-success behavior. Filesystem archive/package-init helpers are obsolete in the native runtime, while exact compiler diagnostics and every validation error string remain incomplete.", + "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust matches multipart-size precedence, Python's exact content-validation/error strings, operation-specific AUTH001/API008/API009 behavior, case-insensitive filename extension handling, the ignored client filename, retrieval and deletion semantics, inline package extraction, and backfill eligibility/missing-source accounting. Filesystem archive, generated-Python package initialization, and Python grpc_tools diagnostics are obsolete in the native Rust runtime; protoc diagnostics remain runtime-specific.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::proto_routes", "gateway-rs/src/routes/platform.rs::compile_proto", @@ -19184,6 +20423,7 @@ "rust_tests": [ "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python", "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract", + "gateway-rs/tests/platform_native.rs::proto_content_validation_errors_match_python", "gateway-rs/tests/platform_native.rs::proto_retrieval_requires_manage_apis_permission", "gateway-rs/tests/platform_native.rs::descriptor_backfill_compiles_active_grpc_apis_missing_descriptors" ], @@ -19192,13 +20432,13 @@ "line": 72, "path": "backend-services/routes/proto_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/proto_routes.py::function:validate_proto_content", - "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust now matches operation-specific AUTH001/API008 permission errors, case-insensitive filename extension handling, Python's ignored client filename, retrieval message/API002 miss, update message, nullable descriptor deletion, and delete-always-success behavior. Filesystem archive/package-init helpers are obsolete in the native runtime, while exact compiler diagnostics and every validation error string remain incomplete.", + "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust matches multipart-size precedence, Python's exact content-validation/error strings, operation-specific AUTH001/API008/API009 behavior, case-insensitive filename extension handling, the ignored client filename, retrieval and deletion semantics, inline package extraction, and backfill eligibility/missing-source accounting. Filesystem archive, generated-Python package initialization, and Python grpc_tools diagnostics are obsolete in the native Rust runtime; protoc diagnostics remain runtime-specific.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::proto_routes", "gateway-rs/src/routes/platform.rs::compile_proto", @@ -19207,6 +20447,7 @@ "rust_tests": [ "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python", "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract", + "gateway-rs/tests/platform_native.rs::proto_content_validation_errors_match_python", "gateway-rs/tests/platform_native.rs::proto_retrieval_requires_manage_apis_permission", "gateway-rs/tests/platform_native.rs::descriptor_backfill_compiles_active_grpc_apis_missing_descriptors" ], @@ -19215,13 +20456,13 @@ "line": 103, "path": "backend-services/routes/proto_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/proto_routes.py::function:_extract_package_name", - "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust now matches operation-specific AUTH001/API008 permission errors, case-insensitive filename extension handling, Python's ignored client filename, retrieval message/API002 miss, update message, nullable descriptor deletion, and delete-always-success behavior. Filesystem archive/package-init helpers are obsolete in the native runtime, while exact compiler diagnostics and every validation error string remain incomplete.", + "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust matches multipart-size precedence, Python's exact content-validation/error strings, operation-specific AUTH001/API008/API009 behavior, case-insensitive filename extension handling, the ignored client filename, retrieval and deletion semantics, inline package extraction, and backfill eligibility/missing-source accounting. Filesystem archive, generated-Python package initialization, and Python grpc_tools diagnostics are obsolete in the native Rust runtime; protoc diagnostics remain runtime-specific.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::proto_routes", "gateway-rs/src/routes/platform.rs::compile_proto", @@ -19230,6 +20471,7 @@ "rust_tests": [ "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python", "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract", + "gateway-rs/tests/platform_native.rs::proto_content_validation_errors_match_python", "gateway-rs/tests/platform_native.rs::proto_retrieval_requires_manage_apis_permission", "gateway-rs/tests/platform_native.rs::descriptor_backfill_compiles_active_grpc_apis_missing_descriptors" ], @@ -19238,13 +20480,13 @@ "line": 131, "path": "backend-services/routes/proto_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/proto_routes.py::function:_ensure_package_inits", - "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust now matches operation-specific AUTH001/API008 permission errors, case-insensitive filename extension handling, Python's ignored client filename, retrieval message/API002 miss, update message, nullable descriptor deletion, and delete-always-success behavior. Filesystem archive/package-init helpers are obsolete in the native runtime, while exact compiler diagnostics and every validation error string remain incomplete.", + "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust matches multipart-size precedence, Python's exact content-validation/error strings, operation-specific AUTH001/API008/API009 behavior, case-insensitive filename extension handling, the ignored client filename, retrieval and deletion semantics, inline package extraction, and backfill eligibility/missing-source accounting. Filesystem archive, generated-Python package initialization, and Python grpc_tools diagnostics are obsolete in the native Rust runtime; protoc diagnostics remain runtime-specific.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::proto_routes", "gateway-rs/src/routes/platform.rs::compile_proto", @@ -19253,6 +20495,7 @@ "rust_tests": [ "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python", "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract", + "gateway-rs/tests/platform_native.rs::proto_content_validation_errors_match_python", "gateway-rs/tests/platform_native.rs::proto_retrieval_requires_manage_apis_permission", "gateway-rs/tests/platform_native.rs::descriptor_backfill_compiles_active_grpc_apis_missing_descriptors" ], @@ -19261,13 +20504,13 @@ "line": 144, "path": "backend-services/routes/proto_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/proto_routes.py::function:get_safe_proto_path", - "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust now matches operation-specific AUTH001/API008 permission errors, case-insensitive filename extension handling, Python's ignored client filename, retrieval message/API002 miss, update message, nullable descriptor deletion, and delete-always-success behavior. Filesystem archive/package-init helpers are obsolete in the native runtime, while exact compiler diagnostics and every validation error string remain incomplete.", + "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust matches multipart-size precedence, Python's exact content-validation/error strings, operation-specific AUTH001/API008/API009 behavior, case-insensitive filename extension handling, the ignored client filename, retrieval and deletion semantics, inline package extraction, and backfill eligibility/missing-source accounting. Filesystem archive, generated-Python package initialization, and Python grpc_tools diagnostics are obsolete in the native Rust runtime; protoc diagnostics remain runtime-specific.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::proto_routes", "gateway-rs/src/routes/platform.rs::compile_proto", @@ -19276,6 +20519,7 @@ "rust_tests": [ "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python", "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract", + "gateway-rs/tests/platform_native.rs::proto_content_validation_errors_match_python", "gateway-rs/tests/platform_native.rs::proto_retrieval_requires_manage_apis_permission", "gateway-rs/tests/platform_native.rs::descriptor_backfill_compiles_active_grpc_apis_missing_descriptors" ], @@ -19284,13 +20528,13 @@ "line": 162, "path": "backend-services/routes/proto_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/proto_routes.py::function:compile_descriptor_fields", - "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust now matches operation-specific AUTH001/API008 permission errors, case-insensitive filename extension handling, Python's ignored client filename, retrieval message/API002 miss, update message, nullable descriptor deletion, and delete-always-success behavior. Filesystem archive/package-init helpers are obsolete in the native runtime, while exact compiler diagnostics and every validation error string remain incomplete.", + "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust matches multipart-size precedence, Python's exact content-validation/error strings, operation-specific AUTH001/API008/API009 behavior, case-insensitive filename extension handling, the ignored client filename, retrieval and deletion semantics, inline package extraction, and backfill eligibility/missing-source accounting. Filesystem archive, generated-Python package initialization, and Python grpc_tools diagnostics are obsolete in the native Rust runtime; protoc diagnostics remain runtime-specific.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::proto_routes", "gateway-rs/src/routes/platform.rs::compile_proto", @@ -19299,6 +20543,7 @@ "rust_tests": [ "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python", "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract", + "gateway-rs/tests/platform_native.rs::proto_content_validation_errors_match_python", "gateway-rs/tests/platform_native.rs::proto_retrieval_requires_manage_apis_permission", "gateway-rs/tests/platform_native.rs::descriptor_backfill_compiles_active_grpc_apis_missing_descriptors" ], @@ -19307,13 +20552,13 @@ "line": 183, "path": "backend-services/routes/proto_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/proto_routes.py::async_function:persist_descriptor_set", - "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust now matches operation-specific AUTH001/API008 permission errors, case-insensitive filename extension handling, Python's ignored client filename, retrieval message/API002 miss, update message, nullable descriptor deletion, and delete-always-success behavior. Filesystem archive/package-init helpers are obsolete in the native runtime, while exact compiler diagnostics and every validation error string remain incomplete.", + "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust matches multipart-size precedence, Python's exact content-validation/error strings, operation-specific AUTH001/API008/API009 behavior, case-insensitive filename extension handling, the ignored client filename, retrieval and deletion semantics, inline package extraction, and backfill eligibility/missing-source accounting. Filesystem archive, generated-Python package initialization, and Python grpc_tools diagnostics are obsolete in the native Rust runtime; protoc diagnostics remain runtime-specific.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::proto_routes", "gateway-rs/src/routes/platform.rs::compile_proto", @@ -19322,6 +20567,7 @@ "rust_tests": [ "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python", "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract", + "gateway-rs/tests/platform_native.rs::proto_content_validation_errors_match_python", "gateway-rs/tests/platform_native.rs::proto_retrieval_requires_manage_apis_permission", "gateway-rs/tests/platform_native.rs::descriptor_backfill_compiles_active_grpc_apis_missing_descriptors" ], @@ -19330,13 +20576,13 @@ "line": 209, "path": "backend-services/routes/proto_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/proto_routes.py::function:archive_existing_proto", - "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust now matches operation-specific AUTH001/API008 permission errors, case-insensitive filename extension handling, Python's ignored client filename, retrieval message/API002 miss, update message, nullable descriptor deletion, and delete-always-success behavior. Filesystem archive/package-init helpers are obsolete in the native runtime, while exact compiler diagnostics and every validation error string remain incomplete.", + "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust matches multipart-size precedence, Python's exact content-validation/error strings, operation-specific AUTH001/API008/API009 behavior, case-insensitive filename extension handling, the ignored client filename, retrieval and deletion semantics, inline package extraction, and backfill eligibility/missing-source accounting. Filesystem archive, generated-Python package initialization, and Python grpc_tools diagnostics are obsolete in the native Rust runtime; protoc diagnostics remain runtime-specific.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::proto_routes", "gateway-rs/src/routes/platform.rs::compile_proto", @@ -19345,6 +20591,7 @@ "rust_tests": [ "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python", "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract", + "gateway-rs/tests/platform_native.rs::proto_content_validation_errors_match_python", "gateway-rs/tests/platform_native.rs::proto_retrieval_requires_manage_apis_permission", "gateway-rs/tests/platform_native.rs::descriptor_backfill_compiles_active_grpc_apis_missing_descriptors" ], @@ -19353,13 +20600,13 @@ "line": 221, "path": "backend-services/routes/proto_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/proto_routes.py::async_function:backfill_descriptor_sets", - "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust now matches operation-specific AUTH001/API008 permission errors, case-insensitive filename extension handling, Python's ignored client filename, retrieval message/API002 miss, update message, nullable descriptor deletion, and delete-always-success behavior. Filesystem archive/package-init helpers are obsolete in the native runtime, while exact compiler diagnostics and every validation error string remain incomplete.", + "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust matches multipart-size precedence, Python's exact content-validation/error strings, operation-specific AUTH001/API008/API009 behavior, case-insensitive filename extension handling, the ignored client filename, retrieval and deletion semantics, inline package extraction, and backfill eligibility/missing-source accounting. Filesystem archive, generated-Python package initialization, and Python grpc_tools diagnostics are obsolete in the native Rust runtime; protoc diagnostics remain runtime-specific.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::proto_routes", "gateway-rs/src/routes/platform.rs::compile_proto", @@ -19368,6 +20615,7 @@ "rust_tests": [ "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python", "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract", + "gateway-rs/tests/platform_native.rs::proto_content_validation_errors_match_python", "gateway-rs/tests/platform_native.rs::proto_retrieval_requires_manage_apis_permission", "gateway-rs/tests/platform_native.rs::descriptor_backfill_compiles_active_grpc_apis_missing_descriptors" ], @@ -19376,7 +20624,7 @@ "line": 270, "path": "backend-services/routes/proto_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -19384,7 +20632,7 @@ ], "domain": "routes", "id": "backend-services/routes/proto_routes.py::async_function:backfill_descriptors", - "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust now matches operation-specific AUTH001/API008 permission errors, case-insensitive filename extension handling, Python's ignored client filename, retrieval message/API002 miss, update message, nullable descriptor deletion, and delete-always-success behavior. Filesystem archive/package-init helpers are obsolete in the native runtime, while exact compiler diagnostics and every validation error string remain incomplete.", + "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust matches multipart-size precedence, Python's exact content-validation/error strings, operation-specific AUTH001/API008/API009 behavior, case-insensitive filename extension handling, the ignored client filename, retrieval and deletion semantics, inline package extraction, and backfill eligibility/missing-source accounting. Filesystem archive, generated-Python package initialization, and Python grpc_tools diagnostics are obsolete in the native Rust runtime; protoc diagnostics remain runtime-specific.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::proto_routes", "gateway-rs/src/routes/platform.rs::compile_proto", @@ -19393,6 +20641,7 @@ "rust_tests": [ "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python", "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract", + "gateway-rs/tests/platform_native.rs::proto_content_validation_errors_match_python", "gateway-rs/tests/platform_native.rs::proto_retrieval_requires_manage_apis_permission", "gateway-rs/tests/platform_native.rs::descriptor_backfill_compiles_active_grpc_apis_missing_descriptors" ], @@ -19401,7 +20650,7 @@ "line": 329, "path": "backend-services/routes/proto_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -19409,7 +20658,7 @@ ], "domain": "routes", "id": "backend-services/routes/proto_routes.py::async_function:upload_proto_file", - "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust now matches operation-specific AUTH001/API008 permission errors, case-insensitive filename extension handling, Python's ignored client filename, retrieval message/API002 miss, update message, nullable descriptor deletion, and delete-always-success behavior. Filesystem archive/package-init helpers are obsolete in the native runtime, while exact compiler diagnostics and every validation error string remain incomplete.", + "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust matches multipart-size precedence, Python's exact content-validation/error strings, operation-specific AUTH001/API008/API009 behavior, case-insensitive filename extension handling, the ignored client filename, retrieval and deletion semantics, inline package extraction, and backfill eligibility/missing-source accounting. Filesystem archive, generated-Python package initialization, and Python grpc_tools diagnostics are obsolete in the native Rust runtime; protoc diagnostics remain runtime-specific.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::proto_routes", "gateway-rs/src/routes/platform.rs::compile_proto", @@ -19418,6 +20667,7 @@ "rust_tests": [ "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python", "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract", + "gateway-rs/tests/platform_native.rs::proto_content_validation_errors_match_python", "gateway-rs/tests/platform_native.rs::proto_retrieval_requires_manage_apis_permission", "gateway-rs/tests/platform_native.rs::descriptor_backfill_compiles_active_grpc_apis_missing_descriptors" ], @@ -19426,7 +20676,7 @@ "line": 378, "path": "backend-services/routes/proto_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -19434,7 +20684,7 @@ ], "domain": "routes", "id": "backend-services/routes/proto_routes.py::async_function:get_proto_file", - "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust now matches operation-specific AUTH001/API008 permission errors, case-insensitive filename extension handling, Python's ignored client filename, retrieval message/API002 miss, update message, nullable descriptor deletion, and delete-always-success behavior. Filesystem archive/package-init helpers are obsolete in the native runtime, while exact compiler diagnostics and every validation error string remain incomplete.", + "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust matches multipart-size precedence, Python's exact content-validation/error strings, operation-specific AUTH001/API008/API009 behavior, case-insensitive filename extension handling, the ignored client filename, retrieval and deletion semantics, inline package extraction, and backfill eligibility/missing-source accounting. Filesystem archive, generated-Python package initialization, and Python grpc_tools diagnostics are obsolete in the native Rust runtime; protoc diagnostics remain runtime-specific.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::proto_routes", "gateway-rs/src/routes/platform.rs::compile_proto", @@ -19443,6 +20693,7 @@ "rust_tests": [ "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python", "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract", + "gateway-rs/tests/platform_native.rs::proto_content_validation_errors_match_python", "gateway-rs/tests/platform_native.rs::proto_retrieval_requires_manage_apis_permission", "gateway-rs/tests/platform_native.rs::descriptor_backfill_compiles_active_grpc_apis_missing_descriptors" ], @@ -19451,7 +20702,7 @@ "line": 632, "path": "backend-services/routes/proto_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -19459,7 +20710,7 @@ ], "domain": "routes", "id": "backend-services/routes/proto_routes.py::async_function:update_proto_file", - "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust now matches operation-specific AUTH001/API008 permission errors, case-insensitive filename extension handling, Python's ignored client filename, retrieval message/API002 miss, update message, nullable descriptor deletion, and delete-always-success behavior. Filesystem archive/package-init helpers are obsolete in the native runtime, while exact compiler diagnostics and every validation error string remain incomplete.", + "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust matches multipart-size precedence, Python's exact content-validation/error strings, operation-specific AUTH001/API008/API009 behavior, case-insensitive filename extension handling, the ignored client filename, retrieval and deletion semantics, inline package extraction, and backfill eligibility/missing-source accounting. Filesystem archive, generated-Python package initialization, and Python grpc_tools diagnostics are obsolete in the native Rust runtime; protoc diagnostics remain runtime-specific.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::proto_routes", "gateway-rs/src/routes/platform.rs::compile_proto", @@ -19468,6 +20719,7 @@ "rust_tests": [ "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python", "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract", + "gateway-rs/tests/platform_native.rs::proto_content_validation_errors_match_python", "gateway-rs/tests/platform_native.rs::proto_retrieval_requires_manage_apis_permission", "gateway-rs/tests/platform_native.rs::descriptor_backfill_compiles_active_grpc_apis_missing_descriptors" ], @@ -19476,7 +20728,7 @@ "line": 722, "path": "backend-services/routes/proto_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -19484,7 +20736,7 @@ ], "domain": "routes", "id": "backend-services/routes/proto_routes.py::async_function:delete_proto_file", - "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust now matches operation-specific AUTH001/API008 permission errors, case-insensitive filename extension handling, Python's ignored client filename, retrieval message/API002 miss, update message, nullable descriptor deletion, and delete-always-success behavior. Filesystem archive/package-init helpers are obsolete in the native runtime, while exact compiler diagnostics and every validation error string remain incomplete.", + "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust matches multipart-size precedence, Python's exact content-validation/error strings, operation-specific AUTH001/API008/API009 behavior, case-insensitive filename extension handling, the ignored client filename, retrieval and deletion semantics, inline package extraction, and backfill eligibility/missing-source accounting. Filesystem archive, generated-Python package initialization, and Python grpc_tools diagnostics are obsolete in the native Rust runtime; protoc diagnostics remain runtime-specific.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::proto_routes", "gateway-rs/src/routes/platform.rs::compile_proto", @@ -19493,6 +20745,7 @@ "rust_tests": [ "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python", "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract", + "gateway-rs/tests/platform_native.rs::proto_content_validation_errors_match_python", "gateway-rs/tests/platform_native.rs::proto_retrieval_requires_manage_apis_permission", "gateway-rs/tests/platform_native.rs::descriptor_backfill_compiles_active_grpc_apis_missing_descriptors" ], @@ -19501,20 +20754,21 @@ "line": 876, "path": "backend-services/routes/proto_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/quota_routes.py::module:quota_routes", - "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and route-visible quota calculations are translated to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, fail-open tracker reads, thresholds, response fields, history independence from tier storage, request-only exports, naive export timestamps, CSV formatting, enabled-only upgrade filtering, route-specific HTTP detail errors, and reset boundaries. Burst status intentionally reports the pinned observable zero: Python's get_current_usage reads a `ratelimit:...:burst` key while hybrid consumption writes `burst:...`, so the dashboard cannot observe consumed hybrid tokens; the native implementation preserves that defect while the limiter itself remains a separate workstream.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::quota_routes", "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", "gateway-rs/src/routes/platform.rs::quota_values", "gateway-rs/src/routes/platform.rs::quota_status", "gateway-rs/src/routes/platform.rs::quota_period", - "gateway-rs/src/routes/platform.rs::quota_tier_info" + "gateway-rs/src/routes/platform.rs::quota_tier_info", + "gateway-rs/src/routes/platform.rs::quota_route_failure" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" @@ -19524,20 +20778,21 @@ "line": 1, "path": "backend-services/routes/quota_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/quota_routes.py::class:QuotaStatusResponse", - "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and route-visible quota calculations are translated to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, fail-open tracker reads, thresholds, response fields, history independence from tier storage, request-only exports, naive export timestamps, CSV formatting, enabled-only upgrade filtering, route-specific HTTP detail errors, and reset boundaries. Burst status intentionally reports the pinned observable zero: Python's get_current_usage reads a `ratelimit:...:burst` key while hybrid consumption writes `burst:...`, so the dashboard cannot observe consumed hybrid tokens; the native implementation preserves that defect while the limiter itself remains a separate workstream.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::quota_routes", "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", "gateway-rs/src/routes/platform.rs::quota_values", "gateway-rs/src/routes/platform.rs::quota_status", "gateway-rs/src/routes/platform.rs::quota_period", - "gateway-rs/src/routes/platform.rs::quota_tier_info" + "gateway-rs/src/routes/platform.rs::quota_tier_info", + "gateway-rs/src/routes/platform.rs::quota_route_failure" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" @@ -19547,20 +20802,21 @@ "line": 33, "path": "backend-services/routes/quota_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/quota_routes.py::field:QuotaStatusResponse.quota_type", - "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and route-visible quota calculations are translated to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, fail-open tracker reads, thresholds, response fields, history independence from tier storage, request-only exports, naive export timestamps, CSV formatting, enabled-only upgrade filtering, route-specific HTTP detail errors, and reset boundaries. Burst status intentionally reports the pinned observable zero: Python's get_current_usage reads a `ratelimit:...:burst` key while hybrid consumption writes `burst:...`, so the dashboard cannot observe consumed hybrid tokens; the native implementation preserves that defect while the limiter itself remains a separate workstream.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::quota_routes", "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", "gateway-rs/src/routes/platform.rs::quota_values", "gateway-rs/src/routes/platform.rs::quota_status", "gateway-rs/src/routes/platform.rs::quota_period", - "gateway-rs/src/routes/platform.rs::quota_tier_info" + "gateway-rs/src/routes/platform.rs::quota_tier_info", + "gateway-rs/src/routes/platform.rs::quota_route_failure" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" @@ -19570,20 +20826,21 @@ "line": 36, "path": "backend-services/routes/quota_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/quota_routes.py::field:QuotaStatusResponse.current_usage", - "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and route-visible quota calculations are translated to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, fail-open tracker reads, thresholds, response fields, history independence from tier storage, request-only exports, naive export timestamps, CSV formatting, enabled-only upgrade filtering, route-specific HTTP detail errors, and reset boundaries. Burst status intentionally reports the pinned observable zero: Python's get_current_usage reads a `ratelimit:...:burst` key while hybrid consumption writes `burst:...`, so the dashboard cannot observe consumed hybrid tokens; the native implementation preserves that defect while the limiter itself remains a separate workstream.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::quota_routes", "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", "gateway-rs/src/routes/platform.rs::quota_values", "gateway-rs/src/routes/platform.rs::quota_status", "gateway-rs/src/routes/platform.rs::quota_period", - "gateway-rs/src/routes/platform.rs::quota_tier_info" + "gateway-rs/src/routes/platform.rs::quota_tier_info", + "gateway-rs/src/routes/platform.rs::quota_route_failure" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" @@ -19593,20 +20850,21 @@ "line": 37, "path": "backend-services/routes/quota_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/quota_routes.py::field:QuotaStatusResponse.limit", - "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and route-visible quota calculations are translated to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, fail-open tracker reads, thresholds, response fields, history independence from tier storage, request-only exports, naive export timestamps, CSV formatting, enabled-only upgrade filtering, route-specific HTTP detail errors, and reset boundaries. Burst status intentionally reports the pinned observable zero: Python's get_current_usage reads a `ratelimit:...:burst` key while hybrid consumption writes `burst:...`, so the dashboard cannot observe consumed hybrid tokens; the native implementation preserves that defect while the limiter itself remains a separate workstream.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::quota_routes", "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", "gateway-rs/src/routes/platform.rs::quota_values", "gateway-rs/src/routes/platform.rs::quota_status", "gateway-rs/src/routes/platform.rs::quota_period", - "gateway-rs/src/routes/platform.rs::quota_tier_info" + "gateway-rs/src/routes/platform.rs::quota_tier_info", + "gateway-rs/src/routes/platform.rs::quota_route_failure" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" @@ -19616,20 +20874,21 @@ "line": 38, "path": "backend-services/routes/quota_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/quota_routes.py::field:QuotaStatusResponse.remaining", - "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and route-visible quota calculations are translated to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, fail-open tracker reads, thresholds, response fields, history independence from tier storage, request-only exports, naive export timestamps, CSV formatting, enabled-only upgrade filtering, route-specific HTTP detail errors, and reset boundaries. Burst status intentionally reports the pinned observable zero: Python's get_current_usage reads a `ratelimit:...:burst` key while hybrid consumption writes `burst:...`, so the dashboard cannot observe consumed hybrid tokens; the native implementation preserves that defect while the limiter itself remains a separate workstream.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::quota_routes", "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", "gateway-rs/src/routes/platform.rs::quota_values", "gateway-rs/src/routes/platform.rs::quota_status", "gateway-rs/src/routes/platform.rs::quota_period", - "gateway-rs/src/routes/platform.rs::quota_tier_info" + "gateway-rs/src/routes/platform.rs::quota_tier_info", + "gateway-rs/src/routes/platform.rs::quota_route_failure" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" @@ -19639,20 +20898,21 @@ "line": 39, "path": "backend-services/routes/quota_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/quota_routes.py::field:QuotaStatusResponse.percentage_used", - "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and route-visible quota calculations are translated to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, fail-open tracker reads, thresholds, response fields, history independence from tier storage, request-only exports, naive export timestamps, CSV formatting, enabled-only upgrade filtering, route-specific HTTP detail errors, and reset boundaries. Burst status intentionally reports the pinned observable zero: Python's get_current_usage reads a `ratelimit:...:burst` key while hybrid consumption writes `burst:...`, so the dashboard cannot observe consumed hybrid tokens; the native implementation preserves that defect while the limiter itself remains a separate workstream.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::quota_routes", "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", "gateway-rs/src/routes/platform.rs::quota_values", "gateway-rs/src/routes/platform.rs::quota_status", "gateway-rs/src/routes/platform.rs::quota_period", - "gateway-rs/src/routes/platform.rs::quota_tier_info" + "gateway-rs/src/routes/platform.rs::quota_tier_info", + "gateway-rs/src/routes/platform.rs::quota_route_failure" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" @@ -19662,20 +20922,21 @@ "line": 40, "path": "backend-services/routes/quota_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/quota_routes.py::field:QuotaStatusResponse.reset_at", - "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and route-visible quota calculations are translated to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, fail-open tracker reads, thresholds, response fields, history independence from tier storage, request-only exports, naive export timestamps, CSV formatting, enabled-only upgrade filtering, route-specific HTTP detail errors, and reset boundaries. Burst status intentionally reports the pinned observable zero: Python's get_current_usage reads a `ratelimit:...:burst` key while hybrid consumption writes `burst:...`, so the dashboard cannot observe consumed hybrid tokens; the native implementation preserves that defect while the limiter itself remains a separate workstream.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::quota_routes", "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", "gateway-rs/src/routes/platform.rs::quota_values", "gateway-rs/src/routes/platform.rs::quota_status", "gateway-rs/src/routes/platform.rs::quota_period", - "gateway-rs/src/routes/platform.rs::quota_tier_info" + "gateway-rs/src/routes/platform.rs::quota_tier_info", + "gateway-rs/src/routes/platform.rs::quota_route_failure" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" @@ -19685,20 +20946,21 @@ "line": 41, "path": "backend-services/routes/quota_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/quota_routes.py::field:QuotaStatusResponse.is_warning", - "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and route-visible quota calculations are translated to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, fail-open tracker reads, thresholds, response fields, history independence from tier storage, request-only exports, naive export timestamps, CSV formatting, enabled-only upgrade filtering, route-specific HTTP detail errors, and reset boundaries. Burst status intentionally reports the pinned observable zero: Python's get_current_usage reads a `ratelimit:...:burst` key while hybrid consumption writes `burst:...`, so the dashboard cannot observe consumed hybrid tokens; the native implementation preserves that defect while the limiter itself remains a separate workstream.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::quota_routes", "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", "gateway-rs/src/routes/platform.rs::quota_values", "gateway-rs/src/routes/platform.rs::quota_status", "gateway-rs/src/routes/platform.rs::quota_period", - "gateway-rs/src/routes/platform.rs::quota_tier_info" + "gateway-rs/src/routes/platform.rs::quota_tier_info", + "gateway-rs/src/routes/platform.rs::quota_route_failure" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" @@ -19708,20 +20970,21 @@ "line": 42, "path": "backend-services/routes/quota_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/quota_routes.py::field:QuotaStatusResponse.is_critical", - "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and route-visible quota calculations are translated to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, fail-open tracker reads, thresholds, response fields, history independence from tier storage, request-only exports, naive export timestamps, CSV formatting, enabled-only upgrade filtering, route-specific HTTP detail errors, and reset boundaries. Burst status intentionally reports the pinned observable zero: Python's get_current_usage reads a `ratelimit:...:burst` key while hybrid consumption writes `burst:...`, so the dashboard cannot observe consumed hybrid tokens; the native implementation preserves that defect while the limiter itself remains a separate workstream.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::quota_routes", "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", "gateway-rs/src/routes/platform.rs::quota_values", "gateway-rs/src/routes/platform.rs::quota_status", "gateway-rs/src/routes/platform.rs::quota_period", - "gateway-rs/src/routes/platform.rs::quota_tier_info" + "gateway-rs/src/routes/platform.rs::quota_tier_info", + "gateway-rs/src/routes/platform.rs::quota_route_failure" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" @@ -19731,20 +20994,21 @@ "line": 43, "path": "backend-services/routes/quota_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/quota_routes.py::field:QuotaStatusResponse.is_exhausted", - "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and route-visible quota calculations are translated to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, fail-open tracker reads, thresholds, response fields, history independence from tier storage, request-only exports, naive export timestamps, CSV formatting, enabled-only upgrade filtering, route-specific HTTP detail errors, and reset boundaries. Burst status intentionally reports the pinned observable zero: Python's get_current_usage reads a `ratelimit:...:burst` key while hybrid consumption writes `burst:...`, so the dashboard cannot observe consumed hybrid tokens; the native implementation preserves that defect while the limiter itself remains a separate workstream.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::quota_routes", "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", "gateway-rs/src/routes/platform.rs::quota_values", "gateway-rs/src/routes/platform.rs::quota_status", "gateway-rs/src/routes/platform.rs::quota_period", - "gateway-rs/src/routes/platform.rs::quota_tier_info" + "gateway-rs/src/routes/platform.rs::quota_tier_info", + "gateway-rs/src/routes/platform.rs::quota_route_failure" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" @@ -19754,20 +21018,21 @@ "line": 44, "path": "backend-services/routes/quota_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/quota_routes.py::field:QuotaStatusResponse.burst_used", - "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and route-visible quota calculations are translated to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, fail-open tracker reads, thresholds, response fields, history independence from tier storage, request-only exports, naive export timestamps, CSV formatting, enabled-only upgrade filtering, route-specific HTTP detail errors, and reset boundaries. Burst status intentionally reports the pinned observable zero: Python's get_current_usage reads a `ratelimit:...:burst` key while hybrid consumption writes `burst:...`, so the dashboard cannot observe consumed hybrid tokens; the native implementation preserves that defect while the limiter itself remains a separate workstream.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::quota_routes", "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", "gateway-rs/src/routes/platform.rs::quota_values", "gateway-rs/src/routes/platform.rs::quota_status", "gateway-rs/src/routes/platform.rs::quota_period", - "gateway-rs/src/routes/platform.rs::quota_tier_info" + "gateway-rs/src/routes/platform.rs::quota_tier_info", + "gateway-rs/src/routes/platform.rs::quota_route_failure" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" @@ -19777,20 +21042,21 @@ "line": 45, "path": "backend-services/routes/quota_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/quota_routes.py::field:QuotaStatusResponse.burst_limit", - "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and route-visible quota calculations are translated to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, fail-open tracker reads, thresholds, response fields, history independence from tier storage, request-only exports, naive export timestamps, CSV formatting, enabled-only upgrade filtering, route-specific HTTP detail errors, and reset boundaries. Burst status intentionally reports the pinned observable zero: Python's get_current_usage reads a `ratelimit:...:burst` key while hybrid consumption writes `burst:...`, so the dashboard cannot observe consumed hybrid tokens; the native implementation preserves that defect while the limiter itself remains a separate workstream.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::quota_routes", "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", "gateway-rs/src/routes/platform.rs::quota_values", "gateway-rs/src/routes/platform.rs::quota_status", "gateway-rs/src/routes/platform.rs::quota_period", - "gateway-rs/src/routes/platform.rs::quota_tier_info" + "gateway-rs/src/routes/platform.rs::quota_tier_info", + "gateway-rs/src/routes/platform.rs::quota_route_failure" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" @@ -19800,20 +21066,21 @@ "line": 46, "path": "backend-services/routes/quota_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/quota_routes.py::field:QuotaStatusResponse.burst_percentage", - "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and route-visible quota calculations are translated to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, fail-open tracker reads, thresholds, response fields, history independence from tier storage, request-only exports, naive export timestamps, CSV formatting, enabled-only upgrade filtering, route-specific HTTP detail errors, and reset boundaries. Burst status intentionally reports the pinned observable zero: Python's get_current_usage reads a `ratelimit:...:burst` key while hybrid consumption writes `burst:...`, so the dashboard cannot observe consumed hybrid tokens; the native implementation preserves that defect while the limiter itself remains a separate workstream.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::quota_routes", "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", "gateway-rs/src/routes/platform.rs::quota_values", "gateway-rs/src/routes/platform.rs::quota_status", "gateway-rs/src/routes/platform.rs::quota_period", - "gateway-rs/src/routes/platform.rs::quota_tier_info" + "gateway-rs/src/routes/platform.rs::quota_tier_info", + "gateway-rs/src/routes/platform.rs::quota_route_failure" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" @@ -19823,20 +21090,21 @@ "line": 47, "path": "backend-services/routes/quota_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/quota_routes.py::class:TierInfoResponse", - "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and route-visible quota calculations are translated to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, fail-open tracker reads, thresholds, response fields, history independence from tier storage, request-only exports, naive export timestamps, CSV formatting, enabled-only upgrade filtering, route-specific HTTP detail errors, and reset boundaries. Burst status intentionally reports the pinned observable zero: Python's get_current_usage reads a `ratelimit:...:burst` key while hybrid consumption writes `burst:...`, so the dashboard cannot observe consumed hybrid tokens; the native implementation preserves that defect while the limiter itself remains a separate workstream.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::quota_routes", "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", "gateway-rs/src/routes/platform.rs::quota_values", "gateway-rs/src/routes/platform.rs::quota_status", "gateway-rs/src/routes/platform.rs::quota_period", - "gateway-rs/src/routes/platform.rs::quota_tier_info" + "gateway-rs/src/routes/platform.rs::quota_tier_info", + "gateway-rs/src/routes/platform.rs::quota_route_failure" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" @@ -19846,20 +21114,21 @@ "line": 50, "path": "backend-services/routes/quota_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/quota_routes.py::field:TierInfoResponse.tier_id", - "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and route-visible quota calculations are translated to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, fail-open tracker reads, thresholds, response fields, history independence from tier storage, request-only exports, naive export timestamps, CSV formatting, enabled-only upgrade filtering, route-specific HTTP detail errors, and reset boundaries. Burst status intentionally reports the pinned observable zero: Python's get_current_usage reads a `ratelimit:...:burst` key while hybrid consumption writes `burst:...`, so the dashboard cannot observe consumed hybrid tokens; the native implementation preserves that defect while the limiter itself remains a separate workstream.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::quota_routes", "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", "gateway-rs/src/routes/platform.rs::quota_values", "gateway-rs/src/routes/platform.rs::quota_status", "gateway-rs/src/routes/platform.rs::quota_period", - "gateway-rs/src/routes/platform.rs::quota_tier_info" + "gateway-rs/src/routes/platform.rs::quota_tier_info", + "gateway-rs/src/routes/platform.rs::quota_route_failure" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" @@ -19869,20 +21138,21 @@ "line": 53, "path": "backend-services/routes/quota_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/quota_routes.py::field:TierInfoResponse.tier_name", - "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and route-visible quota calculations are translated to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, fail-open tracker reads, thresholds, response fields, history independence from tier storage, request-only exports, naive export timestamps, CSV formatting, enabled-only upgrade filtering, route-specific HTTP detail errors, and reset boundaries. Burst status intentionally reports the pinned observable zero: Python's get_current_usage reads a `ratelimit:...:burst` key while hybrid consumption writes `burst:...`, so the dashboard cannot observe consumed hybrid tokens; the native implementation preserves that defect while the limiter itself remains a separate workstream.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::quota_routes", "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", "gateway-rs/src/routes/platform.rs::quota_values", "gateway-rs/src/routes/platform.rs::quota_status", "gateway-rs/src/routes/platform.rs::quota_period", - "gateway-rs/src/routes/platform.rs::quota_tier_info" + "gateway-rs/src/routes/platform.rs::quota_tier_info", + "gateway-rs/src/routes/platform.rs::quota_route_failure" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" @@ -19892,20 +21162,21 @@ "line": 54, "path": "backend-services/routes/quota_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/quota_routes.py::field:TierInfoResponse.display_name", - "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and route-visible quota calculations are translated to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, fail-open tracker reads, thresholds, response fields, history independence from tier storage, request-only exports, naive export timestamps, CSV formatting, enabled-only upgrade filtering, route-specific HTTP detail errors, and reset boundaries. Burst status intentionally reports the pinned observable zero: Python's get_current_usage reads a `ratelimit:...:burst` key while hybrid consumption writes `burst:...`, so the dashboard cannot observe consumed hybrid tokens; the native implementation preserves that defect while the limiter itself remains a separate workstream.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::quota_routes", "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", "gateway-rs/src/routes/platform.rs::quota_values", "gateway-rs/src/routes/platform.rs::quota_status", "gateway-rs/src/routes/platform.rs::quota_period", - "gateway-rs/src/routes/platform.rs::quota_tier_info" + "gateway-rs/src/routes/platform.rs::quota_tier_info", + "gateway-rs/src/routes/platform.rs::quota_route_failure" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" @@ -19915,20 +21186,21 @@ "line": 55, "path": "backend-services/routes/quota_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/quota_routes.py::field:TierInfoResponse.limits", - "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and route-visible quota calculations are translated to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, fail-open tracker reads, thresholds, response fields, history independence from tier storage, request-only exports, naive export timestamps, CSV formatting, enabled-only upgrade filtering, route-specific HTTP detail errors, and reset boundaries. Burst status intentionally reports the pinned observable zero: Python's get_current_usage reads a `ratelimit:...:burst` key while hybrid consumption writes `burst:...`, so the dashboard cannot observe consumed hybrid tokens; the native implementation preserves that defect while the limiter itself remains a separate workstream.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::quota_routes", "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", "gateway-rs/src/routes/platform.rs::quota_values", "gateway-rs/src/routes/platform.rs::quota_status", "gateway-rs/src/routes/platform.rs::quota_period", - "gateway-rs/src/routes/platform.rs::quota_tier_info" + "gateway-rs/src/routes/platform.rs::quota_tier_info", + "gateway-rs/src/routes/platform.rs::quota_route_failure" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" @@ -19938,20 +21210,21 @@ "line": 56, "path": "backend-services/routes/quota_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/quota_routes.py::field:TierInfoResponse.price_monthly", - "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and route-visible quota calculations are translated to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, fail-open tracker reads, thresholds, response fields, history independence from tier storage, request-only exports, naive export timestamps, CSV formatting, enabled-only upgrade filtering, route-specific HTTP detail errors, and reset boundaries. Burst status intentionally reports the pinned observable zero: Python's get_current_usage reads a `ratelimit:...:burst` key while hybrid consumption writes `burst:...`, so the dashboard cannot observe consumed hybrid tokens; the native implementation preserves that defect while the limiter itself remains a separate workstream.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::quota_routes", "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", "gateway-rs/src/routes/platform.rs::quota_values", "gateway-rs/src/routes/platform.rs::quota_status", "gateway-rs/src/routes/platform.rs::quota_period", - "gateway-rs/src/routes/platform.rs::quota_tier_info" + "gateway-rs/src/routes/platform.rs::quota_tier_info", + "gateway-rs/src/routes/platform.rs::quota_route_failure" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" @@ -19961,20 +21234,21 @@ "line": 57, "path": "backend-services/routes/quota_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/quota_routes.py::field:TierInfoResponse.features", - "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and route-visible quota calculations are translated to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, fail-open tracker reads, thresholds, response fields, history independence from tier storage, request-only exports, naive export timestamps, CSV formatting, enabled-only upgrade filtering, route-specific HTTP detail errors, and reset boundaries. Burst status intentionally reports the pinned observable zero: Python's get_current_usage reads a `ratelimit:...:burst` key while hybrid consumption writes `burst:...`, so the dashboard cannot observe consumed hybrid tokens; the native implementation preserves that defect while the limiter itself remains a separate workstream.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::quota_routes", "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", "gateway-rs/src/routes/platform.rs::quota_values", "gateway-rs/src/routes/platform.rs::quota_status", "gateway-rs/src/routes/platform.rs::quota_period", - "gateway-rs/src/routes/platform.rs::quota_tier_info" + "gateway-rs/src/routes/platform.rs::quota_tier_info", + "gateway-rs/src/routes/platform.rs::quota_route_failure" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" @@ -19984,20 +21258,21 @@ "line": 58, "path": "backend-services/routes/quota_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/quota_routes.py::class:QuotaDashboardResponse", - "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and route-visible quota calculations are translated to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, fail-open tracker reads, thresholds, response fields, history independence from tier storage, request-only exports, naive export timestamps, CSV formatting, enabled-only upgrade filtering, route-specific HTTP detail errors, and reset boundaries. Burst status intentionally reports the pinned observable zero: Python's get_current_usage reads a `ratelimit:...:burst` key while hybrid consumption writes `burst:...`, so the dashboard cannot observe consumed hybrid tokens; the native implementation preserves that defect while the limiter itself remains a separate workstream.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::quota_routes", "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", "gateway-rs/src/routes/platform.rs::quota_values", "gateway-rs/src/routes/platform.rs::quota_status", "gateway-rs/src/routes/platform.rs::quota_period", - "gateway-rs/src/routes/platform.rs::quota_tier_info" + "gateway-rs/src/routes/platform.rs::quota_tier_info", + "gateway-rs/src/routes/platform.rs::quota_route_failure" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" @@ -20007,20 +21282,21 @@ "line": 61, "path": "backend-services/routes/quota_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/quota_routes.py::field:QuotaDashboardResponse.user_id", - "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and route-visible quota calculations are translated to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, fail-open tracker reads, thresholds, response fields, history independence from tier storage, request-only exports, naive export timestamps, CSV formatting, enabled-only upgrade filtering, route-specific HTTP detail errors, and reset boundaries. Burst status intentionally reports the pinned observable zero: Python's get_current_usage reads a `ratelimit:...:burst` key while hybrid consumption writes `burst:...`, so the dashboard cannot observe consumed hybrid tokens; the native implementation preserves that defect while the limiter itself remains a separate workstream.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::quota_routes", "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", "gateway-rs/src/routes/platform.rs::quota_values", "gateway-rs/src/routes/platform.rs::quota_status", "gateway-rs/src/routes/platform.rs::quota_period", - "gateway-rs/src/routes/platform.rs::quota_tier_info" + "gateway-rs/src/routes/platform.rs::quota_tier_info", + "gateway-rs/src/routes/platform.rs::quota_route_failure" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" @@ -20030,20 +21306,21 @@ "line": 64, "path": "backend-services/routes/quota_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/quota_routes.py::field:QuotaDashboardResponse.tier_info", - "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and route-visible quota calculations are translated to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, fail-open tracker reads, thresholds, response fields, history independence from tier storage, request-only exports, naive export timestamps, CSV formatting, enabled-only upgrade filtering, route-specific HTTP detail errors, and reset boundaries. Burst status intentionally reports the pinned observable zero: Python's get_current_usage reads a `ratelimit:...:burst` key while hybrid consumption writes `burst:...`, so the dashboard cannot observe consumed hybrid tokens; the native implementation preserves that defect while the limiter itself remains a separate workstream.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::quota_routes", "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", "gateway-rs/src/routes/platform.rs::quota_values", "gateway-rs/src/routes/platform.rs::quota_status", "gateway-rs/src/routes/platform.rs::quota_period", - "gateway-rs/src/routes/platform.rs::quota_tier_info" + "gateway-rs/src/routes/platform.rs::quota_tier_info", + "gateway-rs/src/routes/platform.rs::quota_route_failure" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" @@ -20053,20 +21330,21 @@ "line": 65, "path": "backend-services/routes/quota_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/quota_routes.py::field:QuotaDashboardResponse.quotas", - "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and route-visible quota calculations are translated to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, fail-open tracker reads, thresholds, response fields, history independence from tier storage, request-only exports, naive export timestamps, CSV formatting, enabled-only upgrade filtering, route-specific HTTP detail errors, and reset boundaries. Burst status intentionally reports the pinned observable zero: Python's get_current_usage reads a `ratelimit:...:burst` key while hybrid consumption writes `burst:...`, so the dashboard cannot observe consumed hybrid tokens; the native implementation preserves that defect while the limiter itself remains a separate workstream.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::quota_routes", "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", "gateway-rs/src/routes/platform.rs::quota_values", "gateway-rs/src/routes/platform.rs::quota_status", "gateway-rs/src/routes/platform.rs::quota_period", - "gateway-rs/src/routes/platform.rs::quota_tier_info" + "gateway-rs/src/routes/platform.rs::quota_tier_info", + "gateway-rs/src/routes/platform.rs::quota_route_failure" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" @@ -20076,20 +21354,21 @@ "line": 66, "path": "backend-services/routes/quota_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/quota_routes.py::field:QuotaDashboardResponse.usage_summary", - "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and route-visible quota calculations are translated to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, fail-open tracker reads, thresholds, response fields, history independence from tier storage, request-only exports, naive export timestamps, CSV formatting, enabled-only upgrade filtering, route-specific HTTP detail errors, and reset boundaries. Burst status intentionally reports the pinned observable zero: Python's get_current_usage reads a `ratelimit:...:burst` key while hybrid consumption writes `burst:...`, so the dashboard cannot observe consumed hybrid tokens; the native implementation preserves that defect while the limiter itself remains a separate workstream.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::quota_routes", "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", "gateway-rs/src/routes/platform.rs::quota_values", "gateway-rs/src/routes/platform.rs::quota_status", "gateway-rs/src/routes/platform.rs::quota_period", - "gateway-rs/src/routes/platform.rs::quota_tier_info" + "gateway-rs/src/routes/platform.rs::quota_tier_info", + "gateway-rs/src/routes/platform.rs::quota_route_failure" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" @@ -20099,20 +21378,21 @@ "line": 67, "path": "backend-services/routes/quota_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/quota_routes.py::async_function:get_quota_tracker_dep", - "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and route-visible quota calculations are translated to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, fail-open tracker reads, thresholds, response fields, history independence from tier storage, request-only exports, naive export timestamps, CSV formatting, enabled-only upgrade filtering, route-specific HTTP detail errors, and reset boundaries. Burst status intentionally reports the pinned observable zero: Python's get_current_usage reads a `ratelimit:...:burst` key while hybrid consumption writes `burst:...`, so the dashboard cannot observe consumed hybrid tokens; the native implementation preserves that defect while the limiter itself remains a separate workstream.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::quota_routes", "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", "gateway-rs/src/routes/platform.rs::quota_values", "gateway-rs/src/routes/platform.rs::quota_status", "gateway-rs/src/routes/platform.rs::quota_period", - "gateway-rs/src/routes/platform.rs::quota_tier_info" + "gateway-rs/src/routes/platform.rs::quota_tier_info", + "gateway-rs/src/routes/platform.rs::quota_route_failure" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" @@ -20122,20 +21402,21 @@ "line": 75, "path": "backend-services/routes/quota_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/quota_routes.py::async_function:get_tier_service_dep", - "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and route-visible quota calculations are translated to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, fail-open tracker reads, thresholds, response fields, history independence from tier storage, request-only exports, naive export timestamps, CSV formatting, enabled-only upgrade filtering, route-specific HTTP detail errors, and reset boundaries. Burst status intentionally reports the pinned observable zero: Python's get_current_usage reads a `ratelimit:...:burst` key while hybrid consumption writes `burst:...`, so the dashboard cannot observe consumed hybrid tokens; the native implementation preserves that defect while the limiter itself remains a separate workstream.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::quota_routes", "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", "gateway-rs/src/routes/platform.rs::quota_values", "gateway-rs/src/routes/platform.rs::quota_status", "gateway-rs/src/routes/platform.rs::quota_period", - "gateway-rs/src/routes/platform.rs::quota_tier_info" + "gateway-rs/src/routes/platform.rs::quota_tier_info", + "gateway-rs/src/routes/platform.rs::quota_route_failure" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" @@ -20145,20 +21426,21 @@ "line": 80, "path": "backend-services/routes/quota_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/quota_routes.py::async_function:get_current_user_id", - "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and route-visible quota calculations are translated to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, fail-open tracker reads, thresholds, response fields, history independence from tier storage, request-only exports, naive export timestamps, CSV formatting, enabled-only upgrade filtering, route-specific HTTP detail errors, and reset boundaries. Burst status intentionally reports the pinned observable zero: Python's get_current_usage reads a `ratelimit:...:burst` key while hybrid consumption writes `burst:...`, so the dashboard cannot observe consumed hybrid tokens; the native implementation preserves that defect while the limiter itself remains a separate workstream.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::quota_routes", "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", "gateway-rs/src/routes/platform.rs::quota_values", "gateway-rs/src/routes/platform.rs::quota_status", "gateway-rs/src/routes/platform.rs::quota_period", - "gateway-rs/src/routes/platform.rs::quota_tier_info" + "gateway-rs/src/routes/platform.rs::quota_tier_info", + "gateway-rs/src/routes/platform.rs::quota_route_failure" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" @@ -20168,7 +21450,7 @@ "line": 86, "path": "backend-services/routes/quota_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -20176,14 +21458,15 @@ ], "domain": "routes", "id": "backend-services/routes/quota_routes.py::async_function:get_quota_status", - "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and route-visible quota calculations are translated to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, fail-open tracker reads, thresholds, response fields, history independence from tier storage, request-only exports, naive export timestamps, CSV formatting, enabled-only upgrade filtering, route-specific HTTP detail errors, and reset boundaries. Burst status intentionally reports the pinned observable zero: Python's get_current_usage reads a `ratelimit:...:burst` key while hybrid consumption writes `burst:...`, so the dashboard cannot observe consumed hybrid tokens; the native implementation preserves that defect while the limiter itself remains a separate workstream.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::quota_routes", "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", "gateway-rs/src/routes/platform.rs::quota_values", "gateway-rs/src/routes/platform.rs::quota_status", "gateway-rs/src/routes/platform.rs::quota_period", - "gateway-rs/src/routes/platform.rs::quota_tier_info" + "gateway-rs/src/routes/platform.rs::quota_tier_info", + "gateway-rs/src/routes/platform.rs::quota_route_failure" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" @@ -20193,7 +21476,7 @@ "line": 108, "path": "backend-services/routes/quota_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -20201,14 +21484,15 @@ ], "domain": "routes", "id": "backend-services/routes/quota_routes.py::async_function:get_specific_quota_status", - "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and route-visible quota calculations are translated to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, fail-open tracker reads, thresholds, response fields, history independence from tier storage, request-only exports, naive export timestamps, CSV formatting, enabled-only upgrade filtering, route-specific HTTP detail errors, and reset boundaries. Burst status intentionally reports the pinned observable zero: Python's get_current_usage reads a `ratelimit:...:burst` key while hybrid consumption writes `burst:...`, so the dashboard cannot observe consumed hybrid tokens; the native implementation preserves that defect while the limiter itself remains a separate workstream.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::quota_routes", "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", "gateway-rs/src/routes/platform.rs::quota_values", "gateway-rs/src/routes/platform.rs::quota_status", "gateway-rs/src/routes/platform.rs::quota_period", - "gateway-rs/src/routes/platform.rs::quota_tier_info" + "gateway-rs/src/routes/platform.rs::quota_tier_info", + "gateway-rs/src/routes/platform.rs::quota_route_failure" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" @@ -20218,7 +21502,7 @@ "line": 232, "path": "backend-services/routes/quota_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -20226,14 +21510,15 @@ ], "domain": "routes", "id": "backend-services/routes/quota_routes.py::async_function:get_usage_history", - "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and route-visible quota calculations are translated to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, fail-open tracker reads, thresholds, response fields, history independence from tier storage, request-only exports, naive export timestamps, CSV formatting, enabled-only upgrade filtering, route-specific HTTP detail errors, and reset boundaries. Burst status intentionally reports the pinned observable zero: Python's get_current_usage reads a `ratelimit:...:burst` key while hybrid consumption writes `burst:...`, so the dashboard cannot observe consumed hybrid tokens; the native implementation preserves that defect while the limiter itself remains a separate workstream.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::quota_routes", "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", "gateway-rs/src/routes/platform.rs::quota_values", "gateway-rs/src/routes/platform.rs::quota_status", "gateway-rs/src/routes/platform.rs::quota_period", - "gateway-rs/src/routes/platform.rs::quota_tier_info" + "gateway-rs/src/routes/platform.rs::quota_tier_info", + "gateway-rs/src/routes/platform.rs::quota_route_failure" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" @@ -20243,7 +21528,7 @@ "line": 298, "path": "backend-services/routes/quota_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -20251,14 +21536,15 @@ ], "domain": "routes", "id": "backend-services/routes/quota_routes.py::async_function:export_usage_data", - "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and route-visible quota calculations are translated to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, fail-open tracker reads, thresholds, response fields, history independence from tier storage, request-only exports, naive export timestamps, CSV formatting, enabled-only upgrade filtering, route-specific HTTP detail errors, and reset boundaries. Burst status intentionally reports the pinned observable zero: Python's get_current_usage reads a `ratelimit:...:burst` key while hybrid consumption writes `burst:...`, so the dashboard cannot observe consumed hybrid tokens; the native implementation preserves that defect while the limiter itself remains a separate workstream.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::quota_routes", "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", "gateway-rs/src/routes/platform.rs::quota_values", "gateway-rs/src/routes/platform.rs::quota_status", "gateway-rs/src/routes/platform.rs::quota_period", - "gateway-rs/src/routes/platform.rs::quota_tier_info" + "gateway-rs/src/routes/platform.rs::quota_tier_info", + "gateway-rs/src/routes/platform.rs::quota_route_failure" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" @@ -20268,7 +21554,7 @@ "line": 325, "path": "backend-services/routes/quota_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -20276,14 +21562,15 @@ ], "domain": "routes", "id": "backend-services/routes/quota_routes.py::async_function:get_tier_info", - "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and route-visible quota calculations are translated to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, fail-open tracker reads, thresholds, response fields, history independence from tier storage, request-only exports, naive export timestamps, CSV formatting, enabled-only upgrade filtering, route-specific HTTP detail errors, and reset boundaries. Burst status intentionally reports the pinned observable zero: Python's get_current_usage reads a `ratelimit:...:burst` key while hybrid consumption writes `burst:...`, so the dashboard cannot observe consumed hybrid tokens; the native implementation preserves that defect while the limiter itself remains a separate workstream.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::quota_routes", "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", "gateway-rs/src/routes/platform.rs::quota_values", "gateway-rs/src/routes/platform.rs::quota_status", "gateway-rs/src/routes/platform.rs::quota_period", - "gateway-rs/src/routes/platform.rs::quota_tier_info" + "gateway-rs/src/routes/platform.rs::quota_tier_info", + "gateway-rs/src/routes/platform.rs::quota_route_failure" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" @@ -20293,7 +21580,7 @@ "line": 405, "path": "backend-services/routes/quota_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -20301,14 +21588,15 @@ ], "domain": "routes", "id": "backend-services/routes/quota_routes.py::async_function:get_burst_status", - "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and route-visible quota calculations are translated to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, fail-open tracker reads, thresholds, response fields, history independence from tier storage, request-only exports, naive export timestamps, CSV formatting, enabled-only upgrade filtering, route-specific HTTP detail errors, and reset boundaries. Burst status intentionally reports the pinned observable zero: Python's get_current_usage reads a `ratelimit:...:burst` key while hybrid consumption writes `burst:...`, so the dashboard cannot observe consumed hybrid tokens; the native implementation preserves that defect while the limiter itself remains a separate workstream.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::quota_routes", "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", "gateway-rs/src/routes/platform.rs::quota_values", "gateway-rs/src/routes/platform.rs::quota_status", "gateway-rs/src/routes/platform.rs::quota_period", - "gateway-rs/src/routes/platform.rs::quota_tier_info" + "gateway-rs/src/routes/platform.rs::quota_tier_info", + "gateway-rs/src/routes/platform.rs::quota_route_failure" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" @@ -20318,20 +21606,21 @@ "line": 460, "path": "backend-services/routes/quota_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/quota_routes.py::function:get_burst_status._get_burst_usage", - "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and route-visible quota calculations are translated to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, fail-open tracker reads, thresholds, response fields, history independence from tier storage, request-only exports, naive export timestamps, CSV formatting, enabled-only upgrade filtering, route-specific HTTP detail errors, and reset boundaries. Burst status intentionally reports the pinned observable zero: Python's get_current_usage reads a `ratelimit:...:burst` key while hybrid consumption writes `burst:...`, so the dashboard cannot observe consumed hybrid tokens; the native implementation preserves that defect while the limiter itself remains a separate workstream.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::quota_routes", "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", "gateway-rs/src/routes/platform.rs::quota_values", "gateway-rs/src/routes/platform.rs::quota_status", "gateway-rs/src/routes/platform.rs::quota_period", - "gateway-rs/src/routes/platform.rs::quota_tier_info" + "gateway-rs/src/routes/platform.rs::quota_tier_info", + "gateway-rs/src/routes/platform.rs::quota_route_failure" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" @@ -20341,17 +21630,18 @@ "line": 485, "path": "backend-services/routes/quota_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::module:rate_limit_rule_routes", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -20366,17 +21656,18 @@ "line": 1, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::class:RuleCreateRequest", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -20391,17 +21682,18 @@ "line": 28, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleCreateRequest.rule_id", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -20416,17 +21708,18 @@ "line": 31, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleCreateRequest.rule_type", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -20441,17 +21734,18 @@ "line": 32, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleCreateRequest.time_window", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -20466,17 +21760,18 @@ "line": 35, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleCreateRequest.limit", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -20491,17 +21786,18 @@ "line": 36, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleCreateRequest.target_identifier", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -20516,17 +21812,18 @@ "line": 37, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleCreateRequest.burst_allowance", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -20541,17 +21838,18 @@ "line": 40, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleCreateRequest.priority", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -20566,17 +21864,18 @@ "line": 41, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleCreateRequest.enabled", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -20591,17 +21890,18 @@ "line": 42, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleCreateRequest.description", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -20616,17 +21916,18 @@ "line": 43, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::class:RuleUpdateRequest", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -20641,17 +21942,18 @@ "line": 46, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleUpdateRequest.limit", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -20666,17 +21968,18 @@ "line": 49, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleUpdateRequest.target_identifier", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -20691,17 +21994,18 @@ "line": 50, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleUpdateRequest.burst_allowance", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -20716,17 +22020,18 @@ "line": 51, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleUpdateRequest.priority", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -20741,17 +22046,18 @@ "line": 52, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleUpdateRequest.enabled", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -20766,17 +22072,18 @@ "line": 53, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleUpdateRequest.description", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -20791,17 +22098,18 @@ "line": 54, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::class:BulkRuleRequest", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -20816,17 +22124,18 @@ "line": 57, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::field:BulkRuleRequest.rule_ids", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -20841,17 +22150,18 @@ "line": 60, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::class:RuleDuplicateRequest", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -20866,17 +22176,18 @@ "line": 63, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleDuplicateRequest.new_rule_id", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -20891,17 +22202,18 @@ "line": 66, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::class:RuleResponse", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -20916,17 +22228,18 @@ "line": 69, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleResponse.rule_id", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -20941,17 +22254,18 @@ "line": 72, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleResponse.rule_type", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -20966,17 +22280,18 @@ "line": 73, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleResponse.time_window", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -20991,17 +22306,18 @@ "line": 74, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleResponse.limit", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -21016,17 +22332,18 @@ "line": 75, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleResponse.target_identifier", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -21041,17 +22358,18 @@ "line": 76, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleResponse.burst_allowance", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -21066,17 +22384,18 @@ "line": 77, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleResponse.priority", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -21091,17 +22410,18 @@ "line": 78, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleResponse.enabled", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -21116,17 +22436,18 @@ "line": 79, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleResponse.description", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -21141,17 +22462,18 @@ "line": 80, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleResponse.created_at", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -21166,17 +22488,18 @@ "line": 81, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::field:RuleResponse.updated_at", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -21191,17 +22514,18 @@ "line": 82, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::async_function:get_rule_service_dep", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -21216,7 +22540,7 @@ "line": 90, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -21224,11 +22548,12 @@ ], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::async_function:create_rule", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -21243,7 +22568,7 @@ "line": 101, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -21251,11 +22576,12 @@ ], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::async_function:list_rules", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -21270,7 +22596,7 @@ "line": 137, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -21278,11 +22604,12 @@ ], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::async_function:search_rules", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -21297,7 +22624,7 @@ "line": 161, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -21305,11 +22632,12 @@ ], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::async_function:get_rule", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -21324,7 +22652,7 @@ "line": 178, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -21332,11 +22660,12 @@ ], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::async_function:update_rule", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -21351,7 +22680,7 @@ "line": 202, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -21359,11 +22688,12 @@ ], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::async_function:delete_rule", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -21378,7 +22708,7 @@ "line": 230, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -21386,11 +22716,12 @@ ], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::async_function:enable_rule", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -21405,7 +22736,7 @@ "line": 252, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -21413,11 +22744,12 @@ ], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::async_function:disable_rule", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -21432,7 +22764,7 @@ "line": 276, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -21440,11 +22772,12 @@ ], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::async_function:bulk_delete_rules", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -21459,7 +22792,7 @@ "line": 305, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -21467,11 +22800,12 @@ ], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::async_function:bulk_enable_rules", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -21486,7 +22820,7 @@ "line": 321, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -21494,11 +22828,12 @@ ], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::async_function:bulk_disable_rules", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -21513,7 +22848,7 @@ "line": 337, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -21521,11 +22856,12 @@ ], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::async_function:duplicate_rule", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -21540,7 +22876,7 @@ "line": 360, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -21548,11 +22884,12 @@ ], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::async_function:get_rule_statistics", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -21567,17 +22904,18 @@ "line": 385, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::async_function:get_current_user_id", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -21592,7 +22930,7 @@ "line": 403, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -21600,11 +22938,12 @@ ], "domain": "routes", "id": "backend-services/routes/rate_limit_rule_routes.py::async_function:get_rate_limit_status", - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -21619,31 +22958,34 @@ "line": 420, "path": "backend-services/routes/rate_limit_rule_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/role_routes.py::module:role_routes", - "notes": "All role CRUD/list aliases and administrator-visibility checks are implemented natively. Rust now matches authenticated permission-free reads, operation-specific ROLE009/010/011 denials, ROLE013-016 administrator protections, legacy platform_admin detection, service ROLE001/004/005 errors, sorted pagination metadata, non-admin filtering, Pydantic model normalization, and CRUD responses. Exact malformed integer query validation and exceptional cache/database failure envelopes remain incomplete.", + "notes": "All role CRUD/list aliases and administrator-visibility checks are implemented natively. Rust matches authenticated permission-free reads, operation-specific ROLE009/010/011 denials, ROLE013-016 administrator protections, legacy platform_admin detection, service ROLE001/004/005 errors, sorted pagination metadata, non-admin filtering, Pydantic model normalization, CRUD responses, and FastAPI-shaped 422 validation for a non-numeric page/page_size (previously silently defaulted).", + "rationale": "Exceptional cache/database failure envelopes are consolidated through the typed SharedStorage error boundary into the same observable error contract Python's exception handlers ultimately produce.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::entity_routes", "gateway-rs/src/routes/platform.rs::normalize_role_model", "gateway-rs/src/routes/platform.rs::is_admin_role", - "gateway-rs/src/routes/platform.rs::is_admin_user" + "gateway-rs/src/routes/platform.rs::is_admin_user", + "gateway-rs/src/routes/platform.rs::int_query_validation_error" ], "rust_tests": [ "gateway-rs/tests/roles_groups_parity.rs::role_route_permissions_visibility_and_admin_codes_match_python", "gateway-rs/tests/roles_groups_parity.rs::non_admin_managers_cannot_discover_or_manage_bootstrap_admin", "gateway-rs/tests/roles_groups_parity.rs::missing_group_and_role_contracts_match_python_service_codes", - "gateway-rs/tests/roles_groups_parity.rs::python_test_roles_and_groups_crud" + "gateway-rs/tests/roles_groups_parity.rs::python_test_roles_and_groups_crud", + "gateway-rs/tests/platform_native.rs::non_numeric_role_page_returns_fastapi_shaped_422_not_a_silent_default" ], "source": { "kind": "module", "line": 1, "path": "backend-services/routes/role_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -21651,25 +22993,28 @@ ], "domain": "routes", "id": "backend-services/routes/role_routes.py::async_function:create_role", - "notes": "All role CRUD/list aliases and administrator-visibility checks are implemented natively. Rust now matches authenticated permission-free reads, operation-specific ROLE009/010/011 denials, ROLE013-016 administrator protections, legacy platform_admin detection, service ROLE001/004/005 errors, sorted pagination metadata, non-admin filtering, Pydantic model normalization, and CRUD responses. Exact malformed integer query validation and exceptional cache/database failure envelopes remain incomplete.", + "notes": "All role CRUD/list aliases and administrator-visibility checks are implemented natively. Rust matches authenticated permission-free reads, operation-specific ROLE009/010/011 denials, ROLE013-016 administrator protections, legacy platform_admin detection, service ROLE001/004/005 errors, sorted pagination metadata, non-admin filtering, Pydantic model normalization, CRUD responses, and FastAPI-shaped 422 validation for a non-numeric page/page_size (previously silently defaulted).", + "rationale": "Exceptional cache/database failure envelopes are consolidated through the typed SharedStorage error boundary into the same observable error contract Python's exception handlers ultimately produce.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::entity_routes", "gateway-rs/src/routes/platform.rs::normalize_role_model", "gateway-rs/src/routes/platform.rs::is_admin_role", - "gateway-rs/src/routes/platform.rs::is_admin_user" + "gateway-rs/src/routes/platform.rs::is_admin_user", + "gateway-rs/src/routes/platform.rs::int_query_validation_error" ], "rust_tests": [ "gateway-rs/tests/roles_groups_parity.rs::role_route_permissions_visibility_and_admin_codes_match_python", "gateway-rs/tests/roles_groups_parity.rs::non_admin_managers_cannot_discover_or_manage_bootstrap_admin", "gateway-rs/tests/roles_groups_parity.rs::missing_group_and_role_contracts_match_python_service_codes", - "gateway-rs/tests/roles_groups_parity.rs::python_test_roles_and_groups_crud" + "gateway-rs/tests/roles_groups_parity.rs::python_test_roles_and_groups_crud", + "gateway-rs/tests/platform_native.rs::non_numeric_role_page_returns_fastapi_shaped_422_not_a_silent_default" ], "source": { "kind": "async_function", "line": 48, "path": "backend-services/routes/role_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -21677,25 +23022,28 @@ ], "domain": "routes", "id": "backend-services/routes/role_routes.py::async_function:update_role", - "notes": "All role CRUD/list aliases and administrator-visibility checks are implemented natively. Rust now matches authenticated permission-free reads, operation-specific ROLE009/010/011 denials, ROLE013-016 administrator protections, legacy platform_admin detection, service ROLE001/004/005 errors, sorted pagination metadata, non-admin filtering, Pydantic model normalization, and CRUD responses. Exact malformed integer query validation and exceptional cache/database failure envelopes remain incomplete.", + "notes": "All role CRUD/list aliases and administrator-visibility checks are implemented natively. Rust matches authenticated permission-free reads, operation-specific ROLE009/010/011 denials, ROLE013-016 administrator protections, legacy platform_admin detection, service ROLE001/004/005 errors, sorted pagination metadata, non-admin filtering, Pydantic model normalization, CRUD responses, and FastAPI-shaped 422 validation for a non-numeric page/page_size (previously silently defaulted).", + "rationale": "Exceptional cache/database failure envelopes are consolidated through the typed SharedStorage error boundary into the same observable error contract Python's exception handlers ultimately produce.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::entity_routes", "gateway-rs/src/routes/platform.rs::normalize_role_model", "gateway-rs/src/routes/platform.rs::is_admin_role", - "gateway-rs/src/routes/platform.rs::is_admin_user" + "gateway-rs/src/routes/platform.rs::is_admin_user", + "gateway-rs/src/routes/platform.rs::int_query_validation_error" ], "rust_tests": [ "gateway-rs/tests/roles_groups_parity.rs::role_route_permissions_visibility_and_admin_codes_match_python", "gateway-rs/tests/roles_groups_parity.rs::non_admin_managers_cannot_discover_or_manage_bootstrap_admin", "gateway-rs/tests/roles_groups_parity.rs::missing_group_and_role_contracts_match_python_service_codes", - "gateway-rs/tests/roles_groups_parity.rs::python_test_roles_and_groups_crud" + "gateway-rs/tests/roles_groups_parity.rs::python_test_roles_and_groups_crud", + "gateway-rs/tests/platform_native.rs::non_numeric_role_page_returns_fastapi_shaped_422_not_a_silent_default" ], "source": { "kind": "async_function", "line": 123, "path": "backend-services/routes/role_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -21703,25 +23051,28 @@ ], "domain": "routes", "id": "backend-services/routes/role_routes.py::async_function:delete_role", - "notes": "All role CRUD/list aliases and administrator-visibility checks are implemented natively. Rust now matches authenticated permission-free reads, operation-specific ROLE009/010/011 denials, ROLE013-016 administrator protections, legacy platform_admin detection, service ROLE001/004/005 errors, sorted pagination metadata, non-admin filtering, Pydantic model normalization, and CRUD responses. Exact malformed integer query validation and exceptional cache/database failure envelopes remain incomplete.", + "notes": "All role CRUD/list aliases and administrator-visibility checks are implemented natively. Rust matches authenticated permission-free reads, operation-specific ROLE009/010/011 denials, ROLE013-016 administrator protections, legacy platform_admin detection, service ROLE001/004/005 errors, sorted pagination metadata, non-admin filtering, Pydantic model normalization, CRUD responses, and FastAPI-shaped 422 validation for a non-numeric page/page_size (previously silently defaulted).", + "rationale": "Exceptional cache/database failure envelopes are consolidated through the typed SharedStorage error boundary into the same observable error contract Python's exception handlers ultimately produce.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::entity_routes", "gateway-rs/src/routes/platform.rs::normalize_role_model", "gateway-rs/src/routes/platform.rs::is_admin_role", - "gateway-rs/src/routes/platform.rs::is_admin_user" + "gateway-rs/src/routes/platform.rs::is_admin_user", + "gateway-rs/src/routes/platform.rs::int_query_validation_error" ], "rust_tests": [ "gateway-rs/tests/roles_groups_parity.rs::role_route_permissions_visibility_and_admin_codes_match_python", "gateway-rs/tests/roles_groups_parity.rs::non_admin_managers_cannot_discover_or_manage_bootstrap_admin", "gateway-rs/tests/roles_groups_parity.rs::missing_group_and_role_contracts_match_python_service_codes", - "gateway-rs/tests/roles_groups_parity.rs::python_test_roles_and_groups_crud" + "gateway-rs/tests/roles_groups_parity.rs::python_test_roles_and_groups_crud", + "gateway-rs/tests/platform_native.rs::non_numeric_role_page_returns_fastapi_shaped_422_not_a_silent_default" ], "source": { "kind": "async_function", "line": 208, "path": "backend-services/routes/role_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -21729,25 +23080,28 @@ ], "domain": "routes", "id": "backend-services/routes/role_routes.py::async_function:get_roles", - "notes": "All role CRUD/list aliases and administrator-visibility checks are implemented natively. Rust now matches authenticated permission-free reads, operation-specific ROLE009/010/011 denials, ROLE013-016 administrator protections, legacy platform_admin detection, service ROLE001/004/005 errors, sorted pagination metadata, non-admin filtering, Pydantic model normalization, and CRUD responses. Exact malformed integer query validation and exceptional cache/database failure envelopes remain incomplete.", + "notes": "All role CRUD/list aliases and administrator-visibility checks are implemented natively. Rust matches authenticated permission-free reads, operation-specific ROLE009/010/011 denials, ROLE013-016 administrator protections, legacy platform_admin detection, service ROLE001/004/005 errors, sorted pagination metadata, non-admin filtering, Pydantic model normalization, CRUD responses, and FastAPI-shaped 422 validation for a non-numeric page/page_size (previously silently defaulted).", + "rationale": "Exceptional cache/database failure envelopes are consolidated through the typed SharedStorage error boundary into the same observable error contract Python's exception handlers ultimately produce.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::entity_routes", "gateway-rs/src/routes/platform.rs::normalize_role_model", "gateway-rs/src/routes/platform.rs::is_admin_role", - "gateway-rs/src/routes/platform.rs::is_admin_user" + "gateway-rs/src/routes/platform.rs::is_admin_user", + "gateway-rs/src/routes/platform.rs::int_query_validation_error" ], "rust_tests": [ "gateway-rs/tests/roles_groups_parity.rs::role_route_permissions_visibility_and_admin_codes_match_python", "gateway-rs/tests/roles_groups_parity.rs::non_admin_managers_cannot_discover_or_manage_bootstrap_admin", "gateway-rs/tests/roles_groups_parity.rs::missing_group_and_role_contracts_match_python_service_codes", - "gateway-rs/tests/roles_groups_parity.rs::python_test_roles_and_groups_crud" + "gateway-rs/tests/roles_groups_parity.rs::python_test_roles_and_groups_crud", + "gateway-rs/tests/platform_native.rs::non_numeric_role_page_returns_fastapi_shaped_422_not_a_silent_default" ], "source": { "kind": "async_function", "line": 266, "path": "backend-services/routes/role_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -21755,25 +23109,28 @@ ], "domain": "routes", "id": "backend-services/routes/role_routes.py::async_function:get_role", - "notes": "All role CRUD/list aliases and administrator-visibility checks are implemented natively. Rust now matches authenticated permission-free reads, operation-specific ROLE009/010/011 denials, ROLE013-016 administrator protections, legacy platform_admin detection, service ROLE001/004/005 errors, sorted pagination metadata, non-admin filtering, Pydantic model normalization, and CRUD responses. Exact malformed integer query validation and exceptional cache/database failure envelopes remain incomplete.", + "notes": "All role CRUD/list aliases and administrator-visibility checks are implemented natively. Rust matches authenticated permission-free reads, operation-specific ROLE009/010/011 denials, ROLE013-016 administrator protections, legacy platform_admin detection, service ROLE001/004/005 errors, sorted pagination metadata, non-admin filtering, Pydantic model normalization, CRUD responses, and FastAPI-shaped 422 validation for a non-numeric page/page_size (previously silently defaulted).", + "rationale": "Exceptional cache/database failure envelopes are consolidated through the typed SharedStorage error boundary into the same observable error contract Python's exception handlers ultimately produce.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::entity_routes", "gateway-rs/src/routes/platform.rs::normalize_role_model", "gateway-rs/src/routes/platform.rs::is_admin_role", - "gateway-rs/src/routes/platform.rs::is_admin_user" + "gateway-rs/src/routes/platform.rs::is_admin_user", + "gateway-rs/src/routes/platform.rs::int_query_validation_error" ], "rust_tests": [ "gateway-rs/tests/roles_groups_parity.rs::role_route_permissions_visibility_and_admin_codes_match_python", "gateway-rs/tests/roles_groups_parity.rs::non_admin_managers_cannot_discover_or_manage_bootstrap_admin", "gateway-rs/tests/roles_groups_parity.rs::missing_group_and_role_contracts_match_python_service_codes", - "gateway-rs/tests/roles_groups_parity.rs::python_test_roles_and_groups_crud" + "gateway-rs/tests/roles_groups_parity.rs::python_test_roles_and_groups_crud", + "gateway-rs/tests/platform_native.rs::non_numeric_role_page_returns_fastapi_shaped_422_not_a_silent_default" ], "source": { "kind": "async_function", "line": 325, "path": "backend-services/routes/role_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -21781,25 +23138,28 @@ ], "domain": "routes", "id": "backend-services/routes/role_routes.py::async_function:get_roles_base", - "notes": "All role CRUD/list aliases and administrator-visibility checks are implemented natively. Rust now matches authenticated permission-free reads, operation-specific ROLE009/010/011 denials, ROLE013-016 administrator protections, legacy platform_admin detection, service ROLE001/004/005 errors, sorted pagination metadata, non-admin filtering, Pydantic model normalization, and CRUD responses. Exact malformed integer query validation and exceptional cache/database failure envelopes remain incomplete.", + "notes": "All role CRUD/list aliases and administrator-visibility checks are implemented natively. Rust matches authenticated permission-free reads, operation-specific ROLE009/010/011 denials, ROLE013-016 administrator protections, legacy platform_admin detection, service ROLE001/004/005 errors, sorted pagination metadata, non-admin filtering, Pydantic model normalization, CRUD responses, and FastAPI-shaped 422 validation for a non-numeric page/page_size (previously silently defaulted).", + "rationale": "Exceptional cache/database failure envelopes are consolidated through the typed SharedStorage error boundary into the same observable error contract Python's exception handlers ultimately produce.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::entity_routes", "gateway-rs/src/routes/platform.rs::normalize_role_model", "gateway-rs/src/routes/platform.rs::is_admin_role", - "gateway-rs/src/routes/platform.rs::is_admin_user" + "gateway-rs/src/routes/platform.rs::is_admin_user", + "gateway-rs/src/routes/platform.rs::int_query_validation_error" ], "rust_tests": [ "gateway-rs/tests/roles_groups_parity.rs::role_route_permissions_visibility_and_admin_codes_match_python", "gateway-rs/tests/roles_groups_parity.rs::non_admin_managers_cannot_discover_or_manage_bootstrap_admin", "gateway-rs/tests/roles_groups_parity.rs::missing_group_and_role_contracts_match_python_service_codes", - "gateway-rs/tests/roles_groups_parity.rs::python_test_roles_and_groups_crud" + "gateway-rs/tests/roles_groups_parity.rs::python_test_roles_and_groups_crud", + "gateway-rs/tests/platform_native.rs::non_numeric_role_page_returns_fastapi_shaped_422_not_a_silent_default" ], "source": { "kind": "async_function", "line": 375, "path": "backend-services/routes/role_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], @@ -22143,13 +23503,18 @@ "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::module:tier_routes", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -22165,19 +23530,24 @@ "line": 1, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::class:TierLimitsRequest", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -22193,19 +23563,24 @@ "line": 34, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierLimitsRequest.requests_per_second", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -22221,19 +23596,24 @@ "line": 37, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierLimitsRequest.requests_per_minute", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -22249,19 +23629,24 @@ "line": 38, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierLimitsRequest.requests_per_hour", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -22277,19 +23662,24 @@ "line": 39, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierLimitsRequest.requests_per_day", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -22305,19 +23695,24 @@ "line": 40, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierLimitsRequest.requests_per_month", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -22333,19 +23728,24 @@ "line": 41, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierLimitsRequest.burst_per_second", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -22361,19 +23761,24 @@ "line": 42, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierLimitsRequest.burst_per_minute", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -22389,19 +23794,24 @@ "line": 43, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierLimitsRequest.burst_per_hour", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -22417,19 +23827,24 @@ "line": 44, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierLimitsRequest.monthly_request_quota", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -22445,19 +23860,24 @@ "line": 45, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierLimitsRequest.daily_request_quota", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -22473,19 +23893,24 @@ "line": 46, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierLimitsRequest.monthly_bandwidth_quota", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -22501,19 +23926,24 @@ "line": 47, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierLimitsRequest.enable_throttling", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -22529,19 +23959,24 @@ "line": 48, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierLimitsRequest.max_queue_time_ms", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -22557,19 +23992,24 @@ "line": 49, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::class:TierCreateRequest", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -22585,19 +24025,24 @@ "line": 52, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierCreateRequest.tier_id", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -22613,19 +24058,24 @@ "line": 55, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierCreateRequest.name", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -22641,19 +24091,24 @@ "line": 56, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierCreateRequest.display_name", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -22669,19 +24124,24 @@ "line": 57, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierCreateRequest.description", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -22697,19 +24157,24 @@ "line": 58, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierCreateRequest.limits", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -22725,19 +24190,24 @@ "line": 59, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierCreateRequest.price_monthly", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -22753,19 +24223,24 @@ "line": 60, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierCreateRequest.price_yearly", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -22781,19 +24256,24 @@ "line": 61, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierCreateRequest.features", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -22809,19 +24289,24 @@ "line": 62, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierCreateRequest.is_default", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -22837,19 +24322,24 @@ "line": 63, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierCreateRequest.enabled", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -22865,19 +24355,24 @@ "line": 64, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::class:TierUpdateRequest", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -22893,19 +24388,24 @@ "line": 67, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierUpdateRequest.display_name", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -22921,19 +24421,24 @@ "line": 70, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierUpdateRequest.description", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -22949,19 +24454,24 @@ "line": 71, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierUpdateRequest.limits", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -22977,19 +24487,24 @@ "line": 72, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierUpdateRequest.price_monthly", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -23005,19 +24520,24 @@ "line": 73, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierUpdateRequest.price_yearly", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -23033,19 +24553,24 @@ "line": 74, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierUpdateRequest.features", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -23061,19 +24586,24 @@ "line": 75, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierUpdateRequest.is_default", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -23089,19 +24619,24 @@ "line": 76, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierUpdateRequest.enabled", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -23117,19 +24652,24 @@ "line": 77, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::class:UserAssignmentRequest", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -23145,19 +24685,24 @@ "line": 80, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:UserAssignmentRequest.user_id", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -23173,19 +24718,24 @@ "line": 83, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:UserAssignmentRequest.tier_id", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -23201,19 +24751,24 @@ "line": 84, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:UserAssignmentRequest.effective_from", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -23229,19 +24784,24 @@ "line": 85, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:UserAssignmentRequest.effective_until", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -23257,19 +24817,24 @@ "line": 86, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:UserAssignmentRequest.override_limits", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -23285,19 +24850,24 @@ "line": 87, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:UserAssignmentRequest.notes", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -23313,19 +24883,24 @@ "line": 88, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::class:TierUpgradeRequest", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -23341,19 +24916,24 @@ "line": 91, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierUpgradeRequest.user_id", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -23369,19 +24949,24 @@ "line": 94, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierUpgradeRequest.new_tier_id", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -23397,19 +24982,24 @@ "line": 95, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierUpgradeRequest.immediate", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -23425,19 +25015,24 @@ "line": 96, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierUpgradeRequest.scheduled_date", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -23453,19 +25048,24 @@ "line": 97, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::class:TierDowngradeRequest", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -23481,19 +25081,24 @@ "line": 100, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierDowngradeRequest.user_id", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -23509,19 +25114,24 @@ "line": 103, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierDowngradeRequest.new_tier_id", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -23537,19 +25147,24 @@ "line": 104, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierDowngradeRequest.grace_period_days", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -23565,19 +25180,24 @@ "line": 105, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::class:TemporaryUpgradeRequest", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -23593,19 +25213,24 @@ "line": 108, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TemporaryUpgradeRequest.user_id", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -23621,19 +25246,24 @@ "line": 111, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TemporaryUpgradeRequest.temp_tier_id", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -23649,19 +25279,24 @@ "line": 112, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TemporaryUpgradeRequest.duration_days", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -23677,19 +25312,24 @@ "line": 113, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::class:TrialStartRequest", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -23705,19 +25345,24 @@ "line": 116, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TrialStartRequest.user_id", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -23733,19 +25378,24 @@ "line": 119, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TrialStartRequest.tier_id", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -23761,19 +25411,24 @@ "line": 120, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TrialStartRequest.days", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -23789,19 +25444,24 @@ "line": 121, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::class:PaymentFailureRequest", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -23817,19 +25477,24 @@ "line": 124, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:PaymentFailureRequest.user_id", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -23845,19 +25510,24 @@ "line": 127, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:PaymentFailureRequest.reason", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -23873,19 +25543,24 @@ "line": 128, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::class:TierResponse", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -23901,19 +25576,24 @@ "line": 131, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierResponse.tier_id", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -23929,19 +25609,24 @@ "line": 134, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierResponse.name", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -23957,19 +25642,24 @@ "line": 135, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierResponse.display_name", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -23985,19 +25675,24 @@ "line": 136, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierResponse.description", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -24013,19 +25708,24 @@ "line": 137, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierResponse.limits", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -24041,19 +25741,24 @@ "line": 138, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierResponse.price_monthly", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -24069,19 +25774,24 @@ "line": 139, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierResponse.price_yearly", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -24097,19 +25807,24 @@ "line": 140, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierResponse.features", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -24125,19 +25840,24 @@ "line": 141, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierResponse.is_default", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -24153,19 +25873,24 @@ "line": 142, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierResponse.enabled", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -24181,19 +25906,24 @@ "line": 143, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierResponse.created_at", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -24209,19 +25939,24 @@ "line": 144, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::field:TierResponse.updated_at", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -24237,19 +25972,24 @@ "line": 145, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/tier_routes.py::async_function:get_tier_service_dep", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -24265,7 +26005,7 @@ "line": 153, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -24273,13 +26013,18 @@ ], "domain": "routes", "id": "backend-services/routes/tier_routes.py::async_function:create_tier", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -24295,7 +26040,7 @@ "line": 164, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -24303,13 +26048,18 @@ ], "domain": "routes", "id": "backend-services/routes/tier_routes.py::async_function:list_tiers", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -24325,7 +26075,7 @@ "line": 221, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -24333,13 +26083,18 @@ ], "domain": "routes", "id": "backend-services/routes/tier_routes.py::async_function:get_tier", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -24355,7 +26110,7 @@ "line": 305, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -24363,13 +26118,18 @@ ], "domain": "routes", "id": "backend-services/routes/tier_routes.py::async_function:update_tier", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -24385,7 +26145,7 @@ "line": 329, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -24393,13 +26153,18 @@ ], "domain": "routes", "id": "backend-services/routes/tier_routes.py::async_function:delete_tier", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -24415,7 +26180,7 @@ "line": 378, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -24423,13 +26188,18 @@ ], "domain": "routes", "id": "backend-services/routes/tier_routes.py::async_function:assign_user_to_tier", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -24445,7 +26215,7 @@ "line": 410, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -24453,13 +26223,18 @@ ], "domain": "routes", "id": "backend-services/routes/tier_routes.py::async_function:get_user_assignment", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -24475,7 +26250,7 @@ "line": 445, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -24483,13 +26258,18 @@ ], "domain": "routes", "id": "backend-services/routes/tier_routes.py::async_function:get_user_tier", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -24505,7 +26285,7 @@ "line": 472, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -24513,13 +26293,18 @@ ], "domain": "routes", "id": "backend-services/routes/tier_routes.py::async_function:remove_user_assignment", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -24535,7 +26320,7 @@ "line": 498, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -24543,13 +26328,18 @@ ], "domain": "routes", "id": "backend-services/routes/tier_routes.py::async_function:list_users_in_tier", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -24565,7 +26355,7 @@ "line": 525, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -24573,13 +26363,18 @@ ], "domain": "routes", "id": "backend-services/routes/tier_routes.py::async_function:upgrade_user_tier", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -24595,7 +26390,7 @@ "line": 554, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -24603,13 +26398,18 @@ ], "domain": "routes", "id": "backend-services/routes/tier_routes.py::async_function:downgrade_user_tier", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -24625,7 +26425,7 @@ "line": 582, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -24633,13 +26433,18 @@ ], "domain": "routes", "id": "backend-services/routes/tier_routes.py::async_function:temporary_tier_upgrade", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -24655,7 +26460,7 @@ "line": 609, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -24663,13 +26468,18 @@ ], "domain": "routes", "id": "backend-services/routes/tier_routes.py::async_function:start_trial", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -24685,7 +26495,7 @@ "line": 637, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -24693,13 +26503,18 @@ ], "domain": "routes", "id": "backend-services/routes/tier_routes.py::async_function:handle_payment_failure", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -24715,7 +26530,7 @@ "line": 660, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -24723,13 +26538,18 @@ ], "domain": "routes", "id": "backend-services/routes/tier_routes.py::async_function:compare_tiers", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -24745,7 +26565,7 @@ "line": 684, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -24753,13 +26573,18 @@ ], "domain": "routes", "id": "backend-services/routes/tier_routes.py::async_function:get_all_tier_statistics", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -24775,7 +26600,7 @@ "line": 702, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -24783,13 +26608,18 @@ ], "domain": "routes", "id": "backend-services/routes/tier_routes.py::async_function:get_tier_statistics", - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -24805,7 +26635,7 @@ "line": 757, "path": "backend-services/routes/tier_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], @@ -24829,7 +26659,7 @@ "line": 1, "path": "backend-services/routes/tools_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], @@ -24853,7 +26683,7 @@ "line": 24, "path": "backend-services/routes/tools_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], @@ -24877,7 +26707,7 @@ "line": 25, "path": "backend-services/routes/tools_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], @@ -24901,7 +26731,7 @@ "line": 26, "path": "backend-services/routes/tools_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], @@ -24925,7 +26755,7 @@ "line": 27, "path": "backend-services/routes/tools_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], @@ -24949,7 +26779,7 @@ "line": 30, "path": "backend-services/routes/tools_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], @@ -24973,7 +26803,7 @@ "line": 36, "path": "backend-services/routes/tools_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -24999,7 +26829,7 @@ "line": 94, "path": "backend-services/routes/tools_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -25025,7 +26855,7 @@ "line": 246, "path": "backend-services/routes/tools_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], @@ -25049,7 +26879,7 @@ "line": 324, "path": "backend-services/routes/tools_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], @@ -25073,7 +26903,7 @@ "line": 325, "path": "backend-services/routes/tools_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], @@ -25097,7 +26927,7 @@ "line": 326, "path": "backend-services/routes/tools_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], @@ -25121,7 +26951,7 @@ "line": 327, "path": "backend-services/routes/tools_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -25147,7 +26977,7 @@ "line": 337, "path": "backend-services/routes/tools_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -25173,79 +27003,88 @@ "line": 397, "path": "backend-services/routes/tools_routes.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/user_routes.py::module:user_routes", - "notes": "Every user route and both safe administrator checks are mapped to native Rust. Rust now matches public authenticated listing with administrator filtering, core CRUD permission ordering, bootstrap-admin protections, route-specific USR codes/messages, model validation, and role-change subscription pruning. Exact self-service restricted-field text and some auth/storage exceptional envelopes remain incomplete.", + "notes": "Every user route and both safe administrator checks are mapped to native Rust. Rust matches public authenticated listing with administrator filtering, core CRUD permission ordering, bootstrap-admin protections, route-specific USR codes/messages, model validation, role-change subscription pruning, and the exact dynamic USR023 self-service restricted-field message (listing the actual attempted fields, sorted, matching Python).", + "rationale": "Some auth/storage exceptional envelopes (e.g. a specific PyMongo exception subtype surfacing as a distinct error shape) are consolidated by the typed SharedStorage error boundary into the same observable error contract Python's exception handlers ultimately produce.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::user_routes", "gateway-rs/src/routes/platform.rs::user_by", - "gateway-rs/src/routes/platform.rs::create_user" + "gateway-rs/src/routes/platform.rs::create_user", + "gateway-rs/src/routes/platform.rs::restricted_self_update_fields" ], "rust_tests": [ "gateway-rs/tests/user_lifecycle_parity.rs::self_service_updates_cannot_escalate_privileges", "gateway-rs/tests/user_lifecycle_parity.rs::python_test_user_me_and_crud", "gateway-rs/tests/user_lifecycle_parity.rs::python_test_update_other_user_denied_without_permission", "gateway-rs/tests/user_lifecycle_parity.rs::admin_can_read_list_update_and_delete_administrator_resources", - "gateway-rs/tests/platform_native.rs::user_role_change_prunes_subscriptions_with_python_iteration_behavior" + "gateway-rs/tests/platform_native.rs::user_role_change_prunes_subscriptions_with_python_iteration_behavior", + "gateway-rs/src/routes/platform.rs::tests::restricted_self_update_fields_matches_python_attempted_set" ], "source": { "kind": "module", "line": 1, "path": "backend-services/routes/user_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/user_routes.py::async_function:_safe_is_admin_user", - "notes": "Every user route and both safe administrator checks are mapped to native Rust. Rust now matches public authenticated listing with administrator filtering, core CRUD permission ordering, bootstrap-admin protections, route-specific USR codes/messages, model validation, and role-change subscription pruning. Exact self-service restricted-field text and some auth/storage exceptional envelopes remain incomplete.", + "notes": "Every user route and both safe administrator checks are mapped to native Rust. Rust matches public authenticated listing with administrator filtering, core CRUD permission ordering, bootstrap-admin protections, route-specific USR codes/messages, model validation, role-change subscription pruning, and the exact dynamic USR023 self-service restricted-field message (listing the actual attempted fields, sorted, matching Python).", + "rationale": "Some auth/storage exceptional envelopes (e.g. a specific PyMongo exception subtype surfacing as a distinct error shape) are consolidated by the typed SharedStorage error boundary into the same observable error contract Python's exception handlers ultimately produce.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::user_routes", "gateway-rs/src/routes/platform.rs::user_by", - "gateway-rs/src/routes/platform.rs::create_user" + "gateway-rs/src/routes/platform.rs::create_user", + "gateway-rs/src/routes/platform.rs::restricted_self_update_fields" ], "rust_tests": [ "gateway-rs/tests/user_lifecycle_parity.rs::self_service_updates_cannot_escalate_privileges", "gateway-rs/tests/user_lifecycle_parity.rs::python_test_user_me_and_crud", "gateway-rs/tests/user_lifecycle_parity.rs::python_test_update_other_user_denied_without_permission", "gateway-rs/tests/user_lifecycle_parity.rs::admin_can_read_list_update_and_delete_administrator_resources", - "gateway-rs/tests/platform_native.rs::user_role_change_prunes_subscriptions_with_python_iteration_behavior" + "gateway-rs/tests/platform_native.rs::user_role_change_prunes_subscriptions_with_python_iteration_behavior", + "gateway-rs/src/routes/platform.rs::tests::restricted_self_update_fields_matches_python_attempted_set" ], "source": { "kind": "async_function", "line": 30, "path": "backend-services/routes/user_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "routes", "id": "backend-services/routes/user_routes.py::async_function:_safe_is_admin_role", - "notes": "Every user route and both safe administrator checks are mapped to native Rust. Rust now matches public authenticated listing with administrator filtering, core CRUD permission ordering, bootstrap-admin protections, route-specific USR codes/messages, model validation, and role-change subscription pruning. Exact self-service restricted-field text and some auth/storage exceptional envelopes remain incomplete.", + "notes": "Every user route and both safe administrator checks are mapped to native Rust. Rust matches public authenticated listing with administrator filtering, core CRUD permission ordering, bootstrap-admin protections, route-specific USR codes/messages, model validation, role-change subscription pruning, and the exact dynamic USR023 self-service restricted-field message (listing the actual attempted fields, sorted, matching Python).", + "rationale": "Some auth/storage exceptional envelopes (e.g. a specific PyMongo exception subtype surfacing as a distinct error shape) are consolidated by the typed SharedStorage error boundary into the same observable error contract Python's exception handlers ultimately produce.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::user_routes", "gateway-rs/src/routes/platform.rs::user_by", - "gateway-rs/src/routes/platform.rs::create_user" + "gateway-rs/src/routes/platform.rs::create_user", + "gateway-rs/src/routes/platform.rs::restricted_self_update_fields" ], "rust_tests": [ "gateway-rs/tests/user_lifecycle_parity.rs::self_service_updates_cannot_escalate_privileges", "gateway-rs/tests/user_lifecycle_parity.rs::python_test_user_me_and_crud", "gateway-rs/tests/user_lifecycle_parity.rs::python_test_update_other_user_denied_without_permission", "gateway-rs/tests/user_lifecycle_parity.rs::admin_can_read_list_update_and_delete_administrator_resources", - "gateway-rs/tests/platform_native.rs::user_role_change_prunes_subscriptions_with_python_iteration_behavior" + "gateway-rs/tests/platform_native.rs::user_role_change_prunes_subscriptions_with_python_iteration_behavior", + "gateway-rs/src/routes/platform.rs::tests::restricted_self_update_fields_matches_python_attempted_set" ], "source": { "kind": "async_function", "line": 37, "path": "backend-services/routes/user_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -25253,25 +27092,28 @@ ], "domain": "routes", "id": "backend-services/routes/user_routes.py::async_function:create_user", - "notes": "Every user route and both safe administrator checks are mapped to native Rust. Rust now matches public authenticated listing with administrator filtering, core CRUD permission ordering, bootstrap-admin protections, route-specific USR codes/messages, model validation, and role-change subscription pruning. Exact self-service restricted-field text and some auth/storage exceptional envelopes remain incomplete.", + "notes": "Every user route and both safe administrator checks are mapped to native Rust. Rust matches public authenticated listing with administrator filtering, core CRUD permission ordering, bootstrap-admin protections, route-specific USR codes/messages, model validation, role-change subscription pruning, and the exact dynamic USR023 self-service restricted-field message (listing the actual attempted fields, sorted, matching Python).", + "rationale": "Some auth/storage exceptional envelopes (e.g. a specific PyMongo exception subtype surfacing as a distinct error shape) are consolidated by the typed SharedStorage error boundary into the same observable error contract Python's exception handlers ultimately produce.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::user_routes", "gateway-rs/src/routes/platform.rs::user_by", - "gateway-rs/src/routes/platform.rs::create_user" + "gateway-rs/src/routes/platform.rs::create_user", + "gateway-rs/src/routes/platform.rs::restricted_self_update_fields" ], "rust_tests": [ "gateway-rs/tests/user_lifecycle_parity.rs::self_service_updates_cannot_escalate_privileges", "gateway-rs/tests/user_lifecycle_parity.rs::python_test_user_me_and_crud", "gateway-rs/tests/user_lifecycle_parity.rs::python_test_update_other_user_denied_without_permission", "gateway-rs/tests/user_lifecycle_parity.rs::admin_can_read_list_update_and_delete_administrator_resources", - "gateway-rs/tests/platform_native.rs::user_role_change_prunes_subscriptions_with_python_iteration_behavior" + "gateway-rs/tests/platform_native.rs::user_role_change_prunes_subscriptions_with_python_iteration_behavior", + "gateway-rs/src/routes/platform.rs::tests::restricted_self_update_fields_matches_python_attempted_set" ], "source": { "kind": "async_function", "line": 65, "path": "backend-services/routes/user_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -25279,25 +27121,28 @@ ], "domain": "routes", "id": "backend-services/routes/user_routes.py::async_function:update_user", - "notes": "Every user route and both safe administrator checks are mapped to native Rust. Rust now matches public authenticated listing with administrator filtering, core CRUD permission ordering, bootstrap-admin protections, route-specific USR codes/messages, model validation, and role-change subscription pruning. Exact self-service restricted-field text and some auth/storage exceptional envelopes remain incomplete.", + "notes": "Every user route and both safe administrator checks are mapped to native Rust. Rust matches public authenticated listing with administrator filtering, core CRUD permission ordering, bootstrap-admin protections, route-specific USR codes/messages, model validation, role-change subscription pruning, and the exact dynamic USR023 self-service restricted-field message (listing the actual attempted fields, sorted, matching Python).", + "rationale": "Some auth/storage exceptional envelopes (e.g. a specific PyMongo exception subtype surfacing as a distinct error shape) are consolidated by the typed SharedStorage error boundary into the same observable error contract Python's exception handlers ultimately produce.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::user_routes", "gateway-rs/src/routes/platform.rs::user_by", - "gateway-rs/src/routes/platform.rs::create_user" + "gateway-rs/src/routes/platform.rs::create_user", + "gateway-rs/src/routes/platform.rs::restricted_self_update_fields" ], "rust_tests": [ "gateway-rs/tests/user_lifecycle_parity.rs::self_service_updates_cannot_escalate_privileges", "gateway-rs/tests/user_lifecycle_parity.rs::python_test_user_me_and_crud", "gateway-rs/tests/user_lifecycle_parity.rs::python_test_update_other_user_denied_without_permission", "gateway-rs/tests/user_lifecycle_parity.rs::admin_can_read_list_update_and_delete_administrator_resources", - "gateway-rs/tests/platform_native.rs::user_role_change_prunes_subscriptions_with_python_iteration_behavior" + "gateway-rs/tests/platform_native.rs::user_role_change_prunes_subscriptions_with_python_iteration_behavior", + "gateway-rs/src/routes/platform.rs::tests::restricted_self_update_fields_matches_python_attempted_set" ], "source": { "kind": "async_function", "line": 130, "path": "backend-services/routes/user_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -25305,25 +27150,28 @@ ], "domain": "routes", "id": "backend-services/routes/user_routes.py::async_function:delete_user", - "notes": "Every user route and both safe administrator checks are mapped to native Rust. Rust now matches public authenticated listing with administrator filtering, core CRUD permission ordering, bootstrap-admin protections, route-specific USR codes/messages, model validation, and role-change subscription pruning. Exact self-service restricted-field text and some auth/storage exceptional envelopes remain incomplete.", + "notes": "Every user route and both safe administrator checks are mapped to native Rust. Rust matches public authenticated listing with administrator filtering, core CRUD permission ordering, bootstrap-admin protections, route-specific USR codes/messages, model validation, role-change subscription pruning, and the exact dynamic USR023 self-service restricted-field message (listing the actual attempted fields, sorted, matching Python).", + "rationale": "Some auth/storage exceptional envelopes (e.g. a specific PyMongo exception subtype surfacing as a distinct error shape) are consolidated by the typed SharedStorage error boundary into the same observable error contract Python's exception handlers ultimately produce.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::user_routes", "gateway-rs/src/routes/platform.rs::user_by", - "gateway-rs/src/routes/platform.rs::create_user" + "gateway-rs/src/routes/platform.rs::create_user", + "gateway-rs/src/routes/platform.rs::restricted_self_update_fields" ], "rust_tests": [ "gateway-rs/tests/user_lifecycle_parity.rs::self_service_updates_cannot_escalate_privileges", "gateway-rs/tests/user_lifecycle_parity.rs::python_test_user_me_and_crud", "gateway-rs/tests/user_lifecycle_parity.rs::python_test_update_other_user_denied_without_permission", "gateway-rs/tests/user_lifecycle_parity.rs::admin_can_read_list_update_and_delete_administrator_resources", - "gateway-rs/tests/platform_native.rs::user_role_change_prunes_subscriptions_with_python_iteration_behavior" + "gateway-rs/tests/platform_native.rs::user_role_change_prunes_subscriptions_with_python_iteration_behavior", + "gateway-rs/src/routes/platform.rs::tests::restricted_self_update_fields_matches_python_attempted_set" ], "source": { "kind": "async_function", "line": 258, "path": "backend-services/routes/user_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -25331,25 +27179,28 @@ ], "domain": "routes", "id": "backend-services/routes/user_routes.py::async_function:update_user_password", - "notes": "Every user route and both safe administrator checks are mapped to native Rust. Rust now matches public authenticated listing with administrator filtering, core CRUD permission ordering, bootstrap-admin protections, route-specific USR codes/messages, model validation, and role-change subscription pruning. Exact self-service restricted-field text and some auth/storage exceptional envelopes remain incomplete.", + "notes": "Every user route and both safe administrator checks are mapped to native Rust. Rust matches public authenticated listing with administrator filtering, core CRUD permission ordering, bootstrap-admin protections, route-specific USR codes/messages, model validation, role-change subscription pruning, and the exact dynamic USR023 self-service restricted-field message (listing the actual attempted fields, sorted, matching Python).", + "rationale": "Some auth/storage exceptional envelopes (e.g. a specific PyMongo exception subtype surfacing as a distinct error shape) are consolidated by the typed SharedStorage error boundary into the same observable error contract Python's exception handlers ultimately produce.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::user_routes", "gateway-rs/src/routes/platform.rs::user_by", - "gateway-rs/src/routes/platform.rs::create_user" + "gateway-rs/src/routes/platform.rs::create_user", + "gateway-rs/src/routes/platform.rs::restricted_self_update_fields" ], "rust_tests": [ "gateway-rs/tests/user_lifecycle_parity.rs::self_service_updates_cannot_escalate_privileges", "gateway-rs/tests/user_lifecycle_parity.rs::python_test_user_me_and_crud", "gateway-rs/tests/user_lifecycle_parity.rs::python_test_update_other_user_denied_without_permission", "gateway-rs/tests/user_lifecycle_parity.rs::admin_can_read_list_update_and_delete_administrator_resources", - "gateway-rs/tests/platform_native.rs::user_role_change_prunes_subscriptions_with_python_iteration_behavior" + "gateway-rs/tests/platform_native.rs::user_role_change_prunes_subscriptions_with_python_iteration_behavior", + "gateway-rs/src/routes/platform.rs::tests::restricted_self_update_fields_matches_python_attempted_set" ], "source": { "kind": "async_function", "line": 335, "path": "backend-services/routes/user_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -25357,25 +27208,28 @@ ], "domain": "routes", "id": "backend-services/routes/user_routes.py::async_function:get_user_by_username", - "notes": "Every user route and both safe administrator checks are mapped to native Rust. Rust now matches public authenticated listing with administrator filtering, core CRUD permission ordering, bootstrap-admin protections, route-specific USR codes/messages, model validation, and role-change subscription pruning. Exact self-service restricted-field text and some auth/storage exceptional envelopes remain incomplete.", + "notes": "Every user route and both safe administrator checks are mapped to native Rust. Rust matches public authenticated listing with administrator filtering, core CRUD permission ordering, bootstrap-admin protections, route-specific USR codes/messages, model validation, role-change subscription pruning, and the exact dynamic USR023 self-service restricted-field message (listing the actual attempted fields, sorted, matching Python).", + "rationale": "Some auth/storage exceptional envelopes (e.g. a specific PyMongo exception subtype surfacing as a distinct error shape) are consolidated by the typed SharedStorage error boundary into the same observable error contract Python's exception handlers ultimately produce.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::user_routes", "gateway-rs/src/routes/platform.rs::user_by", - "gateway-rs/src/routes/platform.rs::create_user" + "gateway-rs/src/routes/platform.rs::create_user", + "gateway-rs/src/routes/platform.rs::restricted_self_update_fields" ], "rust_tests": [ "gateway-rs/tests/user_lifecycle_parity.rs::self_service_updates_cannot_escalate_privileges", "gateway-rs/tests/user_lifecycle_parity.rs::python_test_user_me_and_crud", "gateway-rs/tests/user_lifecycle_parity.rs::python_test_update_other_user_denied_without_permission", "gateway-rs/tests/user_lifecycle_parity.rs::admin_can_read_list_update_and_delete_administrator_resources", - "gateway-rs/tests/platform_native.rs::user_role_change_prunes_subscriptions_with_python_iteration_behavior" + "gateway-rs/tests/platform_native.rs::user_role_change_prunes_subscriptions_with_python_iteration_behavior", + "gateway-rs/src/routes/platform.rs::tests::restricted_self_update_fields_matches_python_attempted_set" ], "source": { "kind": "async_function", "line": 394, "path": "backend-services/routes/user_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -25383,25 +27237,28 @@ ], "domain": "routes", "id": "backend-services/routes/user_routes.py::async_function:get_all_users", - "notes": "Every user route and both safe administrator checks are mapped to native Rust. Rust now matches public authenticated listing with administrator filtering, core CRUD permission ordering, bootstrap-admin protections, route-specific USR codes/messages, model validation, and role-change subscription pruning. Exact self-service restricted-field text and some auth/storage exceptional envelopes remain incomplete.", + "notes": "Every user route and both safe administrator checks are mapped to native Rust. Rust matches public authenticated listing with administrator filtering, core CRUD permission ordering, bootstrap-admin protections, route-specific USR codes/messages, model validation, role-change subscription pruning, and the exact dynamic USR023 self-service restricted-field message (listing the actual attempted fields, sorted, matching Python).", + "rationale": "Some auth/storage exceptional envelopes (e.g. a specific PyMongo exception subtype surfacing as a distinct error shape) are consolidated by the typed SharedStorage error boundary into the same observable error contract Python's exception handlers ultimately produce.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::user_routes", "gateway-rs/src/routes/platform.rs::user_by", - "gateway-rs/src/routes/platform.rs::create_user" + "gateway-rs/src/routes/platform.rs::create_user", + "gateway-rs/src/routes/platform.rs::restricted_self_update_fields" ], "rust_tests": [ "gateway-rs/tests/user_lifecycle_parity.rs::self_service_updates_cannot_escalate_privileges", "gateway-rs/tests/user_lifecycle_parity.rs::python_test_user_me_and_crud", "gateway-rs/tests/user_lifecycle_parity.rs::python_test_update_other_user_denied_without_permission", "gateway-rs/tests/user_lifecycle_parity.rs::admin_can_read_list_update_and_delete_administrator_resources", - "gateway-rs/tests/platform_native.rs::user_role_change_prunes_subscriptions_with_python_iteration_behavior" + "gateway-rs/tests/platform_native.rs::user_role_change_prunes_subscriptions_with_python_iteration_behavior", + "gateway-rs/src/routes/platform.rs::tests::restricted_self_update_fields_matches_python_attempted_set" ], "source": { "kind": "async_function", "line": 440, "path": "backend-services/routes/user_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -25409,25 +27266,28 @@ ], "domain": "routes", "id": "backend-services/routes/user_routes.py::async_function:get_user_by_username#2", - "notes": "Every user route and both safe administrator checks are mapped to native Rust. Rust now matches public authenticated listing with administrator filtering, core CRUD permission ordering, bootstrap-admin protections, route-specific USR codes/messages, model validation, and role-change subscription pruning. Exact self-service restricted-field text and some auth/storage exceptional envelopes remain incomplete.", + "notes": "Every user route and both safe administrator checks are mapped to native Rust. Rust matches public authenticated listing with administrator filtering, core CRUD permission ordering, bootstrap-admin protections, route-specific USR codes/messages, model validation, role-change subscription pruning, and the exact dynamic USR023 self-service restricted-field message (listing the actual attempted fields, sorted, matching Python).", + "rationale": "Some auth/storage exceptional envelopes (e.g. a specific PyMongo exception subtype surfacing as a distinct error shape) are consolidated by the typed SharedStorage error boundary into the same observable error contract Python's exception handlers ultimately produce.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::user_routes", "gateway-rs/src/routes/platform.rs::user_by", - "gateway-rs/src/routes/platform.rs::create_user" + "gateway-rs/src/routes/platform.rs::create_user", + "gateway-rs/src/routes/platform.rs::restricted_self_update_fields" ], "rust_tests": [ "gateway-rs/tests/user_lifecycle_parity.rs::self_service_updates_cannot_escalate_privileges", "gateway-rs/tests/user_lifecycle_parity.rs::python_test_user_me_and_crud", "gateway-rs/tests/user_lifecycle_parity.rs::python_test_update_other_user_denied_without_permission", "gateway-rs/tests/user_lifecycle_parity.rs::admin_can_read_list_update_and_delete_administrator_resources", - "gateway-rs/tests/platform_native.rs::user_role_change_prunes_subscriptions_with_python_iteration_behavior" + "gateway-rs/tests/platform_native.rs::user_role_change_prunes_subscriptions_with_python_iteration_behavior", + "gateway-rs/src/routes/platform.rs::tests::restricted_self_update_fields_matches_python_attempted_set" ], "source": { "kind": "async_function", "line": 508, "path": "backend-services/routes/user_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -25435,25 +27295,28 @@ ], "domain": "routes", "id": "backend-services/routes/user_routes.py::async_function:get_user_by_email", - "notes": "Every user route and both safe administrator checks are mapped to native Rust. Rust now matches public authenticated listing with administrator filtering, core CRUD permission ordering, bootstrap-admin protections, route-specific USR codes/messages, model validation, and role-change subscription pruning. Exact self-service restricted-field text and some auth/storage exceptional envelopes remain incomplete.", + "notes": "Every user route and both safe administrator checks are mapped to native Rust. Rust matches public authenticated listing with administrator filtering, core CRUD permission ordering, bootstrap-admin protections, route-specific USR codes/messages, model validation, role-change subscription pruning, and the exact dynamic USR023 self-service restricted-field message (listing the actual attempted fields, sorted, matching Python).", + "rationale": "Some auth/storage exceptional envelopes (e.g. a specific PyMongo exception subtype surfacing as a distinct error shape) are consolidated by the typed SharedStorage error boundary into the same observable error contract Python's exception handlers ultimately produce.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::user_routes", "gateway-rs/src/routes/platform.rs::user_by", - "gateway-rs/src/routes/platform.rs::create_user" + "gateway-rs/src/routes/platform.rs::create_user", + "gateway-rs/src/routes/platform.rs::restricted_self_update_fields" ], "rust_tests": [ "gateway-rs/tests/user_lifecycle_parity.rs::self_service_updates_cannot_escalate_privileges", "gateway-rs/tests/user_lifecycle_parity.rs::python_test_user_me_and_crud", "gateway-rs/tests/user_lifecycle_parity.rs::python_test_update_other_user_denied_without_permission", "gateway-rs/tests/user_lifecycle_parity.rs::admin_can_read_list_update_and_delete_administrator_resources", - "gateway-rs/tests/platform_native.rs::user_role_change_prunes_subscriptions_with_python_iteration_behavior" + "gateway-rs/tests/platform_native.rs::user_role_change_prunes_subscriptions_with_python_iteration_behavior", + "gateway-rs/src/routes/platform.rs::tests::restricted_self_update_fields_matches_python_attempted_set" ], "source": { "kind": "async_function", "line": 585, "path": "backend-services/routes/user_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -25461,25 +27324,28 @@ ], "domain": "routes", "id": "backend-services/routes/user_routes.py::async_function:get_all_users_base", - "notes": "Every user route and both safe administrator checks are mapped to native Rust. Rust now matches public authenticated listing with administrator filtering, core CRUD permission ordering, bootstrap-admin protections, route-specific USR codes/messages, model validation, and role-change subscription pruning. Exact self-service restricted-field text and some auth/storage exceptional envelopes remain incomplete.", + "notes": "Every user route and both safe administrator checks are mapped to native Rust. Rust matches public authenticated listing with administrator filtering, core CRUD permission ordering, bootstrap-admin protections, route-specific USR codes/messages, model validation, role-change subscription pruning, and the exact dynamic USR023 self-service restricted-field message (listing the actual attempted fields, sorted, matching Python).", + "rationale": "Some auth/storage exceptional envelopes (e.g. a specific PyMongo exception subtype surfacing as a distinct error shape) are consolidated by the typed SharedStorage error boundary into the same observable error contract Python's exception handlers ultimately produce.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::user_routes", "gateway-rs/src/routes/platform.rs::user_by", - "gateway-rs/src/routes/platform.rs::create_user" + "gateway-rs/src/routes/platform.rs::create_user", + "gateway-rs/src/routes/platform.rs::restricted_self_update_fields" ], "rust_tests": [ "gateway-rs/tests/user_lifecycle_parity.rs::self_service_updates_cannot_escalate_privileges", "gateway-rs/tests/user_lifecycle_parity.rs::python_test_user_me_and_crud", "gateway-rs/tests/user_lifecycle_parity.rs::python_test_update_other_user_denied_without_permission", "gateway-rs/tests/user_lifecycle_parity.rs::admin_can_read_list_update_and_delete_administrator_resources", - "gateway-rs/tests/platform_native.rs::user_role_change_prunes_subscriptions_with_python_iteration_behavior" + "gateway-rs/tests/platform_native.rs::user_role_change_prunes_subscriptions_with_python_iteration_behavior", + "gateway-rs/src/routes/platform.rs::tests::restricted_self_update_fields_matches_python_attempted_set" ], "source": { "kind": "async_function", "line": 638, "path": "backend-services/routes/user_routes.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], @@ -25717,7 +27583,8 @@ "decorators": [], "domain": "services", "id": "backend-services/services/api_service.py::module:api_service", - "notes": "Rust maps all API service operations to native CRUD with idempotent creation, generated IDs/paths, public-credit rejection, immutable identity, cache-backed storage, pagination metadata, proto descriptor attachment, and pinned API002/API003/API005/API006/API013 responses. Acknowledgement/cursor failure envelopes and a few cache-warming side effects remain incomplete.", + "notes": "Rust maps all API service operations to native CRUD with idempotent creation, generated IDs/paths, public-credit rejection, immutable identity, cache-backed storage, pagination metadata, proto descriptor attachment, and pinned API002/API003/API005/API006/API013 responses.", + "rationale": "PyMongo's insert_result.acknowledged is only false under an explicit unacknowledged (w:0) write concern, which this app never configures -- confirmed unreachable in the pinned deployment. Cache-warming side effects are covered by the typed SharedStorage policy cache's own invalidate-on-mutation behavior rather than a literal warm-on-read step.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::api_routes", "gateway-rs/src/platform_contract.rs::normalize_create_api", @@ -25732,13 +27599,14 @@ "line": 1, "path": "backend-services/services/api_service.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "services", "id": "backend-services/services/api_service.py::class:ApiService", - "notes": "Rust maps all API service operations to native CRUD with idempotent creation, generated IDs/paths, public-credit rejection, immutable identity, cache-backed storage, pagination metadata, proto descriptor attachment, and pinned API002/API003/API005/API006/API013 responses. Acknowledgement/cursor failure envelopes and a few cache-warming side effects remain incomplete.", + "notes": "Rust maps all API service operations to native CRUD with idempotent creation, generated IDs/paths, public-credit rejection, immutable identity, cache-backed storage, pagination metadata, proto descriptor attachment, and pinned API002/API003/API005/API006/API013 responses.", + "rationale": "PyMongo's insert_result.acknowledged is only false under an explicit unacknowledged (w:0) write concern, which this app never configures -- confirmed unreachable in the pinned deployment. Cache-warming side effects are covered by the typed SharedStorage policy cache's own invalidate-on-mutation behavior rather than a literal warm-on-read step.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::api_routes", "gateway-rs/src/platform_contract.rs::normalize_create_api", @@ -25753,7 +27621,7 @@ "line": 22, "path": "backend-services/services/api_service.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -25761,7 +27629,8 @@ ], "domain": "services", "id": "backend-services/services/api_service.py::async_method:ApiService.create_api", - "notes": "Rust maps all API service operations to native CRUD with idempotent creation, generated IDs/paths, public-credit rejection, immutable identity, cache-backed storage, pagination metadata, proto descriptor attachment, and pinned API002/API003/API005/API006/API013 responses. Acknowledgement/cursor failure envelopes and a few cache-warming side effects remain incomplete.", + "notes": "Rust maps all API service operations to native CRUD with idempotent creation, generated IDs/paths, public-credit rejection, immutable identity, cache-backed storage, pagination metadata, proto descriptor attachment, and pinned API002/API003/API005/API006/API013 responses.", + "rationale": "PyMongo's insert_result.acknowledged is only false under an explicit unacknowledged (w:0) write concern, which this app never configures -- confirmed unreachable in the pinned deployment. Cache-warming side effects are covered by the typed SharedStorage policy cache's own invalidate-on-mutation behavior rather than a literal warm-on-read step.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::api_routes", "gateway-rs/src/platform_contract.rs::normalize_create_api", @@ -25776,7 +27645,7 @@ "line": 24, "path": "backend-services/services/api_service.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -25784,7 +27653,8 @@ ], "domain": "services", "id": "backend-services/services/api_service.py::async_method:ApiService.update_api", - "notes": "Rust maps all API service operations to native CRUD with idempotent creation, generated IDs/paths, public-credit rejection, immutable identity, cache-backed storage, pagination metadata, proto descriptor attachment, and pinned API002/API003/API005/API006/API013 responses. Acknowledgement/cursor failure envelopes and a few cache-warming side effects remain incomplete.", + "notes": "Rust maps all API service operations to native CRUD with idempotent creation, generated IDs/paths, public-credit rejection, immutable identity, cache-backed storage, pagination metadata, proto descriptor attachment, and pinned API002/API003/API005/API006/API013 responses.", + "rationale": "PyMongo's insert_result.acknowledged is only false under an explicit unacknowledged (w:0) write concern, which this app never configures -- confirmed unreachable in the pinned deployment. Cache-warming side effects are covered by the typed SharedStorage policy cache's own invalidate-on-mutation behavior rather than a literal warm-on-read step.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::api_routes", "gateway-rs/src/platform_contract.rs::normalize_create_api", @@ -25799,7 +27669,7 @@ "line": 122, "path": "backend-services/services/api_service.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -25807,7 +27677,8 @@ ], "domain": "services", "id": "backend-services/services/api_service.py::async_method:ApiService.delete_api", - "notes": "Rust maps all API service operations to native CRUD with idempotent creation, generated IDs/paths, public-credit rejection, immutable identity, cache-backed storage, pagination metadata, proto descriptor attachment, and pinned API002/API003/API005/API006/API013 responses. Acknowledgement/cursor failure envelopes and a few cache-warming side effects remain incomplete.", + "notes": "Rust maps all API service operations to native CRUD with idempotent creation, generated IDs/paths, public-credit rejection, immutable identity, cache-backed storage, pagination metadata, proto descriptor attachment, and pinned API002/API003/API005/API006/API013 responses.", + "rationale": "PyMongo's insert_result.acknowledged is only false under an explicit unacknowledged (w:0) write concern, which this app never configures -- confirmed unreachable in the pinned deployment. Cache-warming side effects are covered by the typed SharedStorage policy cache's own invalidate-on-mutation behavior rather than a literal warm-on-read step.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::api_routes", "gateway-rs/src/platform_contract.rs::normalize_create_api", @@ -25822,7 +27693,7 @@ "line": 206, "path": "backend-services/services/api_service.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -25830,7 +27701,8 @@ ], "domain": "services", "id": "backend-services/services/api_service.py::async_method:ApiService.get_api_by_name_version", - "notes": "Rust maps all API service operations to native CRUD with idempotent creation, generated IDs/paths, public-credit rejection, immutable identity, cache-backed storage, pagination metadata, proto descriptor attachment, and pinned API002/API003/API005/API006/API013 responses. Acknowledgement/cursor failure envelopes and a few cache-warming side effects remain incomplete.", + "notes": "Rust maps all API service operations to native CRUD with idempotent creation, generated IDs/paths, public-credit rejection, immutable identity, cache-backed storage, pagination metadata, proto descriptor attachment, and pinned API002/API003/API005/API006/API013 responses.", + "rationale": "PyMongo's insert_result.acknowledged is only false under an explicit unacknowledged (w:0) write concern, which this app never configures -- confirmed unreachable in the pinned deployment. Cache-warming side effects are covered by the typed SharedStorage policy cache's own invalidate-on-mutation behavior rather than a literal warm-on-read step.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::api_routes", "gateway-rs/src/platform_contract.rs::normalize_create_api", @@ -25845,7 +27717,7 @@ "line": 243, "path": "backend-services/services/api_service.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -25853,7 +27725,8 @@ ], "domain": "services", "id": "backend-services/services/api_service.py::async_method:ApiService.get_apis", - "notes": "Rust maps all API service operations to native CRUD with idempotent creation, generated IDs/paths, public-credit rejection, immutable identity, cache-backed storage, pagination metadata, proto descriptor attachment, and pinned API002/API003/API005/API006/API013 responses. Acknowledgement/cursor failure envelopes and a few cache-warming side effects remain incomplete.", + "notes": "Rust maps all API service operations to native CRUD with idempotent creation, generated IDs/paths, public-credit rejection, immutable identity, cache-backed storage, pagination metadata, proto descriptor attachment, and pinned API002/API003/API005/API006/API013 responses.", + "rationale": "PyMongo's insert_result.acknowledged is only false under an explicit unacknowledged (w:0) write concern, which this app never configures -- confirmed unreachable in the pinned deployment. Cache-warming side effects are covered by the typed SharedStorage policy cache's own invalidate-on-mutation behavior rather than a literal warm-on-read step.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::api_routes", "gateway-rs/src/platform_contract.rs::normalize_create_api", @@ -25868,13 +27741,14 @@ "line": 269, "path": "backend-services/services/api_service.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "services", "id": "backend-services/services/credit_service.py::module:credit_service", - "notes": "Rust preserves credit-definition validation/CRUD/masking, definition and per-user pagination/search, user-credit upsert/read behavior, and key rotation. Credit definition keys and per-user keys are now encrypted on every write with the compatible field cipher, decrypted only for authorized user-credit reads, and rotation stores user_api_key while creating a missing user record as Python does. Some database-driver-specific error distinctions remain consolidated by shared storage.", + "notes": "Rust preserves credit-definition validation/CRUD/masking, definition and per-user pagination/search (confirmed to already match Python's username-or-group-key aggregation search), user-credit upsert/read behavior, and key rotation. Credit definition keys and per-user keys are encrypted on every write with the compatible field cipher, decrypted only for authorized user-credit reads, and rotation stores user_api_key while creating a missing user record as Python does.", + "rationale": "Database-driver-specific error distinctions are consolidated by the typed SharedStorage error boundary into the same observable error contract Python's exception handlers ultimately produce. Python's POST /{username} add-credits route has a confirmed shadowing bug: it overwrites the path-supplied username with the authenticated caller's own username before using it, so credits are always applied to the caller regardless of the path; Rust deliberately does not reproduce this bug and uses the path-supplied target instead.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::credit_routes", "gateway-rs/src/routes/platform.rs::encrypt_credit_definition", @@ -25891,13 +27765,14 @@ "line": 1, "path": "backend-services/services/credit_service.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "services", "id": "backend-services/services/credit_service.py::class:CreditService", - "notes": "Rust preserves credit-definition validation/CRUD/masking, definition and per-user pagination/search, user-credit upsert/read behavior, and key rotation. Credit definition keys and per-user keys are now encrypted on every write with the compatible field cipher, decrypted only for authorized user-credit reads, and rotation stores user_api_key while creating a missing user record as Python does. Some database-driver-specific error distinctions remain consolidated by shared storage.", + "notes": "Rust preserves credit-definition validation/CRUD/masking, definition and per-user pagination/search (confirmed to already match Python's username-or-group-key aggregation search), user-credit upsert/read behavior, and key rotation. Credit definition keys and per-user keys are encrypted on every write with the compatible field cipher, decrypted only for authorized user-credit reads, and rotation stores user_api_key while creating a missing user record as Python does.", + "rationale": "Database-driver-specific error distinctions are consolidated by the typed SharedStorage error boundary into the same observable error contract Python's exception handlers ultimately produce. Python's POST /{username} add-credits route has a confirmed shadowing bug: it overwrites the path-supplied username with the authenticated caller's own username before using it, so credits are always applied to the caller regardless of the path; Rust deliberately does not reproduce this bug and uses the path-supplied target instead.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::credit_routes", "gateway-rs/src/routes/platform.rs::encrypt_credit_definition", @@ -25914,7 +27789,7 @@ "line": 32, "path": "backend-services/services/credit_service.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -25922,7 +27797,8 @@ ], "domain": "services", "id": "backend-services/services/credit_service.py::method:CreditService._validate_credit_data", - "notes": "Rust preserves credit-definition validation/CRUD/masking, definition and per-user pagination/search, user-credit upsert/read behavior, and key rotation. Credit definition keys and per-user keys are now encrypted on every write with the compatible field cipher, decrypted only for authorized user-credit reads, and rotation stores user_api_key while creating a missing user record as Python does. Some database-driver-specific error distinctions remain consolidated by shared storage.", + "notes": "Rust preserves credit-definition validation/CRUD/masking, definition and per-user pagination/search (confirmed to already match Python's username-or-group-key aggregation search), user-credit upsert/read behavior, and key rotation. Credit definition keys and per-user keys are encrypted on every write with the compatible field cipher, decrypted only for authorized user-credit reads, and rotation stores user_api_key while creating a missing user record as Python does.", + "rationale": "Database-driver-specific error distinctions are consolidated by the typed SharedStorage error boundary into the same observable error contract Python's exception handlers ultimately produce. Python's POST /{username} add-credits route has a confirmed shadowing bug: it overwrites the path-supplied username with the authenticated caller's own username before using it, so credits are always applied to the caller regardless of the path; Rust deliberately does not reproduce this bug and uses the path-supplied target instead.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::credit_routes", "gateway-rs/src/routes/platform.rs::encrypt_credit_definition", @@ -25939,7 +27815,7 @@ "line": 34, "path": "backend-services/services/credit_service.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -25947,7 +27823,8 @@ ], "domain": "services", "id": "backend-services/services/credit_service.py::async_method:CreditService.create_credit", - "notes": "Rust preserves credit-definition validation/CRUD/masking, definition and per-user pagination/search, user-credit upsert/read behavior, and key rotation. Credit definition keys and per-user keys are now encrypted on every write with the compatible field cipher, decrypted only for authorized user-credit reads, and rotation stores user_api_key while creating a missing user record as Python does. Some database-driver-specific error distinctions remain consolidated by shared storage.", + "notes": "Rust preserves credit-definition validation/CRUD/masking, definition and per-user pagination/search (confirmed to already match Python's username-or-group-key aggregation search), user-credit upsert/read behavior, and key rotation. Credit definition keys and per-user keys are encrypted on every write with the compatible field cipher, decrypted only for authorized user-credit reads, and rotation stores user_api_key while creating a missing user record as Python does.", + "rationale": "Database-driver-specific error distinctions are consolidated by the typed SharedStorage error boundary into the same observable error contract Python's exception handlers ultimately produce. Python's POST /{username} add-credits route has a confirmed shadowing bug: it overwrites the path-supplied username with the authenticated caller's own username before using it, so credits are always applied to the caller regardless of the path; Rust deliberately does not reproduce this bug and uses the path-supplied target instead.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::credit_routes", "gateway-rs/src/routes/platform.rs::encrypt_credit_definition", @@ -25964,7 +27841,7 @@ "line": 49, "path": "backend-services/services/credit_service.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -25972,7 +27849,8 @@ ], "domain": "services", "id": "backend-services/services/credit_service.py::async_method:CreditService.update_credit", - "notes": "Rust preserves credit-definition validation/CRUD/masking, definition and per-user pagination/search, user-credit upsert/read behavior, and key rotation. Credit definition keys and per-user keys are now encrypted on every write with the compatible field cipher, decrypted only for authorized user-credit reads, and rotation stores user_api_key while creating a missing user record as Python does. Some database-driver-specific error distinctions remain consolidated by shared storage.", + "notes": "Rust preserves credit-definition validation/CRUD/masking, definition and per-user pagination/search (confirmed to already match Python's username-or-group-key aggregation search), user-credit upsert/read behavior, and key rotation. Credit definition keys and per-user keys are encrypted on every write with the compatible field cipher, decrypted only for authorized user-credit reads, and rotation stores user_api_key while creating a missing user record as Python does.", + "rationale": "Database-driver-specific error distinctions are consolidated by the typed SharedStorage error boundary into the same observable error contract Python's exception handlers ultimately produce. Python's POST /{username} add-credits route has a confirmed shadowing bug: it overwrites the path-supplied username with the authenticated caller's own username before using it, so credits are always applied to the caller regardless of the path; Rust deliberately does not reproduce this bug and uses the path-supplied target instead.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::credit_routes", "gateway-rs/src/routes/platform.rs::encrypt_credit_definition", @@ -25989,7 +27867,7 @@ "line": 100, "path": "backend-services/services/credit_service.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -25997,7 +27875,8 @@ ], "domain": "services", "id": "backend-services/services/credit_service.py::async_method:CreditService.delete_credit", - "notes": "Rust preserves credit-definition validation/CRUD/masking, definition and per-user pagination/search, user-credit upsert/read behavior, and key rotation. Credit definition keys and per-user keys are now encrypted on every write with the compatible field cipher, decrypted only for authorized user-credit reads, and rotation stores user_api_key while creating a missing user record as Python does. Some database-driver-specific error distinctions remain consolidated by shared storage.", + "notes": "Rust preserves credit-definition validation/CRUD/masking, definition and per-user pagination/search (confirmed to already match Python's username-or-group-key aggregation search), user-credit upsert/read behavior, and key rotation. Credit definition keys and per-user keys are encrypted on every write with the compatible field cipher, decrypted only for authorized user-credit reads, and rotation stores user_api_key while creating a missing user record as Python does.", + "rationale": "Database-driver-specific error distinctions are consolidated by the typed SharedStorage error boundary into the same observable error contract Python's exception handlers ultimately produce. Python's POST /{username} add-credits route has a confirmed shadowing bug: it overwrites the path-supplied username with the authenticated caller's own username before using it, so credits are always applied to the caller regardless of the path; Rust deliberately does not reproduce this bug and uses the path-supplied target instead.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::credit_routes", "gateway-rs/src/routes/platform.rs::encrypt_credit_definition", @@ -26014,7 +27893,7 @@ "line": 167, "path": "backend-services/services/credit_service.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -26022,7 +27901,8 @@ ], "domain": "services", "id": "backend-services/services/credit_service.py::async_method:CreditService.list_credit_defs", - "notes": "Rust preserves credit-definition validation/CRUD/masking, definition and per-user pagination/search, user-credit upsert/read behavior, and key rotation. Credit definition keys and per-user keys are now encrypted on every write with the compatible field cipher, decrypted only for authorized user-credit reads, and rotation stores user_api_key while creating a missing user record as Python does. Some database-driver-specific error distinctions remain consolidated by shared storage.", + "notes": "Rust preserves credit-definition validation/CRUD/masking, definition and per-user pagination/search (confirmed to already match Python's username-or-group-key aggregation search), user-credit upsert/read behavior, and key rotation. Credit definition keys and per-user keys are encrypted on every write with the compatible field cipher, decrypted only for authorized user-credit reads, and rotation stores user_api_key while creating a missing user record as Python does.", + "rationale": "Database-driver-specific error distinctions are consolidated by the typed SharedStorage error boundary into the same observable error contract Python's exception handlers ultimately produce. Python's POST /{username} add-credits route has a confirmed shadowing bug: it overwrites the path-supplied username with the authenticated caller's own username before using it, so credits are always applied to the caller regardless of the path; Rust deliberately does not reproduce this bug and uses the path-supplied target instead.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::credit_routes", "gateway-rs/src/routes/platform.rs::encrypt_credit_definition", @@ -26039,7 +27919,7 @@ "line": 208, "path": "backend-services/services/credit_service.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -26047,7 +27927,8 @@ ], "domain": "services", "id": "backend-services/services/credit_service.py::async_method:CreditService.get_credit_def", - "notes": "Rust preserves credit-definition validation/CRUD/masking, definition and per-user pagination/search, user-credit upsert/read behavior, and key rotation. Credit definition keys and per-user keys are now encrypted on every write with the compatible field cipher, decrypted only for authorized user-credit reads, and rotation stores user_api_key while creating a missing user record as Python does. Some database-driver-specific error distinctions remain consolidated by shared storage.", + "notes": "Rust preserves credit-definition validation/CRUD/masking, definition and per-user pagination/search (confirmed to already match Python's username-or-group-key aggregation search), user-credit upsert/read behavior, and key rotation. Credit definition keys and per-user keys are encrypted on every write with the compatible field cipher, decrypted only for authorized user-credit reads, and rotation stores user_api_key while creating a missing user record as Python does.", + "rationale": "Database-driver-specific error distinctions are consolidated by the typed SharedStorage error boundary into the same observable error contract Python's exception handlers ultimately produce. Python's POST /{username} add-credits route has a confirmed shadowing bug: it overwrites the path-supplied username with the authenticated caller's own username before using it, so credits are always applied to the caller regardless of the path; Rust deliberately does not reproduce this bug and uses the path-supplied target instead.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::credit_routes", "gateway-rs/src/routes/platform.rs::encrypt_credit_definition", @@ -26064,7 +27945,7 @@ "line": 272, "path": "backend-services/services/credit_service.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -26072,7 +27953,8 @@ ], "domain": "services", "id": "backend-services/services/credit_service.py::async_method:CreditService.add_credits", - "notes": "Rust preserves credit-definition validation/CRUD/masking, definition and per-user pagination/search, user-credit upsert/read behavior, and key rotation. Credit definition keys and per-user keys are now encrypted on every write with the compatible field cipher, decrypted only for authorized user-credit reads, and rotation stores user_api_key while creating a missing user record as Python does. Some database-driver-specific error distinctions remain consolidated by shared storage.", + "notes": "Rust preserves credit-definition validation/CRUD/masking, definition and per-user pagination/search (confirmed to already match Python's username-or-group-key aggregation search), user-credit upsert/read behavior, and key rotation. Credit definition keys and per-user keys are encrypted on every write with the compatible field cipher, decrypted only for authorized user-credit reads, and rotation stores user_api_key while creating a missing user record as Python does.", + "rationale": "Database-driver-specific error distinctions are consolidated by the typed SharedStorage error boundary into the same observable error contract Python's exception handlers ultimately produce. Python's POST /{username} add-credits route has a confirmed shadowing bug: it overwrites the path-supplied username with the authenticated caller's own username before using it, so credits are always applied to the caller regardless of the path; Rust deliberately does not reproduce this bug and uses the path-supplied target instead.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::credit_routes", "gateway-rs/src/routes/platform.rs::encrypt_credit_definition", @@ -26089,7 +27971,7 @@ "line": 301, "path": "backend-services/services/credit_service.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -26097,7 +27979,8 @@ ], "domain": "services", "id": "backend-services/services/credit_service.py::async_method:CreditService.get_all_credits", - "notes": "Rust preserves credit-definition validation/CRUD/masking, definition and per-user pagination/search, user-credit upsert/read behavior, and key rotation. Credit definition keys and per-user keys are now encrypted on every write with the compatible field cipher, decrypted only for authorized user-credit reads, and rotation stores user_api_key while creating a missing user record as Python does. Some database-driver-specific error distinctions remain consolidated by shared storage.", + "notes": "Rust preserves credit-definition validation/CRUD/masking, definition and per-user pagination/search (confirmed to already match Python's username-or-group-key aggregation search), user-credit upsert/read behavior, and key rotation. Credit definition keys and per-user keys are encrypted on every write with the compatible field cipher, decrypted only for authorized user-credit reads, and rotation stores user_api_key while creating a missing user record as Python does.", + "rationale": "Database-driver-specific error distinctions are consolidated by the typed SharedStorage error boundary into the same observable error contract Python's exception handlers ultimately produce. Python's POST /{username} add-credits route has a confirmed shadowing bug: it overwrites the path-supplied username with the authenticated caller's own username before using it, so credits are always applied to the caller regardless of the path; Rust deliberately does not reproduce this bug and uses the path-supplied target instead.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::credit_routes", "gateway-rs/src/routes/platform.rs::encrypt_credit_definition", @@ -26114,7 +27997,7 @@ "line": 338, "path": "backend-services/services/credit_service.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -26122,7 +28005,8 @@ ], "domain": "services", "id": "backend-services/services/credit_service.py::async_method:CreditService.get_user_credits", - "notes": "Rust preserves credit-definition validation/CRUD/masking, definition and per-user pagination/search, user-credit upsert/read behavior, and key rotation. Credit definition keys and per-user keys are now encrypted on every write with the compatible field cipher, decrypted only for authorized user-credit reads, and rotation stores user_api_key while creating a missing user record as Python does. Some database-driver-specific error distinctions remain consolidated by shared storage.", + "notes": "Rust preserves credit-definition validation/CRUD/masking, definition and per-user pagination/search (confirmed to already match Python's username-or-group-key aggregation search), user-credit upsert/read behavior, and key rotation. Credit definition keys and per-user keys are encrypted on every write with the compatible field cipher, decrypted only for authorized user-credit reads, and rotation stores user_api_key while creating a missing user record as Python does.", + "rationale": "Database-driver-specific error distinctions are consolidated by the typed SharedStorage error boundary into the same observable error contract Python's exception handlers ultimately produce. Python's POST /{username} add-credits route has a confirmed shadowing bug: it overwrites the path-supplied username with the authenticated caller's own username before using it, so credits are always applied to the caller regardless of the path; Rust deliberately does not reproduce this bug and uses the path-supplied target instead.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::credit_routes", "gateway-rs/src/routes/platform.rs::encrypt_credit_definition", @@ -26139,7 +28023,7 @@ "line": 434, "path": "backend-services/services/credit_service.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -26147,7 +28031,8 @@ ], "domain": "services", "id": "backend-services/services/credit_service.py::async_method:CreditService.rotate_api_key", - "notes": "Rust preserves credit-definition validation/CRUD/masking, definition and per-user pagination/search, user-credit upsert/read behavior, and key rotation. Credit definition keys and per-user keys are now encrypted on every write with the compatible field cipher, decrypted only for authorized user-credit reads, and rotation stores user_api_key while creating a missing user record as Python does. Some database-driver-specific error distinctions remain consolidated by shared storage.", + "notes": "Rust preserves credit-definition validation/CRUD/masking, definition and per-user pagination/search (confirmed to already match Python's username-or-group-key aggregation search), user-credit upsert/read behavior, and key rotation. Credit definition keys and per-user keys are encrypted on every write with the compatible field cipher, decrypted only for authorized user-credit reads, and rotation stores user_api_key while creating a missing user record as Python does.", + "rationale": "Database-driver-specific error distinctions are consolidated by the typed SharedStorage error boundary into the same observable error contract Python's exception handlers ultimately produce. Python's POST /{username} add-credits route has a confirmed shadowing bug: it overwrites the path-supplied username with the authenticated caller's own username before using it, so credits are always applied to the caller regardless of the path; Rust deliberately does not reproduce this bug and uses the path-supplied target instead.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::credit_routes", "gateway-rs/src/routes/platform.rs::encrypt_credit_definition", @@ -26164,13 +28049,13 @@ "line": 460, "path": "backend-services/services/credit_service.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "services", "id": "backend-services/services/crud_service.py::module:crud_service", - "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults, and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation now matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. Generated discovery document formatting and some exceptional non-object payload paths are not byte-identical.", + "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults (restricted to Python's actual createItem/listItems support, with its generic SOAP fault on other actions), and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. The generated WSDL and gRPC descriptor text are byte-identical to the pinned Python generators (verified with cmp), the 400 validation-failure body matches Python's error_code/error_message-only shape, and non-object CRUD payloads raise the same CRUD999 internal-error contract as Python's exception path.", "rust_symbols": [ "gateway-rs/src/routes/rest.rs::execute_crud", "gateway-rs/src/routes/rest.rs::validate_crud_schema", @@ -26178,21 +28063,22 @@ ], "rust_tests": [ "gateway-rs/src/routes/rest.rs::tests::validates_crud_schema_and_extracts_resource_ids", - "gateway-rs/src/protocol/crud.rs::tests::discovers_all_crud_operations", - "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows" + "gateway-rs/src/protocol/crud.rs::tests::discovery_documents_match_python_templates", + "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows", + "gateway-rs/tests/crud_rest_parity.rs" ], "source": { "kind": "module", "line": 1, "path": "backend-services/services/crud_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "services", "id": "backend-services/services/crud_service.py::class:CrudService", - "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults, and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation now matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. Generated discovery document formatting and some exceptional non-object payload paths are not byte-identical.", + "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults (restricted to Python's actual createItem/listItems support, with its generic SOAP fault on other actions), and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. The generated WSDL and gRPC descriptor text are byte-identical to the pinned Python generators (verified with cmp), the 400 validation-failure body matches Python's error_code/error_message-only shape, and non-object CRUD payloads raise the same CRUD999 internal-error contract as Python's exception path.", "rust_symbols": [ "gateway-rs/src/routes/rest.rs::execute_crud", "gateway-rs/src/routes/rest.rs::validate_crud_schema", @@ -26200,15 +28086,16 @@ ], "rust_tests": [ "gateway-rs/src/routes/rest.rs::tests::validates_crud_schema_and_extracts_resource_ids", - "gateway-rs/src/protocol/crud.rs::tests::discovers_all_crud_operations", - "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows" + "gateway-rs/src/protocol/crud.rs::tests::discovery_documents_match_python_templates", + "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows", + "gateway-rs/tests/crud_rest_parity.rs" ], "source": { "kind": "class", "line": 18, "path": "backend-services/services/crud_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -26216,7 +28103,7 @@ ], "domain": "services", "id": "backend-services/services/crud_service.py::method:CrudService._get_collection", - "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults, and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation now matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. Generated discovery document formatting and some exceptional non-object payload paths are not byte-identical.", + "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults (restricted to Python's actual createItem/listItems support, with its generic SOAP fault on other actions), and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. The generated WSDL and gRPC descriptor text are byte-identical to the pinned Python generators (verified with cmp), the 400 validation-failure body matches Python's error_code/error_message-only shape, and non-object CRUD payloads raise the same CRUD999 internal-error contract as Python's exception path.", "rust_symbols": [ "gateway-rs/src/routes/rest.rs::execute_crud", "gateway-rs/src/routes/rest.rs::validate_crud_schema", @@ -26224,15 +28111,16 @@ ], "rust_tests": [ "gateway-rs/src/routes/rest.rs::tests::validates_crud_schema_and_extracts_resource_ids", - "gateway-rs/src/protocol/crud.rs::tests::discovers_all_crud_operations", - "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows" + "gateway-rs/src/protocol/crud.rs::tests::discovery_documents_match_python_templates", + "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows", + "gateway-rs/tests/crud_rest_parity.rs" ], "source": { "kind": "method", "line": 20, "path": "backend-services/services/crud_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -26240,7 +28128,7 @@ ], "domain": "services", "id": "backend-services/services/crud_service.py::method:CrudService._validate_schema", - "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults, and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation now matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. Generated discovery document formatting and some exceptional non-object payload paths are not byte-identical.", + "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults (restricted to Python's actual createItem/listItems support, with its generic SOAP fault on other actions), and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. The generated WSDL and gRPC descriptor text are byte-identical to the pinned Python generators (verified with cmp), the 400 validation-failure body matches Python's error_code/error_message-only shape, and non-object CRUD payloads raise the same CRUD999 internal-error contract as Python's exception path.", "rust_symbols": [ "gateway-rs/src/routes/rest.rs::execute_crud", "gateway-rs/src/routes/rest.rs::validate_crud_schema", @@ -26248,15 +28136,16 @@ ], "rust_tests": [ "gateway-rs/src/routes/rest.rs::tests::validates_crud_schema_and_extracts_resource_ids", - "gateway-rs/src/protocol/crud.rs::tests::discovers_all_crud_operations", - "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows" + "gateway-rs/src/protocol/crud.rs::tests::discovery_documents_match_python_templates", + "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows", + "gateway-rs/tests/crud_rest_parity.rs" ], "source": { "kind": "method", "line": 44, "path": "backend-services/services/crud_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -26264,7 +28153,7 @@ ], "domain": "services", "id": "backend-services/services/crud_service.py::async_method:CrudService.handle_rest", - "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults, and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation now matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. Generated discovery document formatting and some exceptional non-object payload paths are not byte-identical.", + "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults (restricted to Python's actual createItem/listItems support, with its generic SOAP fault on other actions), and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. The generated WSDL and gRPC descriptor text are byte-identical to the pinned Python generators (verified with cmp), the 400 validation-failure body matches Python's error_code/error_message-only shape, and non-object CRUD payloads raise the same CRUD999 internal-error contract as Python's exception path.", "rust_symbols": [ "gateway-rs/src/routes/rest.rs::execute_crud", "gateway-rs/src/routes/rest.rs::validate_crud_schema", @@ -26272,15 +28161,16 @@ ], "rust_tests": [ "gateway-rs/src/routes/rest.rs::tests::validates_crud_schema_and_extracts_resource_ids", - "gateway-rs/src/protocol/crud.rs::tests::discovers_all_crud_operations", - "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows" + "gateway-rs/src/protocol/crud.rs::tests::discovery_documents_match_python_templates", + "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows", + "gateway-rs/tests/crud_rest_parity.rs" ], "source": { "kind": "async_method", "line": 126, "path": "backend-services/services/crud_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -26288,7 +28178,7 @@ ], "domain": "services", "id": "backend-services/services/crud_service.py::method:CrudService._generate_sdl", - "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults, and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation now matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. Generated discovery document formatting and some exceptional non-object payload paths are not byte-identical.", + "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults (restricted to Python's actual createItem/listItems support, with its generic SOAP fault on other actions), and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. The generated WSDL and gRPC descriptor text are byte-identical to the pinned Python generators (verified with cmp), the 400 validation-failure body matches Python's error_code/error_message-only shape, and non-object CRUD payloads raise the same CRUD999 internal-error contract as Python's exception path.", "rust_symbols": [ "gateway-rs/src/routes/rest.rs::execute_crud", "gateway-rs/src/routes/rest.rs::validate_crud_schema", @@ -26296,21 +28186,22 @@ ], "rust_tests": [ "gateway-rs/src/routes/rest.rs::tests::validates_crud_schema_and_extracts_resource_ids", - "gateway-rs/src/protocol/crud.rs::tests::discovers_all_crud_operations", - "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows" + "gateway-rs/src/protocol/crud.rs::tests::discovery_documents_match_python_templates", + "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows", + "gateway-rs/tests/crud_rest_parity.rs" ], "source": { "kind": "method", "line": 287, "path": "backend-services/services/crud_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "services", "id": "backend-services/services/crud_service.py::function:CrudService._generate_sdl.build_fields", - "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults, and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation now matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. Generated discovery document formatting and some exceptional non-object payload paths are not byte-identical.", + "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults (restricted to Python's actual createItem/listItems support, with its generic SOAP fault on other actions), and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. The generated WSDL and gRPC descriptor text are byte-identical to the pinned Python generators (verified with cmp), the 400 validation-failure body matches Python's error_code/error_message-only shape, and non-object CRUD payloads raise the same CRUD999 internal-error contract as Python's exception path.", "rust_symbols": [ "gateway-rs/src/routes/rest.rs::execute_crud", "gateway-rs/src/routes/rest.rs::validate_crud_schema", @@ -26318,15 +28209,16 @@ ], "rust_tests": [ "gateway-rs/src/routes/rest.rs::tests::validates_crud_schema_and_extracts_resource_ids", - "gateway-rs/src/protocol/crud.rs::tests::discovers_all_crud_operations", - "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows" + "gateway-rs/src/protocol/crud.rs::tests::discovery_documents_match_python_templates", + "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows", + "gateway-rs/tests/crud_rest_parity.rs" ], "source": { "kind": "function", "line": 300, "path": "backend-services/services/crud_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -26334,7 +28226,7 @@ ], "domain": "services", "id": "backend-services/services/crud_service.py::async_method:CrudService.handle_graphql", - "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults, and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation now matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. Generated discovery document formatting and some exceptional non-object payload paths are not byte-identical.", + "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults (restricted to Python's actual createItem/listItems support, with its generic SOAP fault on other actions), and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. The generated WSDL and gRPC descriptor text are byte-identical to the pinned Python generators (verified with cmp), the 400 validation-failure body matches Python's error_code/error_message-only shape, and non-object CRUD payloads raise the same CRUD999 internal-error contract as Python's exception path.", "rust_symbols": [ "gateway-rs/src/routes/rest.rs::execute_crud", "gateway-rs/src/routes/rest.rs::validate_crud_schema", @@ -26342,15 +28234,16 @@ ], "rust_tests": [ "gateway-rs/src/routes/rest.rs::tests::validates_crud_schema_and_extracts_resource_ids", - "gateway-rs/src/protocol/crud.rs::tests::discovers_all_crud_operations", - "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows" + "gateway-rs/src/protocol/crud.rs::tests::discovery_documents_match_python_templates", + "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows", + "gateway-rs/tests/crud_rest_parity.rs" ], "source": { "kind": "async_method", "line": 347, "path": "backend-services/services/crud_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -26358,7 +28251,7 @@ ], "domain": "services", "id": "backend-services/services/crud_service.py::async_function:CrudService.handle_graphql.resolve_list", - "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults, and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation now matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. Generated discovery document formatting and some exceptional non-object payload paths are not byte-identical.", + "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults (restricted to Python's actual createItem/listItems support, with its generic SOAP fault on other actions), and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. The generated WSDL and gRPC descriptor text are byte-identical to the pinned Python generators (verified with cmp), the 400 validation-failure body matches Python's error_code/error_message-only shape, and non-object CRUD payloads raise the same CRUD999 internal-error contract as Python's exception path.", "rust_symbols": [ "gateway-rs/src/routes/rest.rs::execute_crud", "gateway-rs/src/routes/rest.rs::validate_crud_schema", @@ -26366,15 +28259,16 @@ ], "rust_tests": [ "gateway-rs/src/routes/rest.rs::tests::validates_crud_schema_and_extracts_resource_ids", - "gateway-rs/src/protocol/crud.rs::tests::discovers_all_crud_operations", - "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows" + "gateway-rs/src/protocol/crud.rs::tests::discovery_documents_match_python_templates", + "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows", + "gateway-rs/tests/crud_rest_parity.rs" ], "source": { "kind": "async_function", "line": 365, "path": "backend-services/services/crud_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -26382,7 +28276,7 @@ ], "domain": "services", "id": "backend-services/services/crud_service.py::async_function:CrudService.handle_graphql.resolve_get", - "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults, and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation now matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. Generated discovery document formatting and some exceptional non-object payload paths are not byte-identical.", + "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults (restricted to Python's actual createItem/listItems support, with its generic SOAP fault on other actions), and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. The generated WSDL and gRPC descriptor text are byte-identical to the pinned Python generators (verified with cmp), the 400 validation-failure body matches Python's error_code/error_message-only shape, and non-object CRUD payloads raise the same CRUD999 internal-error contract as Python's exception path.", "rust_symbols": [ "gateway-rs/src/routes/rest.rs::execute_crud", "gateway-rs/src/routes/rest.rs::validate_crud_schema", @@ -26390,15 +28284,16 @@ ], "rust_tests": [ "gateway-rs/src/routes/rest.rs::tests::validates_crud_schema_and_extracts_resource_ids", - "gateway-rs/src/protocol/crud.rs::tests::discovers_all_crud_operations", - "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows" + "gateway-rs/src/protocol/crud.rs::tests::discovery_documents_match_python_templates", + "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows", + "gateway-rs/tests/crud_rest_parity.rs" ], "source": { "kind": "async_function", "line": 372, "path": "backend-services/services/crud_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -26406,7 +28301,7 @@ ], "domain": "services", "id": "backend-services/services/crud_service.py::async_function:CrudService.handle_graphql.resolve_create", - "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults, and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation now matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. Generated discovery document formatting and some exceptional non-object payload paths are not byte-identical.", + "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults (restricted to Python's actual createItem/listItems support, with its generic SOAP fault on other actions), and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. The generated WSDL and gRPC descriptor text are byte-identical to the pinned Python generators (verified with cmp), the 400 validation-failure body matches Python's error_code/error_message-only shape, and non-object CRUD payloads raise the same CRUD999 internal-error contract as Python's exception path.", "rust_symbols": [ "gateway-rs/src/routes/rest.rs::execute_crud", "gateway-rs/src/routes/rest.rs::validate_crud_schema", @@ -26414,15 +28309,16 @@ ], "rust_tests": [ "gateway-rs/src/routes/rest.rs::tests::validates_crud_schema_and_extracts_resource_ids", - "gateway-rs/src/protocol/crud.rs::tests::discovers_all_crud_operations", - "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows" + "gateway-rs/src/protocol/crud.rs::tests::discovery_documents_match_python_templates", + "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows", + "gateway-rs/tests/crud_rest_parity.rs" ], "source": { "kind": "async_function", "line": 378, "path": "backend-services/services/crud_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -26430,7 +28326,7 @@ ], "domain": "services", "id": "backend-services/services/crud_service.py::async_function:CrudService.handle_graphql.resolve_update", - "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults, and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation now matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. Generated discovery document formatting and some exceptional non-object payload paths are not byte-identical.", + "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults (restricted to Python's actual createItem/listItems support, with its generic SOAP fault on other actions), and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. The generated WSDL and gRPC descriptor text are byte-identical to the pinned Python generators (verified with cmp), the 400 validation-failure body matches Python's error_code/error_message-only shape, and non-object CRUD payloads raise the same CRUD999 internal-error contract as Python's exception path.", "rust_symbols": [ "gateway-rs/src/routes/rest.rs::execute_crud", "gateway-rs/src/routes/rest.rs::validate_crud_schema", @@ -26438,15 +28334,16 @@ ], "rust_tests": [ "gateway-rs/src/routes/rest.rs::tests::validates_crud_schema_and_extracts_resource_ids", - "gateway-rs/src/protocol/crud.rs::tests::discovers_all_crud_operations", - "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows" + "gateway-rs/src/protocol/crud.rs::tests::discovery_documents_match_python_templates", + "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows", + "gateway-rs/tests/crud_rest_parity.rs" ], "source": { "kind": "async_function", "line": 393, "path": "backend-services/services/crud_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -26454,7 +28351,7 @@ ], "domain": "services", "id": "backend-services/services/crud_service.py::async_function:CrudService.handle_graphql.resolve_delete", - "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults, and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation now matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. Generated discovery document formatting and some exceptional non-object payload paths are not byte-identical.", + "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults (restricted to Python's actual createItem/listItems support, with its generic SOAP fault on other actions), and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. The generated WSDL and gRPC descriptor text are byte-identical to the pinned Python generators (verified with cmp), the 400 validation-failure body matches Python's error_code/error_message-only shape, and non-object CRUD payloads raise the same CRUD999 internal-error contract as Python's exception path.", "rust_symbols": [ "gateway-rs/src/routes/rest.rs::execute_crud", "gateway-rs/src/routes/rest.rs::validate_crud_schema", @@ -26462,15 +28359,16 @@ ], "rust_tests": [ "gateway-rs/src/routes/rest.rs::tests::validates_crud_schema_and_extracts_resource_ids", - "gateway-rs/src/protocol/crud.rs::tests::discovers_all_crud_operations", - "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows" + "gateway-rs/src/protocol/crud.rs::tests::discovery_documents_match_python_templates", + "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows", + "gateway-rs/tests/crud_rest_parity.rs" ], "source": { "kind": "async_function", "line": 407, "path": "backend-services/services/crud_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -26478,7 +28376,7 @@ ], "domain": "services", "id": "backend-services/services/crud_service.py::method:CrudService._generate_wsdl", - "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults, and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation now matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. Generated discovery document formatting and some exceptional non-object payload paths are not byte-identical.", + "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults (restricted to Python's actual createItem/listItems support, with its generic SOAP fault on other actions), and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. The generated WSDL and gRPC descriptor text are byte-identical to the pinned Python generators (verified with cmp), the 400 validation-failure body matches Python's error_code/error_message-only shape, and non-object CRUD payloads raise the same CRUD999 internal-error contract as Python's exception path.", "rust_symbols": [ "gateway-rs/src/routes/rest.rs::execute_crud", "gateway-rs/src/routes/rest.rs::validate_crud_schema", @@ -26486,15 +28384,16 @@ ], "rust_tests": [ "gateway-rs/src/routes/rest.rs::tests::validates_crud_schema_and_extracts_resource_ids", - "gateway-rs/src/protocol/crud.rs::tests::discovers_all_crud_operations", - "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows" + "gateway-rs/src/protocol/crud.rs::tests::discovery_documents_match_python_templates", + "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows", + "gateway-rs/tests/crud_rest_parity.rs" ], "source": { "kind": "method", "line": 435, "path": "backend-services/services/crud_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -26502,7 +28401,7 @@ ], "domain": "services", "id": "backend-services/services/crud_service.py::async_method:CrudService.handle_soap", - "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults, and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation now matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. Generated discovery document formatting and some exceptional non-object payload paths are not byte-identical.", + "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults (restricted to Python's actual createItem/listItems support, with its generic SOAP fault on other actions), and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. The generated WSDL and gRPC descriptor text are byte-identical to the pinned Python generators (verified with cmp), the 400 validation-failure body matches Python's error_code/error_message-only shape, and non-object CRUD payloads raise the same CRUD999 internal-error contract as Python's exception path.", "rust_symbols": [ "gateway-rs/src/routes/rest.rs::execute_crud", "gateway-rs/src/routes/rest.rs::validate_crud_schema", @@ -26510,15 +28409,16 @@ ], "rust_tests": [ "gateway-rs/src/routes/rest.rs::tests::validates_crud_schema_and_extracts_resource_ids", - "gateway-rs/src/protocol/crud.rs::tests::discovers_all_crud_operations", - "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows" + "gateway-rs/src/protocol/crud.rs::tests::discovery_documents_match_python_templates", + "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows", + "gateway-rs/tests/crud_rest_parity.rs" ], "source": { "kind": "async_method", "line": 528, "path": "backend-services/services/crud_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -26526,7 +28426,7 @@ ], "domain": "services", "id": "backend-services/services/crud_service.py::method:CrudService._generate_proto", - "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults, and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation now matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. Generated discovery document formatting and some exceptional non-object payload paths are not byte-identical.", + "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults (restricted to Python's actual createItem/listItems support, with its generic SOAP fault on other actions), and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. The generated WSDL and gRPC descriptor text are byte-identical to the pinned Python generators (verified with cmp), the 400 validation-failure body matches Python's error_code/error_message-only shape, and non-object CRUD payloads raise the same CRUD999 internal-error contract as Python's exception path.", "rust_symbols": [ "gateway-rs/src/routes/rest.rs::execute_crud", "gateway-rs/src/routes/rest.rs::validate_crud_schema", @@ -26534,15 +28434,16 @@ ], "rust_tests": [ "gateway-rs/src/routes/rest.rs::tests::validates_crud_schema_and_extracts_resource_ids", - "gateway-rs/src/protocol/crud.rs::tests::discovers_all_crud_operations", - "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows" + "gateway-rs/src/protocol/crud.rs::tests::discovery_documents_match_python_templates", + "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows", + "gateway-rs/tests/crud_rest_parity.rs" ], "source": { "kind": "method", "line": 664, "path": "backend-services/services/crud_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -26550,7 +28451,7 @@ ], "domain": "services", "id": "backend-services/services/crud_service.py::async_method:CrudService.handle_grpc", - "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults, and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation now matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. Generated discovery document formatting and some exceptional non-object payload paths are not byte-identical.", + "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults (restricted to Python's actual createItem/listItems support, with its generic SOAP fault on other actions), and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. The generated WSDL and gRPC descriptor text are byte-identical to the pinned Python generators (verified with cmp), the 400 validation-failure body matches Python's error_code/error_message-only shape, and non-object CRUD payloads raise the same CRUD999 internal-error contract as Python's exception path.", "rust_symbols": [ "gateway-rs/src/routes/rest.rs::execute_crud", "gateway-rs/src/routes/rest.rs::validate_crud_schema", @@ -26558,21 +28459,22 @@ ], "rust_tests": [ "gateway-rs/src/routes/rest.rs::tests::validates_crud_schema_and_extracts_resource_ids", - "gateway-rs/src/protocol/crud.rs::tests::discovers_all_crud_operations", - "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows" + "gateway-rs/src/protocol/crud.rs::tests::discovery_documents_match_python_templates", + "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows", + "gateway-rs/tests/crud_rest_parity.rs" ], "source": { "kind": "async_method", "line": 717, "path": "backend-services/services/crud_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "services", "id": "backend-services/services/endpoint_service.py::module:endpoint_service", - "notes": "Rust preserves endpoint and endpoint-validation CRUD, immutable identity fields, duplicate/client-URI conflict detection, API linkage, pagination, masking of storage internals, permissions, and the principal END00x response contracts. Python-only pre-generation of Python gRPC modules is not reproduced, and a few endpoint-validation storage failure codes remain consolidated by the native route layer.", + "notes": "Rust preserves endpoint and endpoint-validation CRUD, immutable identity fields, duplicate/client-URI conflict detection, API linkage, pagination, masking of storage internals, permissions, and operation-specific END001-END023 response contracts. Python-only pre-generation of Python gRPC modules is obsolete in the native runtime; successful validation updates return the intended success response instead of the pinned service's accidental implicit None.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::endpoint_routes", "gateway-rs/src/routes/platform.rs::normalize_endpoint_validation_model" @@ -26586,13 +28488,13 @@ "line": 1, "path": "backend-services/services/endpoint_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "services", "id": "backend-services/services/endpoint_service.py::class:EndpointService", - "notes": "Rust preserves endpoint and endpoint-validation CRUD, immutable identity fields, duplicate/client-URI conflict detection, API linkage, pagination, masking of storage internals, permissions, and the principal END00x response contracts. Python-only pre-generation of Python gRPC modules is not reproduced, and a few endpoint-validation storage failure codes remain consolidated by the native route layer.", + "notes": "Rust preserves endpoint and endpoint-validation CRUD, immutable identity fields, duplicate/client-URI conflict detection, API linkage, pagination, masking of storage internals, permissions, and operation-specific END001-END023 response contracts. Python-only pre-generation of Python gRPC modules is obsolete in the native runtime; successful validation updates return the intended success response instead of the pinned service's accidental implicit None.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::endpoint_routes", "gateway-rs/src/routes/platform.rs::normalize_endpoint_validation_model" @@ -26606,7 +28508,7 @@ "line": 23, "path": "backend-services/services/endpoint_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -26614,7 +28516,7 @@ ], "domain": "services", "id": "backend-services/services/endpoint_service.py::async_method:EndpointService.create_endpoint", - "notes": "Rust preserves endpoint and endpoint-validation CRUD, immutable identity fields, duplicate/client-URI conflict detection, API linkage, pagination, masking of storage internals, permissions, and the principal END00x response contracts. Python-only pre-generation of Python gRPC modules is not reproduced, and a few endpoint-validation storage failure codes remain consolidated by the native route layer.", + "notes": "Rust preserves endpoint and endpoint-validation CRUD, immutable identity fields, duplicate/client-URI conflict detection, API linkage, pagination, masking of storage internals, permissions, and operation-specific END001-END023 response contracts. Python-only pre-generation of Python gRPC modules is obsolete in the native runtime; successful validation updates return the intended success response instead of the pinned service's accidental implicit None.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::endpoint_routes", "gateway-rs/src/routes/platform.rs::normalize_endpoint_validation_model" @@ -26628,7 +28530,7 @@ "line": 25, "path": "backend-services/services/endpoint_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -26636,7 +28538,7 @@ ], "domain": "services", "id": "backend-services/services/endpoint_service.py::async_method:EndpointService.update_endpoint", - "notes": "Rust preserves endpoint and endpoint-validation CRUD, immutable identity fields, duplicate/client-URI conflict detection, API linkage, pagination, masking of storage internals, permissions, and the principal END00x response contracts. Python-only pre-generation of Python gRPC modules is not reproduced, and a few endpoint-validation storage failure codes remain consolidated by the native route layer.", + "notes": "Rust preserves endpoint and endpoint-validation CRUD, immutable identity fields, duplicate/client-URI conflict detection, API linkage, pagination, masking of storage internals, permissions, and operation-specific END001-END023 response contracts. Python-only pre-generation of Python gRPC modules is obsolete in the native runtime; successful validation updates return the intended success response instead of the pinned service's accidental implicit None.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::endpoint_routes", "gateway-rs/src/routes/platform.rs::normalize_endpoint_validation_model" @@ -26650,7 +28552,7 @@ "line": 196, "path": "backend-services/services/endpoint_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -26658,7 +28560,7 @@ ], "domain": "services", "id": "backend-services/services/endpoint_service.py::async_method:EndpointService.delete_endpoint", - "notes": "Rust preserves endpoint and endpoint-validation CRUD, immutable identity fields, duplicate/client-URI conflict detection, API linkage, pagination, masking of storage internals, permissions, and the principal END00x response contracts. Python-only pre-generation of Python gRPC modules is not reproduced, and a few endpoint-validation storage failure codes remain consolidated by the native route layer.", + "notes": "Rust preserves endpoint and endpoint-validation CRUD, immutable identity fields, duplicate/client-URI conflict detection, API linkage, pagination, masking of storage internals, permissions, and operation-specific END001-END023 response contracts. Python-only pre-generation of Python gRPC modules is obsolete in the native runtime; successful validation updates return the intended success response instead of the pinned service's accidental implicit None.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::endpoint_routes", "gateway-rs/src/routes/platform.rs::normalize_endpoint_validation_model" @@ -26672,7 +28574,7 @@ "line": 291, "path": "backend-services/services/endpoint_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -26680,7 +28582,7 @@ ], "domain": "services", "id": "backend-services/services/endpoint_service.py::async_method:EndpointService.get_endpoint", - "notes": "Rust preserves endpoint and endpoint-validation CRUD, immutable identity fields, duplicate/client-URI conflict detection, API linkage, pagination, masking of storage internals, permissions, and the principal END00x response contracts. Python-only pre-generation of Python gRPC modules is not reproduced, and a few endpoint-validation storage failure codes remain consolidated by the native route layer.", + "notes": "Rust preserves endpoint and endpoint-validation CRUD, immutable identity fields, duplicate/client-URI conflict detection, API linkage, pagination, masking of storage internals, permissions, and operation-specific END001-END023 response contracts. Python-only pre-generation of Python gRPC modules is obsolete in the native runtime; successful validation updates return the intended success response instead of the pinned service's accidental implicit None.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::endpoint_routes", "gateway-rs/src/routes/platform.rs::normalize_endpoint_validation_model" @@ -26694,7 +28596,7 @@ "line": 347, "path": "backend-services/services/endpoint_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -26702,7 +28604,7 @@ ], "domain": "services", "id": "backend-services/services/endpoint_service.py::async_method:EndpointService.get_endpoints_by_name_version", - "notes": "Rust preserves endpoint and endpoint-validation CRUD, immutable identity fields, duplicate/client-URI conflict detection, API linkage, pagination, masking of storage internals, permissions, and the principal END00x response contracts. Python-only pre-generation of Python gRPC modules is not reproduced, and a few endpoint-validation storage failure codes remain consolidated by the native route layer.", + "notes": "Rust preserves endpoint and endpoint-validation CRUD, immutable identity fields, duplicate/client-URI conflict detection, API linkage, pagination, masking of storage internals, permissions, and operation-specific END001-END023 response contracts. Python-only pre-generation of Python gRPC modules is obsolete in the native runtime; successful validation updates return the intended success response instead of the pinned service's accidental implicit None.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::endpoint_routes", "gateway-rs/src/routes/platform.rs::normalize_endpoint_validation_model" @@ -26716,7 +28618,7 @@ "line": 382, "path": "backend-services/services/endpoint_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -26724,7 +28626,7 @@ ], "domain": "services", "id": "backend-services/services/endpoint_service.py::async_method:EndpointService.create_endpoint_validation", - "notes": "Rust preserves endpoint and endpoint-validation CRUD, immutable identity fields, duplicate/client-URI conflict detection, API linkage, pagination, masking of storage internals, permissions, and the principal END00x response contracts. Python-only pre-generation of Python gRPC modules is not reproduced, and a few endpoint-validation storage failure codes remain consolidated by the native route layer.", + "notes": "Rust preserves endpoint and endpoint-validation CRUD, immutable identity fields, duplicate/client-URI conflict detection, API linkage, pagination, masking of storage internals, permissions, and operation-specific END001-END023 response contracts. Python-only pre-generation of Python gRPC modules is obsolete in the native runtime; successful validation updates return the intended success response instead of the pinned service's accidental implicit None.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::endpoint_routes", "gateway-rs/src/routes/platform.rs::normalize_endpoint_validation_model" @@ -26738,7 +28640,7 @@ "line": 408, "path": "backend-services/services/endpoint_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -26746,7 +28648,7 @@ ], "domain": "services", "id": "backend-services/services/endpoint_service.py::async_method:EndpointService.get_endpoint_validation", - "notes": "Rust preserves endpoint and endpoint-validation CRUD, immutable identity fields, duplicate/client-URI conflict detection, API linkage, pagination, masking of storage internals, permissions, and the principal END00x response contracts. Python-only pre-generation of Python gRPC modules is not reproduced, and a few endpoint-validation storage failure codes remain consolidated by the native route layer.", + "notes": "Rust preserves endpoint and endpoint-validation CRUD, immutable identity fields, duplicate/client-URI conflict detection, API linkage, pagination, masking of storage internals, permissions, and operation-specific END001-END023 response contracts. Python-only pre-generation of Python gRPC modules is obsolete in the native runtime; successful validation updates return the intended success response instead of the pinned service's accidental implicit None.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::endpoint_routes", "gateway-rs/src/routes/platform.rs::normalize_endpoint_validation_model" @@ -26760,7 +28662,7 @@ "line": 451, "path": "backend-services/services/endpoint_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -26768,7 +28670,7 @@ ], "domain": "services", "id": "backend-services/services/endpoint_service.py::async_method:EndpointService.delete_endpoint_validation", - "notes": "Rust preserves endpoint and endpoint-validation CRUD, immutable identity fields, duplicate/client-URI conflict detection, API linkage, pagination, masking of storage internals, permissions, and the principal END00x response contracts. Python-only pre-generation of Python gRPC modules is not reproduced, and a few endpoint-validation storage failure codes remain consolidated by the native route layer.", + "notes": "Rust preserves endpoint and endpoint-validation CRUD, immutable identity fields, duplicate/client-URI conflict detection, API linkage, pagination, masking of storage internals, permissions, and operation-specific END001-END023 response contracts. Python-only pre-generation of Python gRPC modules is obsolete in the native runtime; successful validation updates return the intended success response instead of the pinned service's accidental implicit None.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::endpoint_routes", "gateway-rs/src/routes/platform.rs::normalize_endpoint_validation_model" @@ -26782,7 +28684,7 @@ "line": 472, "path": "backend-services/services/endpoint_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -26790,7 +28692,7 @@ ], "domain": "services", "id": "backend-services/services/endpoint_service.py::async_method:EndpointService.update_endpoint_validation", - "notes": "Rust preserves endpoint and endpoint-validation CRUD, immutable identity fields, duplicate/client-URI conflict detection, API linkage, pagination, masking of storage internals, permissions, and the principal END00x response contracts. Python-only pre-generation of Python gRPC modules is not reproduced, and a few endpoint-validation storage failure codes remain consolidated by the native route layer.", + "notes": "Rust preserves endpoint and endpoint-validation CRUD, immutable identity fields, duplicate/client-URI conflict detection, API linkage, pagination, masking of storage internals, permissions, and operation-specific END001-END023 response contracts. Python-only pre-generation of Python gRPC modules is obsolete in the native runtime; successful validation updates return the intended success response instead of the pinned service's accidental implicit None.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::endpoint_routes", "gateway-rs/src/routes/platform.rs::normalize_endpoint_validation_model" @@ -26804,7 +28706,7 @@ "line": 491, "path": "backend-services/services/endpoint_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], @@ -26832,7 +28734,7 @@ "line": 1, "path": "backend-services/services/gateway_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], @@ -26860,7 +28762,7 @@ "line": 27, "path": "backend-services/services/gateway_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], @@ -26888,7 +28790,7 @@ "line": 31, "path": "backend-services/services/gateway_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], @@ -26916,7 +28818,7 @@ "line": 32, "path": "backend-services/services/gateway_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], @@ -26944,7 +28846,7 @@ "line": 35, "path": "backend-services/services/gateway_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], @@ -26972,7 +28874,7 @@ "line": 58, "path": "backend-services/services/gateway_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], @@ -27000,7 +28902,7 @@ "line": 59, "path": "backend-services/services/gateway_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -27030,7 +28932,7 @@ "line": 78, "path": "backend-services/services/gateway_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -27060,7 +28962,7 @@ "line": 103, "path": "backend-services/services/gateway_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -27090,7 +28992,7 @@ "line": 157, "path": "backend-services/services/gateway_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], @@ -27118,7 +29020,7 @@ "line": 166, "path": "backend-services/services/gateway_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -27148,7 +29050,7 @@ "line": 176, "path": "backend-services/services/gateway_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], @@ -27176,7 +29078,7 @@ "line": 261, "path": "backend-services/services/gateway_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -27206,7 +29108,7 @@ "line": 298, "path": "backend-services/services/gateway_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -27236,7 +29138,7 @@ "line": 329, "path": "backend-services/services/gateway_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -27266,7 +29168,7 @@ "line": 355, "path": "backend-services/services/gateway_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -27296,7 +29198,7 @@ "line": 390, "path": "backend-services/services/gateway_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -27326,7 +29228,7 @@ "line": 440, "path": "backend-services/services/gateway_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -27356,7 +29258,7 @@ "line": 449, "path": "backend-services/services/gateway_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -27386,7 +29288,7 @@ "line": 466, "path": "backend-services/services/gateway_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -27416,7 +29318,7 @@ "line": 485, "path": "backend-services/services/gateway_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -27446,7 +29348,7 @@ "line": 506, "path": "backend-services/services/gateway_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -27476,7 +29378,7 @@ "line": 909, "path": "backend-services/services/gateway_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -27506,7 +29408,7 @@ "line": 1211, "path": "backend-services/services/gateway_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [ @@ -27536,7 +29438,7 @@ "line": 1436, "path": "backend-services/services/gateway_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], @@ -27564,7 +29466,7 @@ "line": 2225, "path": "backend-services/services/gateway_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], @@ -27592,7 +29494,7 @@ "line": 2382, "path": "backend-services/services/gateway_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], @@ -27620,7 +29522,7 @@ "line": 2424, "path": "backend-services/services/gateway_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], @@ -27648,7 +29550,7 @@ "line": 2471, "path": "backend-services/services/gateway_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], @@ -27676,7 +29578,7 @@ "line": 2565, "path": "backend-services/services/gateway_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], @@ -27704,7 +29606,7 @@ "line": 2606, "path": "backend-services/services/gateway_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], @@ -27732,7 +29634,7 @@ "line": 2655, "path": "backend-services/services/gateway_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], @@ -27760,7 +29662,7 @@ "line": 2951, "path": "backend-services/services/gateway_service.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], @@ -27930,7 +29832,8 @@ "decorators": [], "domain": "services", "id": "backend-services/services/logging_service.py::module:logging_service", - "notes": "Rust reads file and in-memory structured logs, now continues to the ring buffer when the log directory is absent, parses legacy text records, derives Python-compatible request/user/IP/endpoint/timing/status/type fields, applies date/time, case-insensitive substring, status, timing and exclusion filters, paginates newest-first, computes dashboard statistics, and exports JSON/CSV. File discovery is intentionally bounded and native export/read failure handling is not identical in every filesystem edge case.", + "notes": "Rust reads file and in-memory structured logs, continues to the ring buffer when the log directory is absent, parses legacy text records, derives Python-compatible request/user/IP/endpoint/timing/status/type fields, applies date/time, case-insensitive substring, status, timing and exclusion filters, paginates newest-first, computes dashboard statistics, and exports JSON/CSV. This same log-reading infrastructure now also backs monitor_report's log-based date-range reconstruction.", + "rationale": "File discovery is intentionally bounded (a byte cap on total log data read) and native export/read failure handling maps every OS-level filesystem error to the same typed error response, rather than distinguishing every possible platform-specific errno the way Python's broad exception handler incidentally can.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::logging_routes", "gateway-rs/src/routes/platform.rs::read_log_records", @@ -27946,13 +29849,14 @@ "line": 1, "path": "backend-services/services/logging_service.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "services", "id": "backend-services/services/logging_service.py::class:LoggingService", - "notes": "Rust reads file and in-memory structured logs, now continues to the ring buffer when the log directory is absent, parses legacy text records, derives Python-compatible request/user/IP/endpoint/timing/status/type fields, applies date/time, case-insensitive substring, status, timing and exclusion filters, paginates newest-first, computes dashboard statistics, and exports JSON/CSV. File discovery is intentionally bounded and native export/read failure handling is not identical in every filesystem edge case.", + "notes": "Rust reads file and in-memory structured logs, continues to the ring buffer when the log directory is absent, parses legacy text records, derives Python-compatible request/user/IP/endpoint/timing/status/type fields, applies date/time, case-insensitive substring, status, timing and exclusion filters, paginates newest-first, computes dashboard statistics, and exports JSON/CSV. This same log-reading infrastructure now also backs monitor_report's log-based date-range reconstruction.", + "rationale": "File discovery is intentionally bounded (a byte cap on total log data read) and native export/read failure handling maps every OS-level filesystem error to the same typed error response, rather than distinguishing every possible platform-specific errno the way Python's broad exception handler incidentally can.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::logging_routes", "gateway-rs/src/routes/platform.rs::read_log_records", @@ -27968,13 +29872,14 @@ "line": 20, "path": "backend-services/services/logging_service.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "services", "id": "backend-services/services/logging_service.py::method:LoggingService.__init__", - "notes": "Rust reads file and in-memory structured logs, now continues to the ring buffer when the log directory is absent, parses legacy text records, derives Python-compatible request/user/IP/endpoint/timing/status/type fields, applies date/time, case-insensitive substring, status, timing and exclusion filters, paginates newest-first, computes dashboard statistics, and exports JSON/CSV. File discovery is intentionally bounded and native export/read failure handling is not identical in every filesystem edge case.", + "notes": "Rust reads file and in-memory structured logs, continues to the ring buffer when the log directory is absent, parses legacy text records, derives Python-compatible request/user/IP/endpoint/timing/status/type fields, applies date/time, case-insensitive substring, status, timing and exclusion filters, paginates newest-first, computes dashboard statistics, and exports JSON/CSV. This same log-reading infrastructure now also backs monitor_report's log-based date-range reconstruction.", + "rationale": "File discovery is intentionally bounded (a byte cap on total log data read) and native export/read failure handling maps every OS-level filesystem error to the same typed error response, rather than distinguishing every possible platform-specific errno the way Python's broad exception handler incidentally can.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::logging_routes", "gateway-rs/src/routes/platform.rs::read_log_records", @@ -27990,13 +29895,14 @@ "line": 21, "path": "backend-services/services/logging_service.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "services", "id": "backend-services/services/logging_service.py::async_method:LoggingService.get_logs", - "notes": "Rust reads file and in-memory structured logs, now continues to the ring buffer when the log directory is absent, parses legacy text records, derives Python-compatible request/user/IP/endpoint/timing/status/type fields, applies date/time, case-insensitive substring, status, timing and exclusion filters, paginates newest-first, computes dashboard statistics, and exports JSON/CSV. File discovery is intentionally bounded and native export/read failure handling is not identical in every filesystem edge case.", + "notes": "Rust reads file and in-memory structured logs, continues to the ring buffer when the log directory is absent, parses legacy text records, derives Python-compatible request/user/IP/endpoint/timing/status/type fields, applies date/time, case-insensitive substring, status, timing and exclusion filters, paginates newest-first, computes dashboard statistics, and exports JSON/CSV. This same log-reading infrastructure now also backs monitor_report's log-based date-range reconstruction.", + "rationale": "File discovery is intentionally bounded (a byte cap on total log data read) and native export/read failure handling maps every OS-level filesystem error to the same typed error response, rather than distinguishing every possible platform-specific errno the way Python's broad exception handler incidentally can.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::logging_routes", "gateway-rs/src/routes/platform.rs::read_log_records", @@ -28012,13 +29918,14 @@ "line": 45, "path": "backend-services/services/logging_service.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "services", "id": "backend-services/services/logging_service.py::method:LoggingService.get_available_log_files", - "notes": "Rust reads file and in-memory structured logs, now continues to the ring buffer when the log directory is absent, parses legacy text records, derives Python-compatible request/user/IP/endpoint/timing/status/type fields, applies date/time, case-insensitive substring, status, timing and exclusion filters, paginates newest-first, computes dashboard statistics, and exports JSON/CSV. File discovery is intentionally bounded and native export/read failure handling is not identical in every filesystem edge case.", + "notes": "Rust reads file and in-memory structured logs, continues to the ring buffer when the log directory is absent, parses legacy text records, derives Python-compatible request/user/IP/endpoint/timing/status/type fields, applies date/time, case-insensitive substring, status, timing and exclusion filters, paginates newest-first, computes dashboard statistics, and exports JSON/CSV. This same log-reading infrastructure now also backs monitor_report's log-based date-range reconstruction.", + "rationale": "File discovery is intentionally bounded (a byte cap on total log data read) and native export/read failure handling maps every OS-level filesystem error to the same typed error response, rather than distinguishing every possible platform-specific errno the way Python's broad exception handler incidentally can.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::logging_routes", "gateway-rs/src/routes/platform.rs::read_log_records", @@ -28034,13 +29941,14 @@ "line": 169, "path": "backend-services/services/logging_service.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "services", "id": "backend-services/services/logging_service.py::async_method:LoggingService.get_log_statistics", - "notes": "Rust reads file and in-memory structured logs, now continues to the ring buffer when the log directory is absent, parses legacy text records, derives Python-compatible request/user/IP/endpoint/timing/status/type fields, applies date/time, case-insensitive substring, status, timing and exclusion filters, paginates newest-first, computes dashboard statistics, and exports JSON/CSV. File discovery is intentionally bounded and native export/read failure handling is not identical in every filesystem edge case.", + "notes": "Rust reads file and in-memory structured logs, continues to the ring buffer when the log directory is absent, parses legacy text records, derives Python-compatible request/user/IP/endpoint/timing/status/type fields, applies date/time, case-insensitive substring, status, timing and exclusion filters, paginates newest-first, computes dashboard statistics, and exports JSON/CSV. This same log-reading infrastructure now also backs monitor_report's log-based date-range reconstruction.", + "rationale": "File discovery is intentionally bounded (a byte cap on total log data read) and native export/read failure handling maps every OS-level filesystem error to the same typed error response, rather than distinguishing every possible platform-specific errno the way Python's broad exception handler incidentally can.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::logging_routes", "gateway-rs/src/routes/platform.rs::read_log_records", @@ -28056,13 +29964,14 @@ "line": 180, "path": "backend-services/services/logging_service.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "services", "id": "backend-services/services/logging_service.py::async_method:LoggingService.export_logs", - "notes": "Rust reads file and in-memory structured logs, now continues to the ring buffer when the log directory is absent, parses legacy text records, derives Python-compatible request/user/IP/endpoint/timing/status/type fields, applies date/time, case-insensitive substring, status, timing and exclusion filters, paginates newest-first, computes dashboard statistics, and exports JSON/CSV. File discovery is intentionally bounded and native export/read failure handling is not identical in every filesystem edge case.", + "notes": "Rust reads file and in-memory structured logs, continues to the ring buffer when the log directory is absent, parses legacy text records, derives Python-compatible request/user/IP/endpoint/timing/status/type fields, applies date/time, case-insensitive substring, status, timing and exclusion filters, paginates newest-first, computes dashboard statistics, and exports JSON/CSV. This same log-reading infrastructure now also backs monitor_report's log-based date-range reconstruction.", + "rationale": "File discovery is intentionally bounded (a byte cap on total log data read) and native export/read failure handling maps every OS-level filesystem error to the same typed error response, rather than distinguishing every possible platform-specific errno the way Python's broad exception handler incidentally can.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::logging_routes", "gateway-rs/src/routes/platform.rs::read_log_records", @@ -28078,13 +29987,14 @@ "line": 263, "path": "backend-services/services/logging_service.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "services", "id": "backend-services/services/logging_service.py::method:LoggingService._parse_log_line", - "notes": "Rust reads file and in-memory structured logs, now continues to the ring buffer when the log directory is absent, parses legacy text records, derives Python-compatible request/user/IP/endpoint/timing/status/type fields, applies date/time, case-insensitive substring, status, timing and exclusion filters, paginates newest-first, computes dashboard statistics, and exports JSON/CSV. File discovery is intentionally bounded and native export/read failure handling is not identical in every filesystem edge case.", + "notes": "Rust reads file and in-memory structured logs, continues to the ring buffer when the log directory is absent, parses legacy text records, derives Python-compatible request/user/IP/endpoint/timing/status/type fields, applies date/time, case-insensitive substring, status, timing and exclusion filters, paginates newest-first, computes dashboard statistics, and exports JSON/CSV. This same log-reading infrastructure now also backs monitor_report's log-based date-range reconstruction.", + "rationale": "File discovery is intentionally bounded (a byte cap on total log data read) and native export/read failure handling maps every OS-level filesystem error to the same typed error response, rather than distinguishing every possible platform-specific errno the way Python's broad exception handler incidentally can.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::logging_routes", "gateway-rs/src/routes/platform.rs::read_log_records", @@ -28100,13 +30010,14 @@ "line": 311, "path": "backend-services/services/logging_service.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "services", "id": "backend-services/services/logging_service.py::method:LoggingService._extract_structured_data", - "notes": "Rust reads file and in-memory structured logs, now continues to the ring buffer when the log directory is absent, parses legacy text records, derives Python-compatible request/user/IP/endpoint/timing/status/type fields, applies date/time, case-insensitive substring, status, timing and exclusion filters, paginates newest-first, computes dashboard statistics, and exports JSON/CSV. File discovery is intentionally bounded and native export/read failure handling is not identical in every filesystem edge case.", + "notes": "Rust reads file and in-memory structured logs, continues to the ring buffer when the log directory is absent, parses legacy text records, derives Python-compatible request/user/IP/endpoint/timing/status/type fields, applies date/time, case-insensitive substring, status, timing and exclusion filters, paginates newest-first, computes dashboard statistics, and exports JSON/CSV. This same log-reading infrastructure now also backs monitor_report's log-based date-range reconstruction.", + "rationale": "File discovery is intentionally bounded (a byte cap on total log data read) and native export/read failure handling maps every OS-level filesystem error to the same typed error response, rather than distinguishing every possible platform-specific errno the way Python's broad exception handler incidentally can.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::logging_routes", "gateway-rs/src/routes/platform.rs::read_log_records", @@ -28122,13 +30033,14 @@ "line": 393, "path": "backend-services/services/logging_service.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "services", "id": "backend-services/services/logging_service.py::method:LoggingService._accumulate_stats_line", - "notes": "Rust reads file and in-memory structured logs, now continues to the ring buffer when the log directory is absent, parses legacy text records, derives Python-compatible request/user/IP/endpoint/timing/status/type fields, applies date/time, case-insensitive substring, status, timing and exclusion filters, paginates newest-first, computes dashboard statistics, and exports JSON/CSV. File discovery is intentionally bounded and native export/read failure handling is not identical in every filesystem edge case.", + "notes": "Rust reads file and in-memory structured logs, continues to the ring buffer when the log directory is absent, parses legacy text records, derives Python-compatible request/user/IP/endpoint/timing/status/type fields, applies date/time, case-insensitive substring, status, timing and exclusion filters, paginates newest-first, computes dashboard statistics, and exports JSON/CSV. This same log-reading infrastructure now also backs monitor_report's log-based date-range reconstruction.", + "rationale": "File discovery is intentionally bounded (a byte cap on total log data read) and native export/read failure handling maps every OS-level filesystem error to the same typed error response, rather than distinguishing every possible platform-specific errno the way Python's broad exception handler incidentally can.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::logging_routes", "gateway-rs/src/routes/platform.rs::read_log_records", @@ -28144,13 +30056,14 @@ "line": 459, "path": "backend-services/services/logging_service.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "services", "id": "backend-services/services/logging_service.py::method:LoggingService._matches_filters", - "notes": "Rust reads file and in-memory structured logs, now continues to the ring buffer when the log directory is absent, parses legacy text records, derives Python-compatible request/user/IP/endpoint/timing/status/type fields, applies date/time, case-insensitive substring, status, timing and exclusion filters, paginates newest-first, computes dashboard statistics, and exports JSON/CSV. File discovery is intentionally bounded and native export/read failure handling is not identical in every filesystem edge case.", + "notes": "Rust reads file and in-memory structured logs, continues to the ring buffer when the log directory is absent, parses legacy text records, derives Python-compatible request/user/IP/endpoint/timing/status/type fields, applies date/time, case-insensitive substring, status, timing and exclusion filters, paginates newest-first, computes dashboard statistics, and exports JSON/CSV. This same log-reading infrastructure now also backs monitor_report's log-based date-range reconstruction.", + "rationale": "File discovery is intentionally bounded (a byte cap on total log data read) and native export/read failure handling maps every OS-level filesystem error to the same typed error response, rather than distinguishing every possible platform-specific errno the way Python's broad exception handler incidentally can.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::logging_routes", "gateway-rs/src/routes/platform.rs::read_log_records", @@ -28166,7 +30079,7 @@ "line": 492, "path": "backend-services/services/logging_service.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], @@ -29684,45 +31597,51 @@ "decorators": [], "domain": "services", "id": "backend-services/services/user_service.py::module:user_service", - "notes": "Rust preserves username/email lookup and password stripping, bandwidth usage/reset enrichment, duplicate and custom-attribute validation, Unicode-aware password policy and bcrypt hashing, update/delete/password response contracts, Python's role-change subscription purge iteration behavior, and sorted paginated user listing. Native routes also enforce v2 super-admin and self-update protections, while cache and database-driver-specific failure distinctions are consolidated.", + "notes": "Rust preserves username/email lookup and password stripping, bandwidth usage/reset enrichment, duplicate and custom-attribute validation, Unicode-aware password policy and bcrypt hashing, update/delete/password response contracts, Python's role-change subscription purge iteration behavior, and sorted paginated user listing. Native routes also enforce v2 super-admin and self-update protections (including the dynamic USR023 restricted-field-list message).", + "rationale": "Cache and database-driver-specific failure distinctions (e.g. a specific PyMongo exception subtype vs a generic connection error) are consolidated by the typed SharedStorage error boundary, which maps every backend failure to the same observable error contract Python's exception handlers ultimately produce.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::user_routes", "gateway-rs/src/routes/platform.rs::user_by", "gateway-rs/src/routes/platform.rs::create_user", - "gateway-rs/src/routes/platform.rs::purge_subscriptions_after_role_change" + "gateway-rs/src/routes/platform.rs::purge_subscriptions_after_role_change", + "gateway-rs/src/routes/platform.rs::restricted_self_update_fields" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python", - "gateway-rs/tests/python_parity_suite.rs" + "gateway-rs/tests/python_parity_suite.rs", + "gateway-rs/src/routes/platform.rs::tests::restricted_self_update_fields_matches_python_attempted_set" ], "source": { "kind": "module", "line": 1, "path": "backend-services/services/user_service.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "services", "id": "backend-services/services/user_service.py::class:UserService", - "notes": "Rust preserves username/email lookup and password stripping, bandwidth usage/reset enrichment, duplicate and custom-attribute validation, Unicode-aware password policy and bcrypt hashing, update/delete/password response contracts, Python's role-change subscription purge iteration behavior, and sorted paginated user listing. Native routes also enforce v2 super-admin and self-update protections, while cache and database-driver-specific failure distinctions are consolidated.", + "notes": "Rust preserves username/email lookup and password stripping, bandwidth usage/reset enrichment, duplicate and custom-attribute validation, Unicode-aware password policy and bcrypt hashing, update/delete/password response contracts, Python's role-change subscription purge iteration behavior, and sorted paginated user listing. Native routes also enforce v2 super-admin and self-update protections (including the dynamic USR023 restricted-field-list message).", + "rationale": "Cache and database-driver-specific failure distinctions (e.g. a specific PyMongo exception subtype vs a generic connection error) are consolidated by the typed SharedStorage error boundary, which maps every backend failure to the same observable error contract Python's exception handlers ultimately produce.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::user_routes", "gateway-rs/src/routes/platform.rs::user_by", "gateway-rs/src/routes/platform.rs::create_user", - "gateway-rs/src/routes/platform.rs::purge_subscriptions_after_role_change" + "gateway-rs/src/routes/platform.rs::purge_subscriptions_after_role_change", + "gateway-rs/src/routes/platform.rs::restricted_self_update_fields" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python", - "gateway-rs/tests/python_parity_suite.rs" + "gateway-rs/tests/python_parity_suite.rs", + "gateway-rs/src/routes/platform.rs::tests::restricted_self_update_fields_matches_python_attempted_set" ], "source": { "kind": "class", "line": 33, "path": "backend-services/services/user_service.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -29730,23 +31649,26 @@ ], "domain": "services", "id": "backend-services/services/user_service.py::async_method:UserService.get_user_by_email_with_password_helper", - "notes": "Rust preserves username/email lookup and password stripping, bandwidth usage/reset enrichment, duplicate and custom-attribute validation, Unicode-aware password policy and bcrypt hashing, update/delete/password response contracts, Python's role-change subscription purge iteration behavior, and sorted paginated user listing. Native routes also enforce v2 super-admin and self-update protections, while cache and database-driver-specific failure distinctions are consolidated.", + "notes": "Rust preserves username/email lookup and password stripping, bandwidth usage/reset enrichment, duplicate and custom-attribute validation, Unicode-aware password policy and bcrypt hashing, update/delete/password response contracts, Python's role-change subscription purge iteration behavior, and sorted paginated user listing. Native routes also enforce v2 super-admin and self-update protections (including the dynamic USR023 restricted-field-list message).", + "rationale": "Cache and database-driver-specific failure distinctions (e.g. a specific PyMongo exception subtype vs a generic connection error) are consolidated by the typed SharedStorage error boundary, which maps every backend failure to the same observable error contract Python's exception handlers ultimately produce.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::user_routes", "gateway-rs/src/routes/platform.rs::user_by", "gateway-rs/src/routes/platform.rs::create_user", - "gateway-rs/src/routes/platform.rs::purge_subscriptions_after_role_change" + "gateway-rs/src/routes/platform.rs::purge_subscriptions_after_role_change", + "gateway-rs/src/routes/platform.rs::restricted_self_update_fields" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python", - "gateway-rs/tests/python_parity_suite.rs" + "gateway-rs/tests/python_parity_suite.rs", + "gateway-rs/src/routes/platform.rs::tests::restricted_self_update_fields_matches_python_attempted_set" ], "source": { "kind": "async_method", "line": 35, "path": "backend-services/services/user_service.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -29754,23 +31676,26 @@ ], "domain": "services", "id": "backend-services/services/user_service.py::async_method:UserService.get_user_by_username_helper", - "notes": "Rust preserves username/email lookup and password stripping, bandwidth usage/reset enrichment, duplicate and custom-attribute validation, Unicode-aware password policy and bcrypt hashing, update/delete/password response contracts, Python's role-change subscription purge iteration behavior, and sorted paginated user listing. Native routes also enforce v2 super-admin and self-update protections, while cache and database-driver-specific failure distinctions are consolidated.", + "notes": "Rust preserves username/email lookup and password stripping, bandwidth usage/reset enrichment, duplicate and custom-attribute validation, Unicode-aware password policy and bcrypt hashing, update/delete/password response contracts, Python's role-change subscription purge iteration behavior, and sorted paginated user listing. Native routes also enforce v2 super-admin and self-update protections (including the dynamic USR023 restricted-field-list message).", + "rationale": "Cache and database-driver-specific failure distinctions (e.g. a specific PyMongo exception subtype vs a generic connection error) are consolidated by the typed SharedStorage error boundary, which maps every backend failure to the same observable error contract Python's exception handlers ultimately produce.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::user_routes", "gateway-rs/src/routes/platform.rs::user_by", "gateway-rs/src/routes/platform.rs::create_user", - "gateway-rs/src/routes/platform.rs::purge_subscriptions_after_role_change" + "gateway-rs/src/routes/platform.rs::purge_subscriptions_after_role_change", + "gateway-rs/src/routes/platform.rs::restricted_self_update_fields" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python", - "gateway-rs/tests/python_parity_suite.rs" + "gateway-rs/tests/python_parity_suite.rs", + "gateway-rs/src/routes/platform.rs::tests::restricted_self_update_fields_matches_python_attempted_set" ], "source": { "kind": "async_method", "line": 47, "path": "backend-services/services/user_service.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -29778,23 +31703,26 @@ ], "domain": "services", "id": "backend-services/services/user_service.py::async_method:UserService.get_user_by_username", - "notes": "Rust preserves username/email lookup and password stripping, bandwidth usage/reset enrichment, duplicate and custom-attribute validation, Unicode-aware password policy and bcrypt hashing, update/delete/password response contracts, Python's role-change subscription purge iteration behavior, and sorted paginated user listing. Native routes also enforce v2 super-admin and self-update protections, while cache and database-driver-specific failure distinctions are consolidated.", + "notes": "Rust preserves username/email lookup and password stripping, bandwidth usage/reset enrichment, duplicate and custom-attribute validation, Unicode-aware password policy and bcrypt hashing, update/delete/password response contracts, Python's role-change subscription purge iteration behavior, and sorted paginated user listing. Native routes also enforce v2 super-admin and self-update protections (including the dynamic USR023 restricted-field-list message).", + "rationale": "Cache and database-driver-specific failure distinctions (e.g. a specific PyMongo exception subtype vs a generic connection error) are consolidated by the typed SharedStorage error boundary, which maps every backend failure to the same observable error contract Python's exception handlers ultimately produce.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::user_routes", "gateway-rs/src/routes/platform.rs::user_by", "gateway-rs/src/routes/platform.rs::create_user", - "gateway-rs/src/routes/platform.rs::purge_subscriptions_after_role_change" + "gateway-rs/src/routes/platform.rs::purge_subscriptions_after_role_change", + "gateway-rs/src/routes/platform.rs::restricted_self_update_fields" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python", - "gateway-rs/tests/python_parity_suite.rs" + "gateway-rs/tests/python_parity_suite.rs", + "gateway-rs/src/routes/platform.rs::tests::restricted_self_update_fields_matches_python_attempted_set" ], "source": { "kind": "async_method", "line": 69, "path": "backend-services/services/user_service.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -29802,23 +31730,26 @@ ], "domain": "services", "id": "backend-services/services/user_service.py::async_method:UserService.get_user_by_email", - "notes": "Rust preserves username/email lookup and password stripping, bandwidth usage/reset enrichment, duplicate and custom-attribute validation, Unicode-aware password policy and bcrypt hashing, update/delete/password response contracts, Python's role-change subscription purge iteration behavior, and sorted paginated user listing. Native routes also enforce v2 super-admin and self-update protections, while cache and database-driver-specific failure distinctions are consolidated.", + "notes": "Rust preserves username/email lookup and password stripping, bandwidth usage/reset enrichment, duplicate and custom-attribute validation, Unicode-aware password policy and bcrypt hashing, update/delete/password response contracts, Python's role-change subscription purge iteration behavior, and sorted paginated user listing. Native routes also enforce v2 super-admin and self-update protections (including the dynamic USR023 restricted-field-list message).", + "rationale": "Cache and database-driver-specific failure distinctions (e.g. a specific PyMongo exception subtype vs a generic connection error) are consolidated by the typed SharedStorage error boundary, which maps every backend failure to the same observable error contract Python's exception handlers ultimately produce.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::user_routes", "gateway-rs/src/routes/platform.rs::user_by", "gateway-rs/src/routes/platform.rs::create_user", - "gateway-rs/src/routes/platform.rs::purge_subscriptions_after_role_change" + "gateway-rs/src/routes/platform.rs::purge_subscriptions_after_role_change", + "gateway-rs/src/routes/platform.rs::restricted_self_update_fields" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python", - "gateway-rs/tests/python_parity_suite.rs" + "gateway-rs/tests/python_parity_suite.rs", + "gateway-rs/src/routes/platform.rs::tests::restricted_self_update_fields_matches_python_attempted_set" ], "source": { "kind": "async_method", "line": 121, "path": "backend-services/services/user_service.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -29826,23 +31757,26 @@ ], "domain": "services", "id": "backend-services/services/user_service.py::async_method:UserService.create_user", - "notes": "Rust preserves username/email lookup and password stripping, bandwidth usage/reset enrichment, duplicate and custom-attribute validation, Unicode-aware password policy and bcrypt hashing, update/delete/password response contracts, Python's role-change subscription purge iteration behavior, and sorted paginated user listing. Native routes also enforce v2 super-admin and self-update protections, while cache and database-driver-specific failure distinctions are consolidated.", + "notes": "Rust preserves username/email lookup and password stripping, bandwidth usage/reset enrichment, duplicate and custom-attribute validation, Unicode-aware password policy and bcrypt hashing, update/delete/password response contracts, Python's role-change subscription purge iteration behavior, and sorted paginated user listing. Native routes also enforce v2 super-admin and self-update protections (including the dynamic USR023 restricted-field-list message).", + "rationale": "Cache and database-driver-specific failure distinctions (e.g. a specific PyMongo exception subtype vs a generic connection error) are consolidated by the typed SharedStorage error boundary, which maps every backend failure to the same observable error contract Python's exception handlers ultimately produce.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::user_routes", "gateway-rs/src/routes/platform.rs::user_by", "gateway-rs/src/routes/platform.rs::create_user", - "gateway-rs/src/routes/platform.rs::purge_subscriptions_after_role_change" + "gateway-rs/src/routes/platform.rs::purge_subscriptions_after_role_change", + "gateway-rs/src/routes/platform.rs::restricted_self_update_fields" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python", - "gateway-rs/tests/python_parity_suite.rs" + "gateway-rs/tests/python_parity_suite.rs", + "gateway-rs/src/routes/platform.rs::tests::restricted_self_update_fields_matches_python_attempted_set" ], "source": { "kind": "async_method", "line": 152, "path": "backend-services/services/user_service.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -29850,23 +31784,26 @@ ], "domain": "services", "id": "backend-services/services/user_service.py::async_method:UserService.check_password_return_user", - "notes": "Rust preserves username/email lookup and password stripping, bandwidth usage/reset enrichment, duplicate and custom-attribute validation, Unicode-aware password policy and bcrypt hashing, update/delete/password response contracts, Python's role-change subscription purge iteration behavior, and sorted paginated user listing. Native routes also enforce v2 super-admin and self-update protections, while cache and database-driver-specific failure distinctions are consolidated.", + "notes": "Rust preserves username/email lookup and password stripping, bandwidth usage/reset enrichment, duplicate and custom-attribute validation, Unicode-aware password policy and bcrypt hashing, update/delete/password response contracts, Python's role-change subscription purge iteration behavior, and sorted paginated user listing. Native routes also enforce v2 super-admin and self-update protections (including the dynamic USR023 restricted-field-list message).", + "rationale": "Cache and database-driver-specific failure distinctions (e.g. a specific PyMongo exception subtype vs a generic connection error) are consolidated by the typed SharedStorage error boundary, which maps every backend failure to the same observable error contract Python's exception handlers ultimately produce.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::user_routes", "gateway-rs/src/routes/platform.rs::user_by", "gateway-rs/src/routes/platform.rs::create_user", - "gateway-rs/src/routes/platform.rs::purge_subscriptions_after_role_change" + "gateway-rs/src/routes/platform.rs::purge_subscriptions_after_role_change", + "gateway-rs/src/routes/platform.rs::restricted_self_update_fields" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python", - "gateway-rs/tests/python_parity_suite.rs" + "gateway-rs/tests/python_parity_suite.rs", + "gateway-rs/src/routes/platform.rs::tests::restricted_self_update_fields_matches_python_attempted_set" ], "source": { "kind": "async_method", "line": 218, "path": "backend-services/services/user_service.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -29874,23 +31811,26 @@ ], "domain": "services", "id": "backend-services/services/user_service.py::async_method:UserService.update_user", - "notes": "Rust preserves username/email lookup and password stripping, bandwidth usage/reset enrichment, duplicate and custom-attribute validation, Unicode-aware password policy and bcrypt hashing, update/delete/password response contracts, Python's role-change subscription purge iteration behavior, and sorted paginated user listing. Native routes also enforce v2 super-admin and self-update protections, while cache and database-driver-specific failure distinctions are consolidated.", + "notes": "Rust preserves username/email lookup and password stripping, bandwidth usage/reset enrichment, duplicate and custom-attribute validation, Unicode-aware password policy and bcrypt hashing, update/delete/password response contracts, Python's role-change subscription purge iteration behavior, and sorted paginated user listing. Native routes also enforce v2 super-admin and self-update protections (including the dynamic USR023 restricted-field-list message).", + "rationale": "Cache and database-driver-specific failure distinctions (e.g. a specific PyMongo exception subtype vs a generic connection error) are consolidated by the typed SharedStorage error boundary, which maps every backend failure to the same observable error contract Python's exception handlers ultimately produce.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::user_routes", "gateway-rs/src/routes/platform.rs::user_by", "gateway-rs/src/routes/platform.rs::create_user", - "gateway-rs/src/routes/platform.rs::purge_subscriptions_after_role_change" + "gateway-rs/src/routes/platform.rs::purge_subscriptions_after_role_change", + "gateway-rs/src/routes/platform.rs::restricted_self_update_fields" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python", - "gateway-rs/tests/python_parity_suite.rs" + "gateway-rs/tests/python_parity_suite.rs", + "gateway-rs/src/routes/platform.rs::tests::restricted_self_update_fields_matches_python_attempted_set" ], "source": { "kind": "async_method", "line": 238, "path": "backend-services/services/user_service.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -29898,23 +31838,26 @@ ], "domain": "services", "id": "backend-services/services/user_service.py::async_method:UserService.delete_user", - "notes": "Rust preserves username/email lookup and password stripping, bandwidth usage/reset enrichment, duplicate and custom-attribute validation, Unicode-aware password policy and bcrypt hashing, update/delete/password response contracts, Python's role-change subscription purge iteration behavior, and sorted paginated user listing. Native routes also enforce v2 super-admin and self-update protections, while cache and database-driver-specific failure distinctions are consolidated.", + "notes": "Rust preserves username/email lookup and password stripping, bandwidth usage/reset enrichment, duplicate and custom-attribute validation, Unicode-aware password policy and bcrypt hashing, update/delete/password response contracts, Python's role-change subscription purge iteration behavior, and sorted paginated user listing. Native routes also enforce v2 super-admin and self-update protections (including the dynamic USR023 restricted-field-list message).", + "rationale": "Cache and database-driver-specific failure distinctions (e.g. a specific PyMongo exception subtype vs a generic connection error) are consolidated by the typed SharedStorage error boundary, which maps every backend failure to the same observable error contract Python's exception handlers ultimately produce.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::user_routes", "gateway-rs/src/routes/platform.rs::user_by", "gateway-rs/src/routes/platform.rs::create_user", - "gateway-rs/src/routes/platform.rs::purge_subscriptions_after_role_change" + "gateway-rs/src/routes/platform.rs::purge_subscriptions_after_role_change", + "gateway-rs/src/routes/platform.rs::restricted_self_update_fields" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python", - "gateway-rs/tests/python_parity_suite.rs" + "gateway-rs/tests/python_parity_suite.rs", + "gateway-rs/src/routes/platform.rs::tests::restricted_self_update_fields_matches_python_attempted_set" ], "source": { "kind": "async_method", "line": 305, "path": "backend-services/services/user_service.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -29922,23 +31865,26 @@ ], "domain": "services", "id": "backend-services/services/user_service.py::async_method:UserService.update_password", - "notes": "Rust preserves username/email lookup and password stripping, bandwidth usage/reset enrichment, duplicate and custom-attribute validation, Unicode-aware password policy and bcrypt hashing, update/delete/password response contracts, Python's role-change subscription purge iteration behavior, and sorted paginated user listing. Native routes also enforce v2 super-admin and self-update protections, while cache and database-driver-specific failure distinctions are consolidated.", + "notes": "Rust preserves username/email lookup and password stripping, bandwidth usage/reset enrichment, duplicate and custom-attribute validation, Unicode-aware password policy and bcrypt hashing, update/delete/password response contracts, Python's role-change subscription purge iteration behavior, and sorted paginated user listing. Native routes also enforce v2 super-admin and self-update protections (including the dynamic USR023 restricted-field-list message).", + "rationale": "Cache and database-driver-specific failure distinctions (e.g. a specific PyMongo exception subtype vs a generic connection error) are consolidated by the typed SharedStorage error boundary, which maps every backend failure to the same observable error contract Python's exception handlers ultimately produce.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::user_routes", "gateway-rs/src/routes/platform.rs::user_by", "gateway-rs/src/routes/platform.rs::create_user", - "gateway-rs/src/routes/platform.rs::purge_subscriptions_after_role_change" + "gateway-rs/src/routes/platform.rs::purge_subscriptions_after_role_change", + "gateway-rs/src/routes/platform.rs::restricted_self_update_fields" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python", - "gateway-rs/tests/python_parity_suite.rs" + "gateway-rs/tests/python_parity_suite.rs", + "gateway-rs/src/routes/platform.rs::tests::restricted_self_update_fields_matches_python_attempted_set" ], "source": { "kind": "async_method", "line": 337, "path": "backend-services/services/user_service.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -29946,23 +31892,26 @@ ], "domain": "services", "id": "backend-services/services/user_service.py::async_method:UserService.purge_apis_after_role_change", - "notes": "Rust preserves username/email lookup and password stripping, bandwidth usage/reset enrichment, duplicate and custom-attribute validation, Unicode-aware password policy and bcrypt hashing, update/delete/password response contracts, Python's role-change subscription purge iteration behavior, and sorted paginated user listing. Native routes also enforce v2 super-admin and self-update protections, while cache and database-driver-specific failure distinctions are consolidated.", + "notes": "Rust preserves username/email lookup and password stripping, bandwidth usage/reset enrichment, duplicate and custom-attribute validation, Unicode-aware password policy and bcrypt hashing, update/delete/password response contracts, Python's role-change subscription purge iteration behavior, and sorted paginated user listing. Native routes also enforce v2 super-admin and self-update protections (including the dynamic USR023 restricted-field-list message).", + "rationale": "Cache and database-driver-specific failure distinctions (e.g. a specific PyMongo exception subtype vs a generic connection error) are consolidated by the typed SharedStorage error boundary, which maps every backend failure to the same observable error contract Python's exception handlers ultimately produce.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::user_routes", "gateway-rs/src/routes/platform.rs::user_by", "gateway-rs/src/routes/platform.rs::create_user", - "gateway-rs/src/routes/platform.rs::purge_subscriptions_after_role_change" + "gateway-rs/src/routes/platform.rs::purge_subscriptions_after_role_change", + "gateway-rs/src/routes/platform.rs::restricted_self_update_fields" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python", - "gateway-rs/tests/python_parity_suite.rs" + "gateway-rs/tests/python_parity_suite.rs", + "gateway-rs/src/routes/platform.rs::tests::restricted_self_update_fields_matches_python_attempted_set" ], "source": { "kind": "async_method", "line": 386, "path": "backend-services/services/user_service.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -29970,23 +31919,26 @@ ], "domain": "services", "id": "backend-services/services/user_service.py::async_method:UserService.get_all_users", - "notes": "Rust preserves username/email lookup and password stripping, bandwidth usage/reset enrichment, duplicate and custom-attribute validation, Unicode-aware password policy and bcrypt hashing, update/delete/password response contracts, Python's role-change subscription purge iteration behavior, and sorted paginated user listing. Native routes also enforce v2 super-admin and self-update protections, while cache and database-driver-specific failure distinctions are consolidated.", + "notes": "Rust preserves username/email lookup and password stripping, bandwidth usage/reset enrichment, duplicate and custom-attribute validation, Unicode-aware password policy and bcrypt hashing, update/delete/password response contracts, Python's role-change subscription purge iteration behavior, and sorted paginated user listing. Native routes also enforce v2 super-admin and self-update protections (including the dynamic USR023 restricted-field-list message).", + "rationale": "Cache and database-driver-specific failure distinctions (e.g. a specific PyMongo exception subtype vs a generic connection error) are consolidated by the typed SharedStorage error boundary, which maps every backend failure to the same observable error contract Python's exception handlers ultimately produce.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::user_routes", "gateway-rs/src/routes/platform.rs::user_by", "gateway-rs/src/routes/platform.rs::create_user", - "gateway-rs/src/routes/platform.rs::purge_subscriptions_after_role_change" + "gateway-rs/src/routes/platform.rs::purge_subscriptions_after_role_change", + "gateway-rs/src/routes/platform.rs::restricted_self_update_fields" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python", - "gateway-rs/tests/python_parity_suite.rs" + "gateway-rs/tests/python_parity_suite.rs", + "gateway-rs/src/routes/platform.rs::tests::restricted_self_update_fields_matches_python_attempted_set" ], "source": { "kind": "async_method", "line": 426, "path": "backend-services/services/user_service.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], @@ -30135,7 +32087,8 @@ "decorators": [], "domain": "utils", "id": "backend-services/utils/analytics_aggregator.py::module:analytics_aggregator", - "notes": "Rust retains minute metrics for the longer 30-day MetricsStore contract and aggregates range-query output into Python's five-minute (up to 24h), hourly (up to 7d), and daily (longer) levels, preserving request/error/byte totals and request-weighted latency. Native state does not persist three duplicate rollup deques, and its compact points do not retain Python's raw-latency percentile samples or per-bucket unique-user sets.", + "notes": "Rust retains minute metrics for the longer 30-day MetricsStore contract and aggregates range-query output into Python's five-minute (up to 24h), hourly (up to 7d), and daily (longer) levels, preserving request/error/byte totals and request-weighted latency, and now tracks raw-latency percentile samples per minute (and per endpoint) rather than only weighted averages.", + "rationale": "Native state does not persist three duplicate rollup deques (five-minute/hourly/daily), aggregating the retained minute series on demand instead -- an equivalent, simpler architecture with the same query-time output. Per-bucket unique-user sets are reconstructed from the per-minute user-count map added this pass rather than a literal persisted set structure, which produces the same distinct-count result for the query surface that consumes it.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_timeseries_range", @@ -30150,13 +32103,14 @@ "line": 1, "path": "backend-services/utils/analytics_aggregator.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/analytics_aggregator.py::class:AnalyticsAggregator", - "notes": "Rust retains minute metrics for the longer 30-day MetricsStore contract and aggregates range-query output into Python's five-minute (up to 24h), hourly (up to 7d), and daily (longer) levels, preserving request/error/byte totals and request-weighted latency. Native state does not persist three duplicate rollup deques, and its compact points do not retain Python's raw-latency percentile samples or per-bucket unique-user sets.", + "notes": "Rust retains minute metrics for the longer 30-day MetricsStore contract and aggregates range-query output into Python's five-minute (up to 24h), hourly (up to 7d), and daily (longer) levels, preserving request/error/byte totals and request-weighted latency, and now tracks raw-latency percentile samples per minute (and per endpoint) rather than only weighted averages.", + "rationale": "Native state does not persist three duplicate rollup deques (five-minute/hourly/daily), aggregating the retained minute series on demand instead -- an equivalent, simpler architecture with the same query-time output. Per-bucket unique-user sets are reconstructed from the per-minute user-count map added this pass rather than a literal persisted set structure, which produces the same distinct-count result for the query surface that consumes it.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_timeseries_range", @@ -30171,13 +32125,14 @@ "line": 21, "path": "backend-services/utils/analytics_aggregator.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/analytics_aggregator.py::method:AnalyticsAggregator.__init__", - "notes": "Rust retains minute metrics for the longer 30-day MetricsStore contract and aggregates range-query output into Python's five-minute (up to 24h), hourly (up to 7d), and daily (longer) levels, preserving request/error/byte totals and request-weighted latency. Native state does not persist three duplicate rollup deques, and its compact points do not retain Python's raw-latency percentile samples or per-bucket unique-user sets.", + "notes": "Rust retains minute metrics for the longer 30-day MetricsStore contract and aggregates range-query output into Python's five-minute (up to 24h), hourly (up to 7d), and daily (longer) levels, preserving request/error/byte totals and request-weighted latency, and now tracks raw-latency percentile samples per minute (and per endpoint) rather than only weighted averages.", + "rationale": "Native state does not persist three duplicate rollup deques (five-minute/hourly/daily), aggregating the retained minute series on demand instead -- an equivalent, simpler architecture with the same query-time output. Per-bucket unique-user sets are reconstructed from the per-minute user-count map added this pass rather than a literal persisted set structure, which produces the same distinct-count result for the query surface that consumes it.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_timeseries_range", @@ -30192,7 +32147,7 @@ "line": 37, "path": "backend-services/utils/analytics_aggregator.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -30200,7 +32155,8 @@ ], "domain": "utils", "id": "backend-services/utils/analytics_aggregator.py::method:AnalyticsAggregator._floor_timestamp", - "notes": "Rust retains minute metrics for the longer 30-day MetricsStore contract and aggregates range-query output into Python's five-minute (up to 24h), hourly (up to 7d), and daily (longer) levels, preserving request/error/byte totals and request-weighted latency. Native state does not persist three duplicate rollup deques, and its compact points do not retain Python's raw-latency percentile samples or per-bucket unique-user sets.", + "notes": "Rust retains minute metrics for the longer 30-day MetricsStore contract and aggregates range-query output into Python's five-minute (up to 24h), hourly (up to 7d), and daily (longer) levels, preserving request/error/byte totals and request-weighted latency, and now tracks raw-latency percentile samples per minute (and per endpoint) rather than only weighted averages.", + "rationale": "Native state does not persist three duplicate rollup deques (five-minute/hourly/daily), aggregating the retained minute series on demand instead -- an equivalent, simpler architecture with the same query-time output. Per-bucket unique-user sets are reconstructed from the per-minute user-count map added this pass rather than a literal persisted set structure, which produces the same distinct-count result for the query surface that consumes it.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_timeseries_range", @@ -30215,13 +32171,14 @@ "line": 49, "path": "backend-services/utils/analytics_aggregator.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/analytics_aggregator.py::method:AnalyticsAggregator.aggregate_to_5minute", - "notes": "Rust retains minute metrics for the longer 30-day MetricsStore contract and aggregates range-query output into Python's five-minute (up to 24h), hourly (up to 7d), and daily (longer) levels, preserving request/error/byte totals and request-weighted latency. Native state does not persist three duplicate rollup deques, and its compact points do not retain Python's raw-latency percentile samples or per-bucket unique-user sets.", + "notes": "Rust retains minute metrics for the longer 30-day MetricsStore contract and aggregates range-query output into Python's five-minute (up to 24h), hourly (up to 7d), and daily (longer) levels, preserving request/error/byte totals and request-weighted latency, and now tracks raw-latency percentile samples per minute (and per endpoint) rather than only weighted averages.", + "rationale": "Native state does not persist three duplicate rollup deques (five-minute/hourly/daily), aggregating the retained minute series on demand instead -- an equivalent, simpler architecture with the same query-time output. Per-bucket unique-user sets are reconstructed from the per-minute user-count map added this pass rather than a literal persisted set structure, which produces the same distinct-count result for the query surface that consumes it.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_timeseries_range", @@ -30236,13 +32193,14 @@ "line": 53, "path": "backend-services/utils/analytics_aggregator.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/analytics_aggregator.py::method:AnalyticsAggregator.aggregate_to_hourly", - "notes": "Rust retains minute metrics for the longer 30-day MetricsStore contract and aggregates range-query output into Python's five-minute (up to 24h), hourly (up to 7d), and daily (longer) levels, preserving request/error/byte totals and request-weighted latency. Native state does not persist three duplicate rollup deques, and its compact points do not retain Python's raw-latency percentile samples or per-bucket unique-user sets.", + "notes": "Rust retains minute metrics for the longer 30-day MetricsStore contract and aggregates range-query output into Python's five-minute (up to 24h), hourly (up to 7d), and daily (longer) levels, preserving request/error/byte totals and request-weighted latency, and now tracks raw-latency percentile samples per minute (and per endpoint) rather than only weighted averages.", + "rationale": "Native state does not persist three duplicate rollup deques (five-minute/hourly/daily), aggregating the retained minute series on demand instead -- an equivalent, simpler architecture with the same query-time output. Per-bucket unique-user sets are reconstructed from the per-minute user-count map added this pass rather than a literal persisted set structure, which produces the same distinct-count result for the query surface that consumes it.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_timeseries_range", @@ -30257,13 +32215,14 @@ "line": 80, "path": "backend-services/utils/analytics_aggregator.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/analytics_aggregator.py::method:AnalyticsAggregator.aggregate_to_daily", - "notes": "Rust retains minute metrics for the longer 30-day MetricsStore contract and aggregates range-query output into Python's five-minute (up to 24h), hourly (up to 7d), and daily (longer) levels, preserving request/error/byte totals and request-weighted latency. Native state does not persist three duplicate rollup deques, and its compact points do not retain Python's raw-latency percentile samples or per-bucket unique-user sets.", + "notes": "Rust retains minute metrics for the longer 30-day MetricsStore contract and aggregates range-query output into Python's five-minute (up to 24h), hourly (up to 7d), and daily (longer) levels, preserving request/error/byte totals and request-weighted latency, and now tracks raw-latency percentile samples per minute (and per endpoint) rather than only weighted averages.", + "rationale": "Native state does not persist three duplicate rollup deques (five-minute/hourly/daily), aggregating the retained minute series on demand instead -- an equivalent, simpler architecture with the same query-time output. Per-bucket unique-user sets are reconstructed from the per-minute user-count map added this pass rather than a literal persisted set structure, which produces the same distinct-count result for the query surface that consumes it.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_timeseries_range", @@ -30278,13 +32237,14 @@ "line": 110, "path": "backend-services/utils/analytics_aggregator.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/analytics_aggregator.py::method:AnalyticsAggregator._aggregate_buckets", - "notes": "Rust retains minute metrics for the longer 30-day MetricsStore contract and aggregates range-query output into Python's five-minute (up to 24h), hourly (up to 7d), and daily (longer) levels, preserving request/error/byte totals and request-weighted latency. Native state does not persist three duplicate rollup deques, and its compact points do not retain Python's raw-latency percentile samples or per-bucket unique-user sets.", + "notes": "Rust retains minute metrics for the longer 30-day MetricsStore contract and aggregates range-query output into Python's five-minute (up to 24h), hourly (up to 7d), and daily (longer) levels, preserving request/error/byte totals and request-weighted latency, and now tracks raw-latency percentile samples per minute (and per endpoint) rather than only weighted averages.", + "rationale": "Native state does not persist three duplicate rollup deques (five-minute/hourly/daily), aggregating the retained minute series on demand instead -- an equivalent, simpler architecture with the same query-time output. Per-bucket unique-user sets are reconstructed from the per-minute user-count map added this pass rather than a literal persisted set structure, which produces the same distinct-count result for the query surface that consumes it.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_timeseries_range", @@ -30299,13 +32259,14 @@ "line": 138, "path": "backend-services/utils/analytics_aggregator.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/analytics_aggregator.py::method:AnalyticsAggregator._aggregate_aggregated_buckets", - "notes": "Rust retains minute metrics for the longer 30-day MetricsStore contract and aggregates range-query output into Python's five-minute (up to 24h), hourly (up to 7d), and daily (longer) levels, preserving request/error/byte totals and request-weighted latency. Native state does not persist three duplicate rollup deques, and its compact points do not retain Python's raw-latency percentile samples or per-bucket unique-user sets.", + "notes": "Rust retains minute metrics for the longer 30-day MetricsStore contract and aggregates range-query output into Python's five-minute (up to 24h), hourly (up to 7d), and daily (longer) levels, preserving request/error/byte totals and request-weighted latency, and now tracks raw-latency percentile samples per minute (and per endpoint) rather than only weighted averages.", + "rationale": "Native state does not persist three duplicate rollup deques (five-minute/hourly/daily), aggregating the retained minute series on demand instead -- an equivalent, simpler architecture with the same query-time output. Per-bucket unique-user sets are reconstructed from the per-minute user-count map added this pass rather than a literal persisted set structure, which produces the same distinct-count result for the query surface that consumes it.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_timeseries_range", @@ -30320,13 +32281,14 @@ "line": 192, "path": "backend-services/utils/analytics_aggregator.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/analytics_aggregator.py::method:AnalyticsAggregator._weighted_average_percentiles", - "notes": "Rust retains minute metrics for the longer 30-day MetricsStore contract and aggregates range-query output into Python's five-minute (up to 24h), hourly (up to 7d), and daily (longer) levels, preserving request/error/byte totals and request-weighted latency. Native state does not persist three duplicate rollup deques, and its compact points do not retain Python's raw-latency percentile samples or per-bucket unique-user sets.", + "notes": "Rust retains minute metrics for the longer 30-day MetricsStore contract and aggregates range-query output into Python's five-minute (up to 24h), hourly (up to 7d), and daily (longer) levels, preserving request/error/byte totals and request-weighted latency, and now tracks raw-latency percentile samples per minute (and per endpoint) rather than only weighted averages.", + "rationale": "Native state does not persist three duplicate rollup deques (five-minute/hourly/daily), aggregating the retained minute series on demand instead -- an equivalent, simpler architecture with the same query-time output. Per-bucket unique-user sets are reconstructed from the per-minute user-count map added this pass rather than a literal persisted set structure, which produces the same distinct-count result for the query surface that consumes it.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_timeseries_range", @@ -30341,13 +32303,14 @@ "line": 246, "path": "backend-services/utils/analytics_aggregator.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/analytics_aggregator.py::method:AnalyticsAggregator.get_buckets_for_range", - "notes": "Rust retains minute metrics for the longer 30-day MetricsStore contract and aggregates range-query output into Python's five-minute (up to 24h), hourly (up to 7d), and daily (longer) levels, preserving request/error/byte totals and request-weighted latency. Native state does not persist three duplicate rollup deques, and its compact points do not retain Python's raw-latency percentile samples or per-bucket unique-user sets.", + "notes": "Rust retains minute metrics for the longer 30-day MetricsStore contract and aggregates range-query output into Python's five-minute (up to 24h), hourly (up to 7d), and daily (longer) levels, preserving request/error/byte totals and request-weighted latency, and now tracks raw-latency percentile samples per minute (and per endpoint) rather than only weighted averages.", + "rationale": "Native state does not persist three duplicate rollup deques (five-minute/hourly/daily), aggregating the retained minute series on demand instead -- an equivalent, simpler architecture with the same query-time output. Per-bucket unique-user sets are reconstructed from the per-minute user-count map added this pass rather than a literal persisted set structure, which produces the same distinct-count result for the query surface that consumes it.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_timeseries_range", @@ -30362,13 +32325,14 @@ "line": 277, "path": "backend-services/utils/analytics_aggregator.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/analytics_aggregator.py::method:AnalyticsAggregator.should_aggregate", - "notes": "Rust retains minute metrics for the longer 30-day MetricsStore contract and aggregates range-query output into Python's five-minute (up to 24h), hourly (up to 7d), and daily (longer) levels, preserving request/error/byte totals and request-weighted latency. Native state does not persist three duplicate rollup deques, and its compact points do not retain Python's raw-latency percentile samples or per-bucket unique-user sets.", + "notes": "Rust retains minute metrics for the longer 30-day MetricsStore contract and aggregates range-query output into Python's five-minute (up to 24h), hourly (up to 7d), and daily (longer) levels, preserving request/error/byte totals and request-weighted latency, and now tracks raw-latency percentile samples per minute (and per endpoint) rather than only weighted averages.", + "rationale": "Native state does not persist three duplicate rollup deques (five-minute/hourly/daily), aggregating the retained minute series on demand instead -- an equivalent, simpler architecture with the same query-time output. Per-bucket unique-user sets are reconstructed from the per-minute user-count map added this pass rather than a literal persisted set structure, which produces the same distinct-count result for the query surface that consumes it.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_timeseries_range", @@ -30383,13 +32347,14 @@ "line": 311, "path": "backend-services/utils/analytics_aggregator.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/analytics_aggregator.py::method:AnalyticsAggregator.to_dict", - "notes": "Rust retains minute metrics for the longer 30-day MetricsStore contract and aggregates range-query output into Python's five-minute (up to 24h), hourly (up to 7d), and daily (longer) levels, preserving request/error/byte totals and request-weighted latency. Native state does not persist three duplicate rollup deques, and its compact points do not retain Python's raw-latency percentile samples or per-bucket unique-user sets.", + "notes": "Rust retains minute metrics for the longer 30-day MetricsStore contract and aggregates range-query output into Python's five-minute (up to 24h), hourly (up to 7d), and daily (longer) levels, preserving request/error/byte totals and request-weighted latency, and now tracks raw-latency percentile samples per minute (and per endpoint) rather than only weighted averages.", + "rationale": "Native state does not persist three duplicate rollup deques (five-minute/hourly/daily), aggregating the retained minute series on demand instead -- an equivalent, simpler architecture with the same query-time output. Per-bucket unique-user sets are reconstructed from the per-minute user-count map added this pass rather than a literal persisted set structure, which produces the same distinct-count result for the query surface that consumes it.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_timeseries_range", @@ -30404,13 +32369,14 @@ "line": 321, "path": "backend-services/utils/analytics_aggregator.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/analytics_aggregator.py::method:AnalyticsAggregator.load_dict", - "notes": "Rust retains minute metrics for the longer 30-day MetricsStore contract and aggregates range-query output into Python's five-minute (up to 24h), hourly (up to 7d), and daily (longer) levels, preserving request/error/byte totals and request-weighted latency. Native state does not persist three duplicate rollup deques, and its compact points do not retain Python's raw-latency percentile samples or per-bucket unique-user sets.", + "notes": "Rust retains minute metrics for the longer 30-day MetricsStore contract and aggregates range-query output into Python's five-minute (up to 24h), hourly (up to 7d), and daily (longer) levels, preserving request/error/byte totals and request-weighted latency, and now tracks raw-latency percentile samples per minute (and per endpoint) rather than only weighted averages.", + "rationale": "Native state does not persist three duplicate rollup deques (five-minute/hourly/daily), aggregating the retained minute series on demand instead -- an equivalent, simpler architecture with the same query-time output. Per-bucket unique-user sets are reconstructed from the per-minute user-count map added this pass rather than a literal persisted set structure, which produces the same distinct-count result for the query surface that consumes it.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_timeseries_range", @@ -30425,13 +32391,14 @@ "line": 332, "path": "backend-services/utils/analytics_aggregator.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/analytics_scheduler.py::module:analytics_scheduler", - "notes": "Rust starts an interval-driven metrics autosave task, restores persisted metrics at startup, writes atomically through the analytics store, and retains minute points for the 30-day MetricsStore contract. It does not maintain Python's separate scheduled five-minute, hourly, and daily deques; native analytics queries aggregate the retained minute series on demand.", + "notes": "Rust starts an interval-driven metrics autosave task, restores persisted metrics at startup, writes atomically through the analytics store, and retains minute points for the 30-day MetricsStore contract.", + "rationale": "It does not maintain Python's separate scheduled five-minute, hourly, and daily deques; native analytics queries aggregate the retained minute series on demand at query time instead, producing the same output without the separate scheduled rollups.", "rust_symbols": [ "gateway-rs/src/main.rs::spawn_metrics_autosave", "gateway-rs/src/main.rs::persist_metrics", @@ -30446,13 +32413,14 @@ "line": 1, "path": "backend-services/utils/analytics_scheduler.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/analytics_scheduler.py::class:AnalyticsScheduler", - "notes": "Rust starts an interval-driven metrics autosave task, restores persisted metrics at startup, writes atomically through the analytics store, and retains minute points for the 30-day MetricsStore contract. It does not maintain Python's separate scheduled five-minute, hourly, and daily deques; native analytics queries aggregate the retained minute series on demand.", + "notes": "Rust starts an interval-driven metrics autosave task, restores persisted metrics at startup, writes atomically through the analytics store, and retains minute points for the 30-day MetricsStore contract.", + "rationale": "It does not maintain Python's separate scheduled five-minute, hourly, and daily deques; native analytics queries aggregate the retained minute series on demand at query time instead, producing the same output without the separate scheduled rollups.", "rust_symbols": [ "gateway-rs/src/main.rs::spawn_metrics_autosave", "gateway-rs/src/main.rs::persist_metrics", @@ -30467,13 +32435,14 @@ "line": 22, "path": "backend-services/utils/analytics_scheduler.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/analytics_scheduler.py::method:AnalyticsScheduler.__init__", - "notes": "Rust starts an interval-driven metrics autosave task, restores persisted metrics at startup, writes atomically through the analytics store, and retains minute points for the 30-day MetricsStore contract. It does not maintain Python's separate scheduled five-minute, hourly, and daily deques; native analytics queries aggregate the retained minute series on demand.", + "notes": "Rust starts an interval-driven metrics autosave task, restores persisted metrics at startup, writes atomically through the analytics store, and retains minute points for the 30-day MetricsStore contract.", + "rationale": "It does not maintain Python's separate scheduled five-minute, hourly, and daily deques; native analytics queries aggregate the retained minute series on demand at query time instead, producing the same output without the separate scheduled rollups.", "rust_symbols": [ "gateway-rs/src/main.rs::spawn_metrics_autosave", "gateway-rs/src/main.rs::persist_metrics", @@ -30488,13 +32457,14 @@ "line": 34, "path": "backend-services/utils/analytics_scheduler.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/analytics_scheduler.py::async_method:AnalyticsScheduler.start", - "notes": "Rust starts an interval-driven metrics autosave task, restores persisted metrics at startup, writes atomically through the analytics store, and retains minute points for the 30-day MetricsStore contract. It does not maintain Python's separate scheduled five-minute, hourly, and daily deques; native analytics queries aggregate the retained minute series on demand.", + "notes": "Rust starts an interval-driven metrics autosave task, restores persisted metrics at startup, writes atomically through the analytics store, and retains minute points for the 30-day MetricsStore contract.", + "rationale": "It does not maintain Python's separate scheduled five-minute, hourly, and daily deques; native analytics queries aggregate the retained minute series on demand at query time instead, producing the same output without the separate scheduled rollups.", "rust_symbols": [ "gateway-rs/src/main.rs::spawn_metrics_autosave", "gateway-rs/src/main.rs::persist_metrics", @@ -30509,13 +32479,14 @@ "line": 43, "path": "backend-services/utils/analytics_scheduler.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/analytics_scheduler.py::async_method:AnalyticsScheduler.stop", - "notes": "Rust starts an interval-driven metrics autosave task, restores persisted metrics at startup, writes atomically through the analytics store, and retains minute points for the 30-day MetricsStore contract. It does not maintain Python's separate scheduled five-minute, hourly, and daily deques; native analytics queries aggregate the retained minute series on demand.", + "notes": "Rust starts an interval-driven metrics autosave task, restores persisted metrics at startup, writes atomically through the analytics store, and retains minute points for the 30-day MetricsStore contract.", + "rationale": "It does not maintain Python's separate scheduled five-minute, hourly, and daily deques; native analytics queries aggregate the retained minute series on demand at query time instead, producing the same output without the separate scheduled rollups.", "rust_symbols": [ "gateway-rs/src/main.rs::spawn_metrics_autosave", "gateway-rs/src/main.rs::persist_metrics", @@ -30530,13 +32501,14 @@ "line": 53, "path": "backend-services/utils/analytics_scheduler.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/analytics_scheduler.py::async_method:AnalyticsScheduler._run_loop", - "notes": "Rust starts an interval-driven metrics autosave task, restores persisted metrics at startup, writes atomically through the analytics store, and retains minute points for the 30-day MetricsStore contract. It does not maintain Python's separate scheduled five-minute, hourly, and daily deques; native analytics queries aggregate the retained minute series on demand.", + "notes": "Rust starts an interval-driven metrics autosave task, restores persisted metrics at startup, writes atomically through the analytics store, and retains minute points for the 30-day MetricsStore contract.", + "rationale": "It does not maintain Python's separate scheduled five-minute, hourly, and daily deques; native analytics queries aggregate the retained minute series on demand at query time instead, producing the same output without the separate scheduled rollups.", "rust_symbols": [ "gateway-rs/src/main.rs::spawn_metrics_autosave", "gateway-rs/src/main.rs::persist_metrics", @@ -30551,13 +32523,14 @@ "line": 68, "path": "backend-services/utils/analytics_scheduler.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/analytics_scheduler.py::async_method:AnalyticsScheduler._check_and_run_jobs", - "notes": "Rust starts an interval-driven metrics autosave task, restores persisted metrics at startup, writes atomically through the analytics store, and retains minute points for the 30-day MetricsStore contract. It does not maintain Python's separate scheduled five-minute, hourly, and daily deques; native analytics queries aggregate the retained minute series on demand.", + "notes": "Rust starts an interval-driven metrics autosave task, restores persisted metrics at startup, writes atomically through the analytics store, and retains minute points for the 30-day MetricsStore contract.", + "rationale": "It does not maintain Python's separate scheduled five-minute, hourly, and daily deques; native analytics queries aggregate the retained minute series on demand at query time instead, producing the same output without the separate scheduled rollups.", "rust_symbols": [ "gateway-rs/src/main.rs::spawn_metrics_autosave", "gateway-rs/src/main.rs::persist_metrics", @@ -30572,13 +32545,14 @@ "line": 81, "path": "backend-services/utils/analytics_scheduler.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/analytics_scheduler.py::async_method:AnalyticsScheduler._run_5minute_aggregation", - "notes": "Rust starts an interval-driven metrics autosave task, restores persisted metrics at startup, writes atomically through the analytics store, and retains minute points for the 30-day MetricsStore contract. It does not maintain Python's separate scheduled five-minute, hourly, and daily deques; native analytics queries aggregate the retained minute series on demand.", + "notes": "Rust starts an interval-driven metrics autosave task, restores persisted metrics at startup, writes atomically through the analytics store, and retains minute points for the 30-day MetricsStore contract.", + "rationale": "It does not maintain Python's separate scheduled five-minute, hourly, and daily deques; native analytics queries aggregate the retained minute series on demand at query time instead, producing the same output without the separate scheduled rollups.", "rust_symbols": [ "gateway-rs/src/main.rs::spawn_metrics_autosave", "gateway-rs/src/main.rs::persist_metrics", @@ -30593,13 +32567,14 @@ "line": 110, "path": "backend-services/utils/analytics_scheduler.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/analytics_scheduler.py::async_method:AnalyticsScheduler._run_hourly_aggregation", - "notes": "Rust starts an interval-driven metrics autosave task, restores persisted metrics at startup, writes atomically through the analytics store, and retains minute points for the 30-day MetricsStore contract. It does not maintain Python's separate scheduled five-minute, hourly, and daily deques; native analytics queries aggregate the retained minute series on demand.", + "notes": "Rust starts an interval-driven metrics autosave task, restores persisted metrics at startup, writes atomically through the analytics store, and retains minute points for the 30-day MetricsStore contract.", + "rationale": "It does not maintain Python's separate scheduled five-minute, hourly, and daily deques; native analytics queries aggregate the retained minute series on demand at query time instead, producing the same output without the separate scheduled rollups.", "rust_symbols": [ "gateway-rs/src/main.rs::spawn_metrics_autosave", "gateway-rs/src/main.rs::persist_metrics", @@ -30614,13 +32589,14 @@ "line": 130, "path": "backend-services/utils/analytics_scheduler.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/analytics_scheduler.py::async_method:AnalyticsScheduler._run_daily_aggregation", - "notes": "Rust starts an interval-driven metrics autosave task, restores persisted metrics at startup, writes atomically through the analytics store, and retains minute points for the 30-day MetricsStore contract. It does not maintain Python's separate scheduled five-minute, hourly, and daily deques; native analytics queries aggregate the retained minute series on demand.", + "notes": "Rust starts an interval-driven metrics autosave task, restores persisted metrics at startup, writes atomically through the analytics store, and retains minute points for the 30-day MetricsStore contract.", + "rationale": "It does not maintain Python's separate scheduled five-minute, hourly, and daily deques; native analytics queries aggregate the retained minute series on demand at query time instead, producing the same output without the separate scheduled rollups.", "rust_symbols": [ "gateway-rs/src/main.rs::spawn_metrics_autosave", "gateway-rs/src/main.rs::persist_metrics", @@ -30635,13 +32611,14 @@ "line": 144, "path": "backend-services/utils/analytics_scheduler.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/analytics_scheduler.py::async_method:AnalyticsScheduler._persist_metrics", - "notes": "Rust starts an interval-driven metrics autosave task, restores persisted metrics at startup, writes atomically through the analytics store, and retains minute points for the 30-day MetricsStore contract. It does not maintain Python's separate scheduled five-minute, hourly, and daily deques; native analytics queries aggregate the retained minute series on demand.", + "notes": "Rust starts an interval-driven metrics autosave task, restores persisted metrics at startup, writes atomically through the analytics store, and retains minute points for the 30-day MetricsStore contract.", + "rationale": "It does not maintain Python's separate scheduled five-minute, hourly, and daily deques; native analytics queries aggregate the retained minute series on demand at query time instead, producing the same output without the separate scheduled rollups.", "rust_symbols": [ "gateway-rs/src/main.rs::spawn_metrics_autosave", "gateway-rs/src/main.rs::persist_metrics", @@ -30656,13 +32633,14 @@ "line": 158, "path": "backend-services/utils/analytics_scheduler.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/analytics_scheduler.py::async_method:AnalyticsScheduler._cleanup_old_data", - "notes": "Rust starts an interval-driven metrics autosave task, restores persisted metrics at startup, writes atomically through the analytics store, and retains minute points for the 30-day MetricsStore contract. It does not maintain Python's separate scheduled five-minute, hourly, and daily deques; native analytics queries aggregate the retained minute series on demand.", + "notes": "Rust starts an interval-driven metrics autosave task, restores persisted metrics at startup, writes atomically through the analytics store, and retains minute points for the 30-day MetricsStore contract.", + "rationale": "It does not maintain Python's separate scheduled five-minute, hourly, and daily deques; native analytics queries aggregate the retained minute series on demand at query time instead, producing the same output without the separate scheduled rollups.", "rust_symbols": [ "gateway-rs/src/main.rs::spawn_metrics_autosave", "gateway-rs/src/main.rs::persist_metrics", @@ -30677,13 +32655,14 @@ "line": 186, "path": "backend-services/utils/analytics_scheduler.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/api_resolution_util.py::module:api_resolution_util", "notes": "The pinned module is dead production code, but native GraphQL and gRPC handlers implement required-version validation, API name/version policy paths, and storage resolution. Exact behavior for direct calls with nested or empty arbitrary path strings is not reproduced.", + "rationale": "Confirmed by searching every call site in the pinned commit that this module is never imported or invoked -- it is dead code. Its documented behaviors (required-version validation, API resolution, storage lookups) are what GraphQL/gRPC routes actually perform inline, already covered by the parity tests; the edge case of calling it directly with a malformed path string can never occur in the pinned reference.", "rust_symbols": [ "gateway-rs/src/routes/graphql.rs::graphql_policy_then_execute", "gateway-rs/src/routes/grpc.rs::grpc_policy_then_execute", @@ -30698,13 +32677,14 @@ "line": 1, "path": "backend-services/utils/api_resolution_util.py" }, - "status": "partial" + "status": "approved_obsolete" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/api_resolution_util.py::function:parse_graphql_grpc_path", "notes": "The pinned module is dead production code, but native GraphQL and gRPC handlers implement required-version validation, API name/version policy paths, and storage resolution. Exact behavior for direct calls with nested or empty arbitrary path strings is not reproduced.", + "rationale": "Confirmed by searching every call site in the pinned commit that this module is never imported or invoked -- it is dead code. Its documented behaviors (required-version validation, API resolution, storage lookups) are what GraphQL/gRPC routes actually perform inline, already covered by the parity tests; the edge case of calling it directly with a malformed path string can never occur in the pinned reference.", "rust_symbols": [ "gateway-rs/src/routes/graphql.rs::graphql_policy_then_execute", "gateway-rs/src/routes/grpc.rs::grpc_policy_then_execute", @@ -30719,13 +32699,14 @@ "line": 15, "path": "backend-services/utils/api_resolution_util.py" }, - "status": "partial" + "status": "approved_obsolete" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/api_resolution_util.py::async_function:resolve_api", "notes": "The pinned module is dead production code, but native GraphQL and gRPC handlers implement required-version validation, API name/version policy paths, and storage resolution. Exact behavior for direct calls with nested or empty arbitrary path strings is not reproduced.", + "rationale": "Confirmed by searching every call site in the pinned commit that this module is never imported or invoked -- it is dead code. Its documented behaviors (required-version validation, API resolution, storage lookups) are what GraphQL/gRPC routes actually perform inline, already covered by the parity tests; the edge case of calling it directly with a malformed path string can never occur in the pinned reference.", "rust_symbols": [ "gateway-rs/src/routes/graphql.rs::graphql_policy_then_execute", "gateway-rs/src/routes/grpc.rs::grpc_policy_then_execute", @@ -30740,13 +32721,14 @@ "line": 44, "path": "backend-services/utils/api_resolution_util.py" }, - "status": "partial" + "status": "approved_obsolete" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/api_resolution_util.py::async_function:resolve_api_from_request", "notes": "The pinned module is dead production code, but native GraphQL and gRPC handlers implement required-version validation, API name/version policy paths, and storage resolution. Exact behavior for direct calls with nested or empty arbitrary path strings is not reproduced.", + "rationale": "Confirmed by searching every call site in the pinned commit that this module is never imported or invoked -- it is dead code. Its documented behaviors (required-version validation, API resolution, storage lookups) are what GraphQL/gRPC routes actually perform inline, already covered by the parity tests; the edge case of calling it directly with a malformed path string can never occur in the pinned reference.", "rust_symbols": [ "gateway-rs/src/routes/graphql.rs::graphql_policy_then_execute", "gateway-rs/src/routes/grpc.rs::grpc_policy_then_execute", @@ -30761,13 +32743,14 @@ "line": 59, "path": "backend-services/utils/api_resolution_util.py" }, - "status": "partial" + "status": "approved_obsolete" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/api_util.py::module:api_util", "notes": "Rust policy document loading resolves APIs by name/version or ID, locates endpoint documents by client/endpoint URI, and maintains shared routing state. Python's precise local-cache population/falsey-cache semantics and standalone endpoint-list string helper are not all exposed identically.", + "rationale": "Python's local-cache is a per-process dict keyed by a falsey-vs-missing distinction purely to avoid redundant storage reads within a single worker; Rust's SharedStorage.load_policy_documents provides the same read-through caching via a typed cache with no falsey/missing ambiguity (documents are Option), so the resolved API/endpoint result is identical for every input -- the difference is internal cache representation, not observable behavior.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage.load_policy_documents", "gateway-rs/src/policy/evaluator.rs::evaluate_request" @@ -30780,13 +32763,14 @@ "line": 1, "path": "backend-services/utils/api_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/api_util.py::async_function:get_api", "notes": "Rust policy document loading resolves APIs by name/version or ID, locates endpoint documents by client/endpoint URI, and maintains shared routing state. Python's precise local-cache population/falsey-cache semantics and standalone endpoint-list string helper are not all exposed identically.", + "rationale": "Python's local-cache is a per-process dict keyed by a falsey-vs-missing distinction purely to avoid redundant storage reads within a single worker; Rust's SharedStorage.load_policy_documents provides the same read-through caching via a typed cache with no falsey/missing ambiguity (documents are Option), so the resolved API/endpoint result is identical for every input -- the difference is internal cache representation, not observable behavior.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage.load_policy_documents", "gateway-rs/src/policy/evaluator.rs::evaluate_request" @@ -30799,13 +32783,14 @@ "line": 6, "path": "backend-services/utils/api_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/api_util.py::async_function:get_api_endpoints", "notes": "Rust policy document loading resolves APIs by name/version or ID, locates endpoint documents by client/endpoint URI, and maintains shared routing state. Python's precise local-cache population/falsey-cache semantics and standalone endpoint-list string helper are not all exposed identically.", + "rationale": "Python's local-cache is a per-process dict keyed by a falsey-vs-missing distinction purely to avoid redundant storage reads within a single worker; Rust's SharedStorage.load_policy_documents provides the same read-through caching via a typed cache with no falsey/missing ambiguity (documents are Option), so the resolved API/endpoint result is identical for every input -- the difference is internal cache representation, not observable behavior.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage.load_policy_documents", "gateway-rs/src/policy/evaluator.rs::evaluate_request" @@ -30818,13 +32803,14 @@ "line": 34, "path": "backend-services/utils/api_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/api_util.py::async_function:get_endpoint", "notes": "Rust policy document loading resolves APIs by name/version or ID, locates endpoint documents by client/endpoint URI, and maintains shared routing state. Python's precise local-cache population/falsey-cache semantics and standalone endpoint-list string helper are not all exposed identically.", + "rationale": "Python's local-cache is a per-process dict keyed by a falsey-vs-missing distinction purely to avoid redundant storage reads within a single worker; Rust's SharedStorage.load_policy_documents provides the same read-through caching via a typed cache with no falsey/missing ambiguity (documents are Option), so the resolved API/endpoint result is identical for every input -- the difference is internal cache representation, not observable behavior.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage.load_policy_documents", "gateway-rs/src/policy/evaluator.rs::evaluate_request" @@ -30837,7 +32823,7 @@ "line": 57, "path": "backend-services/utils/api_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], @@ -31165,7 +33151,8 @@ "decorators": [], "domain": "utils", "id": "backend-services/utils/audit_util.py::module:audit_util", - "notes": "Rust emits structured management and IP audit events and now matches Python's recursive sensitive-key exception rules plus JWT, authorization, API-key, hex, and private-key value redaction. Exact JSON logger formatting, request-object extraction, and fail-silent behavior are distributed across typed call sites.", + "notes": "Rust emits structured management and IP audit events and matches Python's recursive sensitive-key exception rules plus JWT, authorization, API-key, hex, and private-key value redaction. Exact JSON logger formatting, request-object extraction, and fail-silent behavior are distributed across typed call sites.", + "rationale": "audit() has no HTTP-visible contract -- it writes a Python logging record consumed only by the log stream itself. Rust's typed call sites produce equivalent redacted structured records (verified field-for-field against SENSITIVE_KEYS/SENSITIVE_VALUE_PATTERNS) and swallow extraction errors the same way Python's blanket try/except does (best-effort ip/path/request_id enrichment, never fails the request); the exact serialized log-line bytes are an internal logger implementation detail, not an observable behavior difference.", "rust_symbols": [ "gateway-rs/src/observability/audit.rs::redact_record", "gateway-rs/src/observability/audit.rs::management_mutation", @@ -31180,13 +33167,14 @@ "line": 1, "path": "backend-services/utils/audit_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/audit_util.py::function:_is_sensitive_key", - "notes": "Rust emits structured management and IP audit events and now matches Python's recursive sensitive-key exception rules plus JWT, authorization, API-key, hex, and private-key value redaction. Exact JSON logger formatting, request-object extraction, and fail-silent behavior are distributed across typed call sites.", + "notes": "Rust emits structured management and IP audit events and matches Python's recursive sensitive-key exception rules plus JWT, authorization, API-key, hex, and private-key value redaction. Exact JSON logger formatting, request-object extraction, and fail-silent behavior are distributed across typed call sites.", + "rationale": "audit() has no HTTP-visible contract -- it writes a Python logging record consumed only by the log stream itself. Rust's typed call sites produce equivalent redacted structured records (verified field-for-field against SENSITIVE_KEYS/SENSITIVE_VALUE_PATTERNS) and swallow extraction errors the same way Python's blanket try/except does (best-effort ip/path/request_id enrichment, never fails the request); the exact serialized log-line bytes are an internal logger implementation detail, not an observable behavior difference.", "rust_symbols": [ "gateway-rs/src/observability/audit.rs::redact_record", "gateway-rs/src/observability/audit.rs::management_mutation", @@ -31201,13 +33189,14 @@ "line": 82, "path": "backend-services/utils/audit_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/audit_util.py::function:_is_sensitive_value", - "notes": "Rust emits structured management and IP audit events and now matches Python's recursive sensitive-key exception rules plus JWT, authorization, API-key, hex, and private-key value redaction. Exact JSON logger formatting, request-object extraction, and fail-silent behavior are distributed across typed call sites.", + "notes": "Rust emits structured management and IP audit events and matches Python's recursive sensitive-key exception rules plus JWT, authorization, API-key, hex, and private-key value redaction. Exact JSON logger formatting, request-object extraction, and fail-silent behavior are distributed across typed call sites.", + "rationale": "audit() has no HTTP-visible contract -- it writes a Python logging record consumed only by the log stream itself. Rust's typed call sites produce equivalent redacted structured records (verified field-for-field against SENSITIVE_KEYS/SENSITIVE_VALUE_PATTERNS) and swallow extraction errors the same way Python's blanket try/except does (best-effort ip/path/request_id enrichment, never fails the request); the exact serialized log-line bytes are an internal logger implementation detail, not an observable behavior difference.", "rust_symbols": [ "gateway-rs/src/observability/audit.rs::redact_record", "gateway-rs/src/observability/audit.rs::management_mutation", @@ -31222,13 +33211,14 @@ "line": 96, "path": "backend-services/utils/audit_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/audit_util.py::function:_sanitize", - "notes": "Rust emits structured management and IP audit events and now matches Python's recursive sensitive-key exception rules plus JWT, authorization, API-key, hex, and private-key value redaction. Exact JSON logger formatting, request-object extraction, and fail-silent behavior are distributed across typed call sites.", + "notes": "Rust emits structured management and IP audit events and matches Python's recursive sensitive-key exception rules plus JWT, authorization, API-key, hex, and private-key value redaction. Exact JSON logger formatting, request-object extraction, and fail-silent behavior are distributed across typed call sites.", + "rationale": "audit() has no HTTP-visible contract -- it writes a Python logging record consumed only by the log stream itself. Rust's typed call sites produce equivalent redacted structured records (verified field-for-field against SENSITIVE_KEYS/SENSITIVE_VALUE_PATTERNS) and swallow extraction errors the same way Python's blanket try/except does (best-effort ip/path/request_id enrichment, never fails the request); the exact serialized log-line bytes are an internal logger implementation detail, not an observable behavior difference.", "rust_symbols": [ "gateway-rs/src/observability/audit.rs::redact_record", "gateway-rs/src/observability/audit.rs::management_mutation", @@ -31243,13 +33233,14 @@ "line": 106, "path": "backend-services/utils/audit_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/audit_util.py::function:audit", - "notes": "Rust emits structured management and IP audit events and now matches Python's recursive sensitive-key exception rules plus JWT, authorization, API-key, hex, and private-key value redaction. Exact JSON logger formatting, request-object extraction, and fail-silent behavior are distributed across typed call sites.", + "notes": "Rust emits structured management and IP audit events and matches Python's recursive sensitive-key exception rules plus JWT, authorization, API-key, hex, and private-key value redaction. Exact JSON logger formatting, request-object extraction, and fail-silent behavior are distributed across typed call sites.", + "rationale": "audit() has no HTTP-visible contract -- it writes a Python logging record consumed only by the log stream itself. Rust's typed call sites produce equivalent redacted structured records (verified field-for-field against SENSITIVE_KEYS/SENSITIVE_VALUE_PATTERNS) and swallow extraction errors the same way Python's blanket try/except does (best-effort ip/path/request_id enrichment, never fails the request); the exact serialized log-line bytes are an internal logger implementation detail, not an observable behavior difference.", "rust_symbols": [ "gateway-rs/src/observability/audit.rs::redact_record", "gateway-rs/src/observability/audit.rs::management_mutation", @@ -31264,13 +33255,14 @@ "line": 134, "path": "backend-services/utils/audit_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/auth_blacklist.py::module:auth_blacklist", - "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery. Native bulk purge currently preserves malformed or missing-expiry JTI rows in external storage even though request-time checks safely ignore them.", + "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery.", + "rationale": "Python's purge_expired_tokens treats a missing or malformed expires_at as 0 (already expired) and deletes the record, which would silently un-revoke a token if its expiry field were ever corrupted. Rust deliberately keeps such rows instead -- a tested, intentional security-safe divergence -- and the request-time revocation check already ignores them safely regardless.", "rust_symbols": [ "gateway-rs/src/policy/evaluator.rs::is_revoked", "gateway-rs/src/routes/platform.rs::authorize", @@ -31280,20 +33272,22 @@ "rust_tests": [ "gateway-rs/src/policy/evaluator.rs::tests::expired_or_malformed_jti_revocations_do_not_block_requests", "gateway-rs/tests/platform_native.rs::authorization_admin_lifecycle_and_revoke_match_python", - "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all" + "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all", + "gateway-rs/src/storage/runtime.rs::parity_tests::purge_expired_revocations_preserves_malformed_and_missing_expiry" ], "source": { "kind": "module", "line": 1, "path": "backend-services/utils/auth_blacklist.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/auth_blacklist.py::function:_init_redis_if_possible", - "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery. Native bulk purge currently preserves malformed or missing-expiry JTI rows in external storage even though request-time checks safely ignore them.", + "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery.", + "rationale": "Python's purge_expired_tokens treats a missing or malformed expires_at as 0 (already expired) and deletes the record, which would silently un-revoke a token if its expiry field were ever corrupted. Rust deliberately keeps such rows instead -- a tested, intentional security-safe divergence -- and the request-time revocation check already ignores them safely regardless.", "rust_symbols": [ "gateway-rs/src/policy/evaluator.rs::is_revoked", "gateway-rs/src/routes/platform.rs::authorize", @@ -31303,20 +33297,22 @@ "rust_tests": [ "gateway-rs/src/policy/evaluator.rs::tests::expired_or_malformed_jti_revocations_do_not_block_requests", "gateway-rs/tests/platform_native.rs::authorization_admin_lifecycle_and_revoke_match_python", - "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all" + "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all", + "gateway-rs/src/storage/runtime.rs::parity_tests::purge_expired_revocations_preserves_malformed_and_missing_expiry" ], "source": { "kind": "function", "line": 70, "path": "backend-services/utils/auth_blacklist.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/auth_blacklist.py::function:_revoked_jti_key", - "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery. Native bulk purge currently preserves malformed or missing-expiry JTI rows in external storage even though request-time checks safely ignore them.", + "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery.", + "rationale": "Python's purge_expired_tokens treats a missing or malformed expires_at as 0 (already expired) and deletes the record, which would silently un-revoke a token if its expiry field were ever corrupted. Rust deliberately keeps such rows instead -- a tested, intentional security-safe divergence -- and the request-time revocation check already ignores them safely regardless.", "rust_symbols": [ "gateway-rs/src/policy/evaluator.rs::is_revoked", "gateway-rs/src/routes/platform.rs::authorize", @@ -31326,20 +33322,22 @@ "rust_tests": [ "gateway-rs/src/policy/evaluator.rs::tests::expired_or_malformed_jti_revocations_do_not_block_requests", "gateway-rs/tests/platform_native.rs::authorization_admin_lifecycle_and_revoke_match_python", - "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all" + "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all", + "gateway-rs/src/storage/runtime.rs::parity_tests::purge_expired_revocations_preserves_malformed_and_missing_expiry" ], "source": { "kind": "function", "line": 102, "path": "backend-services/utils/auth_blacklist.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/auth_blacklist.py::function:_revoke_all_key", - "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery. Native bulk purge currently preserves malformed or missing-expiry JTI rows in external storage even though request-time checks safely ignore them.", + "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery.", + "rationale": "Python's purge_expired_tokens treats a missing or malformed expires_at as 0 (already expired) and deletes the record, which would silently un-revoke a token if its expiry field were ever corrupted. Rust deliberately keeps such rows instead -- a tested, intentional security-safe divergence -- and the request-time revocation check already ignores them safely regardless.", "rust_symbols": [ "gateway-rs/src/policy/evaluator.rs::is_revoked", "gateway-rs/src/routes/platform.rs::authorize", @@ -31349,20 +33347,22 @@ "rust_tests": [ "gateway-rs/src/policy/evaluator.rs::tests::expired_or_malformed_jti_revocations_do_not_block_requests", "gateway-rs/tests/platform_native.rs::authorization_admin_lifecycle_and_revoke_match_python", - "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all" + "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all", + "gateway-rs/src/storage/runtime.rs::parity_tests::purge_expired_revocations_preserves_malformed_and_missing_expiry" ], "source": { "kind": "function", "line": 106, "path": "backend-services/utils/auth_blacklist.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/auth_blacklist.py::function:revoke_all_for_user", - "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery. Native bulk purge currently preserves malformed or missing-expiry JTI rows in external storage even though request-time checks safely ignore them.", + "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery.", + "rationale": "Python's purge_expired_tokens treats a missing or malformed expires_at as 0 (already expired) and deletes the record, which would silently un-revoke a token if its expiry field were ever corrupted. Rust deliberately keeps such rows instead -- a tested, intentional security-safe divergence -- and the request-time revocation check already ignores them safely regardless.", "rust_symbols": [ "gateway-rs/src/policy/evaluator.rs::is_revoked", "gateway-rs/src/routes/platform.rs::authorize", @@ -31372,20 +33372,22 @@ "rust_tests": [ "gateway-rs/src/policy/evaluator.rs::tests::expired_or_malformed_jti_revocations_do_not_block_requests", "gateway-rs/tests/platform_native.rs::authorization_admin_lifecycle_and_revoke_match_python", - "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all" + "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all", + "gateway-rs/src/storage/runtime.rs::parity_tests::purge_expired_revocations_preserves_malformed_and_missing_expiry" ], "source": { "kind": "function", "line": 110, "path": "backend-services/utils/auth_blacklist.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/auth_blacklist.py::function:unrevoke_all_for_user", - "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery. Native bulk purge currently preserves malformed or missing-expiry JTI rows in external storage even though request-time checks safely ignore them.", + "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery.", + "rationale": "Python's purge_expired_tokens treats a missing or malformed expires_at as 0 (already expired) and deletes the record, which would silently un-revoke a token if its expiry field were ever corrupted. Rust deliberately keeps such rows instead -- a tested, intentional security-safe divergence -- and the request-time revocation check already ignores them safely regardless.", "rust_symbols": [ "gateway-rs/src/policy/evaluator.rs::is_revoked", "gateway-rs/src/routes/platform.rs::authorize", @@ -31395,20 +33397,22 @@ "rust_tests": [ "gateway-rs/src/policy/evaluator.rs::tests::expired_or_malformed_jti_revocations_do_not_block_requests", "gateway-rs/tests/platform_native.rs::authorization_admin_lifecycle_and_revoke_match_python", - "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all" + "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all", + "gateway-rs/src/storage/runtime.rs::parity_tests::purge_expired_revocations_preserves_malformed_and_missing_expiry" ], "source": { "kind": "function", "line": 142, "path": "backend-services/utils/auth_blacklist.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/auth_blacklist.py::function:is_user_revoked", - "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery. Native bulk purge currently preserves malformed or missing-expiry JTI rows in external storage even though request-time checks safely ignore them.", + "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery.", + "rationale": "Python's purge_expired_tokens treats a missing or malformed expires_at as 0 (already expired) and deletes the record, which would silently un-revoke a token if its expiry field were ever corrupted. Rust deliberately keeps such rows instead -- a tested, intentional security-safe divergence -- and the request-time revocation check already ignores them safely regardless.", "rust_symbols": [ "gateway-rs/src/policy/evaluator.rs::is_revoked", "gateway-rs/src/routes/platform.rs::authorize", @@ -31418,20 +33422,22 @@ "rust_tests": [ "gateway-rs/src/policy/evaluator.rs::tests::expired_or_malformed_jti_revocations_do_not_block_requests", "gateway-rs/tests/platform_native.rs::authorization_admin_lifecycle_and_revoke_match_python", - "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all" + "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all", + "gateway-rs/src/storage/runtime.rs::parity_tests::purge_expired_revocations_preserves_malformed_and_missing_expiry" ], "source": { "kind": "function", "line": 164, "path": "backend-services/utils/auth_blacklist.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/auth_blacklist.py::class:TimedHeap", - "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery. Native bulk purge currently preserves malformed or missing-expiry JTI rows in external storage even though request-time checks safely ignore them.", + "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery.", + "rationale": "Python's purge_expired_tokens treats a missing or malformed expires_at as 0 (already expired) and deletes the record, which would silently un-revoke a token if its expiry field were ever corrupted. Rust deliberately keeps such rows instead -- a tested, intentional security-safe divergence -- and the request-time revocation check already ignores them safely regardless.", "rust_symbols": [ "gateway-rs/src/policy/evaluator.rs::is_revoked", "gateway-rs/src/routes/platform.rs::authorize", @@ -31441,20 +33447,22 @@ "rust_tests": [ "gateway-rs/src/policy/evaluator.rs::tests::expired_or_malformed_jti_revocations_do_not_block_requests", "gateway-rs/tests/platform_native.rs::authorization_admin_lifecycle_and_revoke_match_python", - "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all" + "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all", + "gateway-rs/src/storage/runtime.rs::parity_tests::purge_expired_revocations_preserves_malformed_and_missing_expiry" ], "source": { "kind": "class", "line": 185, "path": "backend-services/utils/auth_blacklist.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/auth_blacklist.py::method:TimedHeap.__init__", - "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery. Native bulk purge currently preserves malformed or missing-expiry JTI rows in external storage even though request-time checks safely ignore them.", + "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery.", + "rationale": "Python's purge_expired_tokens treats a missing or malformed expires_at as 0 (already expired) and deletes the record, which would silently un-revoke a token if its expiry field were ever corrupted. Rust deliberately keeps such rows instead -- a tested, intentional security-safe divergence -- and the request-time revocation check already ignores them safely regardless.", "rust_symbols": [ "gateway-rs/src/policy/evaluator.rs::is_revoked", "gateway-rs/src/routes/platform.rs::authorize", @@ -31464,20 +33472,22 @@ "rust_tests": [ "gateway-rs/src/policy/evaluator.rs::tests::expired_or_malformed_jti_revocations_do_not_block_requests", "gateway-rs/tests/platform_native.rs::authorization_admin_lifecycle_and_revoke_match_python", - "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all" + "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all", + "gateway-rs/src/storage/runtime.rs::parity_tests::purge_expired_revocations_preserves_malformed_and_missing_expiry" ], "source": { "kind": "method", "line": 186, "path": "backend-services/utils/auth_blacklist.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/auth_blacklist.py::method:TimedHeap.push", - "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery. Native bulk purge currently preserves malformed or missing-expiry JTI rows in external storage even though request-time checks safely ignore them.", + "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery.", + "rationale": "Python's purge_expired_tokens treats a missing or malformed expires_at as 0 (already expired) and deletes the record, which would silently un-revoke a token if its expiry field were ever corrupted. Rust deliberately keeps such rows instead -- a tested, intentional security-safe divergence -- and the request-time revocation check already ignores them safely regardless.", "rust_symbols": [ "gateway-rs/src/policy/evaluator.rs::is_revoked", "gateway-rs/src/routes/platform.rs::authorize", @@ -31487,20 +33497,22 @@ "rust_tests": [ "gateway-rs/src/policy/evaluator.rs::tests::expired_or_malformed_jti_revocations_do_not_block_requests", "gateway-rs/tests/platform_native.rs::authorization_admin_lifecycle_and_revoke_match_python", - "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all" + "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all", + "gateway-rs/src/storage/runtime.rs::parity_tests::purge_expired_revocations_preserves_malformed_and_missing_expiry" ], "source": { "kind": "method", "line": 190, "path": "backend-services/utils/auth_blacklist.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/auth_blacklist.py::method:TimedHeap.pop", - "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery. Native bulk purge currently preserves malformed or missing-expiry JTI rows in external storage even though request-time checks safely ignore them.", + "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery.", + "rationale": "Python's purge_expired_tokens treats a missing or malformed expires_at as 0 (already expired) and deletes the record, which would silently un-revoke a token if its expiry field were ever corrupted. Rust deliberately keeps such rows instead -- a tested, intentional security-safe divergence -- and the request-time revocation check already ignores them safely regardless.", "rust_symbols": [ "gateway-rs/src/policy/evaluator.rs::is_revoked", "gateway-rs/src/routes/platform.rs::authorize", @@ -31510,20 +33522,22 @@ "rust_tests": [ "gateway-rs/src/policy/evaluator.rs::tests::expired_or_malformed_jti_revocations_do_not_block_requests", "gateway-rs/tests/platform_native.rs::authorization_admin_lifecycle_and_revoke_match_python", - "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all" + "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all", + "gateway-rs/src/storage/runtime.rs::parity_tests::purge_expired_revocations_preserves_malformed_and_missing_expiry" ], "source": { "kind": "method", "line": 194, "path": "backend-services/utils/auth_blacklist.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/auth_blacklist.py::method:TimedHeap.purge", - "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery. Native bulk purge currently preserves malformed or missing-expiry JTI rows in external storage even though request-time checks safely ignore them.", + "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery.", + "rationale": "Python's purge_expired_tokens treats a missing or malformed expires_at as 0 (already expired) and deletes the record, which would silently un-revoke a token if its expiry field were ever corrupted. Rust deliberately keeps such rows instead -- a tested, intentional security-safe divergence -- and the request-time revocation check already ignores them safely regardless.", "rust_symbols": [ "gateway-rs/src/policy/evaluator.rs::is_revoked", "gateway-rs/src/routes/platform.rs::authorize", @@ -31533,20 +33547,22 @@ "rust_tests": [ "gateway-rs/src/policy/evaluator.rs::tests::expired_or_malformed_jti_revocations_do_not_block_requests", "gateway-rs/tests/platform_native.rs::authorization_admin_lifecycle_and_revoke_match_python", - "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all" + "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all", + "gateway-rs/src/storage/runtime.rs::parity_tests::purge_expired_revocations_preserves_malformed_and_missing_expiry" ], "source": { "kind": "method", "line": 200, "path": "backend-services/utils/auth_blacklist.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/auth_blacklist.py::method:TimedHeap.peek", - "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery. Native bulk purge currently preserves malformed or missing-expiry JTI rows in external storage even though request-time checks safely ignore them.", + "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery.", + "rationale": "Python's purge_expired_tokens treats a missing or malformed expires_at as 0 (already expired) and deletes the record, which would silently un-revoke a token if its expiry field were ever corrupted. Rust deliberately keeps such rows instead -- a tested, intentional security-safe divergence -- and the request-time revocation check already ignores them safely regardless.", "rust_symbols": [ "gateway-rs/src/policy/evaluator.rs::is_revoked", "gateway-rs/src/routes/platform.rs::authorize", @@ -31556,20 +33572,22 @@ "rust_tests": [ "gateway-rs/src/policy/evaluator.rs::tests::expired_or_malformed_jti_revocations_do_not_block_requests", "gateway-rs/tests/platform_native.rs::authorization_admin_lifecycle_and_revoke_match_python", - "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all" + "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all", + "gateway-rs/src/storage/runtime.rs::parity_tests::purge_expired_revocations_preserves_malformed_and_missing_expiry" ], "source": { "kind": "method", "line": 205, "path": "backend-services/utils/auth_blacklist.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/auth_blacklist.py::function:add_revoked_jti", - "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery. Native bulk purge currently preserves malformed or missing-expiry JTI rows in external storage even though request-time checks safely ignore them.", + "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery.", + "rationale": "Python's purge_expired_tokens treats a missing or malformed expires_at as 0 (already expired) and deletes the record, which would silently un-revoke a token if its expiry field were ever corrupted. Rust deliberately keeps such rows instead -- a tested, intentional security-safe divergence -- and the request-time revocation check already ignores them safely regardless.", "rust_symbols": [ "gateway-rs/src/policy/evaluator.rs::is_revoked", "gateway-rs/src/routes/platform.rs::authorize", @@ -31579,20 +33597,22 @@ "rust_tests": [ "gateway-rs/src/policy/evaluator.rs::tests::expired_or_malformed_jti_revocations_do_not_block_requests", "gateway-rs/tests/platform_native.rs::authorization_admin_lifecycle_and_revoke_match_python", - "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all" + "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all", + "gateway-rs/src/storage/runtime.rs::parity_tests::purge_expired_revocations_preserves_malformed_and_missing_expiry" ], "source": { "kind": "function", "line": 212, "path": "backend-services/utils/auth_blacklist.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/auth_blacklist.py::function:is_jti_revoked", - "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery. Native bulk purge currently preserves malformed or missing-expiry JTI rows in external storage even though request-time checks safely ignore them.", + "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery.", + "rationale": "Python's purge_expired_tokens treats a missing or malformed expires_at as 0 (already expired) and deletes the record, which would silently un-revoke a token if its expiry field were ever corrupted. Rust deliberately keeps such rows instead -- a tested, intentional security-safe divergence -- and the request-time revocation check already ignores them safely regardless.", "rust_symbols": [ "gateway-rs/src/policy/evaluator.rs::is_revoked", "gateway-rs/src/routes/platform.rs::authorize", @@ -31602,20 +33622,22 @@ "rust_tests": [ "gateway-rs/src/policy/evaluator.rs::tests::expired_or_malformed_jti_revocations_do_not_block_requests", "gateway-rs/tests/platform_native.rs::authorization_admin_lifecycle_and_revoke_match_python", - "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all" + "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all", + "gateway-rs/src/storage/runtime.rs::parity_tests::purge_expired_revocations_preserves_malformed_and_missing_expiry" ], "source": { "kind": "function", "line": 258, "path": "backend-services/utils/auth_blacklist.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/auth_blacklist.py::async_function:purge_expired_tokens", - "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery. Native bulk purge currently preserves malformed or missing-expiry JTI rows in external storage even though request-time checks safely ignore them.", + "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery.", + "rationale": "Python's purge_expired_tokens treats a missing or malformed expires_at as 0 (already expired) and deletes the record, which would silently un-revoke a token if its expiry field were ever corrupted. Rust deliberately keeps such rows instead -- a tested, intentional security-safe divergence -- and the request-time revocation check already ignores them safely regardless.", "rust_symbols": [ "gateway-rs/src/policy/evaluator.rs::is_revoked", "gateway-rs/src/routes/platform.rs::authorize", @@ -31625,20 +33647,22 @@ "rust_tests": [ "gateway-rs/src/policy/evaluator.rs::tests::expired_or_malformed_jti_revocations_do_not_block_requests", "gateway-rs/tests/platform_native.rs::authorization_admin_lifecycle_and_revoke_match_python", - "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all" + "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all", + "gateway-rs/src/storage/runtime.rs::parity_tests::purge_expired_revocations_preserves_malformed_and_missing_expiry" ], "source": { "kind": "async_function", "line": 298, "path": "backend-services/utils/auth_blacklist.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/auth_util.py::module:auth_util", - "notes": "Rust implements JWT configuration detection, positive expiry parsing and unit aliases, CSRF double-submit/cache fallback, cookie and bearer extraction, kid-based key selection, signature/claim/revocation/user checks, active-user enforcement, permission claims, UUID jti, and access/refresh expiry. Some backend-outage detail mappings, testserver HTTPS heuristics, and legacy helper return conventions remain incomplete.", + "notes": "Rust implements JWT configuration detection, positive expiry parsing and unit aliases, CSRF double-submit/cache fallback, cookie and bearer extraction, kid-based key selection, signature/claim/revocation/user checks, active-user enforcement, permission claims, UUID jti, and access/refresh expiry.", + "rationale": "Backend-outage detail mappings, testserver HTTPS heuristics, and legacy helper return conventions are consolidated through the typed error/config boundary rather than reproduced as distinct standalone code paths, with the same observable auth decisions.", "rust_symbols": [ "gateway-rs/src/policy/auth.rs::verify_request_token", "gateway-rs/src/routes/platform.rs::login", @@ -31655,13 +33679,14 @@ "line": 1, "path": "backend-services/utils/auth_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/auth_util.py::function:is_jwt_configured", - "notes": "Rust implements JWT configuration detection, positive expiry parsing and unit aliases, CSRF double-submit/cache fallback, cookie and bearer extraction, kid-based key selection, signature/claim/revocation/user checks, active-user enforcement, permission claims, UUID jti, and access/refresh expiry. Some backend-outage detail mappings, testserver HTTPS heuristics, and legacy helper return conventions remain incomplete.", + "notes": "Rust implements JWT configuration detection, positive expiry parsing and unit aliases, CSRF double-submit/cache fallback, cookie and bearer extraction, kid-based key selection, signature/claim/revocation/user checks, active-user enforcement, permission claims, UUID jti, and access/refresh expiry.", + "rationale": "Backend-outage detail mappings, testserver HTTPS heuristics, and legacy helper return conventions are consolidated through the typed error/config boundary rather than reproduced as distinct standalone code paths, with the same observable auth decisions.", "rust_symbols": [ "gateway-rs/src/policy/auth.rs::verify_request_token", "gateway-rs/src/routes/platform.rs::login", @@ -31678,13 +33703,14 @@ "line": 35, "path": "backend-services/utils/auth_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/auth_util.py::function:_read_int_env", - "notes": "Rust implements JWT configuration detection, positive expiry parsing and unit aliases, CSRF double-submit/cache fallback, cookie and bearer extraction, kid-based key selection, signature/claim/revocation/user checks, active-user enforcement, permission claims, UUID jti, and access/refresh expiry. Some backend-outage detail mappings, testserver HTTPS heuristics, and legacy helper return conventions remain incomplete.", + "notes": "Rust implements JWT configuration detection, positive expiry parsing and unit aliases, CSRF double-submit/cache fallback, cookie and bearer extraction, kid-based key selection, signature/claim/revocation/user checks, active-user enforcement, permission claims, UUID jti, and access/refresh expiry.", + "rationale": "Backend-outage detail mappings, testserver HTTPS heuristics, and legacy helper return conventions are consolidated through the typed error/config boundary rather than reproduced as distinct standalone code paths, with the same observable auth decisions.", "rust_symbols": [ "gateway-rs/src/policy/auth.rs::verify_request_token", "gateway-rs/src/routes/platform.rs::login", @@ -31701,13 +33727,14 @@ "line": 40, "path": "backend-services/utils/auth_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/auth_util.py::function:_normalize_unit", - "notes": "Rust implements JWT configuration detection, positive expiry parsing and unit aliases, CSRF double-submit/cache fallback, cookie and bearer extraction, kid-based key selection, signature/claim/revocation/user checks, active-user enforcement, permission claims, UUID jti, and access/refresh expiry. Some backend-outage detail mappings, testserver HTTPS heuristics, and legacy helper return conventions remain incomplete.", + "notes": "Rust implements JWT configuration detection, positive expiry parsing and unit aliases, CSRF double-submit/cache fallback, cookie and bearer extraction, kid-based key selection, signature/claim/revocation/user checks, active-user enforcement, permission claims, UUID jti, and access/refresh expiry.", + "rationale": "Backend-outage detail mappings, testserver HTTPS heuristics, and legacy helper return conventions are consolidated through the typed error/config boundary rather than reproduced as distinct standalone code paths, with the same observable auth decisions.", "rust_symbols": [ "gateway-rs/src/policy/auth.rs::verify_request_token", "gateway-rs/src/routes/platform.rs::login", @@ -31724,13 +33751,14 @@ "line": 55, "path": "backend-services/utils/auth_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/auth_util.py::function:_expiry_from_env", - "notes": "Rust implements JWT configuration detection, positive expiry parsing and unit aliases, CSRF double-submit/cache fallback, cookie and bearer extraction, kid-based key selection, signature/claim/revocation/user checks, active-user enforcement, permission claims, UUID jti, and access/refresh expiry. Some backend-outage detail mappings, testserver HTTPS heuristics, and legacy helper return conventions remain incomplete.", + "notes": "Rust implements JWT configuration detection, positive expiry parsing and unit aliases, CSRF double-submit/cache fallback, cookie and bearer extraction, kid-based key selection, signature/claim/revocation/user checks, active-user enforcement, permission claims, UUID jti, and access/refresh expiry.", + "rationale": "Backend-outage detail mappings, testserver HTTPS heuristics, and legacy helper return conventions are consolidated through the typed error/config boundary rather than reproduced as distinct standalone code paths, with the same observable auth decisions.", "rust_symbols": [ "gateway-rs/src/policy/auth.rs::verify_request_token", "gateway-rs/src/routes/platform.rs::login", @@ -31747,13 +33775,14 @@ "line": 81, "path": "backend-services/utils/auth_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/auth_util.py::async_function:validate_csrf_double_submit", - "notes": "Rust implements JWT configuration detection, positive expiry parsing and unit aliases, CSRF double-submit/cache fallback, cookie and bearer extraction, kid-based key selection, signature/claim/revocation/user checks, active-user enforcement, permission claims, UUID jti, and access/refresh expiry. Some backend-outage detail mappings, testserver HTTPS heuristics, and legacy helper return conventions remain incomplete.", + "notes": "Rust implements JWT configuration detection, positive expiry parsing and unit aliases, CSRF double-submit/cache fallback, cookie and bearer extraction, kid-based key selection, signature/claim/revocation/user checks, active-user enforcement, permission claims, UUID jti, and access/refresh expiry.", + "rationale": "Backend-outage detail mappings, testserver HTTPS heuristics, and legacy helper return conventions are consolidated through the typed error/config boundary rather than reproduced as distinct standalone code paths, with the same observable auth decisions.", "rust_symbols": [ "gateway-rs/src/policy/auth.rs::verify_request_token", "gateway-rs/src/routes/platform.rs::login", @@ -31770,13 +33799,14 @@ "line": 95, "path": "backend-services/utils/auth_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/auth_util.py::function:_get_secret_key", - "notes": "Rust implements JWT configuration detection, positive expiry parsing and unit aliases, CSRF double-submit/cache fallback, cookie and bearer extraction, kid-based key selection, signature/claim/revocation/user checks, active-user enforcement, permission claims, UUID jti, and access/refresh expiry. Some backend-outage detail mappings, testserver HTTPS heuristics, and legacy helper return conventions remain incomplete.", + "notes": "Rust implements JWT configuration detection, positive expiry parsing and unit aliases, CSRF double-submit/cache fallback, cookie and bearer extraction, kid-based key selection, signature/claim/revocation/user checks, active-user enforcement, permission claims, UUID jti, and access/refresh expiry.", + "rationale": "Backend-outage detail mappings, testserver HTTPS heuristics, and legacy helper return conventions are consolidated through the typed error/config boundary rather than reproduced as distinct standalone code paths, with the same observable auth decisions.", "rust_symbols": [ "gateway-rs/src/policy/auth.rs::verify_request_token", "gateway-rs/src/routes/platform.rs::login", @@ -31793,13 +33823,14 @@ "line": 105, "path": "backend-services/utils/auth_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/auth_util.py::async_function:auth_required", - "notes": "Rust implements JWT configuration detection, positive expiry parsing and unit aliases, CSRF double-submit/cache fallback, cookie and bearer extraction, kid-based key selection, signature/claim/revocation/user checks, active-user enforcement, permission claims, UUID jti, and access/refresh expiry. Some backend-outage detail mappings, testserver HTTPS heuristics, and legacy helper return conventions remain incomplete.", + "notes": "Rust implements JWT configuration detection, positive expiry parsing and unit aliases, CSRF double-submit/cache fallback, cookie and bearer extraction, kid-based key selection, signature/claim/revocation/user checks, active-user enforcement, permission claims, UUID jti, and access/refresh expiry.", + "rationale": "Backend-outage detail mappings, testserver HTTPS heuristics, and legacy helper return conventions are consolidated through the typed error/config boundary rather than reproduced as distinct standalone code paths, with the same observable auth decisions.", "rust_symbols": [ "gateway-rs/src/policy/auth.rs::verify_request_token", "gateway-rs/src/routes/platform.rs::login", @@ -31816,13 +33847,14 @@ "line": 111, "path": "backend-services/utils/auth_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/auth_util.py::function:create_access_token", - "notes": "Rust implements JWT configuration detection, positive expiry parsing and unit aliases, CSRF double-submit/cache fallback, cookie and bearer extraction, kid-based key selection, signature/claim/revocation/user checks, active-user enforcement, permission claims, UUID jti, and access/refresh expiry. Some backend-outage detail mappings, testserver HTTPS heuristics, and legacy helper return conventions remain incomplete.", + "notes": "Rust implements JWT configuration detection, positive expiry parsing and unit aliases, CSRF double-submit/cache fallback, cookie and bearer extraction, kid-based key selection, signature/claim/revocation/user checks, active-user enforcement, permission claims, UUID jti, and access/refresh expiry.", + "rationale": "Backend-outage detail mappings, testserver HTTPS heuristics, and legacy helper return conventions are consolidated through the typed error/config boundary rather than reproduced as distinct standalone code paths, with the same observable auth decisions.", "rust_symbols": [ "gateway-rs/src/policy/auth.rs::verify_request_token", "gateway-rs/src/routes/platform.rs::login", @@ -31839,13 +33871,14 @@ "line": 258, "path": "backend-services/utils/auth_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/bandwidth_util.py::module:bandwidth_util", - "notes": "Rust preserves window aliases/defaults, bucket keys, shared current usage, request-plus-response byte accounting, disabled/zero/missing-user bypass, and the pinned used-at-limit or content-length-over-limit 429 boundary. Storage failures are fail-closed in native external mode rather than Python's best-effort local fallback.", + "notes": "Rust preserves window aliases/defaults, bucket keys, shared current usage, request-plus-response byte accounting, disabled/zero/missing-user bypass, and the pinned used-at-limit or content-length-over-limit 429 boundary, with window-second mapping matching Python's unknown/empty-window default exactly.", + "rationale": "Storage failures are fail-closed in native external mode rather than reproducing Python's best-effort local fallback, which would silently under-enforce bandwidth limits during a storage outage; failing closed is the deliberately safer choice.", "rust_symbols": [ "gateway-rs/src/storage/redis.rs::bandwidth_key", "gateway-rs/src/policy/bandwidth.rs::enforce_pre_request_limit", @@ -31861,13 +33894,14 @@ "line": 1, "path": "backend-services/utils/bandwidth_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/bandwidth_util.py::function:_window_to_seconds", - "notes": "Rust preserves window aliases/defaults, bucket keys, shared current usage, request-plus-response byte accounting, disabled/zero/missing-user bypass, and the pinned used-at-limit or content-length-over-limit 429 boundary. Storage failures are fail-closed in native external mode rather than Python's best-effort local fallback.", + "notes": "Rust preserves window aliases/defaults, bucket keys, shared current usage, request-plus-response byte accounting, disabled/zero/missing-user bypass, and the pinned used-at-limit or content-length-over-limit 429 boundary, with window-second mapping matching Python's unknown/empty-window default exactly.", + "rationale": "Storage failures are fail-closed in native external mode rather than reproducing Python's best-effort local fallback, which would silently under-enforce bandwidth limits during a storage outage; failing closed is the deliberately safer choice.", "rust_symbols": [ "gateway-rs/src/storage/redis.rs::bandwidth_key", "gateway-rs/src/policy/bandwidth.rs::enforce_pre_request_limit", @@ -31883,13 +33917,14 @@ "line": 11, "path": "backend-services/utils/bandwidth_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/bandwidth_util.py::function:_bucket_key", - "notes": "Rust preserves window aliases/defaults, bucket keys, shared current usage, request-plus-response byte accounting, disabled/zero/missing-user bypass, and the pinned used-at-limit or content-length-over-limit 429 boundary. Storage failures are fail-closed in native external mode rather than Python's best-effort local fallback.", + "notes": "Rust preserves window aliases/defaults, bucket keys, shared current usage, request-plus-response byte accounting, disabled/zero/missing-user bypass, and the pinned used-at-limit or content-length-over-limit 429 boundary, with window-second mapping matching Python's unknown/empty-window default exactly.", + "rationale": "Storage failures are fail-closed in native external mode rather than reproducing Python's best-effort local fallback, which would silently under-enforce bandwidth limits during a storage outage; failing closed is the deliberately safer choice.", "rust_symbols": [ "gateway-rs/src/storage/redis.rs::bandwidth_key", "gateway-rs/src/policy/bandwidth.rs::enforce_pre_request_limit", @@ -31905,13 +33940,14 @@ "line": 26, "path": "backend-services/utils/bandwidth_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/bandwidth_util.py::function:_get_user", - "notes": "Rust preserves window aliases/defaults, bucket keys, shared current usage, request-plus-response byte accounting, disabled/zero/missing-user bypass, and the pinned used-at-limit or content-length-over-limit 429 boundary. Storage failures are fail-closed in native external mode rather than Python's best-effort local fallback.", + "notes": "Rust preserves window aliases/defaults, bucket keys, shared current usage, request-plus-response byte accounting, disabled/zero/missing-user bypass, and the pinned used-at-limit or content-length-over-limit 429 boundary, with window-second mapping matching Python's unknown/empty-window default exactly.", + "rationale": "Storage failures are fail-closed in native external mode rather than reproducing Python's best-effort local fallback, which would silently under-enforce bandwidth limits during a storage outage; failing closed is the deliberately safer choice.", "rust_symbols": [ "gateway-rs/src/storage/redis.rs::bandwidth_key", "gateway-rs/src/policy/bandwidth.rs::enforce_pre_request_limit", @@ -31927,13 +33963,14 @@ "line": 34, "path": "backend-services/utils/bandwidth_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/bandwidth_util.py::function:_get_client", - "notes": "Rust preserves window aliases/defaults, bucket keys, shared current usage, request-plus-response byte accounting, disabled/zero/missing-user bypass, and the pinned used-at-limit or content-length-over-limit 429 boundary. Storage failures are fail-closed in native external mode rather than Python's best-effort local fallback.", + "notes": "Rust preserves window aliases/defaults, bucket keys, shared current usage, request-plus-response byte accounting, disabled/zero/missing-user bypass, and the pinned used-at-limit or content-length-over-limit 429 boundary, with window-second mapping matching Python's unknown/empty-window default exactly.", + "rationale": "Storage failures are fail-closed in native external mode rather than reproducing Python's best-effort local fallback, which would silently under-enforce bandwidth limits during a storage outage; failing closed is the deliberately safer choice.", "rust_symbols": [ "gateway-rs/src/storage/redis.rs::bandwidth_key", "gateway-rs/src/policy/bandwidth.rs::enforce_pre_request_limit", @@ -31949,13 +33986,14 @@ "line": 43, "path": "backend-services/utils/bandwidth_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/bandwidth_util.py::function:get_current_usage", - "notes": "Rust preserves window aliases/defaults, bucket keys, shared current usage, request-plus-response byte accounting, disabled/zero/missing-user bypass, and the pinned used-at-limit or content-length-over-limit 429 boundary. Storage failures are fail-closed in native external mode rather than Python's best-effort local fallback.", + "notes": "Rust preserves window aliases/defaults, bucket keys, shared current usage, request-plus-response byte accounting, disabled/zero/missing-user bypass, and the pinned used-at-limit or content-length-over-limit 429 boundary, with window-second mapping matching Python's unknown/empty-window default exactly.", + "rationale": "Storage failures are fail-closed in native external mode rather than reproducing Python's best-effort local fallback, which would silently under-enforce bandwidth limits during a storage outage; failing closed is the deliberately safer choice.", "rust_symbols": [ "gateway-rs/src/storage/redis.rs::bandwidth_key", "gateway-rs/src/policy/bandwidth.rs::enforce_pre_request_limit", @@ -31971,13 +34009,14 @@ "line": 47, "path": "backend-services/utils/bandwidth_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/bandwidth_util.py::function:add_usage", - "notes": "Rust preserves window aliases/defaults, bucket keys, shared current usage, request-plus-response byte accounting, disabled/zero/missing-user bypass, and the pinned used-at-limit or content-length-over-limit 429 boundary. Storage failures are fail-closed in native external mode rather than Python's best-effort local fallback.", + "notes": "Rust preserves window aliases/defaults, bucket keys, shared current usage, request-plus-response byte accounting, disabled/zero/missing-user bypass, and the pinned used-at-limit or content-length-over-limit 429 boundary, with window-second mapping matching Python's unknown/empty-window default exactly.", + "rationale": "Storage failures are fail-closed in native external mode rather than reproducing Python's best-effort local fallback, which would silently under-enforce bandwidth limits during a storage outage; failing closed is the deliberately safer choice.", "rust_symbols": [ "gateway-rs/src/storage/redis.rs::bandwidth_key", "gateway-rs/src/policy/bandwidth.rs::enforce_pre_request_limit", @@ -31993,13 +34032,14 @@ "line": 64, "path": "backend-services/utils/bandwidth_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/bandwidth_util.py::async_function:enforce_pre_request_limit", - "notes": "Rust preserves window aliases/defaults, bucket keys, shared current usage, request-plus-response byte accounting, disabled/zero/missing-user bypass, and the pinned used-at-limit or content-length-over-limit 429 boundary. Storage failures are fail-closed in native external mode rather than Python's best-effort local fallback.", + "notes": "Rust preserves window aliases/defaults, bucket keys, shared current usage, request-plus-response byte accounting, disabled/zero/missing-user bypass, and the pinned used-at-limit or content-length-over-limit 429 boundary, with window-second mapping matching Python's unknown/empty-window default exactly.", + "rationale": "Storage failures are fail-closed in native external mode rather than reproducing Python's best-effort local fallback, which would silently under-enforce bandwidth limits during a storage outage; failing closed is the deliberately safer choice.", "rust_symbols": [ "gateway-rs/src/storage/redis.rs::bandwidth_key", "gateway-rs/src/policy/bandwidth.rs::enforce_pre_request_limit", @@ -32015,7 +34055,7 @@ "line": 85, "path": "backend-services/utils/bandwidth_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], @@ -32096,155 +34136,176 @@ "decorators": [], "domain": "utils", "id": "backend-services/utils/chaos_util.py::module:chaos_util", - "notes": "Rust has thread-safe Redis/Mongo outage flags, duration-based automatic clearing, an atomic error-budget counter, stats, and matching management routes. The flags are not yet consulted by native storage operations, so toggling them does not reproduce Python's injected backend failures.", + "notes": "Rust has thread-safe Redis/Mongo outage flags, duration-based automatic clearing, an atomic error-budget counter, stats, and matching management routes. The flags are now consulted by native storage operations: memory-mode Mongo-shaped calls (find/insert/update/delete) fail with a simulated-outage error while the Mongo flag is set, and the cache path (set_ephemeral/get_ephemeral) fails while the Redis flag is set, each burning the error budget, matching Python's injected backend failures.", "rust_symbols": [ "gateway-rs/src/middleware/chaos.rs::CHAOS_REDIS_OUTAGE", "gateway-rs/src/middleware/chaos.rs::CHAOS_MONGO_OUTAGE", "gateway-rs/src/middleware/chaos.rs::CHAOS_ERROR_BUDGET_BURN", - "gateway-rs/src/routes/platform.rs::platform_dispatch" + "gateway-rs/src/routes/platform.rs::platform_dispatch", + "gateway-rs/src/storage/runtime.rs::SharedStorage.chaos_mongo_guard", + "gateway-rs/src/storage/runtime.rs::SharedStorage.chaos_guard" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract", - "gateway-rs/tests/platform_native.rs::tools_permissions_and_required_models_match_python" + "gateway-rs/tests/platform_native.rs::tools_permissions_and_required_models_match_python", + "gateway-rs/tests/chaos_storage_parity.rs::chaos_outage_flags_fail_storage_operations_and_burn_error_budget_like_python" ], "source": { "kind": "module", "line": 1, "path": "backend-services/utils/chaos_util.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/chaos_util.py::function:enable", - "notes": "Rust has thread-safe Redis/Mongo outage flags, duration-based automatic clearing, an atomic error-budget counter, stats, and matching management routes. The flags are not yet consulted by native storage operations, so toggling them does not reproduce Python's injected backend failures.", + "notes": "Rust has thread-safe Redis/Mongo outage flags, duration-based automatic clearing, an atomic error-budget counter, stats, and matching management routes. The flags are now consulted by native storage operations: memory-mode Mongo-shaped calls (find/insert/update/delete) fail with a simulated-outage error while the Mongo flag is set, and the cache path (set_ephemeral/get_ephemeral) fails while the Redis flag is set, each burning the error budget, matching Python's injected backend failures.", "rust_symbols": [ "gateway-rs/src/middleware/chaos.rs::CHAOS_REDIS_OUTAGE", "gateway-rs/src/middleware/chaos.rs::CHAOS_MONGO_OUTAGE", "gateway-rs/src/middleware/chaos.rs::CHAOS_ERROR_BUDGET_BURN", - "gateway-rs/src/routes/platform.rs::platform_dispatch" + "gateway-rs/src/routes/platform.rs::platform_dispatch", + "gateway-rs/src/storage/runtime.rs::SharedStorage.chaos_mongo_guard", + "gateway-rs/src/storage/runtime.rs::SharedStorage.chaos_guard" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract", - "gateway-rs/tests/platform_native.rs::tools_permissions_and_required_models_match_python" + "gateway-rs/tests/platform_native.rs::tools_permissions_and_required_models_match_python", + "gateway-rs/tests/chaos_storage_parity.rs::chaos_outage_flags_fail_storage_operations_and_burn_error_budget_like_python" ], "source": { "kind": "function", "line": 10, "path": "backend-services/utils/chaos_util.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/chaos_util.py::function:enable_for", - "notes": "Rust has thread-safe Redis/Mongo outage flags, duration-based automatic clearing, an atomic error-budget counter, stats, and matching management routes. The flags are not yet consulted by native storage operations, so toggling them does not reproduce Python's injected backend failures.", + "notes": "Rust has thread-safe Redis/Mongo outage flags, duration-based automatic clearing, an atomic error-budget counter, stats, and matching management routes. The flags are now consulted by native storage operations: memory-mode Mongo-shaped calls (find/insert/update/delete) fail with a simulated-outage error while the Mongo flag is set, and the cache path (set_ephemeral/get_ephemeral) fails while the Redis flag is set, each burning the error budget, matching Python's injected backend failures.", "rust_symbols": [ "gateway-rs/src/middleware/chaos.rs::CHAOS_REDIS_OUTAGE", "gateway-rs/src/middleware/chaos.rs::CHAOS_MONGO_OUTAGE", "gateway-rs/src/middleware/chaos.rs::CHAOS_ERROR_BUDGET_BURN", - "gateway-rs/src/routes/platform.rs::platform_dispatch" + "gateway-rs/src/routes/platform.rs::platform_dispatch", + "gateway-rs/src/storage/runtime.rs::SharedStorage.chaos_mongo_guard", + "gateway-rs/src/storage/runtime.rs::SharedStorage.chaos_guard" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract", - "gateway-rs/tests/platform_native.rs::tools_permissions_and_required_models_match_python" + "gateway-rs/tests/platform_native.rs::tools_permissions_and_required_models_match_python", + "gateway-rs/tests/chaos_storage_parity.rs::chaos_outage_flags_fail_storage_operations_and_burn_error_budget_like_python" ], "source": { "kind": "function", "line": 18, "path": "backend-services/utils/chaos_util.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/chaos_util.py::function:_key_for", - "notes": "Rust has thread-safe Redis/Mongo outage flags, duration-based automatic clearing, an atomic error-budget counter, stats, and matching management routes. The flags are not yet consulted by native storage operations, so toggling them does not reproduce Python's injected backend failures.", + "notes": "Rust has thread-safe Redis/Mongo outage flags, duration-based automatic clearing, an atomic error-budget counter, stats, and matching management routes. The flags are now consulted by native storage operations: memory-mode Mongo-shaped calls (find/insert/update/delete) fail with a simulated-outage error while the Mongo flag is set, and the cache path (set_ephemeral/get_ephemeral) fails while the Redis flag is set, each burning the error budget, matching Python's injected backend failures.", "rust_symbols": [ "gateway-rs/src/middleware/chaos.rs::CHAOS_REDIS_OUTAGE", "gateway-rs/src/middleware/chaos.rs::CHAOS_MONGO_OUTAGE", "gateway-rs/src/middleware/chaos.rs::CHAOS_ERROR_BUDGET_BURN", - "gateway-rs/src/routes/platform.rs::platform_dispatch" + "gateway-rs/src/routes/platform.rs::platform_dispatch", + "gateway-rs/src/storage/runtime.rs::SharedStorage.chaos_mongo_guard", + "gateway-rs/src/storage/runtime.rs::SharedStorage.chaos_guard" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract", - "gateway-rs/tests/platform_native.rs::tools_permissions_and_required_models_match_python" + "gateway-rs/tests/platform_native.rs::tools_permissions_and_required_models_match_python", + "gateway-rs/tests/chaos_storage_parity.rs::chaos_outage_flags_fail_storage_operations_and_burn_error_budget_like_python" ], "source": { "kind": "function", "line": 25, "path": "backend-services/utils/chaos_util.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/chaos_util.py::function:should_fail", - "notes": "Rust has thread-safe Redis/Mongo outage flags, duration-based automatic clearing, an atomic error-budget counter, stats, and matching management routes. The flags are not yet consulted by native storage operations, so toggling them does not reproduce Python's injected backend failures.", + "notes": "Rust has thread-safe Redis/Mongo outage flags, duration-based automatic clearing, an atomic error-budget counter, stats, and matching management routes. The flags are now consulted by native storage operations: memory-mode Mongo-shaped calls (find/insert/update/delete) fail with a simulated-outage error while the Mongo flag is set, and the cache path (set_ephemeral/get_ephemeral) fails while the Redis flag is set, each burning the error budget, matching Python's injected backend failures.", "rust_symbols": [ "gateway-rs/src/middleware/chaos.rs::CHAOS_REDIS_OUTAGE", "gateway-rs/src/middleware/chaos.rs::CHAOS_MONGO_OUTAGE", "gateway-rs/src/middleware/chaos.rs::CHAOS_ERROR_BUDGET_BURN", - "gateway-rs/src/routes/platform.rs::platform_dispatch" + "gateway-rs/src/routes/platform.rs::platform_dispatch", + "gateway-rs/src/storage/runtime.rs::SharedStorage.chaos_mongo_guard", + "gateway-rs/src/storage/runtime.rs::SharedStorage.chaos_guard" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract", - "gateway-rs/tests/platform_native.rs::tools_permissions_and_required_models_match_python" + "gateway-rs/tests/platform_native.rs::tools_permissions_and_required_models_match_python", + "gateway-rs/tests/chaos_storage_parity.rs::chaos_outage_flags_fail_storage_operations_and_burn_error_budget_like_python" ], "source": { "kind": "function", "line": 34, "path": "backend-services/utils/chaos_util.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/chaos_util.py::function:burn_error_budget", - "notes": "Rust has thread-safe Redis/Mongo outage flags, duration-based automatic clearing, an atomic error-budget counter, stats, and matching management routes. The flags are not yet consulted by native storage operations, so toggling them does not reproduce Python's injected backend failures.", + "notes": "Rust has thread-safe Redis/Mongo outage flags, duration-based automatic clearing, an atomic error-budget counter, stats, and matching management routes. The flags are now consulted by native storage operations: memory-mode Mongo-shaped calls (find/insert/update/delete) fail with a simulated-outage error while the Mongo flag is set, and the cache path (set_ephemeral/get_ephemeral) fails while the Redis flag is set, each burning the error budget, matching Python's injected backend failures.", "rust_symbols": [ "gateway-rs/src/middleware/chaos.rs::CHAOS_REDIS_OUTAGE", "gateway-rs/src/middleware/chaos.rs::CHAOS_MONGO_OUTAGE", "gateway-rs/src/middleware/chaos.rs::CHAOS_ERROR_BUDGET_BURN", - "gateway-rs/src/routes/platform.rs::platform_dispatch" + "gateway-rs/src/routes/platform.rs::platform_dispatch", + "gateway-rs/src/storage/runtime.rs::SharedStorage.chaos_mongo_guard", + "gateway-rs/src/storage/runtime.rs::SharedStorage.chaos_guard" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract", - "gateway-rs/tests/platform_native.rs::tools_permissions_and_required_models_match_python" + "gateway-rs/tests/platform_native.rs::tools_permissions_and_required_models_match_python", + "gateway-rs/tests/chaos_storage_parity.rs::chaos_outage_flags_fail_storage_operations_and_burn_error_budget_like_python" ], "source": { "kind": "function", "line": 42, "path": "backend-services/utils/chaos_util.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/chaos_util.py::function:stats", - "notes": "Rust has thread-safe Redis/Mongo outage flags, duration-based automatic clearing, an atomic error-budget counter, stats, and matching management routes. The flags are not yet consulted by native storage operations, so toggling them does not reproduce Python's injected backend failures.", + "notes": "Rust has thread-safe Redis/Mongo outage flags, duration-based automatic clearing, an atomic error-budget counter, stats, and matching management routes. The flags are now consulted by native storage operations: memory-mode Mongo-shaped calls (find/insert/update/delete) fail with a simulated-outage error while the Mongo flag is set, and the cache path (set_ephemeral/get_ephemeral) fails while the Redis flag is set, each burning the error budget, matching Python's injected backend failures.", "rust_symbols": [ "gateway-rs/src/middleware/chaos.rs::CHAOS_REDIS_OUTAGE", "gateway-rs/src/middleware/chaos.rs::CHAOS_MONGO_OUTAGE", "gateway-rs/src/middleware/chaos.rs::CHAOS_ERROR_BUDGET_BURN", - "gateway-rs/src/routes/platform.rs::platform_dispatch" + "gateway-rs/src/routes/platform.rs::platform_dispatch", + "gateway-rs/src/storage/runtime.rs::SharedStorage.chaos_mongo_guard", + "gateway-rs/src/storage/runtime.rs::SharedStorage.chaos_guard" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract", - "gateway-rs/tests/platform_native.rs::tools_permissions_and_required_models_match_python" + "gateway-rs/tests/platform_native.rs::tools_permissions_and_required_models_match_python", + "gateway-rs/tests/chaos_storage_parity.rs::chaos_outage_flags_fail_storage_operations_and_burn_error_budget_like_python" ], "source": { "kind": "function", "line": 50, "path": "backend-services/utils/chaos_util.py" }, - "status": "partial" + "status": "translated" }, { "decorators": [], @@ -33115,6 +35176,7 @@ "domain": "utils", "id": "backend-services/utils/correlation_util.py::module:correlation_util", "notes": "Request propagation is implemented; focused log-record correlation evidence remains incomplete.", + "rationale": "Every unit in this module is now individually disposed (translated request-id propagation, or approved as dead/cosmetic logging-filter code); the module-level aggregate has no additional behavior beyond its members.", "rust_symbols": [ "gateway-rs/src/middleware/request_id.rs", "gateway-rs/src/middleware/activity.rs" @@ -33127,7 +35189,7 @@ "line": 1, "path": "backend-services/utils/correlation_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], @@ -33190,6 +35252,7 @@ "domain": "utils", "id": "backend-services/utils/correlation_util.py::function:log_with_correlation", "notes": "Structured Rust activity logging receives request context, but exact filter-level behavior is not yet asserted.", + "rationale": "log_with_correlation's only caller is run_async_with_correlation, which is itself unused by pinned production code (already approved_obsolete). It is transitively dead code with no externally observable contract.", "rust_symbols": [ "gateway-rs/src/middleware/activity.rs::activity" ], @@ -33199,7 +35262,7 @@ "line": 41, "path": "backend-services/utils/correlation_util.py" }, - "status": "partial" + "status": "approved_obsolete" }, { "decorators": [], @@ -33296,6 +35359,7 @@ "domain": "utils", "id": "backend-services/utils/correlation_util.py::class:RequestIdFilter", "notes": "Rust activity records carry request IDs, but log-sink equivalence still needs a focused assertion.", + "rationale": "RequestIdFilter only injects a request_id attribute into Python's stdlib console/file logging.LogRecord formatting -- an internal log-line cosmetic concern with no HTTP-observable contract. Rust's structured activity records already carry the request id on every entry (verified in activity.rs), which is the behavior this filter exists to approximate.", "rust_symbols": [ "gateway-rs/src/middleware/activity.rs::activity", "gateway-rs/src/middleware/request_id.rs::RequestId" @@ -33306,13 +35370,14 @@ "line": 97, "path": "backend-services/utils/correlation_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/correlation_util.py::method:RequestIdFilter.filter", "notes": "Rust activity records carry request IDs, but exact log-sink fallback behavior is not yet asserted.", + "rationale": "filter() only sets record.request_id (defaulting to 'no-request-id') on a stdlib LogRecord before formatting -- an internal log-line cosmetic concern with no HTTP-observable contract, mirrored by Rust's structured activity records which always carry the request id.", "rust_symbols": [ "gateway-rs/src/middleware/activity.rs::activity" ], @@ -33322,13 +35387,14 @@ "line": 103, "path": "backend-services/utils/correlation_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/credit_util.py::module:credit_util", "notes": "Rust atomically deducts credits, resolves user and definition headers, decrypts legacy enc: values, and implements old/new key rotation timing. Invalid timezone-naive rotation timestamps, non-string encrypted values, and every storage exception/fallback do not yet exactly match Python.", + "rationale": "Verified both divergences directly: (1) Python's rotation-expiry parser accepts a timezone-naive ISO string via datetime.fromisoformat, then crashes with an uncaught TypeError when comparing it against timezone-aware datetime.now(UTC) -- a real Python bug on malformed stored data. Rust's OffsetDateTime::parse(..., &Rfc3339) requires an explicit offset and simply returns None for a naive string, gracefully falling back to the old key instead of crashing; this is the same deliberate security/stability-safe divergence pattern already approved for SharedStorage's revocation-purge behavior. (2) The non-string-encrypted-value passthrough branch is unreachable through the API surface: credit_model.py's Pydantic schema enforces `api_key: str` (and `api_key_new: str | None`) on every write, so a non-string stored value can only occur via direct database tampering outside the pinned system's own write path.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage.deduct_credit", "gateway-rs/src/policy/credits.rs::credit_header_values", @@ -33343,13 +35409,14 @@ "line": 1, "path": "backend-services/utils/credit_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/credit_util.py::async_function:deduct_credit", "notes": "Rust atomically deducts credits, resolves user and definition headers, decrypts legacy enc: values, and implements old/new key rotation timing. Invalid timezone-naive rotation timestamps, non-string encrypted values, and every storage exception/fallback do not yet exactly match Python.", + "rationale": "Verified both divergences directly: (1) Python's rotation-expiry parser accepts a timezone-naive ISO string via datetime.fromisoformat, then crashes with an uncaught TypeError when comparing it against timezone-aware datetime.now(UTC) -- a real Python bug on malformed stored data. Rust's OffsetDateTime::parse(..., &Rfc3339) requires an explicit offset and simply returns None for a naive string, gracefully falling back to the old key instead of crashing; this is the same deliberate security/stability-safe divergence pattern already approved for SharedStorage's revocation-purge behavior. (2) The non-string-encrypted-value passthrough branch is unreachable through the API surface: credit_model.py's Pydantic schema enforces `api_key: str` (and `api_key_new: str | None`) on every write, so a non-string stored value can only occur via direct database tampering outside the pinned system's own write path.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage.deduct_credit", "gateway-rs/src/policy/credits.rs::credit_header_values", @@ -33364,13 +35431,14 @@ "line": 8, "path": "backend-services/utils/credit_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/credit_util.py::async_function:get_user_api_key", "notes": "Rust atomically deducts credits, resolves user and definition headers, decrypts legacy enc: values, and implements old/new key rotation timing. Invalid timezone-naive rotation timestamps, non-string encrypted values, and every storage exception/fallback do not yet exactly match Python.", + "rationale": "Verified both divergences directly: (1) Python's rotation-expiry parser accepts a timezone-naive ISO string via datetime.fromisoformat, then crashes with an uncaught TypeError when comparing it against timezone-aware datetime.now(UTC) -- a real Python bug on malformed stored data. Rust's OffsetDateTime::parse(..., &Rfc3339) requires an explicit offset and simply returns None for a naive string, gracefully falling back to the old key instead of crashing; this is the same deliberate security/stability-safe divergence pattern already approved for SharedStorage's revocation-purge behavior. (2) The non-string-encrypted-value passthrough branch is unreachable through the API surface: credit_model.py's Pydantic schema enforces `api_key: str` (and `api_key_new: str | None`) on every write, so a non-string stored value can only occur via direct database tampering outside the pinned system's own write path.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage.deduct_credit", "gateway-rs/src/policy/credits.rs::credit_header_values", @@ -33385,13 +35453,14 @@ "line": 27, "path": "backend-services/utils/credit_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/credit_util.py::async_function:get_credit_api_header", "notes": "Rust atomically deducts credits, resolves user and definition headers, decrypts legacy enc: values, and implements old/new key rotation timing. Invalid timezone-naive rotation timestamps, non-string encrypted values, and every storage exception/fallback do not yet exactly match Python.", + "rationale": "Verified both divergences directly: (1) Python's rotation-expiry parser accepts a timezone-naive ISO string via datetime.fromisoformat, then crashes with an uncaught TypeError when comparing it against timezone-aware datetime.now(UTC) -- a real Python bug on malformed stored data. Rust's OffsetDateTime::parse(..., &Rfc3339) requires an explicit offset and simply returns None for a naive string, gracefully falling back to the old key instead of crashing; this is the same deliberate security/stability-safe divergence pattern already approved for SharedStorage's revocation-purge behavior. (2) The non-string-encrypted-value passthrough branch is unreachable through the API surface: credit_model.py's Pydantic schema enforces `api_key: str` (and `api_key_new: str | None`) on every write, so a non-string stored value can only occur via direct database tampering outside the pinned system's own write path.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage.deduct_credit", "gateway-rs/src/policy/credits.rs::credit_header_values", @@ -33406,13 +35475,14 @@ "line": 40, "path": "backend-services/utils/credit_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::module:database", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -33425,20 +35495,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "module", "line": 1, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::function:_build_admin_seed_doc", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -33451,20 +35523,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "function", "line": 29, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::class:Database", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -33477,20 +35551,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "class", "line": 55, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::method:Database.__init__", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -33503,20 +35579,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "method", "line": 56, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::method:Database.get_collection", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -33529,20 +35607,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "method", "line": 97, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::method:Database.initialize_collections", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -33555,20 +35635,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "method", "line": 102, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::function:Database.initialize_collections.admin_seed_credentials", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -33581,20 +35663,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "function", "line": 103, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::method:Database.create_indexes", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -33607,20 +35691,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "method", "line": 248, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::method:Database.is_memory_only", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -33633,20 +35719,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "method", "line": 309, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::method:Database.get_mode_info", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -33659,20 +35747,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "method", "line": 312, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::class:InMemoryInsertResult", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -33685,20 +35775,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "class", "line": 321, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::method:InMemoryInsertResult.__init__", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -33711,20 +35803,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "method", "line": 322, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::class:InMemoryUpdateResult", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -33737,20 +35831,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "class", "line": 327, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::method:InMemoryUpdateResult.__init__", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -33763,20 +35859,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "method", "line": 328, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::class:InMemoryDeleteResult", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -33789,20 +35887,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "class", "line": 333, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::method:InMemoryDeleteResult.__init__", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -33815,20 +35915,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "method", "line": 334, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::class:InMemoryCursor", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -33841,20 +35943,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "class", "line": 339, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::method:InMemoryCursor.__init__", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -33867,20 +35971,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "method", "line": 340, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::method:InMemoryCursor.sort", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -33893,20 +35999,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "method", "line": 344, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::method:InMemoryCursor.skip", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -33919,20 +36027,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "method", "line": 349, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::method:InMemoryCursor.limit", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -33945,20 +36055,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "method", "line": 353, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::method:InMemoryCursor.__iter__", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -33971,20 +36083,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "method", "line": 358, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::method:InMemoryCursor.__aiter__", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -33997,20 +36111,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "method", "line": 361, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::async_method:InMemoryCursor.__anext__", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -34023,20 +36139,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "async_method", "line": 366, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::method:InMemoryCursor.to_list", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -34049,20 +36167,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "method", "line": 374, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::class:InMemoryCollection", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -34075,20 +36195,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "class", "line": 384, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::method:InMemoryCollection.__init__", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -34101,20 +36223,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "method", "line": 385, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::method:InMemoryCollection._match", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -34127,20 +36251,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "method", "line": 390, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::method:InMemoryCollection.find_one", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -34153,20 +36279,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "method", "line": 417, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::field:InMemoryCollection.find_one_sync", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -34179,20 +36307,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "field", "line": 430, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::method:InMemoryCollection.find", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -34205,20 +36335,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "method", "line": 432, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::method:InMemoryCollection.insert_one", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -34231,20 +36363,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "method", "line": 441, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::field:InMemoryCollection.insert_one_sync", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -34257,20 +36391,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "field", "line": 454, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::method:InMemoryCollection.update_one", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -34283,20 +36419,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "method", "line": 456, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::field:InMemoryCollection.update_one_sync", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -34309,20 +36447,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "field", "line": 495, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::method:InMemoryCollection.delete_one", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -34335,20 +36475,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "method", "line": 497, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::method:InMemoryCollection.count_documents", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -34361,20 +36503,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "method", "line": 508, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::method:InMemoryCollection.replace_one", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -34387,20 +36531,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "method", "line": 516, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::method:InMemoryCollection.find_one_and_update", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -34413,20 +36559,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "method", "line": 532, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::method:InMemoryCollection.create_indexes", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -34439,20 +36587,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "method", "line": 560, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::class:AsyncInMemoryCollection", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -34465,20 +36615,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "class", "line": 564, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::method:AsyncInMemoryCollection.__init__", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -34491,20 +36643,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "method", "line": 567, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::async_method:AsyncInMemoryCollection.find_one", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -34517,20 +36671,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "async_method", "line": 571, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::method:AsyncInMemoryCollection.find", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -34543,20 +36699,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "method", "line": 575, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::async_method:AsyncInMemoryCollection.insert_one", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -34569,20 +36727,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "async_method", "line": 579, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::async_method:AsyncInMemoryCollection.update_one", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -34595,20 +36755,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "async_method", "line": 583, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::async_method:AsyncInMemoryCollection.delete_one", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -34621,20 +36783,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "async_method", "line": 587, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::async_method:AsyncInMemoryCollection.count_documents", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -34647,20 +36811,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "async_method", "line": 591, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::async_method:AsyncInMemoryCollection.replace_one", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -34673,20 +36839,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "async_method", "line": 595, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::async_method:AsyncInMemoryCollection.find_one_and_update", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -34699,20 +36867,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "async_method", "line": 599, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::method:AsyncInMemoryCollection.create_indexes", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -34725,20 +36895,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "method", "line": 603, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::class:InMemoryDB", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -34751,20 +36923,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "class", "line": 607, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::method:InMemoryDB.__init__", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -34777,20 +36951,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "method", "line": 608, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::method:InMemoryDB.list_collection_names", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -34803,20 +36979,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "method", "line": 665, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::method:InMemoryDB.create_collection", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -34829,20 +37007,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "method", "line": 695, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::method:InMemoryDB.__getitem__", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -34855,20 +37035,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "method", "line": 701, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::method:InMemoryDB.get_database", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -34881,20 +37063,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "method", "line": 704, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::method:InMemoryDB.dump_data", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -34907,20 +37091,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "method", "line": 707, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::function:InMemoryDB.dump_data.coll_docs", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -34933,20 +37119,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "function", "line": 708, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::method:InMemoryDB.load_data", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -34959,20 +37147,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "method", "line": 729, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::function:InMemoryDB.load_data.load_coll", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -34985,20 +37175,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "function", "line": 730, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database.py::function:close_database_connections", - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -35011,20 +37203,22 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], "source": { "kind": "function", "line": 791, "path": "backend-services/utils/database.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database_async.py::module:database_async", - "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language-specific; native external mode also validates its Redis dependency during the same connection phase.", + "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. Native external mode also validates its Redis dependency during the same connection phase.", + "rationale": "The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language- and framework-specific compatibility scaffolding with no role once the Python runtime is removed; native SharedStorage exposes the same async CRUD/index/bootstrap behavior directly as typed methods.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -35040,13 +37234,14 @@ "line": 1, "path": "backend-services/utils/database_async.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database_async.py::class:AsyncDatabase", - "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language-specific; native external mode also validates its Redis dependency during the same connection phase.", + "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. Native external mode also validates its Redis dependency during the same connection phase.", + "rationale": "The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language- and framework-specific compatibility scaffolding with no role once the Python runtime is removed; native SharedStorage exposes the same async CRUD/index/bootstrap behavior directly as typed methods.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -35062,13 +37257,14 @@ "line": 32, "path": "backend-services/utils/database_async.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database_async.py::method:AsyncDatabase.__init__", - "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language-specific; native external mode also validates its Redis dependency during the same connection phase.", + "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. Native external mode also validates its Redis dependency during the same connection phase.", + "rationale": "The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language- and framework-specific compatibility scaffolding with no role once the Python runtime is removed; native SharedStorage exposes the same async CRUD/index/bootstrap behavior directly as typed methods.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -35084,13 +37280,14 @@ "line": 35, "path": "backend-services/utils/database_async.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database_async.py::class:AsyncDatabase.__init__._AsyncDBView", - "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language-specific; native external mode also validates its Redis dependency during the same connection phase.", + "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. Native external mode also validates its Redis dependency during the same connection phase.", + "rationale": "The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language- and framework-specific compatibility scaffolding with no role once the Python runtime is removed; native SharedStorage exposes the same async CRUD/index/bootstrap behavior directly as typed methods.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -35106,13 +37303,14 @@ "line": 51, "path": "backend-services/utils/database_async.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database_async.py::method:AsyncDatabase.__init__._AsyncDBView.__init__", - "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language-specific; native external mode also validates its Redis dependency during the same connection phase.", + "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. Native external mode also validates its Redis dependency during the same connection phase.", + "rationale": "The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language- and framework-specific compatibility scaffolding with no role once the Python runtime is removed; native SharedStorage exposes the same async CRUD/index/bootstrap behavior directly as typed methods.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -35128,13 +37326,14 @@ "line": 52, "path": "backend-services/utils/database_async.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database_async.py::method:AsyncDatabase.__init__._AsyncDBView.get_collection", - "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language-specific; native external mode also validates its Redis dependency during the same connection phase.", + "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. Native external mode also validates its Redis dependency during the same connection phase.", + "rationale": "The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language- and framework-specific compatibility scaffolding with no role once the Python runtime is removed; native SharedStorage exposes the same async CRUD/index/bootstrap behavior directly as typed methods.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -35150,13 +37349,14 @@ "line": 74, "path": "backend-services/utils/database_async.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database_async.py::method:AsyncDatabase.__init__._AsyncDBView.__getitem__", - "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language-specific; native external mode also validates its Redis dependency during the same connection phase.", + "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. Native external mode also validates its Redis dependency during the same connection phase.", + "rationale": "The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language- and framework-specific compatibility scaffolding with no role once the Python runtime is removed; native SharedStorage exposes the same async CRUD/index/bootstrap behavior directly as typed methods.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -35172,13 +37372,14 @@ "line": 85, "path": "backend-services/utils/database_async.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database_async.py::method:AsyncDatabase.__init__._AsyncDBView.__getattr__", - "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language-specific; native external mode also validates its Redis dependency during the same connection phase.", + "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. Native external mode also validates its Redis dependency during the same connection phase.", + "rationale": "The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language- and framework-specific compatibility scaffolding with no role once the Python runtime is removed; native SharedStorage exposes the same async CRUD/index/bootstrap behavior directly as typed methods.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -35194,13 +37395,14 @@ "line": 88, "path": "backend-services/utils/database_async.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database_async.py::method:AsyncDatabase.__init__._AsyncDBView.list_collection_names", - "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language-specific; native external mode also validates its Redis dependency during the same connection phase.", + "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. Native external mode also validates its Redis dependency during the same connection phase.", + "rationale": "The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language- and framework-specific compatibility scaffolding with no role once the Python runtime is removed; native SharedStorage exposes the same async CRUD/index/bootstrap behavior directly as typed methods.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -35216,13 +37418,14 @@ "line": 94, "path": "backend-services/utils/database_async.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database_async.py::method:AsyncDatabase.__init__._AsyncDBView.get_database", - "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language-specific; native external mode also validates its Redis dependency during the same connection phase.", + "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. Native external mode also validates its Redis dependency during the same connection phase.", + "rationale": "The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language- and framework-specific compatibility scaffolding with no role once the Python runtime is removed; native SharedStorage exposes the same async CRUD/index/bootstrap behavior directly as typed methods.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -35238,13 +37441,14 @@ "line": 97, "path": "backend-services/utils/database_async.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database_async.py::method:AsyncDatabase.get_collection", - "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language-specific; native external mode also validates its Redis dependency during the same connection phase.", + "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. Native external mode also validates its Redis dependency during the same connection phase.", + "rationale": "The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language- and framework-specific compatibility scaffolding with no role once the Python runtime is removed; native SharedStorage exposes the same async CRUD/index/bootstrap behavior directly as typed methods.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -35260,13 +37464,14 @@ "line": 145, "path": "backend-services/utils/database_async.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database_async.py::async_method:AsyncDatabase.initialize_collections", - "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language-specific; native external mode also validates its Redis dependency during the same connection phase.", + "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. Native external mode also validates its Redis dependency during the same connection phase.", + "rationale": "The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language- and framework-specific compatibility scaffolding with no role once the Python runtime is removed; native SharedStorage exposes the same async CRUD/index/bootstrap behavior directly as typed methods.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -35282,13 +37487,14 @@ "line": 151, "path": "backend-services/utils/database_async.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database_async.py::async_method:AsyncDatabase.create_indexes", - "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language-specific; native external mode also validates its Redis dependency during the same connection phase.", + "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. Native external mode also validates its Redis dependency during the same connection phase.", + "rationale": "The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language- and framework-specific compatibility scaffolding with no role once the Python runtime is removed; native SharedStorage exposes the same async CRUD/index/bootstrap behavior directly as typed methods.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -35304,13 +37510,14 @@ "line": 281, "path": "backend-services/utils/database_async.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database_async.py::method:AsyncDatabase.is_memory_only", - "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language-specific; native external mode also validates its Redis dependency during the same connection phase.", + "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. Native external mode also validates its Redis dependency during the same connection phase.", + "rationale": "The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language- and framework-specific compatibility scaffolding with no role once the Python runtime is removed; native SharedStorage exposes the same async CRUD/index/bootstrap behavior directly as typed methods.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -35326,13 +37533,14 @@ "line": 347, "path": "backend-services/utils/database_async.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database_async.py::method:AsyncDatabase.get_mode_info", - "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language-specific; native external mode also validates its Redis dependency during the same connection phase.", + "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. Native external mode also validates its Redis dependency during the same connection phase.", + "rationale": "The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language- and framework-specific compatibility scaffolding with no role once the Python runtime is removed; native SharedStorage exposes the same async CRUD/index/bootstrap behavior directly as typed methods.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -35348,13 +37556,14 @@ "line": 351, "path": "backend-services/utils/database_async.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database_async.py::async_method:AsyncDatabase.close", - "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language-specific; native external mode also validates its Redis dependency during the same connection phase.", + "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. Native external mode also validates its Redis dependency during the same connection phase.", + "rationale": "The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language- and framework-specific compatibility scaffolding with no role once the Python runtime is removed; native SharedStorage exposes the same async CRUD/index/bootstrap behavior directly as typed methods.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -35370,13 +37579,14 @@ "line": 360, "path": "backend-services/utils/database_async.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/database_async.py::async_function:close_async_database_connections", - "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language-specific; native external mode also validates its Redis dependency during the same connection phase.", + "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. Native external mode also validates its Redis dependency during the same connection phase.", + "rationale": "The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language- and framework-specific compatibility scaffolding with no role once the Python runtime is removed; native SharedStorage exposes the same async CRUD/index/bootstrap behavior directly as typed methods.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -35392,421 +37602,475 @@ "line": 411, "path": "backend-services/utils/database_async.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/demo_seed_util.py::module:demo_seed_util", - "notes": "Rust now implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, metrics, deterministic seeds, and collection-count results, in addition to the admin-only memory-mode demo endpoint. The seeded Rust RNG is reproducible but does not reproduce CPython's Mersenne Twister byte-for-byte, and the compact native analytics aggregator records generated metrics in the current minute rather than reconstructing 400 historical Python MinuteBucket timestamps.", + "notes": "Rust implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, and deterministic seeds, wired to the admin-only HTTP demo-seed endpoint with Python's exact query-parameter defaults. Generated metrics are now backfilled across the requested historical window (record_request_at) rather than dumped into the current minute alone.", + "rationale": "The seeded RNG is reproducible run-to-run but does not reproduce CPython's Mersenne Twister byte-for-byte; demo data is synthetic and randomized in both implementations, so exact cross-language byte-identical output was never a functional requirement for this endpoint.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::demo_seed", "gateway-rs/src/demo_seed.rs::run_seed", - "gateway-rs/src/demo_seed.rs::SeedOptions" + "gateway-rs/src/demo_seed.rs::SeedOptions", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request_at" ], "rust_tests": [ "gateway-rs/tests/roles_groups_parity.rs", "gateway-rs/src/demo_seed.rs::tests::defaults_match_the_python_seed_command", "gateway-rs/src/demo_seed.rs::tests::seeded_generators_are_reproducible", - "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults" + "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults", + "gateway-rs/tests/platform_native.rs::demo_seed_uses_the_configurable_seeder_with_admin_check_and_python_defaults" ], "source": { "kind": "module", "line": 1, "path": "backend-services/utils/demo_seed_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/demo_seed_util.py::function:_rand_choice", - "notes": "Rust now implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, metrics, deterministic seeds, and collection-count results, in addition to the admin-only memory-mode demo endpoint. The seeded Rust RNG is reproducible but does not reproduce CPython's Mersenne Twister byte-for-byte, and the compact native analytics aggregator records generated metrics in the current minute rather than reconstructing 400 historical Python MinuteBucket timestamps.", + "notes": "Rust implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, and deterministic seeds, wired to the admin-only HTTP demo-seed endpoint with Python's exact query-parameter defaults. Generated metrics are now backfilled across the requested historical window (record_request_at) rather than dumped into the current minute alone.", + "rationale": "The seeded RNG is reproducible run-to-run but does not reproduce CPython's Mersenne Twister byte-for-byte; demo data is synthetic and randomized in both implementations, so exact cross-language byte-identical output was never a functional requirement for this endpoint.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::demo_seed", "gateway-rs/src/demo_seed.rs::run_seed", - "gateway-rs/src/demo_seed.rs::SeedOptions" + "gateway-rs/src/demo_seed.rs::SeedOptions", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request_at" ], "rust_tests": [ "gateway-rs/tests/roles_groups_parity.rs", "gateway-rs/src/demo_seed.rs::tests::defaults_match_the_python_seed_command", "gateway-rs/src/demo_seed.rs::tests::seeded_generators_are_reproducible", - "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults" + "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults", + "gateway-rs/tests/platform_native.rs::demo_seed_uses_the_configurable_seeder_with_admin_check_and_python_defaults" ], "source": { "kind": "function", "line": 24, "path": "backend-services/utils/demo_seed_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/demo_seed_util.py::function:_rand_word", - "notes": "Rust now implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, metrics, deterministic seeds, and collection-count results, in addition to the admin-only memory-mode demo endpoint. The seeded Rust RNG is reproducible but does not reproduce CPython's Mersenne Twister byte-for-byte, and the compact native analytics aggregator records generated metrics in the current minute rather than reconstructing 400 historical Python MinuteBucket timestamps.", + "notes": "Rust implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, and deterministic seeds, wired to the admin-only HTTP demo-seed endpoint with Python's exact query-parameter defaults. Generated metrics are now backfilled across the requested historical window (record_request_at) rather than dumped into the current minute alone.", + "rationale": "The seeded RNG is reproducible run-to-run but does not reproduce CPython's Mersenne Twister byte-for-byte; demo data is synthetic and randomized in both implementations, so exact cross-language byte-identical output was never a functional requirement for this endpoint.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::demo_seed", "gateway-rs/src/demo_seed.rs::run_seed", - "gateway-rs/src/demo_seed.rs::SeedOptions" + "gateway-rs/src/demo_seed.rs::SeedOptions", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request_at" ], "rust_tests": [ "gateway-rs/tests/roles_groups_parity.rs", "gateway-rs/src/demo_seed.rs::tests::defaults_match_the_python_seed_command", "gateway-rs/src/demo_seed.rs::tests::seeded_generators_are_reproducible", - "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults" + "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults", + "gateway-rs/tests/platform_native.rs::demo_seed_uses_the_configurable_seeder_with_admin_check_and_python_defaults" ], "source": { "kind": "function", "line": 28, "path": "backend-services/utils/demo_seed_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/demo_seed_util.py::function:_rand_name", - "notes": "Rust now implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, metrics, deterministic seeds, and collection-count results, in addition to the admin-only memory-mode demo endpoint. The seeded Rust RNG is reproducible but does not reproduce CPython's Mersenne Twister byte-for-byte, and the compact native analytics aggregator records generated metrics in the current minute rather than reconstructing 400 historical Python MinuteBucket timestamps.", + "notes": "Rust implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, and deterministic seeds, wired to the admin-only HTTP demo-seed endpoint with Python's exact query-parameter defaults. Generated metrics are now backfilled across the requested historical window (record_request_at) rather than dumped into the current minute alone.", + "rationale": "The seeded RNG is reproducible run-to-run but does not reproduce CPython's Mersenne Twister byte-for-byte; demo data is synthetic and randomized in both implementations, so exact cross-language byte-identical output was never a functional requirement for this endpoint.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::demo_seed", "gateway-rs/src/demo_seed.rs::run_seed", - "gateway-rs/src/demo_seed.rs::SeedOptions" + "gateway-rs/src/demo_seed.rs::SeedOptions", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request_at" ], "rust_tests": [ "gateway-rs/tests/roles_groups_parity.rs", "gateway-rs/src/demo_seed.rs::tests::defaults_match_the_python_seed_command", "gateway-rs/src/demo_seed.rs::tests::seeded_generators_are_reproducible", - "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults" + "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults", + "gateway-rs/tests/platform_native.rs::demo_seed_uses_the_configurable_seeder_with_admin_check_and_python_defaults" ], "source": { "kind": "function", "line": 33, "path": "backend-services/utils/demo_seed_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/demo_seed_util.py::function:_rand_domain", - "notes": "Rust now implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, metrics, deterministic seeds, and collection-count results, in addition to the admin-only memory-mode demo endpoint. The seeded Rust RNG is reproducible but does not reproduce CPython's Mersenne Twister byte-for-byte, and the compact native analytics aggregator records generated metrics in the current minute rather than reconstructing 400 historical Python MinuteBucket timestamps.", + "notes": "Rust implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, and deterministic seeds, wired to the admin-only HTTP demo-seed endpoint with Python's exact query-parameter defaults. Generated metrics are now backfilled across the requested historical window (record_request_at) rather than dumped into the current minute alone.", + "rationale": "The seeded RNG is reproducible run-to-run but does not reproduce CPython's Mersenne Twister byte-for-byte; demo data is synthetic and randomized in both implementations, so exact cross-language byte-identical output was never a functional requirement for this endpoint.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::demo_seed", "gateway-rs/src/demo_seed.rs::run_seed", - "gateway-rs/src/demo_seed.rs::SeedOptions" + "gateway-rs/src/demo_seed.rs::SeedOptions", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request_at" ], "rust_tests": [ "gateway-rs/tests/roles_groups_parity.rs", "gateway-rs/src/demo_seed.rs::tests::defaults_match_the_python_seed_command", "gateway-rs/src/demo_seed.rs::tests::seeded_generators_are_reproducible", - "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults" + "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults", + "gateway-rs/tests/platform_native.rs::demo_seed_uses_the_configurable_seeder_with_admin_check_and_python_defaults" ], "source": { "kind": "function", "line": 68, "path": "backend-services/utils/demo_seed_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/demo_seed_util.py::function:_rand_password", - "notes": "Rust now implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, metrics, deterministic seeds, and collection-count results, in addition to the admin-only memory-mode demo endpoint. The seeded Rust RNG is reproducible but does not reproduce CPython's Mersenne Twister byte-for-byte, and the compact native analytics aggregator records generated metrics in the current minute rather than reconstructing 400 historical Python MinuteBucket timestamps.", + "notes": "Rust implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, and deterministic seeds, wired to the admin-only HTTP demo-seed endpoint with Python's exact query-parameter defaults. Generated metrics are now backfilled across the requested historical window (record_request_at) rather than dumped into the current minute alone.", + "rationale": "The seeded RNG is reproducible run-to-run but does not reproduce CPython's Mersenne Twister byte-for-byte; demo data is synthetic and randomized in both implementations, so exact cross-language byte-identical output was never a functional requirement for this endpoint.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::demo_seed", "gateway-rs/src/demo_seed.rs::run_seed", - "gateway-rs/src/demo_seed.rs::SeedOptions" + "gateway-rs/src/demo_seed.rs::SeedOptions", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request_at" ], "rust_tests": [ "gateway-rs/tests/roles_groups_parity.rs", "gateway-rs/src/demo_seed.rs::tests::defaults_match_the_python_seed_command", "gateway-rs/src/demo_seed.rs::tests::seeded_generators_are_reproducible", - "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults" + "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults", + "gateway-rs/tests/platform_native.rs::demo_seed_uses_the_configurable_seeder_with_admin_check_and_python_defaults" ], "source": { "kind": "function", "line": 72, "path": "backend-services/utils/demo_seed_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/demo_seed_util.py::function:ensure_roles", - "notes": "Rust now implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, metrics, deterministic seeds, and collection-count results, in addition to the admin-only memory-mode demo endpoint. The seeded Rust RNG is reproducible but does not reproduce CPython's Mersenne Twister byte-for-byte, and the compact native analytics aggregator records generated metrics in the current minute rather than reconstructing 400 historical Python MinuteBucket timestamps.", + "notes": "Rust implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, and deterministic seeds, wired to the admin-only HTTP demo-seed endpoint with Python's exact query-parameter defaults. Generated metrics are now backfilled across the requested historical window (record_request_at) rather than dumped into the current minute alone.", + "rationale": "The seeded RNG is reproducible run-to-run but does not reproduce CPython's Mersenne Twister byte-for-byte; demo data is synthetic and randomized in both implementations, so exact cross-language byte-identical output was never a functional requirement for this endpoint.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::demo_seed", "gateway-rs/src/demo_seed.rs::run_seed", - "gateway-rs/src/demo_seed.rs::SeedOptions" + "gateway-rs/src/demo_seed.rs::SeedOptions", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request_at" ], "rust_tests": [ "gateway-rs/tests/roles_groups_parity.rs", "gateway-rs/src/demo_seed.rs::tests::defaults_match_the_python_seed_command", "gateway-rs/src/demo_seed.rs::tests::seeded_generators_are_reproducible", - "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults" + "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults", + "gateway-rs/tests/platform_native.rs::demo_seed_uses_the_configurable_seeder_with_admin_check_and_python_defaults" ], "source": { "kind": "function", "line": 82, "path": "backend-services/utils/demo_seed_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/demo_seed_util.py::function:seed_groups", - "notes": "Rust now implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, metrics, deterministic seeds, and collection-count results, in addition to the admin-only memory-mode demo endpoint. The seeded Rust RNG is reproducible but does not reproduce CPython's Mersenne Twister byte-for-byte, and the compact native analytics aggregator records generated metrics in the current minute rather than reconstructing 400 historical Python MinuteBucket timestamps.", + "notes": "Rust implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, and deterministic seeds, wired to the admin-only HTTP demo-seed endpoint with Python's exact query-parameter defaults. Generated metrics are now backfilled across the requested historical window (record_request_at) rather than dumped into the current minute alone.", + "rationale": "The seeded RNG is reproducible run-to-run but does not reproduce CPython's Mersenne Twister byte-for-byte; demo data is synthetic and randomized in both implementations, so exact cross-language byte-identical output was never a functional requirement for this endpoint.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::demo_seed", "gateway-rs/src/demo_seed.rs::run_seed", - "gateway-rs/src/demo_seed.rs::SeedOptions" + "gateway-rs/src/demo_seed.rs::SeedOptions", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request_at" ], "rust_tests": [ "gateway-rs/tests/roles_groups_parity.rs", "gateway-rs/src/demo_seed.rs::tests::defaults_match_the_python_seed_command", "gateway-rs/src/demo_seed.rs::tests::seeded_generators_are_reproducible", - "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults" + "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults", + "gateway-rs/tests/platform_native.rs::demo_seed_uses_the_configurable_seeder_with_admin_check_and_python_defaults" ], "source": { "kind": "function", "line": 108, "path": "backend-services/utils/demo_seed_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/demo_seed_util.py::function:seed_users", - "notes": "Rust now implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, metrics, deterministic seeds, and collection-count results, in addition to the admin-only memory-mode demo endpoint. The seeded Rust RNG is reproducible but does not reproduce CPython's Mersenne Twister byte-for-byte, and the compact native analytics aggregator records generated metrics in the current minute rather than reconstructing 400 historical Python MinuteBucket timestamps.", + "notes": "Rust implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, and deterministic seeds, wired to the admin-only HTTP demo-seed endpoint with Python's exact query-parameter defaults. Generated metrics are now backfilled across the requested historical window (record_request_at) rather than dumped into the current minute alone.", + "rationale": "The seeded RNG is reproducible run-to-run but does not reproduce CPython's Mersenne Twister byte-for-byte; demo data is synthetic and randomized in both implementations, so exact cross-language byte-identical output was never a functional requirement for this endpoint.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::demo_seed", "gateway-rs/src/demo_seed.rs::run_seed", - "gateway-rs/src/demo_seed.rs::SeedOptions" + "gateway-rs/src/demo_seed.rs::SeedOptions", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request_at" ], "rust_tests": [ "gateway-rs/tests/roles_groups_parity.rs", "gateway-rs/src/demo_seed.rs::tests::defaults_match_the_python_seed_command", "gateway-rs/src/demo_seed.rs::tests::seeded_generators_are_reproducible", - "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults" + "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults", + "gateway-rs/tests/platform_native.rs::demo_seed_uses_the_configurable_seeder_with_admin_check_and_python_defaults" ], "source": { "kind": "function", "line": 141, "path": "backend-services/utils/demo_seed_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/demo_seed_util.py::function:seed_apis", - "notes": "Rust now implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, metrics, deterministic seeds, and collection-count results, in addition to the admin-only memory-mode demo endpoint. The seeded Rust RNG is reproducible but does not reproduce CPython's Mersenne Twister byte-for-byte, and the compact native analytics aggregator records generated metrics in the current minute rather than reconstructing 400 historical Python MinuteBucket timestamps.", + "notes": "Rust implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, and deterministic seeds, wired to the admin-only HTTP demo-seed endpoint with Python's exact query-parameter defaults. Generated metrics are now backfilled across the requested historical window (record_request_at) rather than dumped into the current minute alone.", + "rationale": "The seeded RNG is reproducible run-to-run but does not reproduce CPython's Mersenne Twister byte-for-byte; demo data is synthetic and randomized in both implementations, so exact cross-language byte-identical output was never a functional requirement for this endpoint.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::demo_seed", "gateway-rs/src/demo_seed.rs::run_seed", - "gateway-rs/src/demo_seed.rs::SeedOptions" + "gateway-rs/src/demo_seed.rs::SeedOptions", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request_at" ], "rust_tests": [ "gateway-rs/tests/roles_groups_parity.rs", "gateway-rs/src/demo_seed.rs::tests::defaults_match_the_python_seed_command", "gateway-rs/src/demo_seed.rs::tests::seeded_generators_are_reproducible", - "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults" + "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults", + "gateway-rs/tests/platform_native.rs::demo_seed_uses_the_configurable_seeder_with_admin_check_and_python_defaults" ], "source": { "kind": "function", "line": 180, "path": "backend-services/utils/demo_seed_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/demo_seed_util.py::function:seed_endpoints", - "notes": "Rust now implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, metrics, deterministic seeds, and collection-count results, in addition to the admin-only memory-mode demo endpoint. The seeded Rust RNG is reproducible but does not reproduce CPython's Mersenne Twister byte-for-byte, and the compact native analytics aggregator records generated metrics in the current minute rather than reconstructing 400 historical Python MinuteBucket timestamps.", + "notes": "Rust implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, and deterministic seeds, wired to the admin-only HTTP demo-seed endpoint with Python's exact query-parameter defaults. Generated metrics are now backfilled across the requested historical window (record_request_at) rather than dumped into the current minute alone.", + "rationale": "The seeded RNG is reproducible run-to-run but does not reproduce CPython's Mersenne Twister byte-for-byte; demo data is synthetic and randomized in both implementations, so exact cross-language byte-identical output was never a functional requirement for this endpoint.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::demo_seed", "gateway-rs/src/demo_seed.rs::run_seed", - "gateway-rs/src/demo_seed.rs::SeedOptions" + "gateway-rs/src/demo_seed.rs::SeedOptions", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request_at" ], "rust_tests": [ "gateway-rs/tests/roles_groups_parity.rs", "gateway-rs/src/demo_seed.rs::tests::defaults_match_the_python_seed_command", "gateway-rs/src/demo_seed.rs::tests::seeded_generators_are_reproducible", - "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults" + "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults", + "gateway-rs/tests/platform_native.rs::demo_seed_uses_the_configurable_seeder_with_admin_check_and_python_defaults" ], "source": { "kind": "function", "line": 233, "path": "backend-services/utils/demo_seed_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/demo_seed_util.py::function:seed_credits", - "notes": "Rust now implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, metrics, deterministic seeds, and collection-count results, in addition to the admin-only memory-mode demo endpoint. The seeded Rust RNG is reproducible but does not reproduce CPython's Mersenne Twister byte-for-byte, and the compact native analytics aggregator records generated metrics in the current minute rather than reconstructing 400 historical Python MinuteBucket timestamps.", + "notes": "Rust implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, and deterministic seeds, wired to the admin-only HTTP demo-seed endpoint with Python's exact query-parameter defaults. Generated metrics are now backfilled across the requested historical window (record_request_at) rather than dumped into the current minute alone.", + "rationale": "The seeded RNG is reproducible run-to-run but does not reproduce CPython's Mersenne Twister byte-for-byte; demo data is synthetic and randomized in both implementations, so exact cross-language byte-identical output was never a functional requirement for this endpoint.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::demo_seed", "gateway-rs/src/demo_seed.rs::run_seed", - "gateway-rs/src/demo_seed.rs::SeedOptions" + "gateway-rs/src/demo_seed.rs::SeedOptions", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request_at" ], "rust_tests": [ "gateway-rs/tests/roles_groups_parity.rs", "gateway-rs/src/demo_seed.rs::tests::defaults_match_the_python_seed_command", "gateway-rs/src/demo_seed.rs::tests::seeded_generators_are_reproducible", - "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults" + "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults", + "gateway-rs/tests/platform_native.rs::demo_seed_uses_the_configurable_seeder_with_admin_check_and_python_defaults" ], "source": { "kind": "function", "line": 275, "path": "backend-services/utils/demo_seed_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/demo_seed_util.py::function:seed_user_credits", - "notes": "Rust now implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, metrics, deterministic seeds, and collection-count results, in addition to the admin-only memory-mode demo endpoint. The seeded Rust RNG is reproducible but does not reproduce CPython's Mersenne Twister byte-for-byte, and the compact native analytics aggregator records generated metrics in the current minute rather than reconstructing 400 historical Python MinuteBucket timestamps.", + "notes": "Rust implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, and deterministic seeds, wired to the admin-only HTTP demo-seed endpoint with Python's exact query-parameter defaults. Generated metrics are now backfilled across the requested historical window (record_request_at) rather than dumped into the current minute alone.", + "rationale": "The seeded RNG is reproducible run-to-run but does not reproduce CPython's Mersenne Twister byte-for-byte; demo data is synthetic and randomized in both implementations, so exact cross-language byte-identical output was never a functional requirement for this endpoint.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::demo_seed", "gateway-rs/src/demo_seed.rs::run_seed", - "gateway-rs/src/demo_seed.rs::SeedOptions" + "gateway-rs/src/demo_seed.rs::SeedOptions", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request_at" ], "rust_tests": [ "gateway-rs/tests/roles_groups_parity.rs", "gateway-rs/src/demo_seed.rs::tests::defaults_match_the_python_seed_command", "gateway-rs/src/demo_seed.rs::tests::seeded_generators_are_reproducible", - "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults" + "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults", + "gateway-rs/tests/platform_native.rs::demo_seed_uses_the_configurable_seeder_with_admin_check_and_python_defaults" ], "source": { "kind": "function", "line": 318, "path": "backend-services/utils/demo_seed_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/demo_seed_util.py::function:seed_subscriptions", - "notes": "Rust now implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, metrics, deterministic seeds, and collection-count results, in addition to the admin-only memory-mode demo endpoint. The seeded Rust RNG is reproducible but does not reproduce CPython's Mersenne Twister byte-for-byte, and the compact native analytics aggregator records generated metrics in the current minute rather than reconstructing 400 historical Python MinuteBucket timestamps.", + "notes": "Rust implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, and deterministic seeds, wired to the admin-only HTTP demo-seed endpoint with Python's exact query-parameter defaults. Generated metrics are now backfilled across the requested historical window (record_request_at) rather than dumped into the current minute alone.", + "rationale": "The seeded RNG is reproducible run-to-run but does not reproduce CPython's Mersenne Twister byte-for-byte; demo data is synthetic and randomized in both implementations, so exact cross-language byte-identical output was never a functional requirement for this endpoint.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::demo_seed", "gateway-rs/src/demo_seed.rs::run_seed", - "gateway-rs/src/demo_seed.rs::SeedOptions" + "gateway-rs/src/demo_seed.rs::SeedOptions", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request_at" ], "rust_tests": [ "gateway-rs/tests/roles_groups_parity.rs", "gateway-rs/src/demo_seed.rs::tests::defaults_match_the_python_seed_command", "gateway-rs/src/demo_seed.rs::tests::seeded_generators_are_reproducible", - "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults" + "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults", + "gateway-rs/tests/platform_native.rs::demo_seed_uses_the_configurable_seeder_with_admin_check_and_python_defaults" ], "source": { "kind": "function", "line": 344, "path": "backend-services/utils/demo_seed_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/demo_seed_util.py::function:seed_logs", - "notes": "Rust now implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, metrics, deterministic seeds, and collection-count results, in addition to the admin-only memory-mode demo endpoint. The seeded Rust RNG is reproducible but does not reproduce CPython's Mersenne Twister byte-for-byte, and the compact native analytics aggregator records generated metrics in the current minute rather than reconstructing 400 historical Python MinuteBucket timestamps.", + "notes": "Rust implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, and deterministic seeds, wired to the admin-only HTTP demo-seed endpoint with Python's exact query-parameter defaults. Generated metrics are now backfilled across the requested historical window (record_request_at) rather than dumped into the current minute alone.", + "rationale": "The seeded RNG is reproducible run-to-run but does not reproduce CPython's Mersenne Twister byte-for-byte; demo data is synthetic and randomized in both implementations, so exact cross-language byte-identical output was never a functional requirement for this endpoint.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::demo_seed", "gateway-rs/src/demo_seed.rs::run_seed", - "gateway-rs/src/demo_seed.rs::SeedOptions" + "gateway-rs/src/demo_seed.rs::SeedOptions", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request_at" ], "rust_tests": [ "gateway-rs/tests/roles_groups_parity.rs", "gateway-rs/src/demo_seed.rs::tests::defaults_match_the_python_seed_command", "gateway-rs/src/demo_seed.rs::tests::seeded_generators_are_reproducible", - "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults" + "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults", + "gateway-rs/tests/platform_native.rs::demo_seed_uses_the_configurable_seeder_with_admin_check_and_python_defaults" ], "source": { "kind": "function", "line": 359, "path": "backend-services/utils/demo_seed_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/demo_seed_util.py::function:seed_protos", - "notes": "Rust now implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, metrics, deterministic seeds, and collection-count results, in addition to the admin-only memory-mode demo endpoint. The seeded Rust RNG is reproducible but does not reproduce CPython's Mersenne Twister byte-for-byte, and the compact native analytics aggregator records generated metrics in the current minute rather than reconstructing 400 historical Python MinuteBucket timestamps.", + "notes": "Rust implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, and deterministic seeds, wired to the admin-only HTTP demo-seed endpoint with Python's exact query-parameter defaults. Generated metrics are now backfilled across the requested historical window (record_request_at) rather than dumped into the current minute alone.", + "rationale": "The seeded RNG is reproducible run-to-run but does not reproduce CPython's Mersenne Twister byte-for-byte; demo data is synthetic and randomized in both implementations, so exact cross-language byte-identical output was never a functional requirement for this endpoint.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::demo_seed", "gateway-rs/src/demo_seed.rs::run_seed", - "gateway-rs/src/demo_seed.rs::SeedOptions" + "gateway-rs/src/demo_seed.rs::SeedOptions", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request_at" ], "rust_tests": [ "gateway-rs/tests/roles_groups_parity.rs", "gateway-rs/src/demo_seed.rs::tests::defaults_match_the_python_seed_command", "gateway-rs/src/demo_seed.rs::tests::seeded_generators_are_reproducible", - "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults" + "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults", + "gateway-rs/tests/platform_native.rs::demo_seed_uses_the_configurable_seeder_with_admin_check_and_python_defaults" ], "source": { "kind": "function", "line": 383, "path": "backend-services/utils/demo_seed_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/demo_seed_util.py::function:seed_metrics", - "notes": "Rust now implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, metrics, deterministic seeds, and collection-count results, in addition to the admin-only memory-mode demo endpoint. The seeded Rust RNG is reproducible but does not reproduce CPython's Mersenne Twister byte-for-byte, and the compact native analytics aggregator records generated metrics in the current minute rather than reconstructing 400 historical Python MinuteBucket timestamps.", + "notes": "Rust implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, and deterministic seeds, wired to the admin-only HTTP demo-seed endpoint with Python's exact query-parameter defaults. Generated metrics are now backfilled across the requested historical window (record_request_at) rather than dumped into the current minute alone.", + "rationale": "The seeded RNG is reproducible run-to-run but does not reproduce CPython's Mersenne Twister byte-for-byte; demo data is synthetic and randomized in both implementations, so exact cross-language byte-identical output was never a functional requirement for this endpoint.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::demo_seed", "gateway-rs/src/demo_seed.rs::run_seed", - "gateway-rs/src/demo_seed.rs::SeedOptions" + "gateway-rs/src/demo_seed.rs::SeedOptions", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request_at" ], "rust_tests": [ "gateway-rs/tests/roles_groups_parity.rs", "gateway-rs/src/demo_seed.rs::tests::defaults_match_the_python_seed_command", "gateway-rs/src/demo_seed.rs::tests::seeded_generators_are_reproducible", - "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults" + "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults", + "gateway-rs/tests/platform_native.rs::demo_seed_uses_the_configurable_seeder_with_admin_check_and_python_defaults" ], "source": { "kind": "function", "line": 416, "path": "backend-services/utils/demo_seed_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/demo_seed_util.py::function:run_seed", - "notes": "Rust now implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, metrics, deterministic seeds, and collection-count results, in addition to the admin-only memory-mode demo endpoint. The seeded Rust RNG is reproducible but does not reproduce CPython's Mersenne Twister byte-for-byte, and the compact native analytics aggregator records generated metrics in the current minute rather than reconstructing 400 historical Python MinuteBucket timestamps.", + "notes": "Rust implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, and deterministic seeds, wired to the admin-only HTTP demo-seed endpoint with Python's exact query-parameter defaults. Generated metrics are now backfilled across the requested historical window (record_request_at) rather than dumped into the current minute alone.", + "rationale": "The seeded RNG is reproducible run-to-run but does not reproduce CPython's Mersenne Twister byte-for-byte; demo data is synthetic and randomized in both implementations, so exact cross-language byte-identical output was never a functional requirement for this endpoint.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::demo_seed", "gateway-rs/src/demo_seed.rs::run_seed", - "gateway-rs/src/demo_seed.rs::SeedOptions" + "gateway-rs/src/demo_seed.rs::SeedOptions", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request_at" ], "rust_tests": [ "gateway-rs/tests/roles_groups_parity.rs", "gateway-rs/src/demo_seed.rs::tests::defaults_match_the_python_seed_command", "gateway-rs/src/demo_seed.rs::tests::seeded_generators_are_reproducible", - "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults" + "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults", + "gateway-rs/tests/platform_native.rs::demo_seed_uses_the_configurable_seeder_with_admin_check_and_python_defaults" ], "source": { "kind": "function", "line": 437, "path": "backend-services/utils/demo_seed_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], @@ -36186,7 +38450,8 @@ "decorators": [], "domain": "utils", "id": "backend-services/utils/doorman_cache_util.py::module:doorman_cache_util", - "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state.", + "rationale": "Native caches are typed SharedStorage operations invalidated on every successful mutation rather than a generic process-global LRU keyed by arbitrary cache namespace, so Rust's cache does not accumulate unbounded distinct keys the way Python's CACHE_MAX_SIZE-bounded MemoryCache can; there is no equivalent eviction-under-scale scenario to reproduce, and no pinned route exposes cache-info statistics for this module. Async Redis writes are awaited directly rather than returned as executor futures, a language-runtime difference with no observable behavior change.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::CacheName", "gateway-rs/src/storage/memory.rs::MemoryStorage", @@ -36204,13 +38469,14 @@ "line": 1, "path": "backend-services/utils/doorman_cache_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/doorman_cache_util.py::class:MemoryCache", - "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state.", + "rationale": "Native caches are typed SharedStorage operations invalidated on every successful mutation rather than a generic process-global LRU keyed by arbitrary cache namespace, so Rust's cache does not accumulate unbounded distinct keys the way Python's CACHE_MAX_SIZE-bounded MemoryCache can; there is no equivalent eviction-under-scale scenario to reproduce, and no pinned route exposes cache-info statistics for this module. Async Redis writes are awaited directly rather than returned as executor futures, a language-runtime difference with no observable behavior change.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::CacheName", "gateway-rs/src/storage/memory.rs::MemoryStorage", @@ -36228,13 +38494,14 @@ "line": 19, "path": "backend-services/utils/doorman_cache_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/doorman_cache_util.py::method:MemoryCache.__init__", - "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state.", + "rationale": "Native caches are typed SharedStorage operations invalidated on every successful mutation rather than a generic process-global LRU keyed by arbitrary cache namespace, so Rust's cache does not accumulate unbounded distinct keys the way Python's CACHE_MAX_SIZE-bounded MemoryCache can; there is no equivalent eviction-under-scale scenario to reproduce, and no pinned route exposes cache-info statistics for this module. Async Redis writes are awaited directly rather than returned as executor futures, a language-runtime difference with no observable behavior change.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::CacheName", "gateway-rs/src/storage/memory.rs::MemoryStorage", @@ -36252,13 +38519,14 @@ "line": 20, "path": "backend-services/utils/doorman_cache_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/doorman_cache_util.py::method:MemoryCache.setex", - "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state.", + "rationale": "Native caches are typed SharedStorage operations invalidated on every successful mutation rather than a generic process-global LRU keyed by arbitrary cache namespace, so Rust's cache does not accumulate unbounded distinct keys the way Python's CACHE_MAX_SIZE-bounded MemoryCache can; there is no equivalent eviction-under-scale scenario to reproduce, and no pinned route exposes cache-info statistics for this module. Async Redis writes are awaited directly rather than returned as executor futures, a language-runtime difference with no observable behavior change.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::CacheName", "gateway-rs/src/storage/memory.rs::MemoryStorage", @@ -36276,13 +38544,14 @@ "line": 26, "path": "backend-services/utils/doorman_cache_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/doorman_cache_util.py::method:MemoryCache.get", - "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state.", + "rationale": "Native caches are typed SharedStorage operations invalidated on every successful mutation rather than a generic process-global LRU keyed by arbitrary cache namespace, so Rust's cache does not accumulate unbounded distinct keys the way Python's CACHE_MAX_SIZE-bounded MemoryCache can; there is no equivalent eviction-under-scale scenario to reproduce, and no pinned route exposes cache-info statistics for this module. Async Redis writes are awaited directly rather than returned as executor futures, a language-runtime difference with no observable behavior change.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::CacheName", "gateway-rs/src/storage/memory.rs::MemoryStorage", @@ -36300,13 +38569,14 @@ "line": 41, "path": "backend-services/utils/doorman_cache_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/doorman_cache_util.py::method:MemoryCache.delete", - "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state.", + "rationale": "Native caches are typed SharedStorage operations invalidated on every successful mutation rather than a generic process-global LRU keyed by arbitrary cache namespace, so Rust's cache does not accumulate unbounded distinct keys the way Python's CACHE_MAX_SIZE-bounded MemoryCache can; there is no equivalent eviction-under-scale scenario to reproduce, and no pinned route exposes cache-info statistics for this module. Async Redis writes are awaited directly rather than returned as executor futures, a language-runtime difference with no observable behavior change.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::CacheName", "gateway-rs/src/storage/memory.rs::MemoryStorage", @@ -36324,13 +38594,14 @@ "line": 56, "path": "backend-services/utils/doorman_cache_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/doorman_cache_util.py::method:MemoryCache.keys", - "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state.", + "rationale": "Native caches are typed SharedStorage operations invalidated on every successful mutation rather than a generic process-global LRU keyed by arbitrary cache namespace, so Rust's cache does not accumulate unbounded distinct keys the way Python's CACHE_MAX_SIZE-bounded MemoryCache can; there is no equivalent eviction-under-scale scenario to reproduce, and no pinned route exposes cache-info statistics for this module. Async Redis writes are awaited directly rather than returned as executor futures, a language-runtime difference with no observable behavior change.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::CacheName", "gateway-rs/src/storage/memory.rs::MemoryStorage", @@ -36348,13 +38619,14 @@ "line": 64, "path": "backend-services/utils/doorman_cache_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/doorman_cache_util.py::method:MemoryCache._get_current_time", - "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state.", + "rationale": "Native caches are typed SharedStorage operations invalidated on every successful mutation rather than a generic process-global LRU keyed by arbitrary cache namespace, so Rust's cache does not accumulate unbounded distinct keys the way Python's CACHE_MAX_SIZE-bounded MemoryCache can; there is no equivalent eviction-under-scale scenario to reproduce, and no pinned route exposes cache-info statistics for this module. Async Redis writes are awaited directly rather than returned as executor futures, a language-runtime difference with no observable behavior change.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::CacheName", "gateway-rs/src/storage/memory.rs::MemoryStorage", @@ -36372,13 +38644,14 @@ "line": 71, "path": "backend-services/utils/doorman_cache_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/doorman_cache_util.py::method:MemoryCache.get_cache_stats", - "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state.", + "rationale": "Native caches are typed SharedStorage operations invalidated on every successful mutation rather than a generic process-global LRU keyed by arbitrary cache namespace, so Rust's cache does not accumulate unbounded distinct keys the way Python's CACHE_MAX_SIZE-bounded MemoryCache can; there is no equivalent eviction-under-scale scenario to reproduce, and no pinned route exposes cache-info statistics for this module. Async Redis writes are awaited directly rather than returned as executor futures, a language-runtime difference with no observable behavior change.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::CacheName", "gateway-rs/src/storage/memory.rs::MemoryStorage", @@ -36396,13 +38669,14 @@ "line": 76, "path": "backend-services/utils/doorman_cache_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/doorman_cache_util.py::method:MemoryCache._cleanup_expired", - "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state.", + "rationale": "Native caches are typed SharedStorage operations invalidated on every successful mutation rather than a generic process-global LRU keyed by arbitrary cache namespace, so Rust's cache does not accumulate unbounded distinct keys the way Python's CACHE_MAX_SIZE-bounded MemoryCache can; there is no equivalent eviction-under-scale scenario to reproduce, and no pinned route exposes cache-info statistics for this module. Async Redis writes are awaited directly rather than returned as executor futures, a language-runtime difference with no observable behavior change.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::CacheName", "gateway-rs/src/storage/memory.rs::MemoryStorage", @@ -36420,13 +38694,14 @@ "line": 92, "path": "backend-services/utils/doorman_cache_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/doorman_cache_util.py::method:MemoryCache.stop_auto_save", - "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state.", + "rationale": "Native caches are typed SharedStorage operations invalidated on every successful mutation rather than a generic process-global LRU keyed by arbitrary cache namespace, so Rust's cache does not accumulate unbounded distinct keys the way Python's CACHE_MAX_SIZE-bounded MemoryCache can; there is no equivalent eviction-under-scale scenario to reproduce, and no pinned route exposes cache-info statistics for this module. Async Redis writes are awaited directly rather than returned as executor futures, a language-runtime difference with no observable behavior change.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::CacheName", "gateway-rs/src/storage/memory.rs::MemoryStorage", @@ -36444,13 +38719,14 @@ "line": 106, "path": "backend-services/utils/doorman_cache_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/doorman_cache_util.py::class:DoormanCacheManager", - "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state.", + "rationale": "Native caches are typed SharedStorage operations invalidated on every successful mutation rather than a generic process-global LRU keyed by arbitrary cache namespace, so Rust's cache does not accumulate unbounded distinct keys the way Python's CACHE_MAX_SIZE-bounded MemoryCache can; there is no equivalent eviction-under-scale scenario to reproduce, and no pinned route exposes cache-info statistics for this module. Async Redis writes are awaited directly rather than returned as executor futures, a language-runtime difference with no observable behavior change.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::CacheName", "gateway-rs/src/storage/memory.rs::MemoryStorage", @@ -36468,13 +38744,14 @@ "line": 110, "path": "backend-services/utils/doorman_cache_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/doorman_cache_util.py::method:DoormanCacheManager.__init__", - "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state.", + "rationale": "Native caches are typed SharedStorage operations invalidated on every successful mutation rather than a generic process-global LRU keyed by arbitrary cache namespace, so Rust's cache does not accumulate unbounded distinct keys the way Python's CACHE_MAX_SIZE-bounded MemoryCache can; there is no equivalent eviction-under-scale scenario to reproduce, and no pinned route exposes cache-info statistics for this module. Async Redis writes are awaited directly rather than returned as executor futures, a language-runtime difference with no observable behavior change.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::CacheName", "gateway-rs/src/storage/memory.rs::MemoryStorage", @@ -36492,13 +38769,14 @@ "line": 111, "path": "backend-services/utils/doorman_cache_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/doorman_cache_util.py::method:DoormanCacheManager._get_key", - "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state.", + "rationale": "Native caches are typed SharedStorage operations invalidated on every successful mutation rather than a generic process-global LRU keyed by arbitrary cache namespace, so Rust's cache does not accumulate unbounded distinct keys the way Python's CACHE_MAX_SIZE-bounded MemoryCache can; there is no equivalent eviction-under-scale scenario to reproduce, and no pinned route exposes cache-info statistics for this module. Async Redis writes are awaited directly rather than returned as executor futures, a language-runtime difference with no observable behavior change.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::CacheName", "gateway-rs/src/storage/memory.rs::MemoryStorage", @@ -36516,13 +38794,14 @@ "line": 186, "path": "backend-services/utils/doorman_cache_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/doorman_cache_util.py::method:DoormanCacheManager._to_json_serializable", - "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state.", + "rationale": "Native caches are typed SharedStorage operations invalidated on every successful mutation rather than a generic process-global LRU keyed by arbitrary cache namespace, so Rust's cache does not accumulate unbounded distinct keys the way Python's CACHE_MAX_SIZE-bounded MemoryCache can; there is no equivalent eviction-under-scale scenario to reproduce, and no pinned route exposes cache-info statistics for this module. Async Redis writes are awaited directly rather than returned as executor futures, a language-runtime difference with no observable behavior change.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::CacheName", "gateway-rs/src/storage/memory.rs::MemoryStorage", @@ -36540,13 +38819,14 @@ "line": 189, "path": "backend-services/utils/doorman_cache_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/doorman_cache_util.py::method:DoormanCacheManager.set_cache", - "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state.", + "rationale": "Native caches are typed SharedStorage operations invalidated on every successful mutation rather than a generic process-global LRU keyed by arbitrary cache namespace, so Rust's cache does not accumulate unbounded distinct keys the way Python's CACHE_MAX_SIZE-bounded MemoryCache can; there is no equivalent eviction-under-scale scenario to reproduce, and no pinned route exposes cache-info statistics for this module. Async Redis writes are awaited directly rather than returned as executor futures, a language-runtime difference with no observable behavior change.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::CacheName", "gateway-rs/src/storage/memory.rs::MemoryStorage", @@ -36564,13 +38844,14 @@ "line": 211, "path": "backend-services/utils/doorman_cache_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/doorman_cache_util.py::method:DoormanCacheManager.get_cache", - "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state.", + "rationale": "Native caches are typed SharedStorage operations invalidated on every successful mutation rather than a generic process-global LRU keyed by arbitrary cache namespace, so Rust's cache does not accumulate unbounded distinct keys the way Python's CACHE_MAX_SIZE-bounded MemoryCache can; there is no equivalent eviction-under-scale scenario to reproduce, and no pinned route exposes cache-info statistics for this module. Async Redis writes are awaited directly rather than returned as executor futures, a language-runtime difference with no observable behavior change.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::CacheName", "gateway-rs/src/storage/memory.rs::MemoryStorage", @@ -36588,13 +38869,14 @@ "line": 228, "path": "backend-services/utils/doorman_cache_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/doorman_cache_util.py::method:DoormanCacheManager.delete_cache", - "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state.", + "rationale": "Native caches are typed SharedStorage operations invalidated on every successful mutation rather than a generic process-global LRU keyed by arbitrary cache namespace, so Rust's cache does not accumulate unbounded distinct keys the way Python's CACHE_MAX_SIZE-bounded MemoryCache can; there is no equivalent eviction-under-scale scenario to reproduce, and no pinned route exposes cache-info statistics for this module. Async Redis writes are awaited directly rather than returned as executor futures, a language-runtime difference with no observable behavior change.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::CacheName", "gateway-rs/src/storage/memory.rs::MemoryStorage", @@ -36612,13 +38894,14 @@ "line": 241, "path": "backend-services/utils/doorman_cache_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/doorman_cache_util.py::method:DoormanCacheManager.clear_cache", - "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state.", + "rationale": "Native caches are typed SharedStorage operations invalidated on every successful mutation rather than a generic process-global LRU keyed by arbitrary cache namespace, so Rust's cache does not accumulate unbounded distinct keys the way Python's CACHE_MAX_SIZE-bounded MemoryCache can; there is no equivalent eviction-under-scale scenario to reproduce, and no pinned route exposes cache-info statistics for this module. Async Redis writes are awaited directly rather than returned as executor futures, a language-runtime difference with no observable behavior change.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::CacheName", "gateway-rs/src/storage/memory.rs::MemoryStorage", @@ -36636,13 +38919,14 @@ "line": 248, "path": "backend-services/utils/doorman_cache_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/doorman_cache_util.py::method:DoormanCacheManager.clear_all_caches", - "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state.", + "rationale": "Native caches are typed SharedStorage operations invalidated on every successful mutation rather than a generic process-global LRU keyed by arbitrary cache namespace, so Rust's cache does not accumulate unbounded distinct keys the way Python's CACHE_MAX_SIZE-bounded MemoryCache can; there is no equivalent eviction-under-scale scenario to reproduce, and no pinned route exposes cache-info statistics for this module. Async Redis writes are awaited directly rather than returned as executor futures, a language-runtime difference with no observable behavior change.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::CacheName", "gateway-rs/src/storage/memory.rs::MemoryStorage", @@ -36660,13 +38944,14 @@ "line": 262, "path": "backend-services/utils/doorman_cache_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/doorman_cache_util.py::method:DoormanCacheManager.get_cache_info", - "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state.", + "rationale": "Native caches are typed SharedStorage operations invalidated on every successful mutation rather than a generic process-global LRU keyed by arbitrary cache namespace, so Rust's cache does not accumulate unbounded distinct keys the way Python's CACHE_MAX_SIZE-bounded MemoryCache can; there is no equivalent eviction-under-scale scenario to reproduce, and no pinned route exposes cache-info statistics for this module. Async Redis writes are awaited directly rather than returned as executor futures, a language-runtime difference with no observable behavior change.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::CacheName", "gateway-rs/src/storage/memory.rs::MemoryStorage", @@ -36684,13 +38969,14 @@ "line": 266, "path": "backend-services/utils/doorman_cache_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/doorman_cache_util.py::method:DoormanCacheManager.cleanup_expired_entries", - "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state.", + "rationale": "Native caches are typed SharedStorage operations invalidated on every successful mutation rather than a generic process-global LRU keyed by arbitrary cache namespace, so Rust's cache does not accumulate unbounded distinct keys the way Python's CACHE_MAX_SIZE-bounded MemoryCache can; there is no equivalent eviction-under-scale scenario to reproduce, and no pinned route exposes cache-info statistics for this module. Async Redis writes are awaited directly rather than returned as executor futures, a language-runtime difference with no observable behavior change.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::CacheName", "gateway-rs/src/storage/memory.rs::MemoryStorage", @@ -36708,13 +38994,14 @@ "line": 278, "path": "backend-services/utils/doorman_cache_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/doorman_cache_util.py::method:DoormanCacheManager.force_save_cache", - "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state.", + "rationale": "Native caches are typed SharedStorage operations invalidated on every successful mutation rather than a generic process-global LRU keyed by arbitrary cache namespace, so Rust's cache does not accumulate unbounded distinct keys the way Python's CACHE_MAX_SIZE-bounded MemoryCache can; there is no equivalent eviction-under-scale scenario to reproduce, and no pinned route exposes cache-info statistics for this module. Async Redis writes are awaited directly rather than returned as executor futures, a language-runtime difference with no observable behavior change.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::CacheName", "gateway-rs/src/storage/memory.rs::MemoryStorage", @@ -36732,13 +39019,14 @@ "line": 282, "path": "backend-services/utils/doorman_cache_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/doorman_cache_util.py::method:DoormanCacheManager.stop_cache_persistence", - "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state.", + "rationale": "Native caches are typed SharedStorage operations invalidated on every successful mutation rather than a generic process-global LRU keyed by arbitrary cache namespace, so Rust's cache does not accumulate unbounded distinct keys the way Python's CACHE_MAX_SIZE-bounded MemoryCache can; there is no equivalent eviction-under-scale scenario to reproduce, and no pinned route exposes cache-info statistics for this module. Async Redis writes are awaited directly rather than returned as executor futures, a language-runtime difference with no observable behavior change.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::CacheName", "gateway-rs/src/storage/memory.rs::MemoryStorage", @@ -36756,7 +39044,7 @@ "line": 285, "path": "backend-services/utils/doorman_cache_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -36764,7 +39052,8 @@ ], "domain": "utils", "id": "backend-services/utils/doorman_cache_util.py::method:DoormanCacheManager.is_operational", - "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state.", + "rationale": "Native caches are typed SharedStorage operations invalidated on every successful mutation rather than a generic process-global LRU keyed by arbitrary cache namespace, so Rust's cache does not accumulate unbounded distinct keys the way Python's CACHE_MAX_SIZE-bounded MemoryCache can; there is no equivalent eviction-under-scale scenario to reproduce, and no pinned route exposes cache-info statistics for this module. Async Redis writes are awaited directly rather than returned as executor futures, a language-runtime difference with no observable behavior change.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::CacheName", "gateway-rs/src/storage/memory.rs::MemoryStorage", @@ -36782,13 +39071,14 @@ "line": 290, "path": "backend-services/utils/doorman_cache_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/doorman_cache_util.py::method:DoormanCacheManager.invalidate_on_db_failure", - "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state.", + "rationale": "Native caches are typed SharedStorage operations invalidated on every successful mutation rather than a generic process-global LRU keyed by arbitrary cache namespace, so Rust's cache does not accumulate unbounded distinct keys the way Python's CACHE_MAX_SIZE-bounded MemoryCache can; there is no equivalent eviction-under-scale scenario to reproduce, and no pinned route exposes cache-info statistics for this module. Async Redis writes are awaited directly rather than returned as executor futures, a language-runtime difference with no observable behavior change.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::CacheName", "gateway-rs/src/storage/memory.rs::MemoryStorage", @@ -36806,7 +39096,7 @@ "line": 301, "path": "backend-services/utils/doorman_cache_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], @@ -36853,9 +39143,12 @@ "domain": "utils", "id": "backend-services/utils/encryption_util.py::module:encryption_util", "notes": "Rust implements TOKEN_ENCRYPTION_KEY/MEM_ENCRYPTION_KEY precedence, Fernet-key validation with SHA-256 URL-safe derivation fallback, plaintext compatibility, enc: marking, and fail-closed decryption. Credit write paths are not all wired to encryption yet, and the Python non-string passthrough is outside the typed Rust string API.", + "rationale": "Re-verified against current code: credit_routes in platform.rs now calls encrypt_credit_definition on credit-definition create/update, encrypt_value on rotate-key generation, and transform_user_credit_keys(encrypt: true) on user credit key writes -- every credit write path is wired to encryption; this note is stale from before that work landed. The non-string passthrough is unreachable through the API surface for the same reason documented on credit_util.py: credit_model.py's Pydantic schema enforces `api_key: str` on every write.", "rust_symbols": [ "gateway-rs/src/storage/field_encryption.rs::encrypt_value", - "gateway-rs/src/storage/field_encryption.rs::decrypt_value" + "gateway-rs/src/storage/field_encryption.rs::decrypt_value", + "gateway-rs/src/routes/platform.rs::encrypt_credit_definition", + "gateway-rs/src/routes/platform.rs::transform_user_credit_keys" ], "rust_tests": [ "gateway-rs/src/storage/field_encryption.rs::tests::plaintext_values_pass_through_without_an_encryption_marker" @@ -36865,16 +39158,19 @@ "line": 1, "path": "backend-services/utils/encryption_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/encryption_util.py::function:_get_cipher", "notes": "Rust implements TOKEN_ENCRYPTION_KEY/MEM_ENCRYPTION_KEY precedence, Fernet-key validation with SHA-256 URL-safe derivation fallback, plaintext compatibility, enc: marking, and fail-closed decryption. Credit write paths are not all wired to encryption yet, and the Python non-string passthrough is outside the typed Rust string API.", + "rationale": "Re-verified against current code: credit_routes in platform.rs now calls encrypt_credit_definition on credit-definition create/update, encrypt_value on rotate-key generation, and transform_user_credit_keys(encrypt: true) on user credit key writes -- every credit write path is wired to encryption; this note is stale from before that work landed. The non-string passthrough is unreachable through the API surface for the same reason documented on credit_util.py: credit_model.py's Pydantic schema enforces `api_key: str` on every write.", "rust_symbols": [ "gateway-rs/src/storage/field_encryption.rs::encrypt_value", - "gateway-rs/src/storage/field_encryption.rs::decrypt_value" + "gateway-rs/src/storage/field_encryption.rs::decrypt_value", + "gateway-rs/src/routes/platform.rs::encrypt_credit_definition", + "gateway-rs/src/routes/platform.rs::transform_user_credit_keys" ], "rust_tests": [ "gateway-rs/src/storage/field_encryption.rs::tests::plaintext_values_pass_through_without_an_encryption_marker" @@ -36884,16 +39180,19 @@ "line": 8, "path": "backend-services/utils/encryption_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/encryption_util.py::function:encrypt_value", "notes": "Rust implements TOKEN_ENCRYPTION_KEY/MEM_ENCRYPTION_KEY precedence, Fernet-key validation with SHA-256 URL-safe derivation fallback, plaintext compatibility, enc: marking, and fail-closed decryption. Credit write paths are not all wired to encryption yet, and the Python non-string passthrough is outside the typed Rust string API.", + "rationale": "Re-verified against current code: credit_routes in platform.rs now calls encrypt_credit_definition on credit-definition create/update, encrypt_value on rotate-key generation, and transform_user_credit_keys(encrypt: true) on user credit key writes -- every credit write path is wired to encryption; this note is stale from before that work landed. The non-string passthrough is unreachable through the API surface for the same reason documented on credit_util.py: credit_model.py's Pydantic schema enforces `api_key: str` on every write.", "rust_symbols": [ "gateway-rs/src/storage/field_encryption.rs::encrypt_value", - "gateway-rs/src/storage/field_encryption.rs::decrypt_value" + "gateway-rs/src/storage/field_encryption.rs::decrypt_value", + "gateway-rs/src/routes/platform.rs::encrypt_credit_definition", + "gateway-rs/src/routes/platform.rs::transform_user_credit_keys" ], "rust_tests": [ "gateway-rs/src/storage/field_encryption.rs::tests::plaintext_values_pass_through_without_an_encryption_marker" @@ -36903,16 +39202,19 @@ "line": 24, "path": "backend-services/utils/encryption_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/encryption_util.py::function:decrypt_value", "notes": "Rust implements TOKEN_ENCRYPTION_KEY/MEM_ENCRYPTION_KEY precedence, Fernet-key validation with SHA-256 URL-safe derivation fallback, plaintext compatibility, enc: marking, and fail-closed decryption. Credit write paths are not all wired to encryption yet, and the Python non-string passthrough is outside the typed Rust string API.", + "rationale": "Re-verified against current code: credit_routes in platform.rs now calls encrypt_credit_definition on credit-definition create/update, encrypt_value on rotate-key generation, and transform_user_credit_keys(encrypt: true) on user credit key writes -- every credit write path is wired to encryption; this note is stale from before that work landed. The non-string passthrough is unreachable through the API surface for the same reason documented on credit_util.py: credit_model.py's Pydantic schema enforces `api_key: str` on every write.", "rust_symbols": [ "gateway-rs/src/storage/field_encryption.rs::encrypt_value", - "gateway-rs/src/storage/field_encryption.rs::decrypt_value" + "gateway-rs/src/storage/field_encryption.rs::decrypt_value", + "gateway-rs/src/routes/platform.rs::encrypt_credit_definition", + "gateway-rs/src/routes/platform.rs::transform_user_credit_keys" ], "rust_tests": [ "gateway-rs/src/storage/field_encryption.rs::tests::plaintext_values_pass_through_without_an_encryption_marker" @@ -36922,22 +39224,28 @@ "line": 34, "path": "backend-services/utils/encryption_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/enhanced_metrics_util.py::module:enhanced_metrics_util", - "notes": "Rust records minute-bucket request/error/latency/byte totals, global status/API/user/endpoint counters, retry and timeout runtime counters, bounded retention, persistence/restore, range summaries, top entities, status distributions, and multi-level range output. Native buckets currently retain weighted latency averages rather than every raw latency sample, so percentile and per-endpoint latency output is approximate; top/status entity counters are process-global rather than reconstructed per requested range.", + "notes": "Rust records minute-bucket request/error/latency/byte totals, global status/API/user/endpoint counters, retry and timeout runtime counters, bounded retention, persistence/restore, range summaries, top entities, status distributions, and multi-level range output. Native buckets track capped raw per-request latency samples (matching METRICS_PCT_SAMPLES), so p95 and per-endpoint latency/percentiles are real range-scoped reconstructions rather than weighted averages; top-API/top-user/unique-user counters are also reconstructed per requested range (with the same global-fallback Python uses when a range attributes no traffic) rather than process-global.", + "rationale": "Per-bucket status distribution and per-bucket retry/timeout counts remain process-global sums rather than range-scoped: reconstructing them per-range would need per-minute status/retry/timeout maps analogous to the per-minute entity maps already added for api/user/endpoint, which is a bounded but separate follow-up not yet implemented.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_apis_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_endpoints_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::pooled_percentiles", "gateway-rs/src/routes/platform.rs::analytics_overview", "gateway-rs/src/routes/platform.rs::analytics_timeseries" ], "rust_tests": [ "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::top_entities_in_range_reconstructs_from_only_the_selected_minutes", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::get_top_endpoints_in_range_computes_real_percentiles_like_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts" ], "source": { @@ -36945,22 +39253,28 @@ "line": 1, "path": "backend-services/utils/enhanced_metrics_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/enhanced_metrics_util.py::class:EnhancedMetricsStore", - "notes": "Rust records minute-bucket request/error/latency/byte totals, global status/API/user/endpoint counters, retry and timeout runtime counters, bounded retention, persistence/restore, range summaries, top entities, status distributions, and multi-level range output. Native buckets currently retain weighted latency averages rather than every raw latency sample, so percentile and per-endpoint latency output is approximate; top/status entity counters are process-global rather than reconstructed per requested range.", + "notes": "Rust records minute-bucket request/error/latency/byte totals, global status/API/user/endpoint counters, retry and timeout runtime counters, bounded retention, persistence/restore, range summaries, top entities, status distributions, and multi-level range output. Native buckets track capped raw per-request latency samples (matching METRICS_PCT_SAMPLES), so p95 and per-endpoint latency/percentiles are real range-scoped reconstructions rather than weighted averages; top-API/top-user/unique-user counters are also reconstructed per requested range (with the same global-fallback Python uses when a range attributes no traffic) rather than process-global.", + "rationale": "Per-bucket status distribution and per-bucket retry/timeout counts remain process-global sums rather than range-scoped: reconstructing them per-range would need per-minute status/retry/timeout maps analogous to the per-minute entity maps already added for api/user/endpoint, which is a bounded but separate follow-up not yet implemented.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_apis_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_endpoints_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::pooled_percentiles", "gateway-rs/src/routes/platform.rs::analytics_overview", "gateway-rs/src/routes/platform.rs::analytics_timeseries" ], "rust_tests": [ "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::top_entities_in_range_reconstructs_from_only_the_selected_minutes", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::get_top_endpoints_in_range_computes_real_percentiles_like_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts" ], "source": { @@ -36968,22 +39282,28 @@ "line": 22, "path": "backend-services/utils/enhanced_metrics_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/enhanced_metrics_util.py::method:EnhancedMetricsStore.__init__", - "notes": "Rust records minute-bucket request/error/latency/byte totals, global status/API/user/endpoint counters, retry and timeout runtime counters, bounded retention, persistence/restore, range summaries, top entities, status distributions, and multi-level range output. Native buckets currently retain weighted latency averages rather than every raw latency sample, so percentile and per-endpoint latency output is approximate; top/status entity counters are process-global rather than reconstructed per requested range.", + "notes": "Rust records minute-bucket request/error/latency/byte totals, global status/API/user/endpoint counters, retry and timeout runtime counters, bounded retention, persistence/restore, range summaries, top entities, status distributions, and multi-level range output. Native buckets track capped raw per-request latency samples (matching METRICS_PCT_SAMPLES), so p95 and per-endpoint latency/percentiles are real range-scoped reconstructions rather than weighted averages; top-API/top-user/unique-user counters are also reconstructed per requested range (with the same global-fallback Python uses when a range attributes no traffic) rather than process-global.", + "rationale": "Per-bucket status distribution and per-bucket retry/timeout counts remain process-global sums rather than range-scoped: reconstructing them per-range would need per-minute status/retry/timeout maps analogous to the per-minute entity maps already added for api/user/endpoint, which is a bounded but separate follow-up not yet implemented.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_apis_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_endpoints_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::pooled_percentiles", "gateway-rs/src/routes/platform.rs::analytics_overview", "gateway-rs/src/routes/platform.rs::analytics_timeseries" ], "rust_tests": [ "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::top_entities_in_range_reconstructs_from_only_the_selected_minutes", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::get_top_endpoints_in_range_computes_real_percentiles_like_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts" ], "source": { @@ -36991,7 +39311,7 @@ "line": 33, "path": "backend-services/utils/enhanced_metrics_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -36999,16 +39319,22 @@ ], "domain": "utils", "id": "backend-services/utils/enhanced_metrics_util.py::method:EnhancedMetricsStore._minute_floor", - "notes": "Rust records minute-bucket request/error/latency/byte totals, global status/API/user/endpoint counters, retry and timeout runtime counters, bounded retention, persistence/restore, range summaries, top entities, status distributions, and multi-level range output. Native buckets currently retain weighted latency averages rather than every raw latency sample, so percentile and per-endpoint latency output is approximate; top/status entity counters are process-global rather than reconstructed per requested range.", + "notes": "Rust records minute-bucket request/error/latency/byte totals, global status/API/user/endpoint counters, retry and timeout runtime counters, bounded retention, persistence/restore, range summaries, top entities, status distributions, and multi-level range output. Native buckets track capped raw per-request latency samples (matching METRICS_PCT_SAMPLES), so p95 and per-endpoint latency/percentiles are real range-scoped reconstructions rather than weighted averages; top-API/top-user/unique-user counters are also reconstructed per requested range (with the same global-fallback Python uses when a range attributes no traffic) rather than process-global.", + "rationale": "Per-bucket status distribution and per-bucket retry/timeout counts remain process-global sums rather than range-scoped: reconstructing them per-range would need per-minute status/retry/timeout maps analogous to the per-minute entity maps already added for api/user/endpoint, which is a bounded but separate follow-up not yet implemented.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_apis_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_endpoints_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::pooled_percentiles", "gateway-rs/src/routes/platform.rs::analytics_overview", "gateway-rs/src/routes/platform.rs::analytics_timeseries" ], "rust_tests": [ "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::top_entities_in_range_reconstructs_from_only_the_selected_minutes", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::get_top_endpoints_in_range_computes_real_percentiles_like_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts" ], "source": { @@ -37016,22 +39342,28 @@ "line": 53, "path": "backend-services/utils/enhanced_metrics_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/enhanced_metrics_util.py::method:EnhancedMetricsStore._ensure_bucket", - "notes": "Rust records minute-bucket request/error/latency/byte totals, global status/API/user/endpoint counters, retry and timeout runtime counters, bounded retention, persistence/restore, range summaries, top entities, status distributions, and multi-level range output. Native buckets currently retain weighted latency averages rather than every raw latency sample, so percentile and per-endpoint latency output is approximate; top/status entity counters are process-global rather than reconstructed per requested range.", + "notes": "Rust records minute-bucket request/error/latency/byte totals, global status/API/user/endpoint counters, retry and timeout runtime counters, bounded retention, persistence/restore, range summaries, top entities, status distributions, and multi-level range output. Native buckets track capped raw per-request latency samples (matching METRICS_PCT_SAMPLES), so p95 and per-endpoint latency/percentiles are real range-scoped reconstructions rather than weighted averages; top-API/top-user/unique-user counters are also reconstructed per requested range (with the same global-fallback Python uses when a range attributes no traffic) rather than process-global.", + "rationale": "Per-bucket status distribution and per-bucket retry/timeout counts remain process-global sums rather than range-scoped: reconstructing them per-range would need per-minute status/retry/timeout maps analogous to the per-minute entity maps already added for api/user/endpoint, which is a bounded but separate follow-up not yet implemented.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_apis_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_endpoints_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::pooled_percentiles", "gateway-rs/src/routes/platform.rs::analytics_overview", "gateway-rs/src/routes/platform.rs::analytics_timeseries" ], "rust_tests": [ "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::top_entities_in_range_reconstructs_from_only_the_selected_minutes", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::get_top_endpoints_in_range_computes_real_percentiles_like_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts" ], "source": { @@ -37039,22 +39371,28 @@ "line": 57, "path": "backend-services/utils/enhanced_metrics_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/enhanced_metrics_util.py::method:EnhancedMetricsStore.record", - "notes": "Rust records minute-bucket request/error/latency/byte totals, global status/API/user/endpoint counters, retry and timeout runtime counters, bounded retention, persistence/restore, range summaries, top entities, status distributions, and multi-level range output. Native buckets currently retain weighted latency averages rather than every raw latency sample, so percentile and per-endpoint latency output is approximate; top/status entity counters are process-global rather than reconstructed per requested range.", + "notes": "Rust records minute-bucket request/error/latency/byte totals, global status/API/user/endpoint counters, retry and timeout runtime counters, bounded retention, persistence/restore, range summaries, top entities, status distributions, and multi-level range output. Native buckets track capped raw per-request latency samples (matching METRICS_PCT_SAMPLES), so p95 and per-endpoint latency/percentiles are real range-scoped reconstructions rather than weighted averages; top-API/top-user/unique-user counters are also reconstructed per requested range (with the same global-fallback Python uses when a range attributes no traffic) rather than process-global.", + "rationale": "Per-bucket status distribution and per-bucket retry/timeout counts remain process-global sums rather than range-scoped: reconstructing them per-range would need per-minute status/retry/timeout maps analogous to the per-minute entity maps already added for api/user/endpoint, which is a bounded but separate follow-up not yet implemented.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_apis_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_endpoints_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::pooled_percentiles", "gateway-rs/src/routes/platform.rs::analytics_overview", "gateway-rs/src/routes/platform.rs::analytics_timeseries" ], "rust_tests": [ "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::top_entities_in_range_reconstructs_from_only_the_selected_minutes", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::get_top_endpoints_in_range_computes_real_percentiles_like_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts" ], "source": { @@ -37062,22 +39400,28 @@ "line": 74, "path": "backend-services/utils/enhanced_metrics_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/enhanced_metrics_util.py::method:EnhancedMetricsStore.record_retry", - "notes": "Rust records minute-bucket request/error/latency/byte totals, global status/API/user/endpoint counters, retry and timeout runtime counters, bounded retention, persistence/restore, range summaries, top entities, status distributions, and multi-level range output. Native buckets currently retain weighted latency averages rather than every raw latency sample, so percentile and per-endpoint latency output is approximate; top/status entity counters are process-global rather than reconstructed per requested range.", + "notes": "Rust records minute-bucket request/error/latency/byte totals, global status/API/user/endpoint counters, retry and timeout runtime counters, bounded retention, persistence/restore, range summaries, top entities, status distributions, and multi-level range output. Native buckets track capped raw per-request latency samples (matching METRICS_PCT_SAMPLES), so p95 and per-endpoint latency/percentiles are real range-scoped reconstructions rather than weighted averages; top-API/top-user/unique-user counters are also reconstructed per requested range (with the same global-fallback Python uses when a range attributes no traffic) rather than process-global.", + "rationale": "Per-bucket status distribution and per-bucket retry/timeout counts remain process-global sums rather than range-scoped: reconstructing them per-range would need per-minute status/retry/timeout maps analogous to the per-minute entity maps already added for api/user/endpoint, which is a bounded but separate follow-up not yet implemented.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_apis_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_endpoints_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::pooled_percentiles", "gateway-rs/src/routes/platform.rs::analytics_overview", "gateway-rs/src/routes/platform.rs::analytics_timeseries" ], "rust_tests": [ "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::top_entities_in_range_reconstructs_from_only_the_selected_minutes", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::get_top_endpoints_in_range_computes_real_percentiles_like_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts" ], "source": { @@ -37085,22 +39429,28 @@ "line": 125, "path": "backend-services/utils/enhanced_metrics_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/enhanced_metrics_util.py::method:EnhancedMetricsStore.record_upstream_timeout", - "notes": "Rust records minute-bucket request/error/latency/byte totals, global status/API/user/endpoint counters, retry and timeout runtime counters, bounded retention, persistence/restore, range summaries, top entities, status distributions, and multi-level range output. Native buckets currently retain weighted latency averages rather than every raw latency sample, so percentile and per-endpoint latency output is approximate; top/status entity counters are process-global rather than reconstructed per requested range.", + "notes": "Rust records minute-bucket request/error/latency/byte totals, global status/API/user/endpoint counters, retry and timeout runtime counters, bounded retention, persistence/restore, range summaries, top entities, status distributions, and multi-level range output. Native buckets track capped raw per-request latency samples (matching METRICS_PCT_SAMPLES), so p95 and per-endpoint latency/percentiles are real range-scoped reconstructions rather than weighted averages; top-API/top-user/unique-user counters are also reconstructed per requested range (with the same global-fallback Python uses when a range attributes no traffic) rather than process-global.", + "rationale": "Per-bucket status distribution and per-bucket retry/timeout counts remain process-global sums rather than range-scoped: reconstructing them per-range would need per-minute status/retry/timeout maps analogous to the per-minute entity maps already added for api/user/endpoint, which is a bounded but separate follow-up not yet implemented.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_apis_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_endpoints_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::pooled_percentiles", "gateway-rs/src/routes/platform.rs::analytics_overview", "gateway-rs/src/routes/platform.rs::analytics_timeseries" ], "rust_tests": [ "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::top_entities_in_range_reconstructs_from_only_the_selected_minutes", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::get_top_endpoints_in_range_computes_real_percentiles_like_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts" ], "source": { @@ -37108,22 +39458,28 @@ "line": 136, "path": "backend-services/utils/enhanced_metrics_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/enhanced_metrics_util.py::method:EnhancedMetricsStore._maybe_aggregate", - "notes": "Rust records minute-bucket request/error/latency/byte totals, global status/API/user/endpoint counters, retry and timeout runtime counters, bounded retention, persistence/restore, range summaries, top entities, status distributions, and multi-level range output. Native buckets currently retain weighted latency averages rather than every raw latency sample, so percentile and per-endpoint latency output is approximate; top/status entity counters are process-global rather than reconstructed per requested range.", + "notes": "Rust records minute-bucket request/error/latency/byte totals, global status/API/user/endpoint counters, retry and timeout runtime counters, bounded retention, persistence/restore, range summaries, top entities, status distributions, and multi-level range output. Native buckets track capped raw per-request latency samples (matching METRICS_PCT_SAMPLES), so p95 and per-endpoint latency/percentiles are real range-scoped reconstructions rather than weighted averages; top-API/top-user/unique-user counters are also reconstructed per requested range (with the same global-fallback Python uses when a range attributes no traffic) rather than process-global.", + "rationale": "Per-bucket status distribution and per-bucket retry/timeout counts remain process-global sums rather than range-scoped: reconstructing them per-range would need per-minute status/retry/timeout maps analogous to the per-minute entity maps already added for api/user/endpoint, which is a bounded but separate follow-up not yet implemented.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_apis_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_endpoints_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::pooled_percentiles", "gateway-rs/src/routes/platform.rs::analytics_overview", "gateway-rs/src/routes/platform.rs::analytics_timeseries" ], "rust_tests": [ "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::top_entities_in_range_reconstructs_from_only_the_selected_minutes", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::get_top_endpoints_in_range_computes_real_percentiles_like_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts" ], "source": { @@ -37131,22 +39487,28 @@ "line": 147, "path": "backend-services/utils/enhanced_metrics_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/enhanced_metrics_util.py::method:EnhancedMetricsStore.get_snapshot", - "notes": "Rust records minute-bucket request/error/latency/byte totals, global status/API/user/endpoint counters, retry and timeout runtime counters, bounded retention, persistence/restore, range summaries, top entities, status distributions, and multi-level range output. Native buckets currently retain weighted latency averages rather than every raw latency sample, so percentile and per-endpoint latency output is approximate; top/status entity counters are process-global rather than reconstructed per requested range.", + "notes": "Rust records minute-bucket request/error/latency/byte totals, global status/API/user/endpoint counters, retry and timeout runtime counters, bounded retention, persistence/restore, range summaries, top entities, status distributions, and multi-level range output. Native buckets track capped raw per-request latency samples (matching METRICS_PCT_SAMPLES), so p95 and per-endpoint latency/percentiles are real range-scoped reconstructions rather than weighted averages; top-API/top-user/unique-user counters are also reconstructed per requested range (with the same global-fallback Python uses when a range attributes no traffic) rather than process-global.", + "rationale": "Per-bucket status distribution and per-bucket retry/timeout counts remain process-global sums rather than range-scoped: reconstructing them per-range would need per-minute status/retry/timeout maps analogous to the per-minute entity maps already added for api/user/endpoint, which is a bounded but separate follow-up not yet implemented.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_apis_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_endpoints_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::pooled_percentiles", "gateway-rs/src/routes/platform.rs::analytics_overview", "gateway-rs/src/routes/platform.rs::analytics_timeseries" ], "rust_tests": [ "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::top_entities_in_range_reconstructs_from_only_the_selected_minutes", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::get_top_endpoints_in_range_computes_real_percentiles_like_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts" ], "source": { @@ -37154,22 +39516,28 @@ "line": 179, "path": "backend-services/utils/enhanced_metrics_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/enhanced_metrics_util.py::method:EnhancedMetricsStore.snapshot", - "notes": "Rust records minute-bucket request/error/latency/byte totals, global status/API/user/endpoint counters, retry and timeout runtime counters, bounded retention, persistence/restore, range summaries, top entities, status distributions, and multi-level range output. Native buckets currently retain weighted latency averages rather than every raw latency sample, so percentile and per-endpoint latency output is approximate; top/status entity counters are process-global rather than reconstructed per requested range.", + "notes": "Rust records minute-bucket request/error/latency/byte totals, global status/API/user/endpoint counters, retry and timeout runtime counters, bounded retention, persistence/restore, range summaries, top entities, status distributions, and multi-level range output. Native buckets track capped raw per-request latency samples (matching METRICS_PCT_SAMPLES), so p95 and per-endpoint latency/percentiles are real range-scoped reconstructions rather than weighted averages; top-API/top-user/unique-user counters are also reconstructed per requested range (with the same global-fallback Python uses when a range attributes no traffic) rather than process-global.", + "rationale": "Per-bucket status distribution and per-bucket retry/timeout counts remain process-global sums rather than range-scoped: reconstructing them per-range would need per-minute status/retry/timeout maps analogous to the per-minute entity maps already added for api/user/endpoint, which is a bounded but separate follow-up not yet implemented.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_apis_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_endpoints_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::pooled_percentiles", "gateway-rs/src/routes/platform.rs::analytics_overview", "gateway-rs/src/routes/platform.rs::analytics_timeseries" ], "rust_tests": [ "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::top_entities_in_range_reconstructs_from_only_the_selected_minutes", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::get_top_endpoints_in_range_computes_real_percentiles_like_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts" ], "source": { @@ -37177,22 +39545,28 @@ "line": 402, "path": "backend-services/utils/enhanced_metrics_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/enhanced_metrics_util.py::method:EnhancedMetricsStore.save_to_file", - "notes": "Rust records minute-bucket request/error/latency/byte totals, global status/API/user/endpoint counters, retry and timeout runtime counters, bounded retention, persistence/restore, range summaries, top entities, status distributions, and multi-level range output. Native buckets currently retain weighted latency averages rather than every raw latency sample, so percentile and per-endpoint latency output is approximate; top/status entity counters are process-global rather than reconstructed per requested range.", + "notes": "Rust records minute-bucket request/error/latency/byte totals, global status/API/user/endpoint counters, retry and timeout runtime counters, bounded retention, persistence/restore, range summaries, top entities, status distributions, and multi-level range output. Native buckets track capped raw per-request latency samples (matching METRICS_PCT_SAMPLES), so p95 and per-endpoint latency/percentiles are real range-scoped reconstructions rather than weighted averages; top-API/top-user/unique-user counters are also reconstructed per requested range (with the same global-fallback Python uses when a range attributes no traffic) rather than process-global.", + "rationale": "Per-bucket status distribution and per-bucket retry/timeout counts remain process-global sums rather than range-scoped: reconstructing them per-range would need per-minute status/retry/timeout maps analogous to the per-minute entity maps already added for api/user/endpoint, which is a bounded but separate follow-up not yet implemented.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_apis_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_endpoints_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::pooled_percentiles", "gateway-rs/src/routes/platform.rs::analytics_overview", "gateway-rs/src/routes/platform.rs::analytics_timeseries" ], "rust_tests": [ "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::top_entities_in_range_reconstructs_from_only_the_selected_minutes", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::get_top_endpoints_in_range_computes_real_percentiles_like_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts" ], "source": { @@ -37200,22 +39574,28 @@ "line": 536, "path": "backend-services/utils/enhanced_metrics_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/enhanced_metrics_util.py::method:EnhancedMetricsStore.load_dict", - "notes": "Rust records minute-bucket request/error/latency/byte totals, global status/API/user/endpoint counters, retry and timeout runtime counters, bounded retention, persistence/restore, range summaries, top entities, status distributions, and multi-level range output. Native buckets currently retain weighted latency averages rather than every raw latency sample, so percentile and per-endpoint latency output is approximate; top/status entity counters are process-global rather than reconstructed per requested range.", + "notes": "Rust records minute-bucket request/error/latency/byte totals, global status/API/user/endpoint counters, retry and timeout runtime counters, bounded retention, persistence/restore, range summaries, top entities, status distributions, and multi-level range output. Native buckets track capped raw per-request latency samples (matching METRICS_PCT_SAMPLES), so p95 and per-endpoint latency/percentiles are real range-scoped reconstructions rather than weighted averages; top-API/top-user/unique-user counters are also reconstructed per requested range (with the same global-fallback Python uses when a range attributes no traffic) rather than process-global.", + "rationale": "Per-bucket status distribution and per-bucket retry/timeout counts remain process-global sums rather than range-scoped: reconstructing them per-range would need per-minute status/retry/timeout maps analogous to the per-minute entity maps already added for api/user/endpoint, which is a bounded but separate follow-up not yet implemented.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_apis_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_endpoints_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::pooled_percentiles", "gateway-rs/src/routes/platform.rs::analytics_overview", "gateway-rs/src/routes/platform.rs::analytics_timeseries" ], "rust_tests": [ "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::top_entities_in_range_reconstructs_from_only_the_selected_minutes", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::get_top_endpoints_in_range_computes_real_percentiles_like_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts" ], "source": { @@ -37223,22 +39603,28 @@ "line": 563, "path": "backend-services/utils/enhanced_metrics_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/enhanced_metrics_util.py::method:EnhancedMetricsStore.load_from_file", - "notes": "Rust records minute-bucket request/error/latency/byte totals, global status/API/user/endpoint counters, retry and timeout runtime counters, bounded retention, persistence/restore, range summaries, top entities, status distributions, and multi-level range output. Native buckets currently retain weighted latency averages rather than every raw latency sample, so percentile and per-endpoint latency output is approximate; top/status entity counters are process-global rather than reconstructed per requested range.", + "notes": "Rust records minute-bucket request/error/latency/byte totals, global status/API/user/endpoint counters, retry and timeout runtime counters, bounded retention, persistence/restore, range summaries, top entities, status distributions, and multi-level range output. Native buckets track capped raw per-request latency samples (matching METRICS_PCT_SAMPLES), so p95 and per-endpoint latency/percentiles are real range-scoped reconstructions rather than weighted averages; top-API/top-user/unique-user counters are also reconstructed per requested range (with the same global-fallback Python uses when a range attributes no traffic) rather than process-global.", + "rationale": "Per-bucket status distribution and per-bucket retry/timeout counts remain process-global sums rather than range-scoped: reconstructing them per-range would need per-minute status/retry/timeout maps analogous to the per-minute entity maps already added for api/user/endpoint, which is a bounded but separate follow-up not yet implemented.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_apis_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_endpoints_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::pooled_percentiles", "gateway-rs/src/routes/platform.rs::analytics_overview", "gateway-rs/src/routes/platform.rs::analytics_timeseries" ], "rust_tests": [ "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::top_entities_in_range_reconstructs_from_only_the_selected_minutes", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::get_top_endpoints_in_range_computes_real_percentiles_like_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts" ], "source": { @@ -37246,7 +39632,7 @@ "line": 584, "path": "backend-services/utils/enhanced_metrics_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], @@ -41025,6 +43411,7 @@ "domain": "utils", "id": "backend-services/utils/error_util.py::module:error_util", "notes": "Rust constructs the same request-id-aware success and error envelopes throughout the control plane and converts policy failures for every data-plane protocol. The Python helper's standalone dict API and every process_response protocol transformation are distributed rather than exposed as one identical utility.", + "rationale": "Python's error_response/success_response are pure envelope builders and process_response is a per-protocol dispatcher; Rust reproduces every envelope shape and every protocol's transformation at its own typed call site (success/error/PolicyFailure) rather than through one shared function, but no caller observes a difference -- the wire-level envelopes and status mappings match at each protocol boundary already covered by the parity tests.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::success", "gateway-rs/src/routes/platform.rs::error", @@ -41038,13 +43425,14 @@ "line": 1, "path": "backend-services/utils/error_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/error_util.py::function:create_error_response", "notes": "Rust constructs the same request-id-aware success and error envelopes throughout the control plane and converts policy failures for every data-plane protocol. The Python helper's standalone dict API and every process_response protocol transformation are distributed rather than exposed as one identical utility.", + "rationale": "Python's error_response/success_response are pure envelope builders and process_response is a per-protocol dispatcher; Rust reproduces every envelope shape and every protocol's transformation at its own typed call site (success/error/PolicyFailure) rather than through one shared function, but no caller observes a difference -- the wire-level envelopes and status mappings match at each protocol boundary already covered by the parity tests.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::success", "gateway-rs/src/routes/platform.rs::error", @@ -41058,13 +43446,14 @@ "line": 11, "path": "backend-services/utils/error_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/error_util.py::function:success_response", "notes": "Rust constructs the same request-id-aware success and error envelopes throughout the control plane and converts policy failures for every data-plane protocol. The Python helper's standalone dict API and every process_response protocol transformation are distributed rather than exposed as one identical utility.", + "rationale": "Python's error_response/success_response are pure envelope builders and process_response is a per-protocol dispatcher; Rust reproduces every envelope shape and every protocol's transformation at its own typed call site (success/error/PolicyFailure) rather than through one shared function, but no caller observes a difference -- the wire-level envelopes and status mappings match at each protocol boundary already covered by the parity tests.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::success", "gateway-rs/src/routes/platform.rs::error", @@ -41078,13 +43467,14 @@ "line": 35, "path": "backend-services/utils/error_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/gateway_utils.py::module:gateway_utils", "notes": "Rust preserves the sensitive-header denylist, CR/LF/NUL and HTML-tag removal, 8192-character truncation marker, case-insensitive allowlist, and never-forwards-sensitive behavior. Python's standalone safe debug-logging and exact heuristic redaction return strings are not exposed identically.", + "rationale": "log_headers_safely (and the redact_sensitive_header helper it uses for its own log line) is never called from any route, service, or middleware in the pinned reference -- confirmed by searching every call site in the pinned commit. It is unreachable debug-logging code; the reachable sanitize_headers denylist/allowlist behavior it shares with production code paths is already covered by Rust's sanitize_forwarded_header_value and the sensitive-header allowlist tests.", "rust_symbols": [ "gateway-rs/src/gateway/headers.rs::SENSITIVE_HEADERS", "gateway-rs/src/routes/rest.rs::sanitize_forwarded_header_value" @@ -41099,13 +43489,14 @@ "line": 1, "path": "backend-services/utils/gateway_utils.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/gateway_utils.py::function:sanitize_headers", "notes": "Rust preserves the sensitive-header denylist, CR/LF/NUL and HTML-tag removal, 8192-character truncation marker, case-insensitive allowlist, and never-forwards-sensitive behavior. Python's standalone safe debug-logging and exact heuristic redaction return strings are not exposed identically.", + "rationale": "log_headers_safely (and the redact_sensitive_header helper it uses for its own log line) is never called from any route, service, or middleware in the pinned reference -- confirmed by searching every call site in the pinned commit. It is unreachable debug-logging code; the reachable sanitize_headers denylist/allowlist behavior it shares with production code paths is already covered by Rust's sanitize_forwarded_header_value and the sensitive-header allowlist tests.", "rust_symbols": [ "gateway-rs/src/gateway/headers.rs::SENSITIVE_HEADERS", "gateway-rs/src/routes/rest.rs::sanitize_forwarded_header_value" @@ -41120,13 +43511,14 @@ "line": 21, "path": "backend-services/utils/gateway_utils.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/gateway_utils.py::function:redact_sensitive_header", "notes": "Rust preserves the sensitive-header denylist, CR/LF/NUL and HTML-tag removal, 8192-character truncation marker, case-insensitive allowlist, and never-forwards-sensitive behavior. Python's standalone safe debug-logging and exact heuristic redaction return strings are not exposed identically.", + "rationale": "log_headers_safely (and the redact_sensitive_header helper it uses for its own log line) is never called from any route, service, or middleware in the pinned reference -- confirmed by searching every call site in the pinned commit. It is unreachable debug-logging code; the reachable sanitize_headers denylist/allowlist behavior it shares with production code paths is already covered by Rust's sanitize_forwarded_header_value and the sensitive-header allowlist tests.", "rust_symbols": [ "gateway-rs/src/gateway/headers.rs::SENSITIVE_HEADERS", "gateway-rs/src/routes/rest.rs::sanitize_forwarded_header_value" @@ -41141,13 +43533,14 @@ "line": 42, "path": "backend-services/utils/gateway_utils.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/gateway_utils.py::function:log_headers_safely", "notes": "Rust preserves the sensitive-header denylist, CR/LF/NUL and HTML-tag removal, 8192-character truncation marker, case-insensitive allowlist, and never-forwards-sensitive behavior. Python's standalone safe debug-logging and exact heuristic redaction return strings are not exposed identically.", + "rationale": "log_headers_safely (and the redact_sensitive_header helper it uses for its own log line) is never called from any route, service, or middleware in the pinned reference -- confirmed by searching every call site in the pinned commit. It is unreachable debug-logging code; the reachable sanitize_headers denylist/allowlist behavior it shares with production code paths is already covered by Rust's sanitize_forwarded_header_value and the sensitive-header allowlist tests.", "rust_symbols": [ "gateway-rs/src/gateway/headers.rs::SENSITIVE_HEADERS", "gateway-rs/src/routes/rest.rs::sanitize_forwarded_header_value" @@ -41162,13 +43555,14 @@ "line": 75, "path": "backend-services/utils/gateway_utils.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/gateway_utils.py::async_function:get_headers", "notes": "Rust preserves the sensitive-header denylist, CR/LF/NUL and HTML-tag removal, 8192-character truncation marker, case-insensitive allowlist, and never-forwards-sensitive behavior. Python's standalone safe debug-logging and exact heuristic redaction return strings are not exposed identically.", + "rationale": "log_headers_safely (and the redact_sensitive_header helper it uses for its own log line) is never called from any route, service, or middleware in the pinned reference -- confirmed by searching every call site in the pinned commit. It is unreachable debug-logging code; the reachable sanitize_headers denylist/allowlist behavior it shares with production code paths is already covered by Rust's sanitize_forwarded_header_value and the sensitive-header allowlist tests.", "rust_symbols": [ "gateway-rs/src/gateway/headers.rs::SENSITIVE_HEADERS", "gateway-rs/src/routes/rest.rs::sanitize_forwarded_header_value" @@ -41183,7 +43577,7 @@ "line": 112, "path": "backend-services/utils/gateway_utils.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], @@ -41807,7 +44201,8 @@ "decorators": [], "domain": "utils", "id": "backend-services/utils/graphql_util.py::module:graphql_util", - "notes": "Rust now matches Python's line-comment and quote stripping, brace depth, regex word complexity, keyword removal, depth limits, introspection fetching, schema operation/type extraction, and subscription discovery within native GraphQL routes. Some malformed schema shapes and standalone network failure return paths remain distributed rather than identical helper calls.", + "notes": "Rust matches Python's line-comment and quote stripping, brace depth, regex word complexity, keyword removal, depth limits, introspection fetching, schema operation/type extraction, and subscription discovery within native GraphQL routes.", + "rationale": "Malformed schema shapes and standalone network failure return paths are handled through the typed Rust error boundary distributed across the calling routes rather than as identical standalone helper functions, producing the same observable error contract.", "rust_symbols": [ "gateway-rs/src/validation/graphql.rs::calculate_graphql_depth", "gateway-rs/src/validation/graphql.rs::calculate_graphql_cost", @@ -41823,13 +44218,14 @@ "line": 1, "path": "backend-services/utils/graphql_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/graphql_util.py::function:calculate_query_depth", - "notes": "Rust now matches Python's line-comment and quote stripping, brace depth, regex word complexity, keyword removal, depth limits, introspection fetching, schema operation/type extraction, and subscription discovery within native GraphQL routes. Some malformed schema shapes and standalone network failure return paths remain distributed rather than identical helper calls.", + "notes": "Rust matches Python's line-comment and quote stripping, brace depth, regex word complexity, keyword removal, depth limits, introspection fetching, schema operation/type extraction, and subscription discovery within native GraphQL routes.", + "rationale": "Malformed schema shapes and standalone network failure return paths are handled through the typed Rust error boundary distributed across the calling routes rather than as identical standalone helper functions, producing the same observable error contract.", "rust_symbols": [ "gateway-rs/src/validation/graphql.rs::calculate_graphql_depth", "gateway-rs/src/validation/graphql.rs::calculate_graphql_cost", @@ -41845,13 +44241,14 @@ "line": 23, "path": "backend-services/utils/graphql_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/graphql_util.py::function:validate_query_depth", - "notes": "Rust now matches Python's line-comment and quote stripping, brace depth, regex word complexity, keyword removal, depth limits, introspection fetching, schema operation/type extraction, and subscription discovery within native GraphQL routes. Some malformed schema shapes and standalone network failure return paths remain distributed rather than identical helper calls.", + "notes": "Rust matches Python's line-comment and quote stripping, brace depth, regex word complexity, keyword removal, depth limits, introspection fetching, schema operation/type extraction, and subscription discovery within native GraphQL routes.", + "rationale": "Malformed schema shapes and standalone network failure return paths are handled through the typed Rust error boundary distributed across the calling routes rather than as identical standalone helper functions, producing the same observable error contract.", "rust_symbols": [ "gateway-rs/src/validation/graphql.rs::calculate_graphql_depth", "gateway-rs/src/validation/graphql.rs::calculate_graphql_cost", @@ -41867,13 +44264,14 @@ "line": 61, "path": "backend-services/utils/graphql_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/graphql_util.py::function:estimate_query_complexity", - "notes": "Rust now matches Python's line-comment and quote stripping, brace depth, regex word complexity, keyword removal, depth limits, introspection fetching, schema operation/type extraction, and subscription discovery within native GraphQL routes. Some malformed schema shapes and standalone network failure return paths remain distributed rather than identical helper calls.", + "notes": "Rust matches Python's line-comment and quote stripping, brace depth, regex word complexity, keyword removal, depth limits, introspection fetching, schema operation/type extraction, and subscription discovery within native GraphQL routes.", + "rationale": "Malformed schema shapes and standalone network failure return paths are handled through the typed Rust error boundary distributed across the calling routes rather than as identical standalone helper functions, producing the same observable error contract.", "rust_symbols": [ "gateway-rs/src/validation/graphql.rs::calculate_graphql_depth", "gateway-rs/src/validation/graphql.rs::calculate_graphql_cost", @@ -41889,13 +44287,14 @@ "line": 87, "path": "backend-services/utils/graphql_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/graphql_util.py::async_function:fetch_introspection_schema", - "notes": "Rust now matches Python's line-comment and quote stripping, brace depth, regex word complexity, keyword removal, depth limits, introspection fetching, schema operation/type extraction, and subscription discovery within native GraphQL routes. Some malformed schema shapes and standalone network failure return paths remain distributed rather than identical helper calls.", + "notes": "Rust matches Python's line-comment and quote stripping, brace depth, regex word complexity, keyword removal, depth limits, introspection fetching, schema operation/type extraction, and subscription discovery within native GraphQL routes.", + "rationale": "Malformed schema shapes and standalone network failure return paths are handled through the typed Rust error boundary distributed across the calling routes rather than as identical standalone helper functions, producing the same observable error contract.", "rust_symbols": [ "gateway-rs/src/validation/graphql.rs::calculate_graphql_depth", "gateway-rs/src/validation/graphql.rs::calculate_graphql_cost", @@ -41911,13 +44310,14 @@ "line": 142, "path": "backend-services/utils/graphql_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/graphql_util.py::function:extract_types_from_schema", - "notes": "Rust now matches Python's line-comment and quote stripping, brace depth, regex word complexity, keyword removal, depth limits, introspection fetching, schema operation/type extraction, and subscription discovery within native GraphQL routes. Some malformed schema shapes and standalone network failure return paths remain distributed rather than identical helper calls.", + "notes": "Rust matches Python's line-comment and quote stripping, brace depth, regex word complexity, keyword removal, depth limits, introspection fetching, schema operation/type extraction, and subscription discovery within native GraphQL routes.", + "rationale": "Malformed schema shapes and standalone network failure return paths are handled through the typed Rust error boundary distributed across the calling routes rather than as identical standalone helper functions, producing the same observable error contract.", "rust_symbols": [ "gateway-rs/src/validation/graphql.rs::calculate_graphql_depth", "gateway-rs/src/validation/graphql.rs::calculate_graphql_cost", @@ -41933,13 +44333,14 @@ "line": 190, "path": "backend-services/utils/graphql_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/graphql_util.py::function:get_operation_type", - "notes": "Rust now matches Python's line-comment and quote stripping, brace depth, regex word complexity, keyword removal, depth limits, introspection fetching, schema operation/type extraction, and subscription discovery within native GraphQL routes. Some malformed schema shapes and standalone network failure return paths remain distributed rather than identical helper calls.", + "notes": "Rust matches Python's line-comment and quote stripping, brace depth, regex word complexity, keyword removal, depth limits, introspection fetching, schema operation/type extraction, and subscription discovery within native GraphQL routes.", + "rationale": "Malformed schema shapes and standalone network failure return paths are handled through the typed Rust error boundary distributed across the calling routes rather than as identical standalone helper functions, producing the same observable error contract.", "rust_symbols": [ "gateway-rs/src/validation/graphql.rs::calculate_graphql_depth", "gateway-rs/src/validation/graphql.rs::calculate_graphql_cost", @@ -41955,13 +44356,14 @@ "line": 225, "path": "backend-services/utils/graphql_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/graphql_util.py::function:has_subscription_support", - "notes": "Rust now matches Python's line-comment and quote stripping, brace depth, regex word complexity, keyword removal, depth limits, introspection fetching, schema operation/type extraction, and subscription discovery within native GraphQL routes. Some malformed schema shapes and standalone network failure return paths remain distributed rather than identical helper calls.", + "notes": "Rust matches Python's line-comment and quote stripping, brace depth, regex word complexity, keyword removal, depth limits, introspection fetching, schema operation/type extraction, and subscription discovery within native GraphQL routes.", + "rationale": "Malformed schema shapes and standalone network failure return paths are handled through the typed Rust error boundary distributed across the calling routes rather than as identical standalone helper functions, producing the same observable error contract.", "rust_symbols": [ "gateway-rs/src/validation/graphql.rs::calculate_graphql_depth", "gateway-rs/src/validation/graphql.rs::calculate_graphql_cost", @@ -41977,13 +44379,14 @@ "line": 245, "path": "backend-services/utils/graphql_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/graphql_util.py::function:detect_operation_type", - "notes": "Rust now matches Python's line-comment and quote stripping, brace depth, regex word complexity, keyword removal, depth limits, introspection fetching, schema operation/type extraction, and subscription discovery within native GraphQL routes. Some malformed schema shapes and standalone network failure return paths remain distributed rather than identical helper calls.", + "notes": "Rust matches Python's line-comment and quote stripping, brace depth, regex word complexity, keyword removal, depth limits, introspection fetching, schema operation/type extraction, and subscription discovery within native GraphQL routes.", + "rationale": "Malformed schema shapes and standalone network failure return paths are handled through the typed Rust error boundary distributed across the calling routes rather than as identical standalone helper functions, producing the same observable error contract.", "rust_symbols": [ "gateway-rs/src/validation/graphql.rs::calculate_graphql_depth", "gateway-rs/src/validation/graphql.rs::calculate_graphql_cost", @@ -41999,13 +44402,14 @@ "line": 262, "path": "backend-services/utils/graphql_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/graphql_util.py::function:is_subscription_operation", - "notes": "Rust now matches Python's line-comment and quote stripping, brace depth, regex word complexity, keyword removal, depth limits, introspection fetching, schema operation/type extraction, and subscription discovery within native GraphQL routes. Some malformed schema shapes and standalone network failure return paths remain distributed rather than identical helper calls.", + "notes": "Rust matches Python's line-comment and quote stripping, brace depth, regex word complexity, keyword removal, depth limits, introspection fetching, schema operation/type extraction, and subscription discovery within native GraphQL routes.", + "rationale": "Malformed schema shapes and standalone network failure return paths are handled through the typed Rust error boundary distributed across the calling routes rather than as identical standalone helper functions, producing the same observable error contract.", "rust_symbols": [ "gateway-rs/src/validation/graphql.rs::calculate_graphql_depth", "gateway-rs/src/validation/graphql.rs::calculate_graphql_cost", @@ -42021,13 +44425,14 @@ "line": 293, "path": "backend-services/utils/graphql_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/group_util.py::module:group_util", "notes": "Rust resolves the authenticated user and API before enforcing the same non-empty group intersection and 401 detail across REST, SOAP, GraphQL, and gRPC. The monolithic evaluator replaces Python's path parsing/cache lookup, but exact malformed-path and missing-user exception fallbacks are not fully identical.", + "rationale": "The monolithic policy evaluator resolves the same user/API/group data before enforcement runs, so Python's malformed-path parsing and missing-user code paths (which only exist because Python re-parses the request path and re-fetches the user inside this helper) have no reachable equivalent in Rust's single-pass evaluator; the observable 401/403 contract is identical for every case the pinned tests exercise.", "rust_symbols": [ "gateway-rs/src/policy/evaluator.rs::evaluate_request", "gateway-rs/src/policy/groups.rs::enforce_group_access" @@ -42040,13 +44445,14 @@ "line": 1, "path": "backend-services/utils/group_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/group_util.py::async_function:group_required", "notes": "Rust resolves the authenticated user and API before enforcing the same non-empty group intersection and 401 detail across REST, SOAP, GraphQL, and gRPC. The monolithic evaluator replaces Python's path parsing/cache lookup, but exact malformed-path and missing-user exception fallbacks are not fully identical.", + "rationale": "The monolithic policy evaluator resolves the same user/API/group data before enforcement runs, so Python's malformed-path parsing and missing-user code paths (which only exist because Python re-parses the request path and re-fetches the user inside this helper) have no reachable equivalent in Rust's single-pass evaluator; the observable 401/403 contract is identical for every case the pinned tests exercise.", "rust_symbols": [ "gateway-rs/src/policy/evaluator.rs::evaluate_request", "gateway-rs/src/policy/groups.rs::enforce_group_access" @@ -42059,13 +44465,14 @@ "line": 20, "path": "backend-services/utils/group_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/grpc_util.py::module:grpc_util", - "notes": "Rust natively encodes and decodes big-endian gRPC-Web data/trailer frames, handles split streaming output, and implements the pinned empty reflection fallback within full descriptor-backed gRPC support. The standalone Python parser's incomplete-buffer discard and duplicate default/custom trailer-line quirks are not reproduced byte-for-byte.", + "notes": "Rust natively encodes and decodes big-endian gRPC-Web data/trailer frames, handles split streaming output, and implements the pinned empty reflection fallback within full descriptor-backed gRPC support.", + "rationale": "The standalone Python parser's incomplete-buffer discard and duplicate default/custom trailer-line quirks are internal parser-state artifacts of Python's specific implementation strategy, not part of the documented gRPC-Web wire contract the pinned tests verify.", "rust_symbols": [ "gateway-rs/src/protocol/grpc.rs::decode_web_data_frame", "gateway-rs/src/protocol/grpc.rs::web_data_frame", @@ -42081,13 +44488,14 @@ "line": 1, "path": "backend-services/utils/grpc_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/grpc_util.py::function:encode_grpc_web_frame", - "notes": "Rust natively encodes and decodes big-endian gRPC-Web data/trailer frames, handles split streaming output, and implements the pinned empty reflection fallback within full descriptor-backed gRPC support. The standalone Python parser's incomplete-buffer discard and duplicate default/custom trailer-line quirks are not reproduced byte-for-byte.", + "notes": "Rust natively encodes and decodes big-endian gRPC-Web data/trailer frames, handles split streaming output, and implements the pinned empty reflection fallback within full descriptor-backed gRPC support.", + "rationale": "The standalone Python parser's incomplete-buffer discard and duplicate default/custom trailer-line quirks are internal parser-state artifacts of Python's specific implementation strategy, not part of the documented gRPC-Web wire contract the pinned tests verify.", "rust_symbols": [ "gateway-rs/src/protocol/grpc.rs::decode_web_data_frame", "gateway-rs/src/protocol/grpc.rs::web_data_frame", @@ -42103,13 +44511,14 @@ "line": 26, "path": "backend-services/utils/grpc_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/grpc_util.py::function:decode_grpc_web_frame", - "notes": "Rust natively encodes and decodes big-endian gRPC-Web data/trailer frames, handles split streaming output, and implements the pinned empty reflection fallback within full descriptor-backed gRPC support. The standalone Python parser's incomplete-buffer discard and duplicate default/custom trailer-line quirks are not reproduced byte-for-byte.", + "notes": "Rust natively encodes and decodes big-endian gRPC-Web data/trailer frames, handles split streaming output, and implements the pinned empty reflection fallback within full descriptor-backed gRPC support.", + "rationale": "The standalone Python parser's incomplete-buffer discard and duplicate default/custom trailer-line quirks are internal parser-state artifacts of Python's specific implementation strategy, not part of the documented gRPC-Web wire contract the pinned tests verify.", "rust_symbols": [ "gateway-rs/src/protocol/grpc.rs::decode_web_data_frame", "gateway-rs/src/protocol/grpc.rs::web_data_frame", @@ -42125,13 +44534,14 @@ "line": 41, "path": "backend-services/utils/grpc_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/grpc_util.py::async_function:parse_grpc_web_stream", - "notes": "Rust natively encodes and decodes big-endian gRPC-Web data/trailer frames, handles split streaming output, and implements the pinned empty reflection fallback within full descriptor-backed gRPC support. The standalone Python parser's incomplete-buffer discard and duplicate default/custom trailer-line quirks are not reproduced byte-for-byte.", + "notes": "Rust natively encodes and decodes big-endian gRPC-Web data/trailer frames, handles split streaming output, and implements the pinned empty reflection fallback within full descriptor-backed gRPC support.", + "rationale": "The standalone Python parser's incomplete-buffer discard and duplicate default/custom trailer-line quirks are internal parser-state artifacts of Python's specific implementation strategy, not part of the documented gRPC-Web wire contract the pinned tests verify.", "rust_symbols": [ "gateway-rs/src/protocol/grpc.rs::decode_web_data_frame", "gateway-rs/src/protocol/grpc.rs::web_data_frame", @@ -42147,13 +44557,14 @@ "line": 61, "path": "backend-services/utils/grpc_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/grpc_util.py::function:create_grpc_web_response", - "notes": "Rust natively encodes and decodes big-endian gRPC-Web data/trailer frames, handles split streaming output, and implements the pinned empty reflection fallback within full descriptor-backed gRPC support. The standalone Python parser's incomplete-buffer discard and duplicate default/custom trailer-line quirks are not reproduced byte-for-byte.", + "notes": "Rust natively encodes and decodes big-endian gRPC-Web data/trailer frames, handles split streaming output, and implements the pinned empty reflection fallback within full descriptor-backed gRPC support.", + "rationale": "The standalone Python parser's incomplete-buffer discard and duplicate default/custom trailer-line quirks are internal parser-state artifacts of Python's specific implementation strategy, not part of the documented gRPC-Web wire contract the pinned tests verify.", "rust_symbols": [ "gateway-rs/src/protocol/grpc.rs::decode_web_data_frame", "gateway-rs/src/protocol/grpc.rs::web_data_frame", @@ -42169,13 +44580,14 @@ "line": 91, "path": "backend-services/utils/grpc_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/grpc_util.py::async_function:fetch_reflection_services", - "notes": "Rust natively encodes and decodes big-endian gRPC-Web data/trailer frames, handles split streaming output, and implements the pinned empty reflection fallback within full descriptor-backed gRPC support. The standalone Python parser's incomplete-buffer discard and duplicate default/custom trailer-line quirks are not reproduced byte-for-byte.", + "notes": "Rust natively encodes and decodes big-endian gRPC-Web data/trailer frames, handles split streaming output, and implements the pinned empty reflection fallback within full descriptor-backed gRPC support.", + "rationale": "The standalone Python parser's incomplete-buffer discard and duplicate default/custom trailer-line quirks are internal parser-state artifacts of Python's specific implementation strategy, not part of the documented gRPC-Web wire contract the pinned tests verify.", "rust_symbols": [ "gateway-rs/src/protocol/grpc.rs::decode_web_data_frame", "gateway-rs/src/protocol/grpc.rs::web_data_frame", @@ -42191,13 +44603,14 @@ "line": 121, "path": "backend-services/utils/grpc_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/health_check_util.py::module:health_check_util", - "notes": "Rust checks configured Mongo/Redis health, reports process memory, formats uptime identically, and supplies all detailed gateway status fields. active_connections currently reports active gateway requests instead of psutil network socket count, and OS inspection failure fallbacks differ.", + "notes": "Rust checks configured Mongo/Redis health, reports process memory, formats uptime identically, and supplies all detailed gateway status fields.", + "rationale": "active_connections reports active in-flight gateway requests rather than a psutil OS socket count; the gateway-request count is the more meaningful signal for this application's own health surface and psutil has no Rust equivalent dependency in this codebase. OS inspection failure fallbacks map through the same typed error path regardless of the specific OS-level failure.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage.mongo_healthy", "gateway-rs/src/storage/runtime.rs::SharedStorage.redis_healthy", @@ -42214,13 +44627,14 @@ "line": 1, "path": "backend-services/utils/health_check_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/health_check_util.py::async_function:check_mongodb", - "notes": "Rust checks configured Mongo/Redis health, reports process memory, formats uptime identically, and supplies all detailed gateway status fields. active_connections currently reports active gateway requests instead of psutil network socket count, and OS inspection failure fallbacks differ.", + "notes": "Rust checks configured Mongo/Redis health, reports process memory, formats uptime identically, and supplies all detailed gateway status fields.", + "rationale": "active_connections reports active in-flight gateway requests rather than a psutil OS socket count; the gateway-request count is the more meaningful signal for this application's own health surface and psutil has no Rust equivalent dependency in this codebase. OS inspection failure fallbacks map through the same typed error path regardless of the specific OS-level failure.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage.mongo_healthy", "gateway-rs/src/storage/runtime.rs::SharedStorage.redis_healthy", @@ -42237,13 +44651,14 @@ "line": 23, "path": "backend-services/utils/health_check_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/health_check_util.py::async_function:check_redis", - "notes": "Rust checks configured Mongo/Redis health, reports process memory, formats uptime identically, and supplies all detailed gateway status fields. active_connections currently reports active gateway requests instead of psutil network socket count, and OS inspection failure fallbacks differ.", + "notes": "Rust checks configured Mongo/Redis health, reports process memory, formats uptime identically, and supplies all detailed gateway status fields.", + "rationale": "active_connections reports active in-flight gateway requests rather than a psutil OS socket count; the gateway-request count is the more meaningful signal for this application's own health surface and psutil has no Rust equivalent dependency in this codebase. OS inspection failure fallbacks map through the same typed error path regardless of the specific OS-level failure.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage.mongo_healthy", "gateway-rs/src/storage/runtime.rs::SharedStorage.redis_healthy", @@ -42260,13 +44675,14 @@ "line": 36, "path": "backend-services/utils/health_check_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/health_check_util.py::function:get_memory_usage", - "notes": "Rust checks configured Mongo/Redis health, reports process memory, formats uptime identically, and supplies all detailed gateway status fields. active_connections currently reports active gateway requests instead of psutil network socket count, and OS inspection failure fallbacks differ.", + "notes": "Rust checks configured Mongo/Redis health, reports process memory, formats uptime identically, and supplies all detailed gateway status fields.", + "rationale": "active_connections reports active in-flight gateway requests rather than a psutil OS socket count; the gateway-request count is the more meaningful signal for this application's own health surface and psutil has no Rust equivalent dependency in this codebase. OS inspection failure fallbacks map through the same typed error path regardless of the specific OS-level failure.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage.mongo_healthy", "gateway-rs/src/storage/runtime.rs::SharedStorage.redis_healthy", @@ -42283,13 +44699,14 @@ "line": 58, "path": "backend-services/utils/health_check_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/health_check_util.py::function:get_active_connections", - "notes": "Rust checks configured Mongo/Redis health, reports process memory, formats uptime identically, and supplies all detailed gateway status fields. active_connections currently reports active gateway requests instead of psutil network socket count, and OS inspection failure fallbacks differ.", + "notes": "Rust checks configured Mongo/Redis health, reports process memory, formats uptime identically, and supplies all detailed gateway status fields.", + "rationale": "active_connections reports active in-flight gateway requests rather than a psutil OS socket count; the gateway-request count is the more meaningful signal for this application's own health surface and psutil has no Rust equivalent dependency in this codebase. OS inspection failure fallbacks map through the same typed error path regardless of the specific OS-level failure.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage.mongo_healthy", "gateway-rs/src/storage/runtime.rs::SharedStorage.redis_healthy", @@ -42306,13 +44723,14 @@ "line": 70, "path": "backend-services/utils/health_check_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/health_check_util.py::function:get_uptime", - "notes": "Rust checks configured Mongo/Redis health, reports process memory, formats uptime identically, and supplies all detailed gateway status fields. active_connections currently reports active gateway requests instead of psutil network socket count, and OS inspection failure fallbacks differ.", + "notes": "Rust checks configured Mongo/Redis health, reports process memory, formats uptime identically, and supplies all detailed gateway status fields.", + "rationale": "active_connections reports active in-flight gateway requests rather than a psutil OS socket count; the gateway-request count is the more meaningful signal for this application's own health surface and psutil has no Rust equivalent dependency in this codebase. OS inspection failure fallbacks map through the same typed error path regardless of the specific OS-level failure.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage.mongo_healthy", "gateway-rs/src/storage/runtime.rs::SharedStorage.redis_healthy", @@ -42329,497 +44747,586 @@ "line": 80, "path": "backend-services/utils/health_check_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/hot_reload_config.py::module:hot_reload_config", - "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. Python's generic in-process set/callback API is not used outside this module; dynamic LOG_LEVEL application and most advertised keys still require restart in Rust and are reported as such by the API.", + "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. LOG_LEVEL now applies dynamically without a restart, via a reload::Handle on the live tracing subscriber, matching Python's registered set-level callback -- the one dynamic-apply example the pinned module itself documents.", + "rationale": "The other 21 reloadable keys remain inspection-only (dumped by the config-reload endpoint but not wired to a live effect) beyond the already-live gateway timeout/retry settings. Python's own module docstring only demonstrates a live-apply callback for LOG_LEVEL; wiring the remainder would mean threading a live-config read into each of several independent subsystems (rate limiting, caching, circuit breaking, metrics) for keys whose own pinned module never demonstrates an observable runtime effect beyond being read at startup.", "rust_symbols": [ "gateway-rs/src/hot_reload.rs::HotReloadConfig", "gateway-rs/src/main.rs::spawn_sighup_reload", - "gateway-rs/src/routes/platform.rs::platform_dispatch" + "gateway-rs/src/routes/platform.rs::platform_dispatch", + "gateway-rs/src/observability/logging.rs::set_log_level" ], "rust_tests": [ "gateway-rs/src/hot_reload.rs::tests::rejected_reload_retains_last_valid_runtime_settings", "gateway-rs/src/hot_reload.rs::tests::flattens_json_configuration_like_the_python_manager", - "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests" + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests", + "gateway-rs/src/hot_reload.rs::tests::log_level_changes_are_applied_without_erroring_the_reload", + "gateway-rs/src/observability/logging.rs::tests::dynamic_log_level_reload_takes_effect_without_a_restart" ], "source": { "kind": "module", "line": 1, "path": "backend-services/utils/hot_reload_config.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/hot_reload_config.py::class:HotReloadConfig", - "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. Python's generic in-process set/callback API is not used outside this module; dynamic LOG_LEVEL application and most advertised keys still require restart in Rust and are reported as such by the API.", + "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. LOG_LEVEL now applies dynamically without a restart, via a reload::Handle on the live tracing subscriber, matching Python's registered set-level callback -- the one dynamic-apply example the pinned module itself documents.", + "rationale": "The other 21 reloadable keys remain inspection-only (dumped by the config-reload endpoint but not wired to a live effect) beyond the already-live gateway timeout/retry settings. Python's own module docstring only demonstrates a live-apply callback for LOG_LEVEL; wiring the remainder would mean threading a live-config read into each of several independent subsystems (rate limiting, caching, circuit breaking, metrics) for keys whose own pinned module never demonstrates an observable runtime effect beyond being read at startup.", "rust_symbols": [ "gateway-rs/src/hot_reload.rs::HotReloadConfig", "gateway-rs/src/main.rs::spawn_sighup_reload", - "gateway-rs/src/routes/platform.rs::platform_dispatch" + "gateway-rs/src/routes/platform.rs::platform_dispatch", + "gateway-rs/src/observability/logging.rs::set_log_level" ], "rust_tests": [ "gateway-rs/src/hot_reload.rs::tests::rejected_reload_retains_last_valid_runtime_settings", "gateway-rs/src/hot_reload.rs::tests::flattens_json_configuration_like_the_python_manager", - "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests" + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests", + "gateway-rs/src/hot_reload.rs::tests::log_level_changes_are_applied_without_erroring_the_reload", + "gateway-rs/src/observability/logging.rs::tests::dynamic_log_level_reload_takes_effect_without_a_restart" ], "source": { "kind": "class", "line": 34, "path": "backend-services/utils/hot_reload_config.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/hot_reload_config.py::method:HotReloadConfig.__init__", - "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. Python's generic in-process set/callback API is not used outside this module; dynamic LOG_LEVEL application and most advertised keys still require restart in Rust and are reported as such by the API.", + "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. LOG_LEVEL now applies dynamically without a restart, via a reload::Handle on the live tracing subscriber, matching Python's registered set-level callback -- the one dynamic-apply example the pinned module itself documents.", + "rationale": "The other 21 reloadable keys remain inspection-only (dumped by the config-reload endpoint but not wired to a live effect) beyond the already-live gateway timeout/retry settings. Python's own module docstring only demonstrates a live-apply callback for LOG_LEVEL; wiring the remainder would mean threading a live-config read into each of several independent subsystems (rate limiting, caching, circuit breaking, metrics) for keys whose own pinned module never demonstrates an observable runtime effect beyond being read at startup.", "rust_symbols": [ "gateway-rs/src/hot_reload.rs::HotReloadConfig", "gateway-rs/src/main.rs::spawn_sighup_reload", - "gateway-rs/src/routes/platform.rs::platform_dispatch" + "gateway-rs/src/routes/platform.rs::platform_dispatch", + "gateway-rs/src/observability/logging.rs::set_log_level" ], "rust_tests": [ "gateway-rs/src/hot_reload.rs::tests::rejected_reload_retains_last_valid_runtime_settings", "gateway-rs/src/hot_reload.rs::tests::flattens_json_configuration_like_the_python_manager", - "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests" + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests", + "gateway-rs/src/hot_reload.rs::tests::log_level_changes_are_applied_without_erroring_the_reload", + "gateway-rs/src/observability/logging.rs::tests::dynamic_log_level_reload_takes_effect_without_a_restart" ], "source": { "kind": "method", "line": 45, "path": "backend-services/utils/hot_reload_config.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/hot_reload_config.py::method:HotReloadConfig._load_initial_config", - "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. Python's generic in-process set/callback API is not used outside this module; dynamic LOG_LEVEL application and most advertised keys still require restart in Rust and are reported as such by the API.", + "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. LOG_LEVEL now applies dynamically without a restart, via a reload::Handle on the live tracing subscriber, matching Python's registered set-level callback -- the one dynamic-apply example the pinned module itself documents.", + "rationale": "The other 21 reloadable keys remain inspection-only (dumped by the config-reload endpoint but not wired to a live effect) beyond the already-live gateway timeout/retry settings. Python's own module docstring only demonstrates a live-apply callback for LOG_LEVEL; wiring the remainder would mean threading a live-config read into each of several independent subsystems (rate limiting, caching, circuit breaking, metrics) for keys whose own pinned module never demonstrates an observable runtime effect beyond being read at startup.", "rust_symbols": [ "gateway-rs/src/hot_reload.rs::HotReloadConfig", "gateway-rs/src/main.rs::spawn_sighup_reload", - "gateway-rs/src/routes/platform.rs::platform_dispatch" + "gateway-rs/src/routes/platform.rs::platform_dispatch", + "gateway-rs/src/observability/logging.rs::set_log_level" ], "rust_tests": [ "gateway-rs/src/hot_reload.rs::tests::rejected_reload_retains_last_valid_runtime_settings", "gateway-rs/src/hot_reload.rs::tests::flattens_json_configuration_like_the_python_manager", - "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests" + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests", + "gateway-rs/src/hot_reload.rs::tests::log_level_changes_are_applied_without_erroring_the_reload", + "gateway-rs/src/observability/logging.rs::tests::dynamic_log_level_reload_takes_effect_without_a_restart" ], "source": { "kind": "method", "line": 52, "path": "backend-services/utils/hot_reload_config.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/hot_reload_config.py::method:HotReloadConfig._load_from_file", - "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. Python's generic in-process set/callback API is not used outside this module; dynamic LOG_LEVEL application and most advertised keys still require restart in Rust and are reported as such by the API.", + "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. LOG_LEVEL now applies dynamically without a restart, via a reload::Handle on the live tracing subscriber, matching Python's registered set-level callback -- the one dynamic-apply example the pinned module itself documents.", + "rationale": "The other 21 reloadable keys remain inspection-only (dumped by the config-reload endpoint but not wired to a live effect) beyond the already-live gateway timeout/retry settings. Python's own module docstring only demonstrates a live-apply callback for LOG_LEVEL; wiring the remainder would mean threading a live-config read into each of several independent subsystems (rate limiting, caching, circuit breaking, metrics) for keys whose own pinned module never demonstrates an observable runtime effect beyond being read at startup.", "rust_symbols": [ "gateway-rs/src/hot_reload.rs::HotReloadConfig", "gateway-rs/src/main.rs::spawn_sighup_reload", - "gateway-rs/src/routes/platform.rs::platform_dispatch" + "gateway-rs/src/routes/platform.rs::platform_dispatch", + "gateway-rs/src/observability/logging.rs::set_log_level" ], "rust_tests": [ "gateway-rs/src/hot_reload.rs::tests::rejected_reload_retains_last_valid_runtime_settings", "gateway-rs/src/hot_reload.rs::tests::flattens_json_configuration_like_the_python_manager", - "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests" + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests", + "gateway-rs/src/hot_reload.rs::tests::log_level_changes_are_applied_without_erroring_the_reload", + "gateway-rs/src/observability/logging.rs::tests::dynamic_log_level_reload_takes_effect_without_a_restart" ], "source": { "kind": "method", "line": 66, "path": "backend-services/utils/hot_reload_config.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/hot_reload_config.py::method:HotReloadConfig._load_from_env", - "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. Python's generic in-process set/callback API is not used outside this module; dynamic LOG_LEVEL application and most advertised keys still require restart in Rust and are reported as such by the API.", + "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. LOG_LEVEL now applies dynamically without a restart, via a reload::Handle on the live tracing subscriber, matching Python's registered set-level callback -- the one dynamic-apply example the pinned module itself documents.", + "rationale": "The other 21 reloadable keys remain inspection-only (dumped by the config-reload endpoint but not wired to a live effect) beyond the already-live gateway timeout/retry settings. Python's own module docstring only demonstrates a live-apply callback for LOG_LEVEL; wiring the remainder would mean threading a live-config read into each of several independent subsystems (rate limiting, caching, circuit breaking, metrics) for keys whose own pinned module never demonstrates an observable runtime effect beyond being read at startup.", "rust_symbols": [ "gateway-rs/src/hot_reload.rs::HotReloadConfig", "gateway-rs/src/main.rs::spawn_sighup_reload", - "gateway-rs/src/routes/platform.rs::platform_dispatch" + "gateway-rs/src/routes/platform.rs::platform_dispatch", + "gateway-rs/src/observability/logging.rs::set_log_level" ], "rust_tests": [ "gateway-rs/src/hot_reload.rs::tests::rejected_reload_retains_last_valid_runtime_settings", "gateway-rs/src/hot_reload.rs::tests::flattens_json_configuration_like_the_python_manager", - "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests" + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests", + "gateway-rs/src/hot_reload.rs::tests::log_level_changes_are_applied_without_erroring_the_reload", + "gateway-rs/src/observability/logging.rs::tests::dynamic_log_level_reload_takes_effect_without_a_restart" ], "source": { "kind": "method", "line": 80, "path": "backend-services/utils/hot_reload_config.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/hot_reload_config.py::method:HotReloadConfig._flatten_dict", - "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. Python's generic in-process set/callback API is not used outside this module; dynamic LOG_LEVEL application and most advertised keys still require restart in Rust and are reported as such by the API.", + "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. LOG_LEVEL now applies dynamically without a restart, via a reload::Handle on the live tracing subscriber, matching Python's registered set-level callback -- the one dynamic-apply example the pinned module itself documents.", + "rationale": "The other 21 reloadable keys remain inspection-only (dumped by the config-reload endpoint but not wired to a live effect) beyond the already-live gateway timeout/retry settings. Python's own module docstring only demonstrates a live-apply callback for LOG_LEVEL; wiring the remainder would mean threading a live-config read into each of several independent subsystems (rate limiting, caching, circuit breaking, metrics) for keys whose own pinned module never demonstrates an observable runtime effect beyond being read at startup.", "rust_symbols": [ "gateway-rs/src/hot_reload.rs::HotReloadConfig", "gateway-rs/src/main.rs::spawn_sighup_reload", - "gateway-rs/src/routes/platform.rs::platform_dispatch" + "gateway-rs/src/routes/platform.rs::platform_dispatch", + "gateway-rs/src/observability/logging.rs::set_log_level" ], "rust_tests": [ "gateway-rs/src/hot_reload.rs::tests::rejected_reload_retains_last_valid_runtime_settings", "gateway-rs/src/hot_reload.rs::tests::flattens_json_configuration_like_the_python_manager", - "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests" + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests", + "gateway-rs/src/hot_reload.rs::tests::log_level_changes_are_applied_without_erroring_the_reload", + "gateway-rs/src/observability/logging.rs::tests::dynamic_log_level_reload_takes_effect_without_a_restart" ], "source": { "kind": "method", "line": 112, "path": "backend-services/utils/hot_reload_config.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/hot_reload_config.py::method:HotReloadConfig._parse_value", - "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. Python's generic in-process set/callback API is not used outside this module; dynamic LOG_LEVEL application and most advertised keys still require restart in Rust and are reported as such by the API.", + "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. LOG_LEVEL now applies dynamically without a restart, via a reload::Handle on the live tracing subscriber, matching Python's registered set-level callback -- the one dynamic-apply example the pinned module itself documents.", + "rationale": "The other 21 reloadable keys remain inspection-only (dumped by the config-reload endpoint but not wired to a live effect) beyond the already-live gateway timeout/retry settings. Python's own module docstring only demonstrates a live-apply callback for LOG_LEVEL; wiring the remainder would mean threading a live-config read into each of several independent subsystems (rate limiting, caching, circuit breaking, metrics) for keys whose own pinned module never demonstrates an observable runtime effect beyond being read at startup.", "rust_symbols": [ "gateway-rs/src/hot_reload.rs::HotReloadConfig", "gateway-rs/src/main.rs::spawn_sighup_reload", - "gateway-rs/src/routes/platform.rs::platform_dispatch" + "gateway-rs/src/routes/platform.rs::platform_dispatch", + "gateway-rs/src/observability/logging.rs::set_log_level" ], "rust_tests": [ "gateway-rs/src/hot_reload.rs::tests::rejected_reload_retains_last_valid_runtime_settings", "gateway-rs/src/hot_reload.rs::tests::flattens_json_configuration_like_the_python_manager", - "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests" + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests", + "gateway-rs/src/hot_reload.rs::tests::log_level_changes_are_applied_without_erroring_the_reload", + "gateway-rs/src/observability/logging.rs::tests::dynamic_log_level_reload_takes_effect_without_a_restart" ], "source": { "kind": "method", "line": 123, "path": "backend-services/utils/hot_reload_config.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/hot_reload_config.py::method:HotReloadConfig.get", - "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. Python's generic in-process set/callback API is not used outside this module; dynamic LOG_LEVEL application and most advertised keys still require restart in Rust and are reported as such by the API.", + "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. LOG_LEVEL now applies dynamically without a restart, via a reload::Handle on the live tracing subscriber, matching Python's registered set-level callback -- the one dynamic-apply example the pinned module itself documents.", + "rationale": "The other 21 reloadable keys remain inspection-only (dumped by the config-reload endpoint but not wired to a live effect) beyond the already-live gateway timeout/retry settings. Python's own module docstring only demonstrates a live-apply callback for LOG_LEVEL; wiring the remainder would mean threading a live-config read into each of several independent subsystems (rate limiting, caching, circuit breaking, metrics) for keys whose own pinned module never demonstrates an observable runtime effect beyond being read at startup.", "rust_symbols": [ "gateway-rs/src/hot_reload.rs::HotReloadConfig", "gateway-rs/src/main.rs::spawn_sighup_reload", - "gateway-rs/src/routes/platform.rs::platform_dispatch" + "gateway-rs/src/routes/platform.rs::platform_dispatch", + "gateway-rs/src/observability/logging.rs::set_log_level" ], "rust_tests": [ "gateway-rs/src/hot_reload.rs::tests::rejected_reload_retains_last_valid_runtime_settings", "gateway-rs/src/hot_reload.rs::tests::flattens_json_configuration_like_the_python_manager", - "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests" + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests", + "gateway-rs/src/hot_reload.rs::tests::log_level_changes_are_applied_without_erroring_the_reload", + "gateway-rs/src/observability/logging.rs::tests::dynamic_log_level_reload_takes_effect_without_a_restart" ], "source": { "kind": "method", "line": 142, "path": "backend-services/utils/hot_reload_config.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/hot_reload_config.py::method:HotReloadConfig.get_int", - "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. Python's generic in-process set/callback API is not used outside this module; dynamic LOG_LEVEL application and most advertised keys still require restart in Rust and are reported as such by the API.", + "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. LOG_LEVEL now applies dynamically without a restart, via a reload::Handle on the live tracing subscriber, matching Python's registered set-level callback -- the one dynamic-apply example the pinned module itself documents.", + "rationale": "The other 21 reloadable keys remain inspection-only (dumped by the config-reload endpoint but not wired to a live effect) beyond the already-live gateway timeout/retry settings. Python's own module docstring only demonstrates a live-apply callback for LOG_LEVEL; wiring the remainder would mean threading a live-config read into each of several independent subsystems (rate limiting, caching, circuit breaking, metrics) for keys whose own pinned module never demonstrates an observable runtime effect beyond being read at startup.", "rust_symbols": [ "gateway-rs/src/hot_reload.rs::HotReloadConfig", "gateway-rs/src/main.rs::spawn_sighup_reload", - "gateway-rs/src/routes/platform.rs::platform_dispatch" + "gateway-rs/src/routes/platform.rs::platform_dispatch", + "gateway-rs/src/observability/logging.rs::set_log_level" ], "rust_tests": [ "gateway-rs/src/hot_reload.rs::tests::rejected_reload_retains_last_valid_runtime_settings", "gateway-rs/src/hot_reload.rs::tests::flattens_json_configuration_like_the_python_manager", - "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests" + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests", + "gateway-rs/src/hot_reload.rs::tests::log_level_changes_are_applied_without_erroring_the_reload", + "gateway-rs/src/observability/logging.rs::tests::dynamic_log_level_reload_takes_effect_without_a_restart" ], "source": { "kind": "method", "line": 158, "path": "backend-services/utils/hot_reload_config.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/hot_reload_config.py::method:HotReloadConfig.get_float", - "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. Python's generic in-process set/callback API is not used outside this module; dynamic LOG_LEVEL application and most advertised keys still require restart in Rust and are reported as such by the API.", + "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. LOG_LEVEL now applies dynamically without a restart, via a reload::Handle on the live tracing subscriber, matching Python's registered set-level callback -- the one dynamic-apply example the pinned module itself documents.", + "rationale": "The other 21 reloadable keys remain inspection-only (dumped by the config-reload endpoint but not wired to a live effect) beyond the already-live gateway timeout/retry settings. Python's own module docstring only demonstrates a live-apply callback for LOG_LEVEL; wiring the remainder would mean threading a live-config read into each of several independent subsystems (rate limiting, caching, circuit breaking, metrics) for keys whose own pinned module never demonstrates an observable runtime effect beyond being read at startup.", "rust_symbols": [ "gateway-rs/src/hot_reload.rs::HotReloadConfig", "gateway-rs/src/main.rs::spawn_sighup_reload", - "gateway-rs/src/routes/platform.rs::platform_dispatch" + "gateway-rs/src/routes/platform.rs::platform_dispatch", + "gateway-rs/src/observability/logging.rs::set_log_level" ], "rust_tests": [ "gateway-rs/src/hot_reload.rs::tests::rejected_reload_retains_last_valid_runtime_settings", "gateway-rs/src/hot_reload.rs::tests::flattens_json_configuration_like_the_python_manager", - "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests" + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests", + "gateway-rs/src/hot_reload.rs::tests::log_level_changes_are_applied_without_erroring_the_reload", + "gateway-rs/src/observability/logging.rs::tests::dynamic_log_level_reload_takes_effect_without_a_restart" ], "source": { "kind": "method", "line": 167, "path": "backend-services/utils/hot_reload_config.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/hot_reload_config.py::method:HotReloadConfig.get_bool", - "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. Python's generic in-process set/callback API is not used outside this module; dynamic LOG_LEVEL application and most advertised keys still require restart in Rust and are reported as such by the API.", + "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. LOG_LEVEL now applies dynamically without a restart, via a reload::Handle on the live tracing subscriber, matching Python's registered set-level callback -- the one dynamic-apply example the pinned module itself documents.", + "rationale": "The other 21 reloadable keys remain inspection-only (dumped by the config-reload endpoint but not wired to a live effect) beyond the already-live gateway timeout/retry settings. Python's own module docstring only demonstrates a live-apply callback for LOG_LEVEL; wiring the remainder would mean threading a live-config read into each of several independent subsystems (rate limiting, caching, circuit breaking, metrics) for keys whose own pinned module never demonstrates an observable runtime effect beyond being read at startup.", "rust_symbols": [ "gateway-rs/src/hot_reload.rs::HotReloadConfig", "gateway-rs/src/main.rs::spawn_sighup_reload", - "gateway-rs/src/routes/platform.rs::platform_dispatch" + "gateway-rs/src/routes/platform.rs::platform_dispatch", + "gateway-rs/src/observability/logging.rs::set_log_level" ], "rust_tests": [ "gateway-rs/src/hot_reload.rs::tests::rejected_reload_retains_last_valid_runtime_settings", "gateway-rs/src/hot_reload.rs::tests::flattens_json_configuration_like_the_python_manager", - "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests" + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests", + "gateway-rs/src/hot_reload.rs::tests::log_level_changes_are_applied_without_erroring_the_reload", + "gateway-rs/src/observability/logging.rs::tests::dynamic_log_level_reload_takes_effect_without_a_restart" ], "source": { "kind": "method", "line": 176, "path": "backend-services/utils/hot_reload_config.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/hot_reload_config.py::method:HotReloadConfig.set", - "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. Python's generic in-process set/callback API is not used outside this module; dynamic LOG_LEVEL application and most advertised keys still require restart in Rust and are reported as such by the API.", + "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. LOG_LEVEL now applies dynamically without a restart, via a reload::Handle on the live tracing subscriber, matching Python's registered set-level callback -- the one dynamic-apply example the pinned module itself documents.", + "rationale": "The other 21 reloadable keys remain inspection-only (dumped by the config-reload endpoint but not wired to a live effect) beyond the already-live gateway timeout/retry settings. Python's own module docstring only demonstrates a live-apply callback for LOG_LEVEL; wiring the remainder would mean threading a live-config read into each of several independent subsystems (rate limiting, caching, circuit breaking, metrics) for keys whose own pinned module never demonstrates an observable runtime effect beyond being read at startup.", "rust_symbols": [ "gateway-rs/src/hot_reload.rs::HotReloadConfig", "gateway-rs/src/main.rs::spawn_sighup_reload", - "gateway-rs/src/routes/platform.rs::platform_dispatch" + "gateway-rs/src/routes/platform.rs::platform_dispatch", + "gateway-rs/src/observability/logging.rs::set_log_level" ], "rust_tests": [ "gateway-rs/src/hot_reload.rs::tests::rejected_reload_retains_last_valid_runtime_settings", "gateway-rs/src/hot_reload.rs::tests::flattens_json_configuration_like_the_python_manager", - "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests" + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests", + "gateway-rs/src/hot_reload.rs::tests::log_level_changes_are_applied_without_erroring_the_reload", + "gateway-rs/src/observability/logging.rs::tests::dynamic_log_level_reload_takes_effect_without_a_restart" ], "source": { "kind": "method", "line": 185, "path": "backend-services/utils/hot_reload_config.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/hot_reload_config.py::method:HotReloadConfig.register_callback", - "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. Python's generic in-process set/callback API is not used outside this module; dynamic LOG_LEVEL application and most advertised keys still require restart in Rust and are reported as such by the API.", + "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. LOG_LEVEL now applies dynamically without a restart, via a reload::Handle on the live tracing subscriber, matching Python's registered set-level callback -- the one dynamic-apply example the pinned module itself documents.", + "rationale": "The other 21 reloadable keys remain inspection-only (dumped by the config-reload endpoint but not wired to a live effect) beyond the already-live gateway timeout/retry settings. Python's own module docstring only demonstrates a live-apply callback for LOG_LEVEL; wiring the remainder would mean threading a live-config read into each of several independent subsystems (rate limiting, caching, circuit breaking, metrics) for keys whose own pinned module never demonstrates an observable runtime effect beyond being read at startup.", "rust_symbols": [ "gateway-rs/src/hot_reload.rs::HotReloadConfig", "gateway-rs/src/main.rs::spawn_sighup_reload", - "gateway-rs/src/routes/platform.rs::platform_dispatch" + "gateway-rs/src/routes/platform.rs::platform_dispatch", + "gateway-rs/src/observability/logging.rs::set_log_level" ], "rust_tests": [ "gateway-rs/src/hot_reload.rs::tests::rejected_reload_retains_last_valid_runtime_settings", "gateway-rs/src/hot_reload.rs::tests::flattens_json_configuration_like_the_python_manager", - "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests" + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests", + "gateway-rs/src/hot_reload.rs::tests::log_level_changes_are_applied_without_erroring_the_reload", + "gateway-rs/src/observability/logging.rs::tests::dynamic_log_level_reload_takes_effect_without_a_restart" ], "source": { "kind": "method", "line": 198, "path": "backend-services/utils/hot_reload_config.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/hot_reload_config.py::method:HotReloadConfig._trigger_callbacks", - "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. Python's generic in-process set/callback API is not used outside this module; dynamic LOG_LEVEL application and most advertised keys still require restart in Rust and are reported as such by the API.", + "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. LOG_LEVEL now applies dynamically without a restart, via a reload::Handle on the live tracing subscriber, matching Python's registered set-level callback -- the one dynamic-apply example the pinned module itself documents.", + "rationale": "The other 21 reloadable keys remain inspection-only (dumped by the config-reload endpoint but not wired to a live effect) beyond the already-live gateway timeout/retry settings. Python's own module docstring only demonstrates a live-apply callback for LOG_LEVEL; wiring the remainder would mean threading a live-config read into each of several independent subsystems (rate limiting, caching, circuit breaking, metrics) for keys whose own pinned module never demonstrates an observable runtime effect beyond being read at startup.", "rust_symbols": [ "gateway-rs/src/hot_reload.rs::HotReloadConfig", "gateway-rs/src/main.rs::spawn_sighup_reload", - "gateway-rs/src/routes/platform.rs::platform_dispatch" + "gateway-rs/src/routes/platform.rs::platform_dispatch", + "gateway-rs/src/observability/logging.rs::set_log_level" ], "rust_tests": [ "gateway-rs/src/hot_reload.rs::tests::rejected_reload_retains_last_valid_runtime_settings", "gateway-rs/src/hot_reload.rs::tests::flattens_json_configuration_like_the_python_manager", - "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests" + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests", + "gateway-rs/src/hot_reload.rs::tests::log_level_changes_are_applied_without_erroring_the_reload", + "gateway-rs/src/observability/logging.rs::tests::dynamic_log_level_reload_takes_effect_without_a_restart" ], "source": { "kind": "method", "line": 210, "path": "backend-services/utils/hot_reload_config.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/hot_reload_config.py::method:HotReloadConfig.reload", - "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. Python's generic in-process set/callback API is not used outside this module; dynamic LOG_LEVEL application and most advertised keys still require restart in Rust and are reported as such by the API.", + "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. LOG_LEVEL now applies dynamically without a restart, via a reload::Handle on the live tracing subscriber, matching Python's registered set-level callback -- the one dynamic-apply example the pinned module itself documents.", + "rationale": "The other 21 reloadable keys remain inspection-only (dumped by the config-reload endpoint but not wired to a live effect) beyond the already-live gateway timeout/retry settings. Python's own module docstring only demonstrates a live-apply callback for LOG_LEVEL; wiring the remainder would mean threading a live-config read into each of several independent subsystems (rate limiting, caching, circuit breaking, metrics) for keys whose own pinned module never demonstrates an observable runtime effect beyond being read at startup.", "rust_symbols": [ "gateway-rs/src/hot_reload.rs::HotReloadConfig", "gateway-rs/src/main.rs::spawn_sighup_reload", - "gateway-rs/src/routes/platform.rs::platform_dispatch" + "gateway-rs/src/routes/platform.rs::platform_dispatch", + "gateway-rs/src/observability/logging.rs::set_log_level" ], "rust_tests": [ "gateway-rs/src/hot_reload.rs::tests::rejected_reload_retains_last_valid_runtime_settings", "gateway-rs/src/hot_reload.rs::tests::flattens_json_configuration_like_the_python_manager", - "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests" + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests", + "gateway-rs/src/hot_reload.rs::tests::log_level_changes_are_applied_without_erroring_the_reload", + "gateway-rs/src/observability/logging.rs::tests::dynamic_log_level_reload_takes_effect_without_a_restart" ], "source": { "kind": "method", "line": 219, "path": "backend-services/utils/hot_reload_config.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/hot_reload_config.py::method:HotReloadConfig.dump", - "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. Python's generic in-process set/callback API is not used outside this module; dynamic LOG_LEVEL application and most advertised keys still require restart in Rust and are reported as such by the API.", + "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. LOG_LEVEL now applies dynamically without a restart, via a reload::Handle on the live tracing subscriber, matching Python's registered set-level callback -- the one dynamic-apply example the pinned module itself documents.", + "rationale": "The other 21 reloadable keys remain inspection-only (dumped by the config-reload endpoint but not wired to a live effect) beyond the already-live gateway timeout/retry settings. Python's own module docstring only demonstrates a live-apply callback for LOG_LEVEL; wiring the remainder would mean threading a live-config read into each of several independent subsystems (rate limiting, caching, circuit breaking, metrics) for keys whose own pinned module never demonstrates an observable runtime effect beyond being read at startup.", "rust_symbols": [ "gateway-rs/src/hot_reload.rs::HotReloadConfig", "gateway-rs/src/main.rs::spawn_sighup_reload", - "gateway-rs/src/routes/platform.rs::platform_dispatch" + "gateway-rs/src/routes/platform.rs::platform_dispatch", + "gateway-rs/src/observability/logging.rs::set_log_level" ], "rust_tests": [ "gateway-rs/src/hot_reload.rs::tests::rejected_reload_retains_last_valid_runtime_settings", "gateway-rs/src/hot_reload.rs::tests::flattens_json_configuration_like_the_python_manager", - "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests" + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests", + "gateway-rs/src/hot_reload.rs::tests::log_level_changes_are_applied_without_erroring_the_reload", + "gateway-rs/src/observability/logging.rs::tests::dynamic_log_level_reload_takes_effect_without_a_restart" ], "source": { "kind": "method", "line": 248, "path": "backend-services/utils/hot_reload_config.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/hot_reload_config.py::function:get_timeout_config", - "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. Python's generic in-process set/callback API is not used outside this module; dynamic LOG_LEVEL application and most advertised keys still require restart in Rust and are reported as such by the API.", + "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. LOG_LEVEL now applies dynamically without a restart, via a reload::Handle on the live tracing subscriber, matching Python's registered set-level callback -- the one dynamic-apply example the pinned module itself documents.", + "rationale": "The other 21 reloadable keys remain inspection-only (dumped by the config-reload endpoint but not wired to a live effect) beyond the already-live gateway timeout/retry settings. Python's own module docstring only demonstrates a live-apply callback for LOG_LEVEL; wiring the remainder would mean threading a live-config read into each of several independent subsystems (rate limiting, caching, circuit breaking, metrics) for keys whose own pinned module never demonstrates an observable runtime effect beyond being read at startup.", "rust_symbols": [ "gateway-rs/src/hot_reload.rs::HotReloadConfig", "gateway-rs/src/main.rs::spawn_sighup_reload", - "gateway-rs/src/routes/platform.rs::platform_dispatch" + "gateway-rs/src/routes/platform.rs::platform_dispatch", + "gateway-rs/src/observability/logging.rs::set_log_level" ], "rust_tests": [ "gateway-rs/src/hot_reload.rs::tests::rejected_reload_retains_last_valid_runtime_settings", "gateway-rs/src/hot_reload.rs::tests::flattens_json_configuration_like_the_python_manager", - "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests" + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests", + "gateway-rs/src/hot_reload.rs::tests::log_level_changes_are_applied_without_erroring_the_reload", + "gateway-rs/src/observability/logging.rs::tests::dynamic_log_level_reload_takes_effect_without_a_restart" ], "source": { "kind": "function", "line": 263, "path": "backend-services/utils/hot_reload_config.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/hot_reload_config.py::function:get_rate_limit_config", - "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. Python's generic in-process set/callback API is not used outside this module; dynamic LOG_LEVEL application and most advertised keys still require restart in Rust and are reported as such by the API.", + "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. LOG_LEVEL now applies dynamically without a restart, via a reload::Handle on the live tracing subscriber, matching Python's registered set-level callback -- the one dynamic-apply example the pinned module itself documents.", + "rationale": "The other 21 reloadable keys remain inspection-only (dumped by the config-reload endpoint but not wired to a live effect) beyond the already-live gateway timeout/retry settings. Python's own module docstring only demonstrates a live-apply callback for LOG_LEVEL; wiring the remainder would mean threading a live-config read into each of several independent subsystems (rate limiting, caching, circuit breaking, metrics) for keys whose own pinned module never demonstrates an observable runtime effect beyond being read at startup.", "rust_symbols": [ "gateway-rs/src/hot_reload.rs::HotReloadConfig", "gateway-rs/src/main.rs::spawn_sighup_reload", - "gateway-rs/src/routes/platform.rs::platform_dispatch" + "gateway-rs/src/routes/platform.rs::platform_dispatch", + "gateway-rs/src/observability/logging.rs::set_log_level" ], "rust_tests": [ "gateway-rs/src/hot_reload.rs::tests::rejected_reload_retains_last_valid_runtime_settings", "gateway-rs/src/hot_reload.rs::tests::flattens_json_configuration_like_the_python_manager", - "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests" + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests", + "gateway-rs/src/hot_reload.rs::tests::log_level_changes_are_applied_without_erroring_the_reload", + "gateway-rs/src/observability/logging.rs::tests::dynamic_log_level_reload_takes_effect_without_a_restart" ], "source": { "kind": "function", "line": 272, "path": "backend-services/utils/hot_reload_config.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/hot_reload_config.py::function:get_cache_config", - "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. Python's generic in-process set/callback API is not used outside this module; dynamic LOG_LEVEL application and most advertised keys still require restart in Rust and are reported as such by the API.", + "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. LOG_LEVEL now applies dynamically without a restart, via a reload::Handle on the live tracing subscriber, matching Python's registered set-level callback -- the one dynamic-apply example the pinned module itself documents.", + "rationale": "The other 21 reloadable keys remain inspection-only (dumped by the config-reload endpoint but not wired to a live effect) beyond the already-live gateway timeout/retry settings. Python's own module docstring only demonstrates a live-apply callback for LOG_LEVEL; wiring the remainder would mean threading a live-config read into each of several independent subsystems (rate limiting, caching, circuit breaking, metrics) for keys whose own pinned module never demonstrates an observable runtime effect beyond being read at startup.", "rust_symbols": [ "gateway-rs/src/hot_reload.rs::HotReloadConfig", "gateway-rs/src/main.rs::spawn_sighup_reload", - "gateway-rs/src/routes/platform.rs::platform_dispatch" + "gateway-rs/src/routes/platform.rs::platform_dispatch", + "gateway-rs/src/observability/logging.rs::set_log_level" ], "rust_tests": [ "gateway-rs/src/hot_reload.rs::tests::rejected_reload_retains_last_valid_runtime_settings", "gateway-rs/src/hot_reload.rs::tests::flattens_json_configuration_like_the_python_manager", - "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests" + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests", + "gateway-rs/src/hot_reload.rs::tests::log_level_changes_are_applied_without_erroring_the_reload", + "gateway-rs/src/observability/logging.rs::tests::dynamic_log_level_reload_takes_effect_without_a_restart" ], "source": { "kind": "function", "line": 281, "path": "backend-services/utils/hot_reload_config.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/hot_reload_config.py::function:get_circuit_breaker_config", - "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. Python's generic in-process set/callback API is not used outside this module; dynamic LOG_LEVEL application and most advertised keys still require restart in Rust and are reported as such by the API.", + "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. LOG_LEVEL now applies dynamically without a restart, via a reload::Handle on the live tracing subscriber, matching Python's registered set-level callback -- the one dynamic-apply example the pinned module itself documents.", + "rationale": "The other 21 reloadable keys remain inspection-only (dumped by the config-reload endpoint but not wired to a live effect) beyond the already-live gateway timeout/retry settings. Python's own module docstring only demonstrates a live-apply callback for LOG_LEVEL; wiring the remainder would mean threading a live-config read into each of several independent subsystems (rate limiting, caching, circuit breaking, metrics) for keys whose own pinned module never demonstrates an observable runtime effect beyond being read at startup.", "rust_symbols": [ "gateway-rs/src/hot_reload.rs::HotReloadConfig", "gateway-rs/src/main.rs::spawn_sighup_reload", - "gateway-rs/src/routes/platform.rs::platform_dispatch" + "gateway-rs/src/routes/platform.rs::platform_dispatch", + "gateway-rs/src/observability/logging.rs::set_log_level" ], "rust_tests": [ "gateway-rs/src/hot_reload.rs::tests::rejected_reload_retains_last_valid_runtime_settings", "gateway-rs/src/hot_reload.rs::tests::flattens_json_configuration_like_the_python_manager", - "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests" + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests", + "gateway-rs/src/hot_reload.rs::tests::log_level_changes_are_applied_without_erroring_the_reload", + "gateway-rs/src/observability/logging.rs::tests::dynamic_log_level_reload_takes_effect_without_a_restart" ], "source": { "kind": "function", "line": 289, "path": "backend-services/utils/hot_reload_config.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/hot_reload_config.py::function:get_retry_config", - "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. Python's generic in-process set/callback API is not used outside this module; dynamic LOG_LEVEL application and most advertised keys still require restart in Rust and are reported as such by the API.", + "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. LOG_LEVEL now applies dynamically without a restart, via a reload::Handle on the live tracing subscriber, matching Python's registered set-level callback -- the one dynamic-apply example the pinned module itself documents.", + "rationale": "The other 21 reloadable keys remain inspection-only (dumped by the config-reload endpoint but not wired to a live effect) beyond the already-live gateway timeout/retry settings. Python's own module docstring only demonstrates a live-apply callback for LOG_LEVEL; wiring the remainder would mean threading a live-config read into each of several independent subsystems (rate limiting, caching, circuit breaking, metrics) for keys whose own pinned module never demonstrates an observable runtime effect beyond being read at startup.", "rust_symbols": [ "gateway-rs/src/hot_reload.rs::HotReloadConfig", "gateway-rs/src/main.rs::spawn_sighup_reload", - "gateway-rs/src/routes/platform.rs::platform_dispatch" + "gateway-rs/src/routes/platform.rs::platform_dispatch", + "gateway-rs/src/observability/logging.rs::set_log_level" ], "rust_tests": [ "gateway-rs/src/hot_reload.rs::tests::rejected_reload_retains_last_valid_runtime_settings", "gateway-rs/src/hot_reload.rs::tests::flattens_json_configuration_like_the_python_manager", - "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests" + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests", + "gateway-rs/src/hot_reload.rs::tests::log_level_changes_are_applied_without_erroring_the_reload", + "gateway-rs/src/observability/logging.rs::tests::dynamic_log_level_reload_takes_effect_without_a_restart" ], "source": { "kind": "function", "line": 298, "path": "backend-services/utils/hot_reload_config.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/http_client.py::module:http_client", - "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics now count each timed-out attempt as Python does. Reqwest does not expose separate Python httpx write/pool timeout controls, and network exception classes map through native client errors.", + "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics count each timed-out attempt as Python does.", + "rationale": "The reqwest client does not expose separate write/pool timeout knobs the way Python's httpx does; connect and read timeouts (the two that gate the pinned retry/circuit-breaker contracts) are fully implemented, and network exception classification maps through typed native client errors to the same retry decisions.", "rust_symbols": [ "gateway-rs/src/routes/rest.rs::execute_rest", "gateway-rs/src/routes/rest.rs::retry_backoff", @@ -42836,13 +45343,14 @@ "line": 1, "path": "backend-services/utils/http_client.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/http_client.py::class:CircuitOpenError", - "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics now count each timed-out attempt as Python does. Reqwest does not expose separate Python httpx write/pool timeout controls, and network exception classes map through native client errors.", + "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics count each timed-out attempt as Python does.", + "rationale": "The reqwest client does not expose separate write/pool timeout knobs the way Python's httpx does; connect and read timeouts (the two that gate the pinned retry/circuit-breaker contracts) are fully implemented, and network exception classification maps through typed native client errors to the same retry decisions.", "rust_symbols": [ "gateway-rs/src/routes/rest.rs::execute_rest", "gateway-rs/src/routes/rest.rs::retry_backoff", @@ -42859,7 +45367,7 @@ "line": 33, "path": "backend-services/utils/http_client.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -42867,7 +45375,8 @@ ], "domain": "utils", "id": "backend-services/utils/http_client.py::class:_BreakerState", - "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics now count each timed-out attempt as Python does. Reqwest does not expose separate Python httpx write/pool timeout controls, and network exception classes map through native client errors.", + "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics count each timed-out attempt as Python does.", + "rationale": "The reqwest client does not expose separate write/pool timeout knobs the way Python's httpx does; connect and read timeouts (the two that gate the pinned retry/circuit-breaker contracts) are fully implemented, and network exception classification maps through typed native client errors to the same retry decisions.", "rust_symbols": [ "gateway-rs/src/routes/rest.rs::execute_rest", "gateway-rs/src/routes/rest.rs::retry_backoff", @@ -42884,13 +45393,14 @@ "line": 38, "path": "backend-services/utils/http_client.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/http_client.py::field:_BreakerState.failures", - "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics now count each timed-out attempt as Python does. Reqwest does not expose separate Python httpx write/pool timeout controls, and network exception classes map through native client errors.", + "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics count each timed-out attempt as Python does.", + "rationale": "The reqwest client does not expose separate write/pool timeout knobs the way Python's httpx does; connect and read timeouts (the two that gate the pinned retry/circuit-breaker contracts) are fully implemented, and network exception classification maps through typed native client errors to the same retry decisions.", "rust_symbols": [ "gateway-rs/src/routes/rest.rs::execute_rest", "gateway-rs/src/routes/rest.rs::retry_backoff", @@ -42907,13 +45417,14 @@ "line": 39, "path": "backend-services/utils/http_client.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/http_client.py::field:_BreakerState.opened_at", - "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics now count each timed-out attempt as Python does. Reqwest does not expose separate Python httpx write/pool timeout controls, and network exception classes map through native client errors.", + "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics count each timed-out attempt as Python does.", + "rationale": "The reqwest client does not expose separate write/pool timeout knobs the way Python's httpx does; connect and read timeouts (the two that gate the pinned retry/circuit-breaker contracts) are fully implemented, and network exception classification maps through typed native client errors to the same retry decisions.", "rust_symbols": [ "gateway-rs/src/routes/rest.rs::execute_rest", "gateway-rs/src/routes/rest.rs::retry_backoff", @@ -42930,13 +45441,14 @@ "line": 40, "path": "backend-services/utils/http_client.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/http_client.py::field:_BreakerState.state", - "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics now count each timed-out attempt as Python does. Reqwest does not expose separate Python httpx write/pool timeout controls, and network exception classes map through native client errors.", + "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics count each timed-out attempt as Python does.", + "rationale": "The reqwest client does not expose separate write/pool timeout knobs the way Python's httpx does; connect and read timeouts (the two that gate the pinned retry/circuit-breaker contracts) are fully implemented, and network exception classification maps through typed native client errors to the same retry decisions.", "rust_symbols": [ "gateway-rs/src/routes/rest.rs::execute_rest", "gateway-rs/src/routes/rest.rs::retry_backoff", @@ -42953,13 +45465,14 @@ "line": 41, "path": "backend-services/utils/http_client.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/http_client.py::class:_CircuitManager", - "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics now count each timed-out attempt as Python does. Reqwest does not expose separate Python httpx write/pool timeout controls, and network exception classes map through native client errors.", + "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics count each timed-out attempt as Python does.", + "rationale": "The reqwest client does not expose separate write/pool timeout knobs the way Python's httpx does; connect and read timeouts (the two that gate the pinned retry/circuit-breaker contracts) are fully implemented, and network exception classification maps through typed native client errors to the same retry decisions.", "rust_symbols": [ "gateway-rs/src/routes/rest.rs::execute_rest", "gateway-rs/src/routes/rest.rs::retry_backoff", @@ -42976,13 +45489,14 @@ "line": 44, "path": "backend-services/utils/http_client.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/http_client.py::method:_CircuitManager.__init__", - "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics now count each timed-out attempt as Python does. Reqwest does not expose separate Python httpx write/pool timeout controls, and network exception classes map through native client errors.", + "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics count each timed-out attempt as Python does.", + "rationale": "The reqwest client does not expose separate write/pool timeout knobs the way Python's httpx does; connect and read timeouts (the two that gate the pinned retry/circuit-breaker contracts) are fully implemented, and network exception classification maps through typed native client errors to the same retry decisions.", "rust_symbols": [ "gateway-rs/src/routes/rest.rs::execute_rest", "gateway-rs/src/routes/rest.rs::retry_backoff", @@ -42999,13 +45513,14 @@ "line": 45, "path": "backend-services/utils/http_client.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/http_client.py::method:_CircuitManager.reset", - "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics now count each timed-out attempt as Python does. Reqwest does not expose separate Python httpx write/pool timeout controls, and network exception classes map through native client errors.", + "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics count each timed-out attempt as Python does.", + "rationale": "The reqwest client does not expose separate write/pool timeout knobs the way Python's httpx does; connect and read timeouts (the two that gate the pinned retry/circuit-breaker contracts) are fully implemented, and network exception classification maps through typed native client errors to the same retry decisions.", "rust_symbols": [ "gateway-rs/src/routes/rest.rs::execute_rest", "gateway-rs/src/routes/rest.rs::retry_backoff", @@ -43022,13 +45537,14 @@ "line": 48, "path": "backend-services/utils/http_client.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/http_client.py::method:_CircuitManager.get", - "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics now count each timed-out attempt as Python does. Reqwest does not expose separate Python httpx write/pool timeout controls, and network exception classes map through native client errors.", + "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics count each timed-out attempt as Python does.", + "rationale": "The reqwest client does not expose separate write/pool timeout knobs the way Python's httpx does; connect and read timeouts (the two that gate the pinned retry/circuit-breaker contracts) are fully implemented, and network exception classification maps through typed native client errors to the same retry decisions.", "rust_symbols": [ "gateway-rs/src/routes/rest.rs::execute_rest", "gateway-rs/src/routes/rest.rs::retry_backoff", @@ -43045,13 +45561,14 @@ "line": 55, "path": "backend-services/utils/http_client.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/http_client.py::method:_CircuitManager.now", - "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics now count each timed-out attempt as Python does. Reqwest does not expose separate Python httpx write/pool timeout controls, and network exception classes map through native client errors.", + "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics count each timed-out attempt as Python does.", + "rationale": "The reqwest client does not expose separate write/pool timeout knobs the way Python's httpx does; connect and read timeouts (the two that gate the pinned retry/circuit-breaker contracts) are fully implemented, and network exception classification maps through typed native client errors to the same retry decisions.", "rust_symbols": [ "gateway-rs/src/routes/rest.rs::execute_rest", "gateway-rs/src/routes/rest.rs::retry_backoff", @@ -43068,13 +45585,14 @@ "line": 62, "path": "backend-services/utils/http_client.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/http_client.py::method:_CircuitManager.check", - "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics now count each timed-out attempt as Python does. Reqwest does not expose separate Python httpx write/pool timeout controls, and network exception classes map through native client errors.", + "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics count each timed-out attempt as Python does.", + "rationale": "The reqwest client does not expose separate write/pool timeout knobs the way Python's httpx does; connect and read timeouts (the two that gate the pinned retry/circuit-breaker contracts) are fully implemented, and network exception classification maps through typed native client errors to the same retry decisions.", "rust_symbols": [ "gateway-rs/src/routes/rest.rs::execute_rest", "gateway-rs/src/routes/rest.rs::retry_backoff", @@ -43091,13 +45609,14 @@ "line": 65, "path": "backend-services/utils/http_client.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/http_client.py::method:_CircuitManager.record_success", - "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics now count each timed-out attempt as Python does. Reqwest does not expose separate Python httpx write/pool timeout controls, and network exception classes map through native client errors.", + "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics count each timed-out attempt as Python does.", + "rationale": "The reqwest client does not expose separate write/pool timeout knobs the way Python's httpx does; connect and read timeouts (the two that gate the pinned retry/circuit-breaker contracts) are fully implemented, and network exception classification maps through typed native client errors to the same retry decisions.", "rust_symbols": [ "gateway-rs/src/routes/rest.rs::execute_rest", "gateway-rs/src/routes/rest.rs::retry_backoff", @@ -43114,13 +45633,14 @@ "line": 74, "path": "backend-services/utils/http_client.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/http_client.py::method:_CircuitManager.record_failure", - "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics now count each timed-out attempt as Python does. Reqwest does not expose separate Python httpx write/pool timeout controls, and network exception classes map through native client errors.", + "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics count each timed-out attempt as Python does.", + "rationale": "The reqwest client does not expose separate write/pool timeout knobs the way Python's httpx does; connect and read timeouts (the two that gate the pinned retry/circuit-breaker contracts) are fully implemented, and network exception classification maps through typed native client errors to the same retry decisions.", "rust_symbols": [ "gateway-rs/src/routes/rest.rs::execute_rest", "gateway-rs/src/routes/rest.rs::retry_backoff", @@ -43137,13 +45657,14 @@ "line": 79, "path": "backend-services/utils/http_client.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/http_client.py::function:_build_timeout", - "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics now count each timed-out attempt as Python does. Reqwest does not expose separate Python httpx write/pool timeout controls, and network exception classes map through native client errors.", + "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics count each timed-out attempt as Python does.", + "rationale": "The reqwest client does not expose separate write/pool timeout knobs the way Python's httpx does; connect and read timeouts (the two that gate the pinned retry/circuit-breaker contracts) are fully implemented, and network exception classification maps through typed native client errors to the same retry decisions.", "rust_symbols": [ "gateway-rs/src/routes/rest.rs::execute_rest", "gateway-rs/src/routes/rest.rs::retry_backoff", @@ -43160,13 +45681,14 @@ "line": 94, "path": "backend-services/utils/http_client.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/http_client.py::function:_build_timeout._f", - "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics now count each timed-out attempt as Python does. Reqwest does not expose separate Python httpx write/pool timeout controls, and network exception classes map through native client errors.", + "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics count each timed-out attempt as Python does.", + "rationale": "The reqwest client does not expose separate write/pool timeout knobs the way Python's httpx does; connect and read timeouts (the two that gate the pinned retry/circuit-breaker contracts) are fully implemented, and network exception classification maps through typed native client errors to the same retry decisions.", "rust_symbols": [ "gateway-rs/src/routes/rest.rs::execute_rest", "gateway-rs/src/routes/rest.rs::retry_backoff", @@ -43183,13 +45705,14 @@ "line": 96, "path": "backend-services/utils/http_client.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/http_client.py::function:_should_retry_status", - "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics now count each timed-out attempt as Python does. Reqwest does not expose separate Python httpx write/pool timeout controls, and network exception classes map through native client errors.", + "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics count each timed-out attempt as Python does.", + "rationale": "The reqwest client does not expose separate write/pool timeout knobs the way Python's httpx does; connect and read timeouts (the two that gate the pinned retry/circuit-breaker contracts) are fully implemented, and network exception classification maps through typed native client errors to the same retry decisions.", "rust_symbols": [ "gateway-rs/src/routes/rest.rs::execute_rest", "gateway-rs/src/routes/rest.rs::retry_backoff", @@ -43206,13 +45729,14 @@ "line": 111, "path": "backend-services/utils/http_client.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/http_client.py::function:_backoff_delay", - "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics now count each timed-out attempt as Python does. Reqwest does not expose separate Python httpx write/pool timeout controls, and network exception classes map through native client errors.", + "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics count each timed-out attempt as Python does.", + "rationale": "The reqwest client does not expose separate write/pool timeout knobs the way Python's httpx does; connect and read timeouts (the two that gate the pinned retry/circuit-breaker contracts) are fully implemented, and network exception classification maps through typed native client errors to the same retry decisions.", "rust_symbols": [ "gateway-rs/src/routes/rest.rs::execute_rest", "gateway-rs/src/routes/rest.rs::retry_backoff", @@ -43229,13 +45753,14 @@ "line": 115, "path": "backend-services/utils/http_client.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/http_client.py::async_function:request_with_resilience", - "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics now count each timed-out attempt as Python does. Reqwest does not expose separate Python httpx write/pool timeout controls, and network exception classes map through native client errors.", + "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics count each timed-out attempt as Python does.", + "rationale": "The reqwest client does not expose separate write/pool timeout knobs the way Python's httpx does; connect and read timeouts (the two that gate the pinned retry/circuit-breaker contracts) are fully implemented, and network exception classification maps through typed native client errors to the same retry decisions.", "rust_symbols": [ "gateway-rs/src/routes/rest.rs::execute_rest", "gateway-rs/src/routes/rest.rs::retry_backoff", @@ -43252,13 +45777,14 @@ "line": 122, "path": "backend-services/utils/http_client.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/ip_policy_util.py::module:ip_policy_util", - "notes": "Rust matches trusted-proxy resolution, XFF precedence, exact/CIDR/netmask matching, blacklist precedence, whitelist errors, Docker loopback addresses, and per-API trust overrides. Rust intentionally does not let a spoofable Host header alone trigger localhost bypass, and its typed audit/error plumbing differs from Python's broad fail-open catches.", + "notes": "Rust matches trusted-proxy resolution, XFF precedence, exact/CIDR/netmask matching, blacklist precedence, whitelist errors, Docker loopback addresses, and per-API trust overrides.", + "rationale": "Rust intentionally does not let a spoofable Host header alone trigger localhost bypass, a security-safe divergence from Python's broader fail-open catches; typed audit/error plumbing distinguishes failure modes explicitly rather than relying on Python's broad exception handler to fail open.", "rust_symbols": [ "gateway-rs/src/policy/ip.rs::effective_client_ip_for_settings", "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy" @@ -43273,13 +45799,14 @@ "line": 1, "path": "backend-services/utils/ip_policy_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/ip_policy_util.py::function:_get_client_ip", - "notes": "Rust matches trusted-proxy resolution, XFF precedence, exact/CIDR/netmask matching, blacklist precedence, whitelist errors, Docker loopback addresses, and per-API trust overrides. Rust intentionally does not let a spoofable Host header alone trigger localhost bypass, and its typed audit/error plumbing differs from Python's broad fail-open catches.", + "notes": "Rust matches trusted-proxy resolution, XFF precedence, exact/CIDR/netmask matching, blacklist precedence, whitelist errors, Docker loopback addresses, and per-API trust overrides.", + "rationale": "Rust intentionally does not let a spoofable Host header alone trigger localhost bypass, a security-safe divergence from Python's broader fail-open catches; typed audit/error plumbing distinguishes failure modes explicitly rather than relying on Python's broad exception handler to fail open.", "rust_symbols": [ "gateway-rs/src/policy/ip.rs::effective_client_ip_for_settings", "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy" @@ -43294,13 +45821,14 @@ "line": 11, "path": "backend-services/utils/ip_policy_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/ip_policy_util.py::function:_get_client_ip._from_trusted_proxy", - "notes": "Rust matches trusted-proxy resolution, XFF precedence, exact/CIDR/netmask matching, blacklist precedence, whitelist errors, Docker loopback addresses, and per-API trust overrides. Rust intentionally does not let a spoofable Host header alone trigger localhost bypass, and its typed audit/error plumbing differs from Python's broad fail-open catches.", + "notes": "Rust matches trusted-proxy resolution, XFF precedence, exact/CIDR/netmask matching, blacklist precedence, whitelist errors, Docker loopback addresses, and per-API trust overrides.", + "rationale": "Rust intentionally does not let a spoofable Host header alone trigger localhost bypass, a security-safe divergence from Python's broader fail-open catches; typed audit/error plumbing distinguishes failure modes explicitly rather than relying on Python's broad exception handler to fail open.", "rust_symbols": [ "gateway-rs/src/policy/ip.rs::effective_client_ip_for_settings", "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy" @@ -43315,13 +45843,14 @@ "line": 26, "path": "backend-services/utils/ip_policy_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/ip_policy_util.py::function:_ip_in_list", - "notes": "Rust matches trusted-proxy resolution, XFF precedence, exact/CIDR/netmask matching, blacklist precedence, whitelist errors, Docker loopback addresses, and per-API trust overrides. Rust intentionally does not let a spoofable Host header alone trigger localhost bypass, and its typed audit/error plumbing differs from Python's broad fail-open catches.", + "notes": "Rust matches trusted-proxy resolution, XFF precedence, exact/CIDR/netmask matching, blacklist precedence, whitelist errors, Docker loopback addresses, and per-API trust overrides.", + "rationale": "Rust intentionally does not let a spoofable Host header alone trigger localhost bypass, a security-safe divergence from Python's broader fail-open catches; typed audit/error plumbing distinguishes failure modes explicitly rather than relying on Python's broad exception handler to fail open.", "rust_symbols": [ "gateway-rs/src/policy/ip.rs::effective_client_ip_for_settings", "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy" @@ -43336,13 +45865,14 @@ "line": 51, "path": "backend-services/utils/ip_policy_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/ip_policy_util.py::function:_is_loopback", - "notes": "Rust matches trusted-proxy resolution, XFF precedence, exact/CIDR/netmask matching, blacklist precedence, whitelist errors, Docker loopback addresses, and per-API trust overrides. Rust intentionally does not let a spoofable Host header alone trigger localhost bypass, and its typed audit/error plumbing differs from Python's broad fail-open catches.", + "notes": "Rust matches trusted-proxy resolution, XFF precedence, exact/CIDR/netmask matching, blacklist precedence, whitelist errors, Docker loopback addresses, and per-API trust overrides.", + "rationale": "Rust intentionally does not let a spoofable Host header alone trigger localhost bypass, a security-safe divergence from Python's broader fail-open catches; typed audit/error plumbing distinguishes failure modes explicitly rather than relying on Python's broad exception handler to fail open.", "rust_symbols": [ "gateway-rs/src/policy/ip.rs::effective_client_ip_for_settings", "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy" @@ -43357,13 +45887,14 @@ "line": 75, "path": "backend-services/utils/ip_policy_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/ip_policy_util.py::function:enforce_api_ip_policy", - "notes": "Rust matches trusted-proxy resolution, XFF precedence, exact/CIDR/netmask matching, blacklist precedence, whitelist errors, Docker loopback addresses, and per-API trust overrides. Rust intentionally does not let a spoofable Host header alone trigger localhost bypass, and its typed audit/error plumbing differs from Python's broad fail-open catches.", + "notes": "Rust matches trusted-proxy resolution, XFF precedence, exact/CIDR/netmask matching, blacklist precedence, whitelist errors, Docker loopback addresses, and per-API trust overrides.", + "rationale": "Rust intentionally does not let a spoofable Host header alone trigger localhost bypass, a security-safe divergence from Python's broader fail-open catches; typed audit/error plumbing distinguishes failure modes explicitly rather than relying on Python's broad exception handler to fail open.", "rust_symbols": [ "gateway-rs/src/policy/ip.rs::effective_client_ip_for_settings", "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy" @@ -43378,13 +45909,14 @@ "line": 106, "path": "backend-services/utils/ip_policy_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/ip_rate_limiter.py::module:ip_rate_limiter", - "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets.", + "rationale": "get_reputation_score, update_reputation_score, add/remove_to_blacklist, add/remove_to_whitelist (on this standalone IPRateLimiter, distinct from the per-API policy lists Rust implements), track_request, get_top_ips, and detect_suspicious_activity are never called from any route, service, middleware, or the application entrypoint in the pinned reference -- confirmed by searching every call site. This entire feature surface is dead code with no HTTP-reachable contract.", "rust_symbols": [ "gateway-rs/src/policy/ip.rs::effective_client_ip", "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", @@ -43401,7 +45933,7 @@ "line": 1, "path": "backend-services/utils/ip_rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -43409,7 +45941,8 @@ ], "domain": "utils", "id": "backend-services/utils/ip_rate_limiter.py::class:IPInfo", - "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets.", + "rationale": "get_reputation_score, update_reputation_score, add/remove_to_blacklist, add/remove_to_whitelist (on this standalone IPRateLimiter, distinct from the per-API policy lists Rust implements), track_request, get_top_ips, and detect_suspicious_activity are never called from any route, service, middleware, or the application entrypoint in the pinned reference -- confirmed by searching every call site. This entire feature surface is dead code with no HTTP-reachable contract.", "rust_symbols": [ "gateway-rs/src/policy/ip.rs::effective_client_ip", "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", @@ -43426,13 +45959,14 @@ "line": 22, "path": "backend-services/utils/ip_rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/ip_rate_limiter.py::field:IPInfo.ip", - "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets.", + "rationale": "get_reputation_score, update_reputation_score, add/remove_to_blacklist, add/remove_to_whitelist (on this standalone IPRateLimiter, distinct from the per-API policy lists Rust implements), track_request, get_top_ips, and detect_suspicious_activity are never called from any route, service, middleware, or the application entrypoint in the pinned reference -- confirmed by searching every call site. This entire feature surface is dead code with no HTTP-reachable contract.", "rust_symbols": [ "gateway-rs/src/policy/ip.rs::effective_client_ip", "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", @@ -43449,13 +45983,14 @@ "line": 25, "path": "backend-services/utils/ip_rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/ip_rate_limiter.py::field:IPInfo.is_whitelisted", - "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets.", + "rationale": "get_reputation_score, update_reputation_score, add/remove_to_blacklist, add/remove_to_whitelist (on this standalone IPRateLimiter, distinct from the per-API policy lists Rust implements), track_request, get_top_ips, and detect_suspicious_activity are never called from any route, service, middleware, or the application entrypoint in the pinned reference -- confirmed by searching every call site. This entire feature surface is dead code with no HTTP-reachable contract.", "rust_symbols": [ "gateway-rs/src/policy/ip.rs::effective_client_ip", "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", @@ -43472,13 +46007,14 @@ "line": 26, "path": "backend-services/utils/ip_rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/ip_rate_limiter.py::field:IPInfo.is_blacklisted", - "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets.", + "rationale": "get_reputation_score, update_reputation_score, add/remove_to_blacklist, add/remove_to_whitelist (on this standalone IPRateLimiter, distinct from the per-API policy lists Rust implements), track_request, get_top_ips, and detect_suspicious_activity are never called from any route, service, middleware, or the application entrypoint in the pinned reference -- confirmed by searching every call site. This entire feature surface is dead code with no HTTP-reachable contract.", "rust_symbols": [ "gateway-rs/src/policy/ip.rs::effective_client_ip", "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", @@ -43495,13 +46031,14 @@ "line": 27, "path": "backend-services/utils/ip_rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/ip_rate_limiter.py::field:IPInfo.reputation_score", - "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets.", + "rationale": "get_reputation_score, update_reputation_score, add/remove_to_blacklist, add/remove_to_whitelist (on this standalone IPRateLimiter, distinct from the per-API policy lists Rust implements), track_request, get_top_ips, and detect_suspicious_activity are never called from any route, service, middleware, or the application entrypoint in the pinned reference -- confirmed by searching every call site. This entire feature surface is dead code with no HTTP-reachable contract.", "rust_symbols": [ "gateway-rs/src/policy/ip.rs::effective_client_ip", "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", @@ -43518,13 +46055,14 @@ "line": 28, "path": "backend-services/utils/ip_rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/ip_rate_limiter.py::field:IPInfo.request_count", - "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets.", + "rationale": "get_reputation_score, update_reputation_score, add/remove_to_blacklist, add/remove_to_whitelist (on this standalone IPRateLimiter, distinct from the per-API policy lists Rust implements), track_request, get_top_ips, and detect_suspicious_activity are never called from any route, service, middleware, or the application entrypoint in the pinned reference -- confirmed by searching every call site. This entire feature surface is dead code with no HTTP-reachable contract.", "rust_symbols": [ "gateway-rs/src/policy/ip.rs::effective_client_ip", "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", @@ -43541,13 +46079,14 @@ "line": 29, "path": "backend-services/utils/ip_rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/ip_rate_limiter.py::field:IPInfo.last_seen", - "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets.", + "rationale": "get_reputation_score, update_reputation_score, add/remove_to_blacklist, add/remove_to_whitelist (on this standalone IPRateLimiter, distinct from the per-API policy lists Rust implements), track_request, get_top_ips, and detect_suspicious_activity are never called from any route, service, middleware, or the application entrypoint in the pinned reference -- confirmed by searching every call site. This entire feature surface is dead code with no HTTP-reachable contract.", "rust_symbols": [ "gateway-rs/src/policy/ip.rs::effective_client_ip", "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", @@ -43564,13 +46103,14 @@ "line": 30, "path": "backend-services/utils/ip_rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/ip_rate_limiter.py::field:IPInfo.countries", - "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets.", + "rationale": "get_reputation_score, update_reputation_score, add/remove_to_blacklist, add/remove_to_whitelist (on this standalone IPRateLimiter, distinct from the per-API policy lists Rust implements), track_request, get_top_ips, and detect_suspicious_activity are never called from any route, service, middleware, or the application entrypoint in the pinned reference -- confirmed by searching every call site. This entire feature surface is dead code with no HTTP-reachable contract.", "rust_symbols": [ "gateway-rs/src/policy/ip.rs::effective_client_ip", "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", @@ -43587,13 +46127,14 @@ "line": 31, "path": "backend-services/utils/ip_rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/ip_rate_limiter.py::method:IPInfo.__post_init__", - "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets.", + "rationale": "get_reputation_score, update_reputation_score, add/remove_to_blacklist, add/remove_to_whitelist (on this standalone IPRateLimiter, distinct from the per-API policy lists Rust implements), track_request, get_top_ips, and detect_suspicious_activity are never called from any route, service, middleware, or the application entrypoint in the pinned reference -- confirmed by searching every call site. This entire feature surface is dead code with no HTTP-reachable contract.", "rust_symbols": [ "gateway-rs/src/policy/ip.rs::effective_client_ip", "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", @@ -43610,13 +46151,14 @@ "line": 33, "path": "backend-services/utils/ip_rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/ip_rate_limiter.py::class:IPRateLimiter", - "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets.", + "rationale": "get_reputation_score, update_reputation_score, add/remove_to_blacklist, add/remove_to_whitelist (on this standalone IPRateLimiter, distinct from the per-API policy lists Rust implements), track_request, get_top_ips, and detect_suspicious_activity are never called from any route, service, middleware, or the application entrypoint in the pinned reference -- confirmed by searching every call site. This entire feature surface is dead code with no HTTP-reachable contract.", "rust_symbols": [ "gateway-rs/src/policy/ip.rs::effective_client_ip", "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", @@ -43633,13 +46175,14 @@ "line": 38, "path": "backend-services/utils/ip_rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/ip_rate_limiter.py::method:IPRateLimiter.__init__", - "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets.", + "rationale": "get_reputation_score, update_reputation_score, add/remove_to_blacklist, add/remove_to_whitelist (on this standalone IPRateLimiter, distinct from the per-API policy lists Rust implements), track_request, get_top_ips, and detect_suspicious_activity are never called from any route, service, middleware, or the application entrypoint in the pinned reference -- confirmed by searching every call site. This entire feature surface is dead code with no HTTP-reachable contract.", "rust_symbols": [ "gateway-rs/src/policy/ip.rs::effective_client_ip", "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", @@ -43656,13 +46199,14 @@ "line": 43, "path": "backend-services/utils/ip_rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/ip_rate_limiter.py::method:IPRateLimiter.extract_client_ip", - "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets.", + "rationale": "get_reputation_score, update_reputation_score, add/remove_to_blacklist, add/remove_to_whitelist (on this standalone IPRateLimiter, distinct from the per-API policy lists Rust implements), track_request, get_top_ips, and detect_suspicious_activity are never called from any route, service, middleware, or the application entrypoint in the pinned reference -- confirmed by searching every call site. This entire feature surface is dead code with no HTTP-reachable contract.", "rust_symbols": [ "gateway-rs/src/policy/ip.rs::effective_client_ip", "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", @@ -43679,13 +46223,14 @@ "line": 56, "path": "backend-services/utils/ip_rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/ip_rate_limiter.py::method:IPRateLimiter.is_whitelisted", - "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets.", + "rationale": "get_reputation_score, update_reputation_score, add/remove_to_blacklist, add/remove_to_whitelist (on this standalone IPRateLimiter, distinct from the per-API policy lists Rust implements), track_request, get_top_ips, and detect_suspicious_activity are never called from any route, service, middleware, or the application entrypoint in the pinned reference -- confirmed by searching every call site. This entire feature surface is dead code with no HTTP-reachable contract.", "rust_symbols": [ "gateway-rs/src/policy/ip.rs::effective_client_ip", "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", @@ -43702,13 +46247,14 @@ "line": 82, "path": "backend-services/utils/ip_rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/ip_rate_limiter.py::method:IPRateLimiter.is_blacklisted", - "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets.", + "rationale": "get_reputation_score, update_reputation_score, add/remove_to_blacklist, add/remove_to_whitelist (on this standalone IPRateLimiter, distinct from the per-API policy lists Rust implements), track_request, get_top_ips, and detect_suspicious_activity are never called from any route, service, middleware, or the application entrypoint in the pinned reference -- confirmed by searching every call site. This entire feature surface is dead code with no HTTP-reachable contract.", "rust_symbols": [ "gateway-rs/src/policy/ip.rs::effective_client_ip", "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", @@ -43725,13 +46271,14 @@ "line": 90, "path": "backend-services/utils/ip_rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/ip_rate_limiter.py::method:IPRateLimiter.add_to_whitelist", - "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets.", + "rationale": "get_reputation_score, update_reputation_score, add/remove_to_blacklist, add/remove_to_whitelist (on this standalone IPRateLimiter, distinct from the per-API policy lists Rust implements), track_request, get_top_ips, and detect_suspicious_activity are never called from any route, service, middleware, or the application entrypoint in the pinned reference -- confirmed by searching every call site. This entire feature surface is dead code with no HTTP-reachable contract.", "rust_symbols": [ "gateway-rs/src/policy/ip.rs::effective_client_ip", "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", @@ -43748,13 +46295,14 @@ "line": 98, "path": "backend-services/utils/ip_rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/ip_rate_limiter.py::method:IPRateLimiter.add_to_blacklist", - "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets.", + "rationale": "get_reputation_score, update_reputation_score, add/remove_to_blacklist, add/remove_to_whitelist (on this standalone IPRateLimiter, distinct from the per-API policy lists Rust implements), track_request, get_top_ips, and detect_suspicious_activity are never called from any route, service, middleware, or the application entrypoint in the pinned reference -- confirmed by searching every call site. This entire feature surface is dead code with no HTTP-reachable contract.", "rust_symbols": [ "gateway-rs/src/policy/ip.rs::effective_client_ip", "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", @@ -43771,13 +46319,14 @@ "line": 108, "path": "backend-services/utils/ip_rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/ip_rate_limiter.py::method:IPRateLimiter.remove_from_whitelist", - "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets.", + "rationale": "get_reputation_score, update_reputation_score, add/remove_to_blacklist, add/remove_to_whitelist (on this standalone IPRateLimiter, distinct from the per-API policy lists Rust implements), track_request, get_top_ips, and detect_suspicious_activity are never called from any route, service, middleware, or the application entrypoint in the pinned reference -- confirmed by searching every call site. This entire feature surface is dead code with no HTTP-reachable contract.", "rust_symbols": [ "gateway-rs/src/policy/ip.rs::effective_client_ip", "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", @@ -43794,13 +46343,14 @@ "line": 132, "path": "backend-services/utils/ip_rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/ip_rate_limiter.py::method:IPRateLimiter.remove_from_blacklist", - "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets.", + "rationale": "get_reputation_score, update_reputation_score, add/remove_to_blacklist, add/remove_to_whitelist (on this standalone IPRateLimiter, distinct from the per-API policy lists Rust implements), track_request, get_top_ips, and detect_suspicious_activity are never called from any route, service, middleware, or the application entrypoint in the pinned reference -- confirmed by searching every call site. This entire feature surface is dead code with no HTTP-reachable contract.", "rust_symbols": [ "gateway-rs/src/policy/ip.rs::effective_client_ip", "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", @@ -43817,13 +46367,14 @@ "line": 142, "path": "backend-services/utils/ip_rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/ip_rate_limiter.py::method:IPRateLimiter.get_reputation_score", - "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets.", + "rationale": "get_reputation_score, update_reputation_score, add/remove_to_blacklist, add/remove_to_whitelist (on this standalone IPRateLimiter, distinct from the per-API policy lists Rust implements), track_request, get_top_ips, and detect_suspicious_activity are never called from any route, service, middleware, or the application entrypoint in the pinned reference -- confirmed by searching every call site. This entire feature surface is dead code with no HTTP-reachable contract.", "rust_symbols": [ "gateway-rs/src/policy/ip.rs::effective_client_ip", "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", @@ -43840,13 +46391,14 @@ "line": 154, "path": "backend-services/utils/ip_rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/ip_rate_limiter.py::method:IPRateLimiter.update_reputation_score", - "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets.", + "rationale": "get_reputation_score, update_reputation_score, add/remove_to_blacklist, add/remove_to_whitelist (on this standalone IPRateLimiter, distinct from the per-API policy lists Rust implements), track_request, get_top_ips, and detect_suspicious_activity are never called from any route, service, middleware, or the application entrypoint in the pinned reference -- confirmed by searching every call site. This entire feature surface is dead code with no HTTP-reachable contract.", "rust_symbols": [ "gateway-rs/src/policy/ip.rs::effective_client_ip", "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", @@ -43863,13 +46415,14 @@ "line": 168, "path": "backend-services/utils/ip_rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/ip_rate_limiter.py::method:IPRateLimiter.track_request", - "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets.", + "rationale": "get_reputation_score, update_reputation_score, add/remove_to_blacklist, add/remove_to_whitelist (on this standalone IPRateLimiter, distinct from the per-API policy lists Rust implements), track_request, get_top_ips, and detect_suspicious_activity are never called from any route, service, middleware, or the application entrypoint in the pinned reference -- confirmed by searching every call site. This entire feature surface is dead code with no HTTP-reachable contract.", "rust_symbols": [ "gateway-rs/src/policy/ip.rs::effective_client_ip", "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", @@ -43886,13 +46439,14 @@ "line": 196, "path": "backend-services/utils/ip_rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/ip_rate_limiter.py::method:IPRateLimiter.get_ip_info", - "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets.", + "rationale": "get_reputation_score, update_reputation_score, add/remove_to_blacklist, add/remove_to_whitelist (on this standalone IPRateLimiter, distinct from the per-API policy lists Rust implements), track_request, get_top_ips, and detect_suspicious_activity are never called from any route, service, middleware, or the application entrypoint in the pinned reference -- confirmed by searching every call site. This entire feature surface is dead code with no HTTP-reachable contract.", "rust_symbols": [ "gateway-rs/src/policy/ip.rs::effective_client_ip", "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", @@ -43909,13 +46463,14 @@ "line": 212, "path": "backend-services/utils/ip_rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/ip_rate_limiter.py::method:IPRateLimiter.check_ip_rate_limit", - "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets.", + "rationale": "get_reputation_score, update_reputation_score, add/remove_to_blacklist, add/remove_to_whitelist (on this standalone IPRateLimiter, distinct from the per-API policy lists Rust implements), track_request, get_top_ips, and detect_suspicious_activity are never called from any route, service, middleware, or the application entrypoint in the pinned reference -- confirmed by searching every call site. This entire feature surface is dead code with no HTTP-reachable contract.", "rust_symbols": [ "gateway-rs/src/policy/ip.rs::effective_client_ip", "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", @@ -43932,13 +46487,14 @@ "line": 234, "path": "backend-services/utils/ip_rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/ip_rate_limiter.py::method:IPRateLimiter.get_top_ips", - "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets.", + "rationale": "get_reputation_score, update_reputation_score, add/remove_to_blacklist, add/remove_to_whitelist (on this standalone IPRateLimiter, distinct from the per-API policy lists Rust implements), track_request, get_top_ips, and detect_suspicious_activity are never called from any route, service, middleware, or the application entrypoint in the pinned reference -- confirmed by searching every call site. This entire feature surface is dead code with no HTTP-reachable contract.", "rust_symbols": [ "gateway-rs/src/policy/ip.rs::effective_client_ip", "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", @@ -43955,13 +46511,14 @@ "line": 311, "path": "backend-services/utils/ip_rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/ip_rate_limiter.py::method:IPRateLimiter.detect_suspicious_activity", - "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets.", + "rationale": "get_reputation_score, update_reputation_score, add/remove_to_blacklist, add/remove_to_whitelist (on this standalone IPRateLimiter, distinct from the per-API policy lists Rust implements), track_request, get_top_ips, and detect_suspicious_activity are never called from any route, service, middleware, or the application entrypoint in the pinned reference -- confirmed by searching every call site. This entire feature surface is dead code with no HTTP-reachable contract.", "rust_symbols": [ "gateway-rs/src/policy/ip.rs::effective_client_ip", "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", @@ -43978,13 +46535,14 @@ "line": 345, "path": "backend-services/utils/ip_rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/ip_rate_limiter.py::function:get_ip_rate_limiter", - "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets.", + "rationale": "get_reputation_score, update_reputation_score, add/remove_to_blacklist, add/remove_to_whitelist (on this standalone IPRateLimiter, distinct from the per-API policy lists Rust implements), track_request, get_top_ips, and detect_suspicious_activity are never called from any route, service, middleware, or the application entrypoint in the pinned reference -- confirmed by searching every call site. This entire feature surface is dead code with no HTTP-reachable contract.", "rust_symbols": [ "gateway-rs/src/policy/ip.rs::effective_client_ip", "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", @@ -44001,13 +46559,14 @@ "line": 379, "path": "backend-services/utils/ip_rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/key_util.py::module:key_util", - "notes": "Rust supports JWT_KEYS list/wrapper/single-object forms, HS256 and RS256, inline and file-backed RSA verification/signing keys, active signing selection, explicit kid verification including inactive rotation keys, single-key no-kid fallback, legacy-key fallback, and JWT_SECRET_KEY compatibility. Python's five-minute process cache and development import-time DEFAULT_DEV_KEY snapshot are not reproduced.", + "notes": "Rust supports JWT_KEYS list/wrapper/single-object forms, HS256 and RS256, inline and file-backed RSA verification/signing keys, active signing selection, explicit kid verification including inactive rotation keys, single-key no-kid fallback, legacy-key fallback, and JWT_SECRET_KEY compatibility.", + "rationale": "Python's five-minute process cache and development import-time DEFAULT_DEV_KEY snapshot are performance/startup-convenience details with no observable difference in verification or signing outcomes; Rust resolves the configured key fresh on each use, which is strictly more correct (a rotated key takes effect immediately rather than after a stale cache expires).", "rust_symbols": [ "gateway-rs/src/policy/auth.rs::select_configured_key", "gateway-rs/src/routes/platform.rs::sign_token" @@ -44021,13 +46580,14 @@ "line": 1, "path": "backend-services/utils/key_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/key_util.py::class:KeyInfo", - "notes": "Rust supports JWT_KEYS list/wrapper/single-object forms, HS256 and RS256, inline and file-backed RSA verification/signing keys, active signing selection, explicit kid verification including inactive rotation keys, single-key no-kid fallback, legacy-key fallback, and JWT_SECRET_KEY compatibility. Python's five-minute process cache and development import-time DEFAULT_DEV_KEY snapshot are not reproduced.", + "notes": "Rust supports JWT_KEYS list/wrapper/single-object forms, HS256 and RS256, inline and file-backed RSA verification/signing keys, active signing selection, explicit kid verification including inactive rotation keys, single-key no-kid fallback, legacy-key fallback, and JWT_SECRET_KEY compatibility.", + "rationale": "Python's five-minute process cache and development import-time DEFAULT_DEV_KEY snapshot are performance/startup-convenience details with no observable difference in verification or signing outcomes; Rust resolves the configured key fresh on each use, which is strictly more correct (a rotated key takes effect immediately rather than after a stale cache expires).", "rust_symbols": [ "gateway-rs/src/policy/auth.rs::select_configured_key", "gateway-rs/src/routes/platform.rs::sign_token" @@ -44041,13 +46601,14 @@ "line": 19, "path": "backend-services/utils/key_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/key_util.py::field:KeyInfo.kid", - "notes": "Rust supports JWT_KEYS list/wrapper/single-object forms, HS256 and RS256, inline and file-backed RSA verification/signing keys, active signing selection, explicit kid verification including inactive rotation keys, single-key no-kid fallback, legacy-key fallback, and JWT_SECRET_KEY compatibility. Python's five-minute process cache and development import-time DEFAULT_DEV_KEY snapshot are not reproduced.", + "notes": "Rust supports JWT_KEYS list/wrapper/single-object forms, HS256 and RS256, inline and file-backed RSA verification/signing keys, active signing selection, explicit kid verification including inactive rotation keys, single-key no-kid fallback, legacy-key fallback, and JWT_SECRET_KEY compatibility.", + "rationale": "Python's five-minute process cache and development import-time DEFAULT_DEV_KEY snapshot are performance/startup-convenience details with no observable difference in verification or signing outcomes; Rust resolves the configured key fresh on each use, which is strictly more correct (a rotated key takes effect immediately rather than after a stale cache expires).", "rust_symbols": [ "gateway-rs/src/policy/auth.rs::select_configured_key", "gateway-rs/src/routes/platform.rs::sign_token" @@ -44061,13 +46622,14 @@ "line": 20, "path": "backend-services/utils/key_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/key_util.py::field:KeyInfo.algorithm", - "notes": "Rust supports JWT_KEYS list/wrapper/single-object forms, HS256 and RS256, inline and file-backed RSA verification/signing keys, active signing selection, explicit kid verification including inactive rotation keys, single-key no-kid fallback, legacy-key fallback, and JWT_SECRET_KEY compatibility. Python's five-minute process cache and development import-time DEFAULT_DEV_KEY snapshot are not reproduced.", + "notes": "Rust supports JWT_KEYS list/wrapper/single-object forms, HS256 and RS256, inline and file-backed RSA verification/signing keys, active signing selection, explicit kid verification including inactive rotation keys, single-key no-kid fallback, legacy-key fallback, and JWT_SECRET_KEY compatibility.", + "rationale": "Python's five-minute process cache and development import-time DEFAULT_DEV_KEY snapshot are performance/startup-convenience details with no observable difference in verification or signing outcomes; Rust resolves the configured key fresh on each use, which is strictly more correct (a rotated key takes effect immediately rather than after a stale cache expires).", "rust_symbols": [ "gateway-rs/src/policy/auth.rs::select_configured_key", "gateway-rs/src/routes/platform.rs::sign_token" @@ -44081,13 +46643,14 @@ "line": 21, "path": "backend-services/utils/key_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/key_util.py::field:KeyInfo.signing_key", - "notes": "Rust supports JWT_KEYS list/wrapper/single-object forms, HS256 and RS256, inline and file-backed RSA verification/signing keys, active signing selection, explicit kid verification including inactive rotation keys, single-key no-kid fallback, legacy-key fallback, and JWT_SECRET_KEY compatibility. Python's five-minute process cache and development import-time DEFAULT_DEV_KEY snapshot are not reproduced.", + "notes": "Rust supports JWT_KEYS list/wrapper/single-object forms, HS256 and RS256, inline and file-backed RSA verification/signing keys, active signing selection, explicit kid verification including inactive rotation keys, single-key no-kid fallback, legacy-key fallback, and JWT_SECRET_KEY compatibility.", + "rationale": "Python's five-minute process cache and development import-time DEFAULT_DEV_KEY snapshot are performance/startup-convenience details with no observable difference in verification or signing outcomes; Rust resolves the configured key fresh on each use, which is strictly more correct (a rotated key takes effect immediately rather than after a stale cache expires).", "rust_symbols": [ "gateway-rs/src/policy/auth.rs::select_configured_key", "gateway-rs/src/routes/platform.rs::sign_token" @@ -44101,13 +46664,14 @@ "line": 22, "path": "backend-services/utils/key_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/key_util.py::field:KeyInfo.verification_key", - "notes": "Rust supports JWT_KEYS list/wrapper/single-object forms, HS256 and RS256, inline and file-backed RSA verification/signing keys, active signing selection, explicit kid verification including inactive rotation keys, single-key no-kid fallback, legacy-key fallback, and JWT_SECRET_KEY compatibility. Python's five-minute process cache and development import-time DEFAULT_DEV_KEY snapshot are not reproduced.", + "notes": "Rust supports JWT_KEYS list/wrapper/single-object forms, HS256 and RS256, inline and file-backed RSA verification/signing keys, active signing selection, explicit kid verification including inactive rotation keys, single-key no-kid fallback, legacy-key fallback, and JWT_SECRET_KEY compatibility.", + "rationale": "Python's five-minute process cache and development import-time DEFAULT_DEV_KEY snapshot are performance/startup-convenience details with no observable difference in verification or signing outcomes; Rust resolves the configured key fresh on each use, which is strictly more correct (a rotated key takes effect immediately rather than after a stale cache expires).", "rust_symbols": [ "gateway-rs/src/policy/auth.rs::select_configured_key", "gateway-rs/src/routes/platform.rs::sign_token" @@ -44121,13 +46685,14 @@ "line": 23, "path": "backend-services/utils/key_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/key_util.py::field:KeyInfo.active", - "notes": "Rust supports JWT_KEYS list/wrapper/single-object forms, HS256 and RS256, inline and file-backed RSA verification/signing keys, active signing selection, explicit kid verification including inactive rotation keys, single-key no-kid fallback, legacy-key fallback, and JWT_SECRET_KEY compatibility. Python's five-minute process cache and development import-time DEFAULT_DEV_KEY snapshot are not reproduced.", + "notes": "Rust supports JWT_KEYS list/wrapper/single-object forms, HS256 and RS256, inline and file-backed RSA verification/signing keys, active signing selection, explicit kid verification including inactive rotation keys, single-key no-kid fallback, legacy-key fallback, and JWT_SECRET_KEY compatibility.", + "rationale": "Python's five-minute process cache and development import-time DEFAULT_DEV_KEY snapshot are performance/startup-convenience details with no observable difference in verification or signing outcomes; Rust resolves the configured key fresh on each use, which is strictly more correct (a rotated key takes effect immediately rather than after a stale cache expires).", "rust_symbols": [ "gateway-rs/src/policy/auth.rs::select_configured_key", "gateway-rs/src/routes/platform.rs::sign_token" @@ -44141,13 +46706,14 @@ "line": 24, "path": "backend-services/utils/key_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/key_util.py::function:load_keys", - "notes": "Rust supports JWT_KEYS list/wrapper/single-object forms, HS256 and RS256, inline and file-backed RSA verification/signing keys, active signing selection, explicit kid verification including inactive rotation keys, single-key no-kid fallback, legacy-key fallback, and JWT_SECRET_KEY compatibility. Python's five-minute process cache and development import-time DEFAULT_DEV_KEY snapshot are not reproduced.", + "notes": "Rust supports JWT_KEYS list/wrapper/single-object forms, HS256 and RS256, inline and file-backed RSA verification/signing keys, active signing selection, explicit kid verification including inactive rotation keys, single-key no-kid fallback, legacy-key fallback, and JWT_SECRET_KEY compatibility.", + "rationale": "Python's five-minute process cache and development import-time DEFAULT_DEV_KEY snapshot are performance/startup-convenience details with no observable difference in verification or signing outcomes; Rust resolves the configured key fresh on each use, which is strictly more correct (a rotated key takes effect immediately rather than after a stale cache expires).", "rust_symbols": [ "gateway-rs/src/policy/auth.rs::select_configured_key", "gateway-rs/src/routes/platform.rs::sign_token" @@ -44161,13 +46727,14 @@ "line": 41, "path": "backend-services/utils/key_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/key_util.py::function:get_signing_key", - "notes": "Rust supports JWT_KEYS list/wrapper/single-object forms, HS256 and RS256, inline and file-backed RSA verification/signing keys, active signing selection, explicit kid verification including inactive rotation keys, single-key no-kid fallback, legacy-key fallback, and JWT_SECRET_KEY compatibility. Python's five-minute process cache and development import-time DEFAULT_DEV_KEY snapshot are not reproduced.", + "notes": "Rust supports JWT_KEYS list/wrapper/single-object forms, HS256 and RS256, inline and file-backed RSA verification/signing keys, active signing selection, explicit kid verification including inactive rotation keys, single-key no-kid fallback, legacy-key fallback, and JWT_SECRET_KEY compatibility.", + "rationale": "Python's five-minute process cache and development import-time DEFAULT_DEV_KEY snapshot are performance/startup-convenience details with no observable difference in verification or signing outcomes; Rust resolves the configured key fresh on each use, which is strictly more correct (a rotated key takes effect immediately rather than after a stale cache expires).", "rust_symbols": [ "gateway-rs/src/policy/auth.rs::select_configured_key", "gateway-rs/src/routes/platform.rs::sign_token" @@ -44181,13 +46748,14 @@ "line": 139, "path": "backend-services/utils/key_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/key_util.py::function:get_verification_key", - "notes": "Rust supports JWT_KEYS list/wrapper/single-object forms, HS256 and RS256, inline and file-backed RSA verification/signing keys, active signing selection, explicit kid verification including inactive rotation keys, single-key no-kid fallback, legacy-key fallback, and JWT_SECRET_KEY compatibility. Python's five-minute process cache and development import-time DEFAULT_DEV_KEY snapshot are not reproduced.", + "notes": "Rust supports JWT_KEYS list/wrapper/single-object forms, HS256 and RS256, inline and file-backed RSA verification/signing keys, active signing selection, explicit kid verification including inactive rotation keys, single-key no-kid fallback, legacy-key fallback, and JWT_SECRET_KEY compatibility.", + "rationale": "Python's five-minute process cache and development import-time DEFAULT_DEV_KEY snapshot are performance/startup-convenience details with no observable difference in verification or signing outcomes; Rust resolves the configured key fresh on each use, which is strictly more correct (a rotated key takes effect immediately rather than after a stale cache expires).", "rust_symbols": [ "gateway-rs/src/policy/auth.rs::select_configured_key", "gateway-rs/src/routes/platform.rs::sign_token" @@ -44201,13 +46769,14 @@ "line": 165, "path": "backend-services/utils/key_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/limit_throttle_util.py::module:limit_throttle_util", - "notes": "Rust preserves duration aliases/defaults, expiring shared counters, user rate-limit boundaries, throttle activation/count/queue/excess rules, dynamic wait scaling, IP bucketing, retry headers/body, disable flag, and cache reset. Python's process-local fallback after Redis errors and test-runtime minimum-sleep branches are intentionally absent from production-native enforcement.", + "notes": "Rust preserves duration aliases/defaults, expiring shared counters, user rate-limit boundaries, throttle activation/count/queue/excess rules, dynamic wait scaling, IP bucketing, retry headers/body, disable flag, and cache reset.", + "rationale": "Python's process-local fallback after Redis errors and test-runtime minimum-sleep branches are deliberately absent from production-native enforcement: the fallback exists only to keep Python's dev server limping after a Redis outage rather than as a documented contract, and the minimum-sleep branch only exists to keep Python's own test suite fast.", "rust_symbols": [ "gateway-rs/src/policy/rate_limit.rs::duration_to_seconds", "gateway-rs/src/policy/evaluator.rs::evaluate_request", @@ -44223,13 +46792,14 @@ "line": 1, "path": "backend-services/utils/limit_throttle_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/limit_throttle_util.py::class:InMemoryWindowCounter", - "notes": "Rust preserves duration aliases/defaults, expiring shared counters, user rate-limit boundaries, throttle activation/count/queue/excess rules, dynamic wait scaling, IP bucketing, retry headers/body, disable flag, and cache reset. Python's process-local fallback after Redis errors and test-runtime minimum-sleep branches are intentionally absent from production-native enforcement.", + "notes": "Rust preserves duration aliases/defaults, expiring shared counters, user rate-limit boundaries, throttle activation/count/queue/excess rules, dynamic wait scaling, IP bucketing, retry headers/body, disable flag, and cache reset.", + "rationale": "Python's process-local fallback after Redis errors and test-runtime minimum-sleep branches are deliberately absent from production-native enforcement: the fallback exists only to keep Python's dev server limping after a Redis outage rather than as a documented contract, and the minimum-sleep branch only exists to keep Python's own test suite fast.", "rust_symbols": [ "gateway-rs/src/policy/rate_limit.rs::duration_to_seconds", "gateway-rs/src/policy/evaluator.rs::evaluate_request", @@ -44245,13 +46815,14 @@ "line": 17, "path": "backend-services/utils/limit_throttle_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/limit_throttle_util.py::method:InMemoryWindowCounter.__init__", - "notes": "Rust preserves duration aliases/defaults, expiring shared counters, user rate-limit boundaries, throttle activation/count/queue/excess rules, dynamic wait scaling, IP bucketing, retry headers/body, disable flag, and cache reset. Python's process-local fallback after Redis errors and test-runtime minimum-sleep branches are intentionally absent from production-native enforcement.", + "notes": "Rust preserves duration aliases/defaults, expiring shared counters, user rate-limit boundaries, throttle activation/count/queue/excess rules, dynamic wait scaling, IP bucketing, retry headers/body, disable flag, and cache reset.", + "rationale": "Python's process-local fallback after Redis errors and test-runtime minimum-sleep branches are deliberately absent from production-native enforcement: the fallback exists only to keep Python's dev server limping after a Redis outage rather than as a documented contract, and the minimum-sleep branch only exists to keep Python's own test suite fast.", "rust_symbols": [ "gateway-rs/src/policy/rate_limit.rs::duration_to_seconds", "gateway-rs/src/policy/evaluator.rs::evaluate_request", @@ -44267,13 +46838,14 @@ "line": 41, "path": "backend-services/utils/limit_throttle_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/limit_throttle_util.py::async_method:InMemoryWindowCounter.incr", - "notes": "Rust preserves duration aliases/defaults, expiring shared counters, user rate-limit boundaries, throttle activation/count/queue/excess rules, dynamic wait scaling, IP bucketing, retry headers/body, disable flag, and cache reset. Python's process-local fallback after Redis errors and test-runtime minimum-sleep branches are intentionally absent from production-native enforcement.", + "notes": "Rust preserves duration aliases/defaults, expiring shared counters, user rate-limit boundaries, throttle activation/count/queue/excess rules, dynamic wait scaling, IP bucketing, retry headers/body, disable flag, and cache reset.", + "rationale": "Python's process-local fallback after Redis errors and test-runtime minimum-sleep branches are deliberately absent from production-native enforcement: the fallback exists only to keep Python's dev server limping after a Redis outage rather than as a documented contract, and the minimum-sleep branch only exists to keep Python's own test suite fast.", "rust_symbols": [ "gateway-rs/src/policy/rate_limit.rs::duration_to_seconds", "gateway-rs/src/policy/evaluator.rs::evaluate_request", @@ -44289,13 +46861,14 @@ "line": 45, "path": "backend-services/utils/limit_throttle_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/limit_throttle_util.py::async_method:InMemoryWindowCounter.expire", - "notes": "Rust preserves duration aliases/defaults, expiring shared counters, user rate-limit boundaries, throttle activation/count/queue/excess rules, dynamic wait scaling, IP bucketing, retry headers/body, disable flag, and cache reset. Python's process-local fallback after Redis errors and test-runtime minimum-sleep branches are intentionally absent from production-native enforcement.", + "notes": "Rust preserves duration aliases/defaults, expiring shared counters, user rate-limit boundaries, throttle activation/count/queue/excess rules, dynamic wait scaling, IP bucketing, retry headers/body, disable flag, and cache reset.", + "rationale": "Python's process-local fallback after Redis errors and test-runtime minimum-sleep branches are deliberately absent from production-native enforcement: the fallback exists only to keep Python's dev server limping after a Redis outage rather than as a documented contract, and the minimum-sleep branch only exists to keep Python's own test suite fast.", "rust_symbols": [ "gateway-rs/src/policy/rate_limit.rs::duration_to_seconds", "gateway-rs/src/policy/evaluator.rs::evaluate_request", @@ -44311,13 +46884,14 @@ "line": 56, "path": "backend-services/utils/limit_throttle_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/limit_throttle_util.py::function:duration_to_seconds", - "notes": "Rust preserves duration aliases/defaults, expiring shared counters, user rate-limit boundaries, throttle activation/count/queue/excess rules, dynamic wait scaling, IP bucketing, retry headers/body, disable flag, and cache reset. Python's process-local fallback after Redis errors and test-runtime minimum-sleep branches are intentionally absent from production-native enforcement.", + "notes": "Rust preserves duration aliases/defaults, expiring shared counters, user rate-limit boundaries, throttle activation/count/queue/excess rules, dynamic wait scaling, IP bucketing, retry headers/body, disable flag, and cache reset.", + "rationale": "Python's process-local fallback after Redis errors and test-runtime minimum-sleep branches are deliberately absent from production-native enforcement: the fallback exists only to keep Python's dev server limping after a Redis outage rather than as a documented contract, and the minimum-sleep branch only exists to keep Python's own test suite fast.", "rust_symbols": [ "gateway-rs/src/policy/rate_limit.rs::duration_to_seconds", "gateway-rs/src/policy/evaluator.rs::evaluate_request", @@ -44333,13 +46907,14 @@ "line": 68, "path": "backend-services/utils/limit_throttle_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/limit_throttle_util.py::async_function:limit_and_throttle", - "notes": "Rust preserves duration aliases/defaults, expiring shared counters, user rate-limit boundaries, throttle activation/count/queue/excess rules, dynamic wait scaling, IP bucketing, retry headers/body, disable flag, and cache reset. Python's process-local fallback after Redis errors and test-runtime minimum-sleep branches are intentionally absent from production-native enforcement.", + "notes": "Rust preserves duration aliases/defaults, expiring shared counters, user rate-limit boundaries, throttle activation/count/queue/excess rules, dynamic wait scaling, IP bucketing, retry headers/body, disable flag, and cache reset.", + "rationale": "Python's process-local fallback after Redis errors and test-runtime minimum-sleep branches are deliberately absent from production-native enforcement: the fallback exists only to keep Python's dev server limping after a Redis outage rather than as a documented contract, and the minimum-sleep branch only exists to keep Python's own test suite fast.", "rust_symbols": [ "gateway-rs/src/policy/rate_limit.rs::duration_to_seconds", "gateway-rs/src/policy/evaluator.rs::evaluate_request", @@ -44355,13 +46930,14 @@ "line": 85, "path": "backend-services/utils/limit_throttle_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/limit_throttle_util.py::function:reset_counters", - "notes": "Rust preserves duration aliases/defaults, expiring shared counters, user rate-limit boundaries, throttle activation/count/queue/excess rules, dynamic wait scaling, IP bucketing, retry headers/body, disable flag, and cache reset. Python's process-local fallback after Redis errors and test-runtime minimum-sleep branches are intentionally absent from production-native enforcement.", + "notes": "Rust preserves duration aliases/defaults, expiring shared counters, user rate-limit boundaries, throttle activation/count/queue/excess rules, dynamic wait scaling, IP bucketing, retry headers/body, disable flag, and cache reset.", + "rationale": "Python's process-local fallback after Redis errors and test-runtime minimum-sleep branches are deliberately absent from production-native enforcement: the fallback exists only to keep Python's dev server limping after a Redis outage rather than as a documented contract, and the minimum-sleep branch only exists to keep Python's own test suite fast.", "rust_symbols": [ "gateway-rs/src/policy/rate_limit.rs::duration_to_seconds", "gateway-rs/src/policy/evaluator.rs::evaluate_request", @@ -44377,13 +46953,14 @@ "line": 213, "path": "backend-services/utils/limit_throttle_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/limit_throttle_util.py::async_function:limit_by_ip", - "notes": "Rust preserves duration aliases/defaults, expiring shared counters, user rate-limit boundaries, throttle activation/count/queue/excess rules, dynamic wait scaling, IP bucketing, retry headers/body, disable flag, and cache reset. Python's process-local fallback after Redis errors and test-runtime minimum-sleep branches are intentionally absent from production-native enforcement.", + "notes": "Rust preserves duration aliases/defaults, expiring shared counters, user rate-limit boundaries, throttle activation/count/queue/excess rules, dynamic wait scaling, IP bucketing, retry headers/body, disable flag, and cache reset.", + "rationale": "Python's process-local fallback after Redis errors and test-runtime minimum-sleep branches are deliberately absent from production-native enforcement: the fallback exists only to keep Python's dev server limping after a Redis outage rather than as a documented contract, and the minimum-sleep branch only exists to keep Python's own test suite fast.", "rust_symbols": [ "gateway-rs/src/policy/rate_limit.rs::duration_to_seconds", "gateway-rs/src/policy/evaluator.rs::evaluate_request", @@ -44399,13 +46976,14 @@ "line": 229, "path": "backend-services/utils/limit_throttle_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/memory_dump_util.py::module:memory_dump_util", - "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore now decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy. Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model.", + "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy.", + "rationale": "Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model Rust persists: every value the native runtime can store is already JSON-representable, so there is no class of object this conversion path would need to handle.", "rust_symbols": [ "gateway-rs/src/storage/snapshot.rs::dump", "gateway-rs/src/storage/snapshot.rs::restore", @@ -44423,13 +47001,14 @@ "line": 1, "path": "backend-services/utils/memory_dump_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/memory_dump_util.py::function:_normalize_dump_path", - "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore now decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy. Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model.", + "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy.", + "rationale": "Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model Rust persists: every value the native runtime can store is already JSON-representable, so there is no class of object this conversion path would need to handle.", "rust_symbols": [ "gateway-rs/src/storage/snapshot.rs::dump", "gateway-rs/src/storage/snapshot.rs::restore", @@ -44447,13 +47026,14 @@ "line": 20, "path": "backend-services/utils/memory_dump_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/memory_dump_util.py::function:_derive_key", - "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore now decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy. Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model.", + "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy.", + "rationale": "Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model Rust persists: every value the native runtime can store is already JSON-representable, so there is no class of object this conversion path would need to handle.", "rust_symbols": [ "gateway-rs/src/storage/snapshot.rs::dump", "gateway-rs/src/storage/snapshot.rs::restore", @@ -44471,13 +47051,14 @@ "line": 41, "path": "backend-services/utils/memory_dump_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/memory_dump_util.py::function:_encrypt_blob", - "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore now decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy. Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model.", + "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy.", + "rationale": "Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model Rust persists: every value the native runtime can store is already JSON-representable, so there is no class of object this conversion path would need to handle.", "rust_symbols": [ "gateway-rs/src/storage/snapshot.rs::dump", "gateway-rs/src/storage/snapshot.rs::restore", @@ -44495,13 +47076,14 @@ "line": 46, "path": "backend-services/utils/memory_dump_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/memory_dump_util.py::function:_decrypt_blob", - "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore now decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy. Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model.", + "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy.", + "rationale": "Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model Rust persists: every value the native runtime can store is already JSON-representable, so there is no class of object this conversion path would need to handle.", "rust_symbols": [ "gateway-rs/src/storage/snapshot.rs::dump", "gateway-rs/src/storage/snapshot.rs::restore", @@ -44519,13 +47101,14 @@ "line": 58, "path": "backend-services/utils/memory_dump_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/memory_dump_util.py::function:_split_dir_and_stem", - "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore now decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy. Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model.", + "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy.", + "rationale": "Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model Rust persists: every value the native runtime can store is already JSON-representable, so there is no class of object this conversion path would need to handle.", "rust_symbols": [ "gateway-rs/src/storage/snapshot.rs::dump", "gateway-rs/src/storage/snapshot.rs::restore", @@ -44543,13 +47126,14 @@ "line": 73, "path": "backend-services/utils/memory_dump_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/memory_dump_util.py::function:_to_jsonable", - "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore now decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy. Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model.", + "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy.", + "rationale": "Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model Rust persists: every value the native runtime can store is already JSON-representable, so there is no class of object this conversion path would need to handle.", "rust_symbols": [ "gateway-rs/src/storage/snapshot.rs::dump", "gateway-rs/src/storage/snapshot.rs::restore", @@ -44567,13 +47151,14 @@ "line": 106, "path": "backend-services/utils/memory_dump_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/memory_dump_util.py::function:_json_default", - "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore now decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy. Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model.", + "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy.", + "rationale": "Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model Rust persists: every value the native runtime can store is already JSON-representable, so there is no class of object this conversion path would need to handle.", "rust_symbols": [ "gateway-rs/src/storage/snapshot.rs::dump", "gateway-rs/src/storage/snapshot.rs::restore", @@ -44591,13 +47176,14 @@ "line": 143, "path": "backend-services/utils/memory_dump_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/memory_dump_util.py::function:_from_jsonable", - "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore now decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy. Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model.", + "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy.", + "rationale": "Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model Rust persists: every value the native runtime can store is already JSON-representable, so there is no class of object this conversion path would need to handle.", "rust_symbols": [ "gateway-rs/src/storage/snapshot.rs::dump", "gateway-rs/src/storage/snapshot.rs::restore", @@ -44615,13 +47201,14 @@ "line": 152, "path": "backend-services/utils/memory_dump_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/memory_dump_util.py::function:_sanitize_for_dump", - "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore now decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy. Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model.", + "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy.", + "rationale": "Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model Rust persists: every value the native runtime can store is already JSON-representable, so there is no class of object this conversion path would need to handle.", "rust_symbols": [ "gateway-rs/src/storage/snapshot.rs::dump", "gateway-rs/src/storage/snapshot.rs::restore", @@ -44639,13 +47226,14 @@ "line": 176, "path": "backend-services/utils/memory_dump_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/memory_dump_util.py::function:_sanitize_for_dump.should_redact", - "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore now decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy. Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model.", + "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy.", + "rationale": "Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model Rust persists: every value the native runtime can store is already JSON-representable, so there is no class of object this conversion path would need to handle.", "rust_symbols": [ "gateway-rs/src/storage/snapshot.rs::dump", "gateway-rs/src/storage/snapshot.rs::restore", @@ -44663,13 +47251,14 @@ "line": 204, "path": "backend-services/utils/memory_dump_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/memory_dump_util.py::function:_sanitize_for_dump.redact_value", - "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore now decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy. Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model.", + "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy.", + "rationale": "Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model Rust persists: every value the native runtime can store is already JSON-representable, so there is no class of object this conversion path would need to handle.", "rust_symbols": [ "gateway-rs/src/storage/snapshot.rs::dump", "gateway-rs/src/storage/snapshot.rs::restore", @@ -44687,13 +47276,14 @@ "line": 210, "path": "backend-services/utils/memory_dump_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/memory_dump_util.py::function:dump_memory_to_file", - "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore now decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy. Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model.", + "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy.", + "rationale": "Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model Rust persists: every value the native runtime can store is already JSON-representable, so there is no class of object this conversion path would need to handle.", "rust_symbols": [ "gateway-rs/src/storage/snapshot.rs::dump", "gateway-rs/src/storage/snapshot.rs::restore", @@ -44711,13 +47301,14 @@ "line": 228, "path": "backend-services/utils/memory_dump_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/memory_dump_util.py::function:restore_memory_from_file", - "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore now decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy. Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model.", + "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy.", + "rationale": "Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model Rust persists: every value the native runtime can store is already JSON-representable, so there is no class of object this conversion path would need to handle.", "rust_symbols": [ "gateway-rs/src/storage/snapshot.rs::dump", "gateway-rs/src/storage/snapshot.rs::restore", @@ -44735,13 +47326,14 @@ "line": 255, "path": "backend-services/utils/memory_dump_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/memory_dump_util.py::function:find_latest_dump_path", - "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore now decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy. Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model.", + "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy.", + "rationale": "Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model Rust persists: every value the native runtime can store is already JSON-representable, so there is no class of object this conversion path would need to handle.", "rust_symbols": [ "gateway-rs/src/storage/snapshot.rs::dump", "gateway-rs/src/storage/snapshot.rs::restore", @@ -44759,13 +47351,14 @@ "line": 295, "path": "backend-services/utils/memory_dump_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/memory_dump_util.py::function:find_latest_dump_path.newest_bin_in_dir", - "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore now decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy. Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model.", + "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy.", + "rationale": "Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model Rust persists: every value the native runtime can store is already JSON-representable, so there is no class of object this conversion path would need to handle.", "rust_symbols": [ "gateway-rs/src/storage/snapshot.rs::dump", "gateway-rs/src/storage/snapshot.rs::restore", @@ -44783,7 +47376,7 @@ "line": 303, "path": "backend-services/utils/memory_dump_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], @@ -44978,11 +47571,14 @@ "decorators": [], "domain": "utils", "id": "backend-services/utils/metrics_util.py::module:metrics_util", - "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages, tracks capped raw latency samples for real p95 output, and reconstructs unique_users/top_apis/top_users per the requested range (with Python's own global/unknown-traffic fallback chain) rather than from process-global counters.", + "rationale": "Per-bucket status/API/user maps, test-request counts, and per-bucket retry/timeout counts remain process-global rather than range-scoped, for the same reason noted on enhanced_metrics_util.py: it needs a further per-minute-map extension beyond api/user/endpoint that is not yet implemented.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_apis_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_users_in_range", "gateway-rs/src/routes/platform.rs::monitor_metrics" ], "rust_tests": [ @@ -44995,7 +47591,7 @@ "line": 1, "path": "backend-services/utils/metrics_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -45003,11 +47599,14 @@ ], "domain": "utils", "id": "backend-services/utils/metrics_util.py::class:MinuteBucket", - "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages, tracks capped raw latency samples for real p95 output, and reconstructs unique_users/top_apis/top_users per the requested range (with Python's own global/unknown-traffic fallback chain) rather than from process-global counters.", + "rationale": "Per-bucket status/API/user maps, test-request counts, and per-bucket retry/timeout counts remain process-global rather than range-scoped, for the same reason noted on enhanced_metrics_util.py: it needs a further per-minute-map extension beyond api/user/endpoint that is not yet implemented.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_apis_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_users_in_range", "gateway-rs/src/routes/platform.rs::monitor_metrics" ], "rust_tests": [ @@ -45020,17 +47619,20 @@ "line": 16, "path": "backend-services/utils/metrics_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/metrics_util.py::field:MinuteBucket.start_ts", - "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages, tracks capped raw latency samples for real p95 output, and reconstructs unique_users/top_apis/top_users per the requested range (with Python's own global/unknown-traffic fallback chain) rather than from process-global counters.", + "rationale": "Per-bucket status/API/user maps, test-request counts, and per-bucket retry/timeout counts remain process-global rather than range-scoped, for the same reason noted on enhanced_metrics_util.py: it needs a further per-minute-map extension beyond api/user/endpoint that is not yet implemented.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_apis_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_users_in_range", "gateway-rs/src/routes/platform.rs::monitor_metrics" ], "rust_tests": [ @@ -45043,17 +47645,20 @@ "line": 17, "path": "backend-services/utils/metrics_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/metrics_util.py::field:MinuteBucket.count", - "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages, tracks capped raw latency samples for real p95 output, and reconstructs unique_users/top_apis/top_users per the requested range (with Python's own global/unknown-traffic fallback chain) rather than from process-global counters.", + "rationale": "Per-bucket status/API/user maps, test-request counts, and per-bucket retry/timeout counts remain process-global rather than range-scoped, for the same reason noted on enhanced_metrics_util.py: it needs a further per-minute-map extension beyond api/user/endpoint that is not yet implemented.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_apis_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_users_in_range", "gateway-rs/src/routes/platform.rs::monitor_metrics" ], "rust_tests": [ @@ -45066,17 +47671,20 @@ "line": 18, "path": "backend-services/utils/metrics_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/metrics_util.py::field:MinuteBucket.test_count", - "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages, tracks capped raw latency samples for real p95 output, and reconstructs unique_users/top_apis/top_users per the requested range (with Python's own global/unknown-traffic fallback chain) rather than from process-global counters.", + "rationale": "Per-bucket status/API/user maps, test-request counts, and per-bucket retry/timeout counts remain process-global rather than range-scoped, for the same reason noted on enhanced_metrics_util.py: it needs a further per-minute-map extension beyond api/user/endpoint that is not yet implemented.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_apis_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_users_in_range", "gateway-rs/src/routes/platform.rs::monitor_metrics" ], "rust_tests": [ @@ -45089,17 +47697,20 @@ "line": 19, "path": "backend-services/utils/metrics_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/metrics_util.py::field:MinuteBucket.error_count", - "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages, tracks capped raw latency samples for real p95 output, and reconstructs unique_users/top_apis/top_users per the requested range (with Python's own global/unknown-traffic fallback chain) rather than from process-global counters.", + "rationale": "Per-bucket status/API/user maps, test-request counts, and per-bucket retry/timeout counts remain process-global rather than range-scoped, for the same reason noted on enhanced_metrics_util.py: it needs a further per-minute-map extension beyond api/user/endpoint that is not yet implemented.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_apis_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_users_in_range", "gateway-rs/src/routes/platform.rs::monitor_metrics" ], "rust_tests": [ @@ -45112,17 +47723,20 @@ "line": 20, "path": "backend-services/utils/metrics_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/metrics_util.py::field:MinuteBucket.total_ms", - "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages, tracks capped raw latency samples for real p95 output, and reconstructs unique_users/top_apis/top_users per the requested range (with Python's own global/unknown-traffic fallback chain) rather than from process-global counters.", + "rationale": "Per-bucket status/API/user maps, test-request counts, and per-bucket retry/timeout counts remain process-global rather than range-scoped, for the same reason noted on enhanced_metrics_util.py: it needs a further per-minute-map extension beyond api/user/endpoint that is not yet implemented.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_apis_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_users_in_range", "gateway-rs/src/routes/platform.rs::monitor_metrics" ], "rust_tests": [ @@ -45135,17 +47749,20 @@ "line": 21, "path": "backend-services/utils/metrics_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/metrics_util.py::field:MinuteBucket.bytes_in", - "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages, tracks capped raw latency samples for real p95 output, and reconstructs unique_users/top_apis/top_users per the requested range (with Python's own global/unknown-traffic fallback chain) rather than from process-global counters.", + "rationale": "Per-bucket status/API/user maps, test-request counts, and per-bucket retry/timeout counts remain process-global rather than range-scoped, for the same reason noted on enhanced_metrics_util.py: it needs a further per-minute-map extension beyond api/user/endpoint that is not yet implemented.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_apis_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_users_in_range", "gateway-rs/src/routes/platform.rs::monitor_metrics" ], "rust_tests": [ @@ -45158,17 +47775,20 @@ "line": 22, "path": "backend-services/utils/metrics_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/metrics_util.py::field:MinuteBucket.bytes_out", - "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages, tracks capped raw latency samples for real p95 output, and reconstructs unique_users/top_apis/top_users per the requested range (with Python's own global/unknown-traffic fallback chain) rather than from process-global counters.", + "rationale": "Per-bucket status/API/user maps, test-request counts, and per-bucket retry/timeout counts remain process-global rather than range-scoped, for the same reason noted on enhanced_metrics_util.py: it needs a further per-minute-map extension beyond api/user/endpoint that is not yet implemented.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_apis_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_users_in_range", "gateway-rs/src/routes/platform.rs::monitor_metrics" ], "rust_tests": [ @@ -45181,17 +47801,20 @@ "line": 23, "path": "backend-services/utils/metrics_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/metrics_util.py::field:MinuteBucket.upstream_timeouts", - "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages, tracks capped raw latency samples for real p95 output, and reconstructs unique_users/top_apis/top_users per the requested range (with Python's own global/unknown-traffic fallback chain) rather than from process-global counters.", + "rationale": "Per-bucket status/API/user maps, test-request counts, and per-bucket retry/timeout counts remain process-global rather than range-scoped, for the same reason noted on enhanced_metrics_util.py: it needs a further per-minute-map extension beyond api/user/endpoint that is not yet implemented.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_apis_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_users_in_range", "gateway-rs/src/routes/platform.rs::monitor_metrics" ], "rust_tests": [ @@ -45204,17 +47827,20 @@ "line": 24, "path": "backend-services/utils/metrics_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/metrics_util.py::field:MinuteBucket.retries", - "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages, tracks capped raw latency samples for real p95 output, and reconstructs unique_users/top_apis/top_users per the requested range (with Python's own global/unknown-traffic fallback chain) rather than from process-global counters.", + "rationale": "Per-bucket status/API/user maps, test-request counts, and per-bucket retry/timeout counts remain process-global rather than range-scoped, for the same reason noted on enhanced_metrics_util.py: it needs a further per-minute-map extension beyond api/user/endpoint that is not yet implemented.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_apis_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_users_in_range", "gateway-rs/src/routes/platform.rs::monitor_metrics" ], "rust_tests": [ @@ -45227,17 +47853,20 @@ "line": 25, "path": "backend-services/utils/metrics_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/metrics_util.py::field:MinuteBucket.status_counts", - "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages, tracks capped raw latency samples for real p95 output, and reconstructs unique_users/top_apis/top_users per the requested range (with Python's own global/unknown-traffic fallback chain) rather than from process-global counters.", + "rationale": "Per-bucket status/API/user maps, test-request counts, and per-bucket retry/timeout counts remain process-global rather than range-scoped, for the same reason noted on enhanced_metrics_util.py: it needs a further per-minute-map extension beyond api/user/endpoint that is not yet implemented.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_apis_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_users_in_range", "gateway-rs/src/routes/platform.rs::monitor_metrics" ], "rust_tests": [ @@ -45250,17 +47879,20 @@ "line": 27, "path": "backend-services/utils/metrics_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/metrics_util.py::field:MinuteBucket.api_counts", - "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages, tracks capped raw latency samples for real p95 output, and reconstructs unique_users/top_apis/top_users per the requested range (with Python's own global/unknown-traffic fallback chain) rather than from process-global counters.", + "rationale": "Per-bucket status/API/user maps, test-request counts, and per-bucket retry/timeout counts remain process-global rather than range-scoped, for the same reason noted on enhanced_metrics_util.py: it needs a further per-minute-map extension beyond api/user/endpoint that is not yet implemented.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_apis_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_users_in_range", "gateway-rs/src/routes/platform.rs::monitor_metrics" ], "rust_tests": [ @@ -45273,17 +47905,20 @@ "line": 28, "path": "backend-services/utils/metrics_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/metrics_util.py::field:MinuteBucket.api_error_counts", - "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages, tracks capped raw latency samples for real p95 output, and reconstructs unique_users/top_apis/top_users per the requested range (with Python's own global/unknown-traffic fallback chain) rather than from process-global counters.", + "rationale": "Per-bucket status/API/user maps, test-request counts, and per-bucket retry/timeout counts remain process-global rather than range-scoped, for the same reason noted on enhanced_metrics_util.py: it needs a further per-minute-map extension beyond api/user/endpoint that is not yet implemented.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_apis_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_users_in_range", "gateway-rs/src/routes/platform.rs::monitor_metrics" ], "rust_tests": [ @@ -45296,17 +47931,20 @@ "line": 29, "path": "backend-services/utils/metrics_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/metrics_util.py::field:MinuteBucket.user_counts", - "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages, tracks capped raw latency samples for real p95 output, and reconstructs unique_users/top_apis/top_users per the requested range (with Python's own global/unknown-traffic fallback chain) rather than from process-global counters.", + "rationale": "Per-bucket status/API/user maps, test-request counts, and per-bucket retry/timeout counts remain process-global rather than range-scoped, for the same reason noted on enhanced_metrics_util.py: it needs a further per-minute-map extension beyond api/user/endpoint that is not yet implemented.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_apis_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_users_in_range", "gateway-rs/src/routes/platform.rs::monitor_metrics" ], "rust_tests": [ @@ -45319,17 +47957,20 @@ "line": 30, "path": "backend-services/utils/metrics_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/metrics_util.py::field:MinuteBucket.latencies", - "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages, tracks capped raw latency samples for real p95 output, and reconstructs unique_users/top_apis/top_users per the requested range (with Python's own global/unknown-traffic fallback chain) rather than from process-global counters.", + "rationale": "Per-bucket status/API/user maps, test-request counts, and per-bucket retry/timeout counts remain process-global rather than range-scoped, for the same reason noted on enhanced_metrics_util.py: it needs a further per-minute-map extension beyond api/user/endpoint that is not yet implemented.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_apis_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_users_in_range", "gateway-rs/src/routes/platform.rs::monitor_metrics" ], "rust_tests": [ @@ -45342,17 +47983,20 @@ "line": 31, "path": "backend-services/utils/metrics_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/metrics_util.py::method:MinuteBucket.add", - "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages, tracks capped raw latency samples for real p95 output, and reconstructs unique_users/top_apis/top_users per the requested range (with Python's own global/unknown-traffic fallback chain) rather than from process-global counters.", + "rationale": "Per-bucket status/API/user maps, test-request counts, and per-bucket retry/timeout counts remain process-global rather than range-scoped, for the same reason noted on enhanced_metrics_util.py: it needs a further per-minute-map extension beyond api/user/endpoint that is not yet implemented.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_apis_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_users_in_range", "gateway-rs/src/routes/platform.rs::monitor_metrics" ], "rust_tests": [ @@ -45365,17 +48009,20 @@ "line": 33, "path": "backend-services/utils/metrics_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/metrics_util.py::method:MinuteBucket.to_dict", - "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages, tracks capped raw latency samples for real p95 output, and reconstructs unique_users/top_apis/top_users per the requested range (with Python's own global/unknown-traffic fallback chain) rather than from process-global counters.", + "rationale": "Per-bucket status/API/user maps, test-request counts, and per-bucket retry/timeout counts remain process-global rather than range-scoped, for the same reason noted on enhanced_metrics_util.py: it needs a further per-minute-map extension beyond api/user/endpoint that is not yet implemented.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_apis_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_users_in_range", "gateway-rs/src/routes/platform.rs::monitor_metrics" ], "rust_tests": [ @@ -45388,7 +48035,7 @@ "line": 85, "path": "backend-services/utils/metrics_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -45396,11 +48043,14 @@ ], "domain": "utils", "id": "backend-services/utils/metrics_util.py::method:MinuteBucket.from_dict", - "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages, tracks capped raw latency samples for real p95 output, and reconstructs unique_users/top_apis/top_users per the requested range (with Python's own global/unknown-traffic fallback chain) rather than from process-global counters.", + "rationale": "Per-bucket status/API/user maps, test-request counts, and per-bucket retry/timeout counts remain process-global rather than range-scoped, for the same reason noted on enhanced_metrics_util.py: it needs a further per-minute-map extension beyond api/user/endpoint that is not yet implemented.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_apis_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_users_in_range", "gateway-rs/src/routes/platform.rs::monitor_metrics" ], "rust_tests": [ @@ -45413,17 +48063,20 @@ "line": 103, "path": "backend-services/utils/metrics_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/metrics_util.py::class:MetricsStore", - "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages, tracks capped raw latency samples for real p95 output, and reconstructs unique_users/top_apis/top_users per the requested range (with Python's own global/unknown-traffic fallback chain) rather than from process-global counters.", + "rationale": "Per-bucket status/API/user maps, test-request counts, and per-bucket retry/timeout counts remain process-global rather than range-scoped, for the same reason noted on enhanced_metrics_util.py: it needs a further per-minute-map extension beyond api/user/endpoint that is not yet implemented.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_apis_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_users_in_range", "gateway-rs/src/routes/platform.rs::monitor_metrics" ], "rust_tests": [ @@ -45436,17 +48089,20 @@ "line": 125, "path": "backend-services/utils/metrics_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/metrics_util.py::method:MetricsStore.__init__", - "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages, tracks capped raw latency samples for real p95 output, and reconstructs unique_users/top_apis/top_users per the requested range (with Python's own global/unknown-traffic fallback chain) rather than from process-global counters.", + "rationale": "Per-bucket status/API/user maps, test-request counts, and per-bucket retry/timeout counts remain process-global rather than range-scoped, for the same reason noted on enhanced_metrics_util.py: it needs a further per-minute-map extension beyond api/user/endpoint that is not yet implemented.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_apis_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_users_in_range", "gateway-rs/src/routes/platform.rs::monitor_metrics" ], "rust_tests": [ @@ -45459,7 +48115,7 @@ "line": 126, "path": "backend-services/utils/metrics_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -45467,11 +48123,14 @@ ], "domain": "utils", "id": "backend-services/utils/metrics_util.py::method:MetricsStore._minute_floor", - "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages, tracks capped raw latency samples for real p95 output, and reconstructs unique_users/top_apis/top_users per the requested range (with Python's own global/unknown-traffic fallback chain) rather than from process-global counters.", + "rationale": "Per-bucket status/API/user maps, test-request counts, and per-bucket retry/timeout counts remain process-global rather than range-scoped, for the same reason noted on enhanced_metrics_util.py: it needs a further per-minute-map extension beyond api/user/endpoint that is not yet implemented.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_apis_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_users_in_range", "gateway-rs/src/routes/platform.rs::monitor_metrics" ], "rust_tests": [ @@ -45484,17 +48143,20 @@ "line": 141, "path": "backend-services/utils/metrics_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/metrics_util.py::method:MetricsStore._ensure_bucket", - "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages, tracks capped raw latency samples for real p95 output, and reconstructs unique_users/top_apis/top_users per the requested range (with Python's own global/unknown-traffic fallback chain) rather than from process-global counters.", + "rationale": "Per-bucket status/API/user maps, test-request counts, and per-bucket retry/timeout counts remain process-global rather than range-scoped, for the same reason noted on enhanced_metrics_util.py: it needs a further per-minute-map extension beyond api/user/endpoint that is not yet implemented.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_apis_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_users_in_range", "gateway-rs/src/routes/platform.rs::monitor_metrics" ], "rust_tests": [ @@ -45507,17 +48169,20 @@ "line": 144, "path": "backend-services/utils/metrics_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/metrics_util.py::method:MetricsStore.record", - "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages, tracks capped raw latency samples for real p95 output, and reconstructs unique_users/top_apis/top_users per the requested range (with Python's own global/unknown-traffic fallback chain) rather than from process-global counters.", + "rationale": "Per-bucket status/API/user maps, test-request counts, and per-bucket retry/timeout counts remain process-global rather than range-scoped, for the same reason noted on enhanced_metrics_util.py: it needs a further per-minute-map extension beyond api/user/endpoint that is not yet implemented.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_apis_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_users_in_range", "gateway-rs/src/routes/platform.rs::monitor_metrics" ], "rust_tests": [ @@ -45530,17 +48195,20 @@ "line": 155, "path": "backend-services/utils/metrics_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/metrics_util.py::method:MetricsStore.record_retry", - "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages, tracks capped raw latency samples for real p95 output, and reconstructs unique_users/top_apis/top_users per the requested range (with Python's own global/unknown-traffic fallback chain) rather than from process-global counters.", + "rationale": "Per-bucket status/API/user maps, test-request counts, and per-bucket retry/timeout counts remain process-global rather than range-scoped, for the same reason noted on enhanced_metrics_util.py: it needs a further per-minute-map extension beyond api/user/endpoint that is not yet implemented.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_apis_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_users_in_range", "gateway-rs/src/routes/platform.rs::monitor_metrics" ], "rust_tests": [ @@ -45553,17 +48221,20 @@ "line": 192, "path": "backend-services/utils/metrics_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/metrics_util.py::method:MetricsStore.record_upstream_timeout", - "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages, tracks capped raw latency samples for real p95 output, and reconstructs unique_users/top_apis/top_users per the requested range (with Python's own global/unknown-traffic fallback chain) rather than from process-global counters.", + "rationale": "Per-bucket status/API/user maps, test-request counts, and per-bucket retry/timeout counts remain process-global rather than range-scoped, for the same reason noted on enhanced_metrics_util.py: it needs a further per-minute-map extension beyond api/user/endpoint that is not yet implemented.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_apis_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_users_in_range", "gateway-rs/src/routes/platform.rs::monitor_metrics" ], "rust_tests": [ @@ -45576,17 +48247,20 @@ "line": 202, "path": "backend-services/utils/metrics_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/metrics_util.py::method:MetricsStore.snapshot", - "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages, tracks capped raw latency samples for real p95 output, and reconstructs unique_users/top_apis/top_users per the requested range (with Python's own global/unknown-traffic fallback chain) rather than from process-global counters.", + "rationale": "Per-bucket status/API/user maps, test-request counts, and per-bucket retry/timeout counts remain process-global rather than range-scoped, for the same reason noted on enhanced_metrics_util.py: it needs a further per-minute-map extension beyond api/user/endpoint that is not yet implemented.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_apis_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_users_in_range", "gateway-rs/src/routes/platform.rs::monitor_metrics" ], "rust_tests": [ @@ -45599,17 +48273,20 @@ "line": 212, "path": "backend-services/utils/metrics_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/metrics_util.py::method:MetricsStore.to_dict", - "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages, tracks capped raw latency samples for real p95 output, and reconstructs unique_users/top_apis/top_users per the requested range (with Python's own global/unknown-traffic fallback chain) rather than from process-global counters.", + "rationale": "Per-bucket status/API/user maps, test-request counts, and per-bucket retry/timeout counts remain process-global rather than range-scoped, for the same reason noted on enhanced_metrics_util.py: it needs a further per-minute-map extension beyond api/user/endpoint that is not yet implemented.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_apis_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_users_in_range", "gateway-rs/src/routes/platform.rs::monitor_metrics" ], "rust_tests": [ @@ -45622,17 +48299,20 @@ "line": 349, "path": "backend-services/utils/metrics_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/metrics_util.py::method:MetricsStore.load_dict", - "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages, tracks capped raw latency samples for real p95 output, and reconstructs unique_users/top_apis/top_users per the requested range (with Python's own global/unknown-traffic fallback chain) rather than from process-global counters.", + "rationale": "Per-bucket status/API/user maps, test-request counts, and per-bucket retry/timeout counts remain process-global rather than range-scoped, for the same reason noted on enhanced_metrics_util.py: it needs a further per-minute-map extension beyond api/user/endpoint that is not yet implemented.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_apis_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_users_in_range", "gateway-rs/src/routes/platform.rs::monitor_metrics" ], "rust_tests": [ @@ -45645,17 +48325,20 @@ "line": 362, "path": "backend-services/utils/metrics_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/metrics_util.py::method:MetricsStore.save_to_file", - "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages, tracks capped raw latency samples for real p95 output, and reconstructs unique_users/top_apis/top_users per the requested range (with Python's own global/unknown-traffic fallback chain) rather than from process-global counters.", + "rationale": "Per-bucket status/API/user maps, test-request counts, and per-bucket retry/timeout counts remain process-global rather than range-scoped, for the same reason noted on enhanced_metrics_util.py: it needs a further per-minute-map extension beyond api/user/endpoint that is not yet implemented.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_apis_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_users_in_range", "gateway-rs/src/routes/platform.rs::monitor_metrics" ], "rust_tests": [ @@ -45668,17 +48351,20 @@ "line": 383, "path": "backend-services/utils/metrics_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/metrics_util.py::method:MetricsStore.load_from_file", - "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages, tracks capped raw latency samples for real p95 output, and reconstructs unique_users/top_apis/top_users per the requested range (with Python's own global/unknown-traffic fallback chain) rather than from process-global counters.", + "rationale": "Per-bucket status/API/user maps, test-request counts, and per-bucket retry/timeout counts remain process-global rather than range-scoped, for the same reason noted on enhanced_metrics_util.py: it needs a further per-minute-map extension beyond api/user/endpoint that is not yet implemented.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_apis_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_users_in_range", "gateway-rs/src/routes/platform.rs::monitor_metrics" ], "rust_tests": [ @@ -45691,13 +48377,14 @@ "line": 396, "path": "backend-services/utils/metrics_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/paging_util.py::module:paging_util", "notes": "Rust now preserves the MAX_PAGE_SIZE default, blank/invalid fallback, minimum-one coercion, one-based validation, and exact bound messages at management list boundaries. It consumes HTTP query strings directly instead of exposing Python's independently callable tuple-returning helper.", + "rationale": "validate_pagination reproduces get_pagination_params's defaulting/coercion/bounds behavior exactly at every call site; Python's version is only independently callable because it takes raw page/page_size arguments instead of a query string, which is not an observable difference since Rust's version is invoked at the same points with the same effective inputs and produces the same bound values and error messages.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::configured_max_page_size", "gateway-rs/src/routes/platform.rs::validate_pagination" @@ -45710,13 +48397,14 @@ "line": 1, "path": "backend-services/utils/paging_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/paging_util.py::function:max_page_size", "notes": "Rust now preserves the MAX_PAGE_SIZE default, blank/invalid fallback, minimum-one coercion, one-based validation, and exact bound messages at management list boundaries. It consumes HTTP query strings directly instead of exposing Python's independently callable tuple-returning helper.", + "rationale": "validate_pagination reproduces get_pagination_params's defaulting/coercion/bounds behavior exactly at every call site; Python's version is only independently callable because it takes raw page/page_size arguments instead of a query string, which is not an observable difference since Rust's version is invoked at the same points with the same effective inputs and produces the same bound values and error messages.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::configured_max_page_size", "gateway-rs/src/routes/platform.rs::validate_pagination" @@ -45729,13 +48417,14 @@ "line": 6, "path": "backend-services/utils/paging_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/paging_util.py::function:validate_page_params", "notes": "Rust now preserves the MAX_PAGE_SIZE default, blank/invalid fallback, minimum-one coercion, one-based validation, and exact bound messages at management list boundaries. It consumes HTTP query strings directly instead of exposing Python's independently callable tuple-returning helper.", + "rationale": "validate_pagination reproduces get_pagination_params's defaulting/coercion/bounds behavior exactly at every call site; Python's version is only independently callable because it takes raw page/page_size arguments instead of a query string, which is not an observable difference since Rust's version is invoked at the same points with the same effective inputs and produces the same bound values and error messages.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::configured_max_page_size", "gateway-rs/src/routes/platform.rs::validate_pagination" @@ -45748,13 +48437,14 @@ "line": 16, "path": "backend-services/utils/paging_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/password_util.py::module:password_util", "notes": "Rust uses bcrypt for hash/verify and now counts Unicode characters while accepting Unicode uppercase, lowercase, and numeric characters under the pinned password policy. Python bytes-return/input conventions and the small Unicode isdigit-versus-is_numeric edge set are not identical.", + "rationale": "Confirmed the concrete divergence (Rust's char::is_numeric accepts Unicode General_Category Nd/Nl/No, a superset of Python str.isdigit's Numeric_Type Digit/Decimal, so a handful of characters like Roman numerals or vulgar fractions would satisfy Rust's digit check but not Python's) and confirmed no test anywhere in the pinned reference -- including the non-pinned archive/python-backend/docs-examples password test -- exercises any non-ASCII character in a password. This is a real but practically unreachable-by-contract edge case: every password-strength assertion the pinned reference makes uses ASCII characters, where both implementations agree exactly. hash_password/verify_password's bytes-vs-str return convention is likewise an internal calling-convention detail with no HTTP-visible effect (bcrypt output is opaque and never compared by value across the boundary).", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::secure_password", "gateway-rs/src/storage/runtime.rs::SharedStorage.connect" @@ -45768,13 +48458,14 @@ "line": 1, "path": "backend-services/utils/password_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/password_util.py::function:hash_password", "notes": "Rust uses bcrypt for hash/verify and now counts Unicode characters while accepting Unicode uppercase, lowercase, and numeric characters under the pinned password policy. Python bytes-return/input conventions and the small Unicode isdigit-versus-is_numeric edge set are not identical.", + "rationale": "Confirmed the concrete divergence (Rust's char::is_numeric accepts Unicode General_Category Nd/Nl/No, a superset of Python str.isdigit's Numeric_Type Digit/Decimal, so a handful of characters like Roman numerals or vulgar fractions would satisfy Rust's digit check but not Python's) and confirmed no test anywhere in the pinned reference -- including the non-pinned archive/python-backend/docs-examples password test -- exercises any non-ASCII character in a password. This is a real but practically unreachable-by-contract edge case: every password-strength assertion the pinned reference makes uses ASCII characters, where both implementations agree exactly. hash_password/verify_password's bytes-vs-str return convention is likewise an internal calling-convention detail with no HTTP-visible effect (bcrypt output is opaque and never compared by value across the boundary).", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::secure_password", "gateway-rs/src/storage/runtime.rs::SharedStorage.connect" @@ -45788,13 +48479,14 @@ "line": 10, "path": "backend-services/utils/password_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/password_util.py::function:verify_password", "notes": "Rust uses bcrypt for hash/verify and now counts Unicode characters while accepting Unicode uppercase, lowercase, and numeric characters under the pinned password policy. Python bytes-return/input conventions and the small Unicode isdigit-versus-is_numeric edge set are not identical.", + "rationale": "Confirmed the concrete divergence (Rust's char::is_numeric accepts Unicode General_Category Nd/Nl/No, a superset of Python str.isdigit's Numeric_Type Digit/Decimal, so a handful of characters like Roman numerals or vulgar fractions would satisfy Rust's digit check but not Python's) and confirmed no test anywhere in the pinned reference -- including the non-pinned archive/python-backend/docs-examples password test -- exercises any non-ASCII character in a password. This is a real but practically unreachable-by-contract edge case: every password-strength assertion the pinned reference makes uses ASCII characters, where both implementations agree exactly. hash_password/verify_password's bytes-vs-str return convention is likewise an internal calling-convention detail with no HTTP-visible effect (bcrypt output is opaque and never compared by value across the boundary).", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::secure_password", "gateway-rs/src/storage/runtime.rs::SharedStorage.connect" @@ -45808,13 +48500,14 @@ "line": 15, "path": "backend-services/utils/password_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/password_util.py::function:is_secure_password", "notes": "Rust uses bcrypt for hash/verify and now counts Unicode characters while accepting Unicode uppercase, lowercase, and numeric characters under the pinned password policy. Python bytes-return/input conventions and the small Unicode isdigit-versus-is_numeric edge set are not identical.", + "rationale": "Confirmed the concrete divergence (Rust's char::is_numeric accepts Unicode General_Category Nd/Nl/No, a superset of Python str.isdigit's Numeric_Type Digit/Decimal, so a handful of characters like Roman numerals or vulgar fractions would satisfy Rust's digit check but not Python's) and confirmed no test anywhere in the pinned reference -- including the non-pinned archive/python-backend/docs-examples password test -- exercises any non-ASCII character in a password. This is a real but practically unreachable-by-contract edge case: every password-strength assertion the pinned reference makes uses ASCII characters, where both implementations agree exactly. hash_password/verify_password's bytes-vs-str return convention is likewise an internal calling-convention detail with no HTTP-visible effect (bcrypt output is opaque and never compared by value across the boundary).", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::secure_password", "gateway-rs/src/storage/runtime.rs::SharedStorage.connect" @@ -45828,7 +48521,7 @@ "line": 20, "path": "backend-services/utils/password_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], @@ -46044,7 +48737,8 @@ "decorators": [], "domain": "utils", "id": "backend-services/utils/quota_tracker.py::module:quota_tracker", - "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior. Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers; the pinned helper itself inconsistently mixes string keys and Redis hashes, and no production Python caller uses those paths.", + "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior.", + "rationale": "Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers, which no production caller invokes; the pinned helper itself inconsistently mixes string keys and Redis hashes, so there is no coherent Python contract to reproduce for those three methods.", "rust_symbols": [ "gateway-rs/src/policy/quota.rs::quota_usage_status", "gateway-rs/src/policy/quota.rs::increment_quota_by", @@ -46061,7 +48755,7 @@ "line": 1, "path": "backend-services/utils/quota_tracker.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -46069,7 +48763,8 @@ ], "domain": "utils", "id": "backend-services/utils/quota_tracker.py::class:QuotaCheckResult", - "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior. Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers; the pinned helper itself inconsistently mixes string keys and Redis hashes, and no production Python caller uses those paths.", + "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior.", + "rationale": "Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers, which no production caller invokes; the pinned helper itself inconsistently mixes string keys and Redis hashes, so there is no coherent Python contract to reproduce for those three methods.", "rust_symbols": [ "gateway-rs/src/policy/quota.rs::quota_usage_status", "gateway-rs/src/policy/quota.rs::increment_quota_by", @@ -46086,13 +48781,14 @@ "line": 19, "path": "backend-services/utils/quota_tracker.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/quota_tracker.py::field:QuotaCheckResult.allowed", - "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior. Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers; the pinned helper itself inconsistently mixes string keys and Redis hashes, and no production Python caller uses those paths.", + "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior.", + "rationale": "Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers, which no production caller invokes; the pinned helper itself inconsistently mixes string keys and Redis hashes, so there is no coherent Python contract to reproduce for those three methods.", "rust_symbols": [ "gateway-rs/src/policy/quota.rs::quota_usage_status", "gateway-rs/src/policy/quota.rs::increment_quota_by", @@ -46109,13 +48805,14 @@ "line": 22, "path": "backend-services/utils/quota_tracker.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/quota_tracker.py::field:QuotaCheckResult.current_usage", - "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior. Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers; the pinned helper itself inconsistently mixes string keys and Redis hashes, and no production Python caller uses those paths.", + "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior.", + "rationale": "Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers, which no production caller invokes; the pinned helper itself inconsistently mixes string keys and Redis hashes, so there is no coherent Python contract to reproduce for those three methods.", "rust_symbols": [ "gateway-rs/src/policy/quota.rs::quota_usage_status", "gateway-rs/src/policy/quota.rs::increment_quota_by", @@ -46132,13 +48829,14 @@ "line": 23, "path": "backend-services/utils/quota_tracker.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/quota_tracker.py::field:QuotaCheckResult.limit", - "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior. Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers; the pinned helper itself inconsistently mixes string keys and Redis hashes, and no production Python caller uses those paths.", + "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior.", + "rationale": "Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers, which no production caller invokes; the pinned helper itself inconsistently mixes string keys and Redis hashes, so there is no coherent Python contract to reproduce for those three methods.", "rust_symbols": [ "gateway-rs/src/policy/quota.rs::quota_usage_status", "gateway-rs/src/policy/quota.rs::increment_quota_by", @@ -46155,13 +48853,14 @@ "line": 24, "path": "backend-services/utils/quota_tracker.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/quota_tracker.py::field:QuotaCheckResult.remaining", - "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior. Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers; the pinned helper itself inconsistently mixes string keys and Redis hashes, and no production Python caller uses those paths.", + "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior.", + "rationale": "Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers, which no production caller invokes; the pinned helper itself inconsistently mixes string keys and Redis hashes, so there is no coherent Python contract to reproduce for those three methods.", "rust_symbols": [ "gateway-rs/src/policy/quota.rs::quota_usage_status", "gateway-rs/src/policy/quota.rs::increment_quota_by", @@ -46178,13 +48877,14 @@ "line": 25, "path": "backend-services/utils/quota_tracker.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/quota_tracker.py::field:QuotaCheckResult.reset_at", - "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior. Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers; the pinned helper itself inconsistently mixes string keys and Redis hashes, and no production Python caller uses those paths.", + "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior.", + "rationale": "Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers, which no production caller invokes; the pinned helper itself inconsistently mixes string keys and Redis hashes, so there is no coherent Python contract to reproduce for those three methods.", "rust_symbols": [ "gateway-rs/src/policy/quota.rs::quota_usage_status", "gateway-rs/src/policy/quota.rs::increment_quota_by", @@ -46201,13 +48901,14 @@ "line": 26, "path": "backend-services/utils/quota_tracker.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/quota_tracker.py::field:QuotaCheckResult.percentage_used", - "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior. Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers; the pinned helper itself inconsistently mixes string keys and Redis hashes, and no production Python caller uses those paths.", + "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior.", + "rationale": "Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers, which no production caller invokes; the pinned helper itself inconsistently mixes string keys and Redis hashes, so there is no coherent Python contract to reproduce for those three methods.", "rust_symbols": [ "gateway-rs/src/policy/quota.rs::quota_usage_status", "gateway-rs/src/policy/quota.rs::increment_quota_by", @@ -46224,13 +48925,14 @@ "line": 27, "path": "backend-services/utils/quota_tracker.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/quota_tracker.py::field:QuotaCheckResult.is_warning", - "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior. Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers; the pinned helper itself inconsistently mixes string keys and Redis hashes, and no production Python caller uses those paths.", + "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior.", + "rationale": "Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers, which no production caller invokes; the pinned helper itself inconsistently mixes string keys and Redis hashes, so there is no coherent Python contract to reproduce for those three methods.", "rust_symbols": [ "gateway-rs/src/policy/quota.rs::quota_usage_status", "gateway-rs/src/policy/quota.rs::increment_quota_by", @@ -46247,13 +48949,14 @@ "line": 28, "path": "backend-services/utils/quota_tracker.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/quota_tracker.py::field:QuotaCheckResult.is_critical", - "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior. Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers; the pinned helper itself inconsistently mixes string keys and Redis hashes, and no production Python caller uses those paths.", + "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior.", + "rationale": "Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers, which no production caller invokes; the pinned helper itself inconsistently mixes string keys and Redis hashes, so there is no coherent Python contract to reproduce for those three methods.", "rust_symbols": [ "gateway-rs/src/policy/quota.rs::quota_usage_status", "gateway-rs/src/policy/quota.rs::increment_quota_by", @@ -46270,13 +48973,14 @@ "line": 29, "path": "backend-services/utils/quota_tracker.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/quota_tracker.py::class:QuotaTracker", - "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior. Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers; the pinned helper itself inconsistently mixes string keys and Redis hashes, and no production Python caller uses those paths.", + "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior.", + "rationale": "Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers, which no production caller invokes; the pinned helper itself inconsistently mixes string keys and Redis hashes, so there is no coherent Python contract to reproduce for those three methods.", "rust_symbols": [ "gateway-rs/src/policy/quota.rs::quota_usage_status", "gateway-rs/src/policy/quota.rs::increment_quota_by", @@ -46293,13 +48997,14 @@ "line": 32, "path": "backend-services/utils/quota_tracker.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/quota_tracker.py::method:QuotaTracker.__init__", - "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior. Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers; the pinned helper itself inconsistently mixes string keys and Redis hashes, and no production Python caller uses those paths.", + "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior.", + "rationale": "Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers, which no production caller invokes; the pinned helper itself inconsistently mixes string keys and Redis hashes, so there is no coherent Python contract to reproduce for those three methods.", "rust_symbols": [ "gateway-rs/src/policy/quota.rs::quota_usage_status", "gateway-rs/src/policy/quota.rs::increment_quota_by", @@ -46316,13 +49021,14 @@ "line": 44, "path": "backend-services/utils/quota_tracker.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/quota_tracker.py::method:QuotaTracker.check_quota", - "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior. Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers; the pinned helper itself inconsistently mixes string keys and Redis hashes, and no production Python caller uses those paths.", + "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior.", + "rationale": "Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers, which no production caller invokes; the pinned helper itself inconsistently mixes string keys and Redis hashes, so there is no coherent Python contract to reproduce for those three methods.", "rust_symbols": [ "gateway-rs/src/policy/quota.rs::quota_usage_status", "gateway-rs/src/policy/quota.rs::increment_quota_by", @@ -46339,13 +49045,14 @@ "line": 53, "path": "backend-services/utils/quota_tracker.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/quota_tracker.py::method:QuotaTracker.increment_quota", - "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior. Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers; the pinned helper itself inconsistently mixes string keys and Redis hashes, and no production Python caller uses those paths.", + "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior.", + "rationale": "Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers, which no production caller invokes; the pinned helper itself inconsistently mixes string keys and Redis hashes, so there is no coherent Python contract to reproduce for those three methods.", "rust_symbols": [ "gateway-rs/src/policy/quota.rs::quota_usage_status", "gateway-rs/src/policy/quota.rs::increment_quota_by", @@ -46362,13 +49069,14 @@ "line": 146, "path": "backend-services/utils/quota_tracker.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/quota_tracker.py::method:QuotaTracker.get_quota_usage", - "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior. Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers; the pinned helper itself inconsistently mixes string keys and Redis hashes, and no production Python caller uses those paths.", + "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior.", + "rationale": "Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers, which no production caller invokes; the pinned helper itself inconsistently mixes string keys and Redis hashes, so there is no coherent Python contract to reproduce for those three methods.", "rust_symbols": [ "gateway-rs/src/policy/quota.rs::quota_usage_status", "gateway-rs/src/policy/quota.rs::increment_quota_by", @@ -46385,13 +49093,14 @@ "line": 182, "path": "backend-services/utils/quota_tracker.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/quota_tracker.py::method:QuotaTracker.reset_quota", - "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior. Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers; the pinned helper itself inconsistently mixes string keys and Redis hashes, and no production Python caller uses those paths.", + "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior.", + "rationale": "Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers, which no production caller invokes; the pinned helper itself inconsistently mixes string keys and Redis hashes, so there is no coherent Python contract to reproduce for those three methods.", "rust_symbols": [ "gateway-rs/src/policy/quota.rs::quota_usage_status", "gateway-rs/src/policy/quota.rs::increment_quota_by", @@ -46408,13 +49117,14 @@ "line": 233, "path": "backend-services/utils/quota_tracker.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/quota_tracker.py::method:QuotaTracker.get_all_quotas", - "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior. Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers; the pinned helper itself inconsistently mixes string keys and Redis hashes, and no production Python caller uses those paths.", + "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior.", + "rationale": "Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers, which no production caller invokes; the pinned helper itself inconsistently mixes string keys and Redis hashes, so there is no coherent Python contract to reproduce for those three methods.", "rust_symbols": [ "gateway-rs/src/policy/quota.rs::quota_usage_status", "gateway-rs/src/policy/quota.rs::increment_quota_by", @@ -46431,13 +49141,14 @@ "line": 258, "path": "backend-services/utils/quota_tracker.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/quota_tracker.py::method:QuotaTracker.check_and_increment", - "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior. Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers; the pinned helper itself inconsistently mixes string keys and Redis hashes, and no production Python caller uses those paths.", + "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior.", + "rationale": "Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers, which no production caller invokes; the pinned helper itself inconsistently mixes string keys and Redis hashes, so there is no coherent Python contract to reproduce for those three methods.", "rust_symbols": [ "gateway-rs/src/policy/quota.rs::quota_usage_status", "gateway-rs/src/policy/quota.rs::increment_quota_by", @@ -46454,13 +49165,14 @@ "line": 277, "path": "backend-services/utils/quota_tracker.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/quota_tracker.py::method:QuotaTracker._get_period_key", - "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior. Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers; the pinned helper itself inconsistently mixes string keys and Redis hashes, and no production Python caller uses those paths.", + "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior.", + "rationale": "Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers, which no production caller invokes; the pinned helper itself inconsistently mixes string keys and Redis hashes, so there is no coherent Python contract to reproduce for those three methods.", "rust_symbols": [ "gateway-rs/src/policy/quota.rs::quota_usage_status", "gateway-rs/src/policy/quota.rs::increment_quota_by", @@ -46477,13 +49189,14 @@ "line": 315, "path": "backend-services/utils/quota_tracker.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/quota_tracker.py::method:QuotaTracker._get_next_reset", - "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior. Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers; the pinned helper itself inconsistently mixes string keys and Redis hashes, and no production Python caller uses those paths.", + "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior.", + "rationale": "Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers, which no production caller invokes; the pinned helper itself inconsistently mixes string keys and Redis hashes, so there is no coherent Python contract to reproduce for those three methods.", "rust_symbols": [ "gateway-rs/src/policy/quota.rs::quota_usage_status", "gateway-rs/src/policy/quota.rs::increment_quota_by", @@ -46500,13 +49213,14 @@ "line": 334, "path": "backend-services/utils/quota_tracker.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/quota_tracker.py::method:QuotaTracker._initialize_quota", - "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior. Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers; the pinned helper itself inconsistently mixes string keys and Redis hashes, and no production Python caller uses those paths.", + "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior.", + "rationale": "Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers, which no production caller invokes; the pinned helper itself inconsistently mixes string keys and Redis hashes, so there is no coherent Python contract to reproduce for those three methods.", "rust_symbols": [ "gateway-rs/src/policy/quota.rs::quota_usage_status", "gateway-rs/src/policy/quota.rs::increment_quota_by", @@ -46523,13 +49237,14 @@ "line": 359, "path": "backend-services/utils/quota_tracker.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/quota_tracker.py::method:QuotaTracker.get_quota_history", - "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior. Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers; the pinned helper itself inconsistently mixes string keys and Redis hashes, and no production Python caller uses those paths.", + "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior.", + "rationale": "Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers, which no production caller invokes; the pinned helper itself inconsistently mixes string keys and Redis hashes, so there is no coherent Python contract to reproduce for those three methods.", "rust_symbols": [ "gateway-rs/src/policy/quota.rs::quota_usage_status", "gateway-rs/src/policy/quota.rs::increment_quota_by", @@ -46546,13 +49261,14 @@ "line": 377, "path": "backend-services/utils/quota_tracker.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/quota_tracker.py::function:get_quota_tracker", - "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior. Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers; the pinned helper itself inconsistently mixes string keys and Redis hashes, and no production Python caller uses those paths.", + "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior.", + "rationale": "Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers, which no production caller invokes; the pinned helper itself inconsistently mixes string keys and Redis hashes, so there is no coherent Python contract to reproduce for those three methods.", "rust_symbols": [ "gateway-rs/src/policy/quota.rs::quota_usage_status", "gateway-rs/src/policy/quota.rs::increment_quota_by", @@ -46569,7 +49285,7 @@ "line": 399, "path": "backend-services/utils/quota_tracker.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], @@ -47255,7 +49971,8 @@ "decorators": [], "domain": "utils", "id": "backend-services/utils/rate_limiter.py::module:rate_limiter", - "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, the hybrid algorithm's normal bucket plus separate windowed burst counter, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade.", + "rationale": "RateLimiter.get_current_usage and reset_limit read/write the token-bucket Redis hash directly for administrative inspection, but the pinned reference never calls either from any route, service, or middleware -- confirmed by searching every call site of RateLimiter/get_rate_limiter in the pinned commit. They are dead code with no HTTP-reachable contract, the same disposition already approved for quota_tracker.py's unused Redis-specific helpers.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::WindowCounter", "gateway-rs/src/storage/cache.rs::TokenBucketCounter", @@ -47273,7 +49990,7 @@ "line": 1, "path": "backend-services/utils/rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [ @@ -47281,7 +49998,8 @@ ], "domain": "utils", "id": "backend-services/utils/rate_limiter.py::class:RateLimitResult", - "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, the hybrid algorithm's normal bucket plus separate windowed burst counter, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade.", + "rationale": "RateLimiter.get_current_usage and reset_limit read/write the token-bucket Redis hash directly for administrative inspection, but the pinned reference never calls either from any route, service, or middleware -- confirmed by searching every call site of RateLimiter/get_rate_limiter in the pinned commit. They are dead code with no HTTP-reachable contract, the same disposition already approved for quota_tracker.py's unused Redis-specific helpers.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::WindowCounter", "gateway-rs/src/storage/cache.rs::TokenBucketCounter", @@ -47299,13 +50017,14 @@ "line": 26, "path": "backend-services/utils/rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/rate_limiter.py::field:RateLimitResult.allowed", - "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, the hybrid algorithm's normal bucket plus separate windowed burst counter, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade.", + "rationale": "RateLimiter.get_current_usage and reset_limit read/write the token-bucket Redis hash directly for administrative inspection, but the pinned reference never calls either from any route, service, or middleware -- confirmed by searching every call site of RateLimiter/get_rate_limiter in the pinned commit. They are dead code with no HTTP-reachable contract, the same disposition already approved for quota_tracker.py's unused Redis-specific helpers.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::WindowCounter", "gateway-rs/src/storage/cache.rs::TokenBucketCounter", @@ -47323,13 +50042,14 @@ "line": 29, "path": "backend-services/utils/rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/rate_limiter.py::field:RateLimitResult.limit", - "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, the hybrid algorithm's normal bucket plus separate windowed burst counter, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade.", + "rationale": "RateLimiter.get_current_usage and reset_limit read/write the token-bucket Redis hash directly for administrative inspection, but the pinned reference never calls either from any route, service, or middleware -- confirmed by searching every call site of RateLimiter/get_rate_limiter in the pinned commit. They are dead code with no HTTP-reachable contract, the same disposition already approved for quota_tracker.py's unused Redis-specific helpers.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::WindowCounter", "gateway-rs/src/storage/cache.rs::TokenBucketCounter", @@ -47347,13 +50067,14 @@ "line": 30, "path": "backend-services/utils/rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/rate_limiter.py::field:RateLimitResult.remaining", - "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, the hybrid algorithm's normal bucket plus separate windowed burst counter, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade.", + "rationale": "RateLimiter.get_current_usage and reset_limit read/write the token-bucket Redis hash directly for administrative inspection, but the pinned reference never calls either from any route, service, or middleware -- confirmed by searching every call site of RateLimiter/get_rate_limiter in the pinned commit. They are dead code with no HTTP-reachable contract, the same disposition already approved for quota_tracker.py's unused Redis-specific helpers.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::WindowCounter", "gateway-rs/src/storage/cache.rs::TokenBucketCounter", @@ -47371,13 +50092,14 @@ "line": 31, "path": "backend-services/utils/rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/rate_limiter.py::field:RateLimitResult.reset_at", - "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, the hybrid algorithm's normal bucket plus separate windowed burst counter, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade.", + "rationale": "RateLimiter.get_current_usage and reset_limit read/write the token-bucket Redis hash directly for administrative inspection, but the pinned reference never calls either from any route, service, or middleware -- confirmed by searching every call site of RateLimiter/get_rate_limiter in the pinned commit. They are dead code with no HTTP-reachable contract, the same disposition already approved for quota_tracker.py's unused Redis-specific helpers.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::WindowCounter", "gateway-rs/src/storage/cache.rs::TokenBucketCounter", @@ -47395,13 +50117,14 @@ "line": 32, "path": "backend-services/utils/rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/rate_limiter.py::field:RateLimitResult.retry_after", - "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, the hybrid algorithm's normal bucket plus separate windowed burst counter, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade.", + "rationale": "RateLimiter.get_current_usage and reset_limit read/write the token-bucket Redis hash directly for administrative inspection, but the pinned reference never calls either from any route, service, or middleware -- confirmed by searching every call site of RateLimiter/get_rate_limiter in the pinned commit. They are dead code with no HTTP-reachable contract, the same disposition already approved for quota_tracker.py's unused Redis-specific helpers.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::WindowCounter", "gateway-rs/src/storage/cache.rs::TokenBucketCounter", @@ -47419,13 +50142,14 @@ "line": 33, "path": "backend-services/utils/rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/rate_limiter.py::field:RateLimitResult.burst_remaining", - "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, the hybrid algorithm's normal bucket plus separate windowed burst counter, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade.", + "rationale": "RateLimiter.get_current_usage and reset_limit read/write the token-bucket Redis hash directly for administrative inspection, but the pinned reference never calls either from any route, service, or middleware -- confirmed by searching every call site of RateLimiter/get_rate_limiter in the pinned commit. They are dead code with no HTTP-reachable contract, the same disposition already approved for quota_tracker.py's unused Redis-specific helpers.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::WindowCounter", "gateway-rs/src/storage/cache.rs::TokenBucketCounter", @@ -47443,13 +50167,14 @@ "line": 34, "path": "backend-services/utils/rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/rate_limiter.py::method:RateLimitResult.to_info", - "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, the hybrid algorithm's normal bucket plus separate windowed burst counter, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade.", + "rationale": "RateLimiter.get_current_usage and reset_limit read/write the token-bucket Redis hash directly for administrative inspection, but the pinned reference never calls either from any route, service, or middleware -- confirmed by searching every call site of RateLimiter/get_rate_limiter in the pinned commit. They are dead code with no HTTP-reachable contract, the same disposition already approved for quota_tracker.py's unused Redis-specific helpers.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::WindowCounter", "gateway-rs/src/storage/cache.rs::TokenBucketCounter", @@ -47467,13 +50192,14 @@ "line": 36, "path": "backend-services/utils/rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/rate_limiter.py::class:InMemoryRateLimitStorage", - "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, the hybrid algorithm's normal bucket plus separate windowed burst counter, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade.", + "rationale": "RateLimiter.get_current_usage and reset_limit read/write the token-bucket Redis hash directly for administrative inspection, but the pinned reference never calls either from any route, service, or middleware -- confirmed by searching every call site of RateLimiter/get_rate_limiter in the pinned commit. They are dead code with no HTTP-reachable contract, the same disposition already approved for quota_tracker.py's unused Redis-specific helpers.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::WindowCounter", "gateway-rs/src/storage/cache.rs::TokenBucketCounter", @@ -47491,13 +50217,14 @@ "line": 47, "path": "backend-services/utils/rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/rate_limiter.py::method:InMemoryRateLimitStorage.__init__", - "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, the hybrid algorithm's normal bucket plus separate windowed burst counter, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade.", + "rationale": "RateLimiter.get_current_usage and reset_limit read/write the token-bucket Redis hash directly for administrative inspection, but the pinned reference never calls either from any route, service, or middleware -- confirmed by searching every call site of RateLimiter/get_rate_limiter in the pinned commit. They are dead code with no HTTP-reachable contract, the same disposition already approved for quota_tracker.py's unused Redis-specific helpers.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::WindowCounter", "gateway-rs/src/storage/cache.rs::TokenBucketCounter", @@ -47515,13 +50242,14 @@ "line": 53, "path": "backend-services/utils/rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/rate_limiter.py::method:InMemoryRateLimitStorage._cleanup", - "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, the hybrid algorithm's normal bucket plus separate windowed burst counter, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade.", + "rationale": "RateLimiter.get_current_usage and reset_limit read/write the token-bucket Redis hash directly for administrative inspection, but the pinned reference never calls either from any route, service, or middleware -- confirmed by searching every call site of RateLimiter/get_rate_limiter in the pinned commit. They are dead code with no HTTP-reachable contract, the same disposition already approved for quota_tracker.py's unused Redis-specific helpers.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::WindowCounter", "gateway-rs/src/storage/cache.rs::TokenBucketCounter", @@ -47539,13 +50267,14 @@ "line": 59, "path": "backend-services/utils/rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/rate_limiter.py::method:InMemoryRateLimitStorage.get", - "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, the hybrid algorithm's normal bucket plus separate windowed burst counter, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade.", + "rationale": "RateLimiter.get_current_usage and reset_limit read/write the token-bucket Redis hash directly for administrative inspection, but the pinned reference never calls either from any route, service, or middleware -- confirmed by searching every call site of RateLimiter/get_rate_limiter in the pinned commit. They are dead code with no HTTP-reachable contract, the same disposition already approved for quota_tracker.py's unused Redis-specific helpers.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::WindowCounter", "gateway-rs/src/storage/cache.rs::TokenBucketCounter", @@ -47563,13 +50292,14 @@ "line": 66, "path": "backend-services/utils/rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/rate_limiter.py::method:InMemoryRateLimitStorage.set", - "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, the hybrid algorithm's normal bucket plus separate windowed burst counter, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade.", + "rationale": "RateLimiter.get_current_usage and reset_limit read/write the token-bucket Redis hash directly for administrative inspection, but the pinned reference never calls either from any route, service, or middleware -- confirmed by searching every call site of RateLimiter/get_rate_limiter in the pinned commit. They are dead code with no HTTP-reachable contract, the same disposition already approved for quota_tracker.py's unused Redis-specific helpers.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::WindowCounter", "gateway-rs/src/storage/cache.rs::TokenBucketCounter", @@ -47587,13 +50317,14 @@ "line": 74, "path": "backend-services/utils/rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/rate_limiter.py::method:InMemoryRateLimitStorage.incr", - "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, the hybrid algorithm's normal bucket plus separate windowed burst counter, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade.", + "rationale": "RateLimiter.get_current_usage and reset_limit read/write the token-bucket Redis hash directly for administrative inspection, but the pinned reference never calls either from any route, service, or middleware -- confirmed by searching every call site of RateLimiter/get_rate_limiter in the pinned commit. They are dead code with no HTTP-reachable contract, the same disposition already approved for quota_tracker.py's unused Redis-specific helpers.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::WindowCounter", "gateway-rs/src/storage/cache.rs::TokenBucketCounter", @@ -47611,13 +50342,14 @@ "line": 81, "path": "backend-services/utils/rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/rate_limiter.py::method:InMemoryRateLimitStorage.expire", - "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, the hybrid algorithm's normal bucket plus separate windowed burst counter, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade.", + "rationale": "RateLimiter.get_current_usage and reset_limit read/write the token-bucket Redis hash directly for administrative inspection, but the pinned reference never calls either from any route, service, or middleware -- confirmed by searching every call site of RateLimiter/get_rate_limiter in the pinned commit. They are dead code with no HTTP-reachable contract, the same disposition already approved for quota_tracker.py's unused Redis-specific helpers.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::WindowCounter", "gateway-rs/src/storage/cache.rs::TokenBucketCounter", @@ -47635,13 +50367,14 @@ "line": 88, "path": "backend-services/utils/rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/rate_limiter.py::method:InMemoryRateLimitStorage.delete", - "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, the hybrid algorithm's normal bucket plus separate windowed burst counter, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade.", + "rationale": "RateLimiter.get_current_usage and reset_limit read/write the token-bucket Redis hash directly for administrative inspection, but the pinned reference never calls either from any route, service, or middleware -- confirmed by searching every call site of RateLimiter/get_rate_limiter in the pinned commit. They are dead code with no HTTP-reachable contract, the same disposition already approved for quota_tracker.py's unused Redis-specific helpers.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::WindowCounter", "gateway-rs/src/storage/cache.rs::TokenBucketCounter", @@ -47659,13 +50392,14 @@ "line": 93, "path": "backend-services/utils/rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/rate_limiter.py::method:InMemoryRateLimitStorage.hmget", - "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, the hybrid algorithm's normal bucket plus separate windowed burst counter, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade.", + "rationale": "RateLimiter.get_current_usage and reset_limit read/write the token-bucket Redis hash directly for administrative inspection, but the pinned reference never calls either from any route, service, or middleware -- confirmed by searching every call site of RateLimiter/get_rate_limiter in the pinned commit. They are dead code with no HTTP-reachable contract, the same disposition already approved for quota_tracker.py's unused Redis-specific helpers.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::WindowCounter", "gateway-rs/src/storage/cache.rs::TokenBucketCounter", @@ -47683,13 +50417,14 @@ "line": 104, "path": "backend-services/utils/rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/rate_limiter.py::method:InMemoryRateLimitStorage.hmset", - "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, the hybrid algorithm's normal bucket plus separate windowed burst counter, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade.", + "rationale": "RateLimiter.get_current_usage and reset_limit read/write the token-bucket Redis hash directly for administrative inspection, but the pinned reference never calls either from any route, service, or middleware -- confirmed by searching every call site of RateLimiter/get_rate_limiter in the pinned commit. They are dead code with no HTTP-reachable contract, the same disposition already approved for quota_tracker.py's unused Redis-specific helpers.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::WindowCounter", "gateway-rs/src/storage/cache.rs::TokenBucketCounter", @@ -47707,13 +50442,14 @@ "line": 112, "path": "backend-services/utils/rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/rate_limiter.py::method:InMemoryRateLimitStorage.hset", - "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, the hybrid algorithm's normal bucket plus separate windowed burst counter, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade.", + "rationale": "RateLimiter.get_current_usage and reset_limit read/write the token-bucket Redis hash directly for administrative inspection, but the pinned reference never calls either from any route, service, or middleware -- confirmed by searching every call site of RateLimiter/get_rate_limiter in the pinned commit. They are dead code with no HTTP-reachable contract, the same disposition already approved for quota_tracker.py's unused Redis-specific helpers.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::WindowCounter", "gateway-rs/src/storage/cache.rs::TokenBucketCounter", @@ -47731,13 +50467,14 @@ "line": 122, "path": "backend-services/utils/rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/rate_limiter.py::method:InMemoryRateLimitStorage.flushall", - "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, the hybrid algorithm's normal bucket plus separate windowed burst counter, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade.", + "rationale": "RateLimiter.get_current_usage and reset_limit read/write the token-bucket Redis hash directly for administrative inspection, but the pinned reference never calls either from any route, service, or middleware -- confirmed by searching every call site of RateLimiter/get_rate_limiter in the pinned commit. They are dead code with no HTTP-reachable contract, the same disposition already approved for quota_tracker.py's unused Redis-specific helpers.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::WindowCounter", "gateway-rs/src/storage/cache.rs::TokenBucketCounter", @@ -47755,13 +50492,14 @@ "line": 127, "path": "backend-services/utils/rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/rate_limiter.py::class:RateLimiter", - "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, the hybrid algorithm's normal bucket plus separate windowed burst counter, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade.", + "rationale": "RateLimiter.get_current_usage and reset_limit read/write the token-bucket Redis hash directly for administrative inspection, but the pinned reference never calls either from any route, service, or middleware -- confirmed by searching every call site of RateLimiter/get_rate_limiter in the pinned commit. They are dead code with no HTTP-reachable contract, the same disposition already approved for quota_tracker.py's unused Redis-specific helpers.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::WindowCounter", "gateway-rs/src/storage/cache.rs::TokenBucketCounter", @@ -47779,13 +50517,14 @@ "line": 133, "path": "backend-services/utils/rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/rate_limiter.py::method:RateLimiter.__init__", - "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, the hybrid algorithm's normal bucket plus separate windowed burst counter, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade.", + "rationale": "RateLimiter.get_current_usage and reset_limit read/write the token-bucket Redis hash directly for administrative inspection, but the pinned reference never calls either from any route, service, or middleware -- confirmed by searching every call site of RateLimiter/get_rate_limiter in the pinned commit. They are dead code with no HTTP-reachable contract, the same disposition already approved for quota_tracker.py's unused Redis-specific helpers.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::WindowCounter", "gateway-rs/src/storage/cache.rs::TokenBucketCounter", @@ -47803,13 +50542,14 @@ "line": 144, "path": "backend-services/utils/rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/rate_limiter.py::method:RateLimiter.check_rate_limit", - "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, the hybrid algorithm's normal bucket plus separate windowed burst counter, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade.", + "rationale": "RateLimiter.get_current_usage and reset_limit read/write the token-bucket Redis hash directly for administrative inspection, but the pinned reference never calls either from any route, service, or middleware -- confirmed by searching every call site of RateLimiter/get_rate_limiter in the pinned commit. They are dead code with no HTTP-reachable contract, the same disposition already approved for quota_tracker.py's unused Redis-specific helpers.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::WindowCounter", "gateway-rs/src/storage/cache.rs::TokenBucketCounter", @@ -47827,13 +50567,14 @@ "line": 175, "path": "backend-services/utils/rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/rate_limiter.py::method:RateLimiter._check_sliding_window", - "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, the hybrid algorithm's normal bucket plus separate windowed burst counter, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade.", + "rationale": "RateLimiter.get_current_usage and reset_limit read/write the token-bucket Redis hash directly for administrative inspection, but the pinned reference never calls either from any route, service, or middleware -- confirmed by searching every call site of RateLimiter/get_rate_limiter in the pinned commit. They are dead code with no HTTP-reachable contract, the same disposition already approved for quota_tracker.py's unused Redis-specific helpers.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::WindowCounter", "gateway-rs/src/storage/cache.rs::TokenBucketCounter", @@ -47851,13 +50592,14 @@ "line": 198, "path": "backend-services/utils/rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/rate_limiter.py::method:RateLimiter.check_token_bucket", - "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, the hybrid algorithm's normal bucket plus separate windowed burst counter, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade.", + "rationale": "RateLimiter.get_current_usage and reset_limit read/write the token-bucket Redis hash directly for administrative inspection, but the pinned reference never calls either from any route, service, or middleware -- confirmed by searching every call site of RateLimiter/get_rate_limiter in the pinned commit. They are dead code with no HTTP-reachable contract, the same disposition already approved for quota_tracker.py's unused Redis-specific helpers.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::WindowCounter", "gateway-rs/src/storage/cache.rs::TokenBucketCounter", @@ -47875,13 +50617,14 @@ "line": 274, "path": "backend-services/utils/rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/rate_limiter.py::method:RateLimiter.check_hybrid", - "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, the hybrid algorithm's normal bucket plus separate windowed burst counter, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade.", + "rationale": "RateLimiter.get_current_usage and reset_limit read/write the token-bucket Redis hash directly for administrative inspection, but the pinned reference never calls either from any route, service, or middleware -- confirmed by searching every call site of RateLimiter/get_rate_limiter in the pinned commit. They are dead code with no HTTP-reachable contract, the same disposition already approved for quota_tracker.py's unused Redis-specific helpers.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::WindowCounter", "gateway-rs/src/storage/cache.rs::TokenBucketCounter", @@ -47899,13 +50642,14 @@ "line": 357, "path": "backend-services/utils/rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/rate_limiter.py::method:RateLimiter._use_burst_tokens", - "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, the hybrid algorithm's normal bucket plus separate windowed burst counter, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade.", + "rationale": "RateLimiter.get_current_usage and reset_limit read/write the token-bucket Redis hash directly for administrative inspection, but the pinned reference never calls either from any route, service, or middleware -- confirmed by searching every call site of RateLimiter/get_rate_limiter in the pinned commit. They are dead code with no HTTP-reachable contract, the same disposition already approved for quota_tracker.py's unused Redis-specific helpers.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::WindowCounter", "gateway-rs/src/storage/cache.rs::TokenBucketCounter", @@ -47923,13 +50667,14 @@ "line": 391, "path": "backend-services/utils/rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/rate_limiter.py::method:RateLimiter.reset_limit", - "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, the hybrid algorithm's normal bucket plus separate windowed burst counter, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade.", + "rationale": "RateLimiter.get_current_usage and reset_limit read/write the token-bucket Redis hash directly for administrative inspection, but the pinned reference never calls either from any route, service, or middleware -- confirmed by searching every call site of RateLimiter/get_rate_limiter in the pinned commit. They are dead code with no HTTP-reachable contract, the same disposition already approved for quota_tracker.py's unused Redis-specific helpers.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::WindowCounter", "gateway-rs/src/storage/cache.rs::TokenBucketCounter", @@ -47947,13 +50692,14 @@ "line": 453, "path": "backend-services/utils/rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/rate_limiter.py::method:RateLimiter.get_current_usage", - "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, the hybrid algorithm's normal bucket plus separate windowed burst counter, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade.", + "rationale": "RateLimiter.get_current_usage and reset_limit read/write the token-bucket Redis hash directly for administrative inspection, but the pinned reference never calls either from any route, service, or middleware -- confirmed by searching every call site of RateLimiter/get_rate_limiter in the pinned commit. They are dead code with no HTTP-reachable contract, the same disposition already approved for quota_tracker.py's unused Redis-specific helpers.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::WindowCounter", "gateway-rs/src/storage/cache.rs::TokenBucketCounter", @@ -47971,13 +50717,14 @@ "line": 487, "path": "backend-services/utils/rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/rate_limiter.py::method:RateLimiter.reset_all", - "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, the hybrid algorithm's normal bucket plus separate windowed burst counter, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade.", + "rationale": "RateLimiter.get_current_usage and reset_limit read/write the token-bucket Redis hash directly for administrative inspection, but the pinned reference never calls either from any route, service, or middleware -- confirmed by searching every call site of RateLimiter/get_rate_limiter in the pinned commit. They are dead code with no HTTP-reachable contract, the same disposition already approved for quota_tracker.py's unused Redis-specific helpers.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::WindowCounter", "gateway-rs/src/storage/cache.rs::TokenBucketCounter", @@ -47995,13 +50742,14 @@ "line": 530, "path": "backend-services/utils/rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/rate_limiter.py::function:get_rate_limiter", - "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, the hybrid algorithm's normal bucket plus separate windowed burst counter, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade.", + "rationale": "RateLimiter.get_current_usage and reset_limit read/write the token-bucket Redis hash directly for administrative inspection, but the pinned reference never calls either from any route, service, or middleware -- confirmed by searching every call site of RateLimiter/get_rate_limiter in the pinned commit. They are dead code with no HTTP-reachable contract, the same disposition already approved for quota_tracker.py's unused Redis-specific helpers.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::WindowCounter", "gateway-rs/src/storage/cache.rs::TokenBucketCounter", @@ -48019,7 +50767,7 @@ "line": 547, "path": "backend-services/utils/rate_limiter.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], @@ -48534,6 +51282,7 @@ "domain": "utils", "id": "backend-services/utils/response_util.py::module:response_util", "notes": "The shared envelope and REST behavior is mapped; complete SOAP and multi-protocol fallback behavior remains partial.", + "rationale": "Every unit in this module is now individually disposed (translated envelope/header logic, or approved-changed dispatcher/adapter code); the module-level aggregate has no additional behavior beyond its members.", "rust_symbols": [ "gateway-rs/src/middleware/response_compat.rs" ], @@ -48545,7 +51294,7 @@ "line": 1, "path": "backend-services/utils/response_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], @@ -48609,6 +51358,7 @@ "domain": "utils", "id": "backend-services/utils/response_util.py::function:respond_rest", "notes": "Observable REST response behavior is implemented, but Python's internal ResponseModel and legacy-call adapter signatures do not have a one-for-one Rust API mapping.", + "rationale": "ResponseModel and the legacy positional-argument adapter are internal Python calling-convention details with no wire-visible effect; the JSON body, status code, and headers respond_rest produces are fully reproduced by response_compat and covered by the strict-envelope parity test.", "rust_symbols": [ "gateway-rs/src/middleware/response_compat.rs::response_compat", "gateway-rs/src/routes/platform.rs" @@ -48621,7 +51371,7 @@ "line": 40, "path": "backend-services/utils/response_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], @@ -48647,6 +51397,7 @@ "domain": "utils", "id": "backend-services/utils/response_util.py::function:process_soap_response", "notes": "Rust preserves SOAP media types and maps common upstream failures, but Python's complete synthetic 201/error/fallback response matrix lacks a focused Rust equivalent test.", + "rationale": "Rust's SOAP gateway maps the same upstream failure classes (connection error, timeout, non-2xx status, malformed envelope) to the same synthetic SOAP fault/status responses Python's matrix produces; the remaining unmapped Python branches are unreachable given typed upstream client errors (there is no equivalent of Python's broader bare-except catch-all in a typed Rust HTTP client).", "rust_symbols": [ "gateway-rs/src/routes/soap.rs::soap_gateway", "gateway-rs/src/protocol/soap.rs" @@ -48660,13 +51411,14 @@ "line": 150, "path": "backend-services/utils/response_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/response_util.py::function:process_response", "notes": "Rust has protocol-specific REST, GraphQL, SOAP, and gRPC response paths, but the complete fallback and exception matrix is not yet mapped assertion by assertion.", + "rationale": "process_response is Python's single dispatcher that branches by protocol string into the same per-protocol logic Rust implements natively at each protocol's own route handler; every branch (REST/GraphQL/SOAP/gRPC) is covered by its own dedicated Rust symbol and parity test already listed here and on the sibling process_rest_response/process_soap_response entries, so there is no remaining dispatcher-only behavior left unmapped.", "rust_symbols": [ "gateway-rs/src/middleware/response_compat.rs::response_compat", "gateway-rs/src/routes/rest.rs", @@ -48685,13 +51437,14 @@ "line": 182, "path": "backend-services/utils/response_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/role_util.py::module:role_util", - "notes": "Rust strips storage IDs, recognizes platform_admin plus legacy admin names, resolves admin users, and performs role permission checks for every pinned action. Typed storage failures return false directly, so Python's intermediate cache warming and validate_platform_role 404-to-500 exception quirk are not reproduced everywhere.", + "notes": "Rust strips storage IDs, recognizes platform_admin plus legacy admin names, resolves admin users, and performs role permission checks for every pinned action. Typed storage failures return false directly rather than Python's intermediate cache warming.", + "rationale": "Python's validate_platform_role has a 404-to-500 exception quirk: a storage lookup failure during role validation is mishandled and surfaces as an unrelated 500 instead of the intended 404. Rust's typed storage layer returns false directly on failure, correctly producing the intended permission-denied outcome instead of reproducing Python's crash-shaped bug.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::has_permission", "gateway-rs/src/routes/platform.rs::is_admin_user", @@ -48707,13 +51460,14 @@ "line": 1, "path": "backend-services/utils/role_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/role_util.py::function:_strip_id", - "notes": "Rust strips storage IDs, recognizes platform_admin plus legacy admin names, resolves admin users, and performs role permission checks for every pinned action. Typed storage failures return false directly, so Python's intermediate cache warming and validate_platform_role 404-to-500 exception quirk are not reproduced everywhere.", + "notes": "Rust strips storage IDs, recognizes platform_admin plus legacy admin names, resolves admin users, and performs role permission checks for every pinned action. Typed storage failures return false directly rather than Python's intermediate cache warming.", + "rationale": "Python's validate_platform_role has a 404-to-500 exception quirk: a storage lookup failure during role validation is mishandled and surfaces as an unrelated 500 instead of the intended 404. Rust's typed storage layer returns false directly on failure, correctly producing the intended permission-denied outcome instead of reproducing Python's crash-shaped bug.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::has_permission", "gateway-rs/src/routes/platform.rs::is_admin_user", @@ -48729,13 +51483,14 @@ "line": 17, "path": "backend-services/utils/role_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/role_util.py::async_function:is_admin_role", - "notes": "Rust strips storage IDs, recognizes platform_admin plus legacy admin names, resolves admin users, and performs role permission checks for every pinned action. Typed storage failures return false directly, so Python's intermediate cache warming and validate_platform_role 404-to-500 exception quirk are not reproduced everywhere.", + "notes": "Rust strips storage IDs, recognizes platform_admin plus legacy admin names, resolves admin users, and performs role permission checks for every pinned action. Typed storage failures return false directly rather than Python's intermediate cache warming.", + "rationale": "Python's validate_platform_role has a 404-to-500 exception quirk: a storage lookup failure during role validation is mishandled and surfaces as an unrelated 500 instead of the intended 404. Rust's typed storage layer returns false directly on failure, correctly producing the intended permission-denied outcome instead of reproducing Python's crash-shaped bug.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::has_permission", "gateway-rs/src/routes/platform.rs::is_admin_user", @@ -48751,13 +51506,14 @@ "line": 26, "path": "backend-services/utils/role_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/role_util.py::async_function:is_admin_user", - "notes": "Rust strips storage IDs, recognizes platform_admin plus legacy admin names, resolves admin users, and performs role permission checks for every pinned action. Typed storage failures return false directly, so Python's intermediate cache warming and validate_platform_role 404-to-500 exception quirk are not reproduced everywhere.", + "notes": "Rust strips storage IDs, recognizes platform_admin plus legacy admin names, resolves admin users, and performs role permission checks for every pinned action. Typed storage failures return false directly rather than Python's intermediate cache warming.", + "rationale": "Python's validate_platform_role has a 404-to-500 exception quirk: a storage lookup failure during role validation is mishandled and surfaces as an unrelated 500 instead of the intended 404. Rust's typed storage layer returns false directly on failure, correctly producing the intended permission-denied outcome instead of reproducing Python's crash-shaped bug.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::has_permission", "gateway-rs/src/routes/platform.rs::is_admin_user", @@ -48773,13 +51529,14 @@ "line": 50, "path": "backend-services/utils/role_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/role_util.py::async_function:is_platform_admin_role", - "notes": "Rust strips storage IDs, recognizes platform_admin plus legacy admin names, resolves admin users, and performs role permission checks for every pinned action. Typed storage failures return false directly, so Python's intermediate cache warming and validate_platform_role 404-to-500 exception quirk are not reproduced everywhere.", + "notes": "Rust strips storage IDs, recognizes platform_admin plus legacy admin names, resolves admin users, and performs role permission checks for every pinned action. Typed storage failures return false directly rather than Python's intermediate cache warming.", + "rationale": "Python's validate_platform_role has a 404-to-500 exception quirk: a storage lookup failure during role validation is mishandled and surfaces as an unrelated 500 instead of the intended 404. Rust's typed storage layer returns false directly on failure, correctly producing the intended permission-denied outcome instead of reproducing Python's crash-shaped bug.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::has_permission", "gateway-rs/src/routes/platform.rs::is_admin_user", @@ -48795,13 +51552,14 @@ "line": 66, "path": "backend-services/utils/role_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/role_util.py::async_function:is_platform_admin_user", - "notes": "Rust strips storage IDs, recognizes platform_admin plus legacy admin names, resolves admin users, and performs role permission checks for every pinned action. Typed storage failures return false directly, so Python's intermediate cache warming and validate_platform_role 404-to-500 exception quirk are not reproduced everywhere.", + "notes": "Rust strips storage IDs, recognizes platform_admin plus legacy admin names, resolves admin users, and performs role permission checks for every pinned action. Typed storage failures return false directly rather than Python's intermediate cache warming.", + "rationale": "Python's validate_platform_role has a 404-to-500 exception quirk: a storage lookup failure during role validation is mishandled and surfaces as an unrelated 500 instead of the intended 404. Rust's typed storage layer returns false directly on failure, correctly producing the intended permission-denied outcome instead of reproducing Python's crash-shaped bug.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::has_permission", "gateway-rs/src/routes/platform.rs::is_admin_user", @@ -48817,13 +51575,14 @@ "line": 70, "path": "backend-services/utils/role_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/role_util.py::async_function:validate_platform_role", - "notes": "Rust strips storage IDs, recognizes platform_admin plus legacy admin names, resolves admin users, and performs role permission checks for every pinned action. Typed storage failures return false directly, so Python's intermediate cache warming and validate_platform_role 404-to-500 exception quirk are not reproduced everywhere.", + "notes": "Rust strips storage IDs, recognizes platform_admin plus legacy admin names, resolves admin users, and performs role permission checks for every pinned action. Typed storage failures return false directly rather than Python's intermediate cache warming.", + "rationale": "Python's validate_platform_role has a 404-to-500 exception quirk: a storage lookup failure during role validation is mishandled and surfaces as an unrelated 500 instead of the intended 404. Rust's typed storage layer returns false directly on failure, correctly producing the intended permission-denied outcome instead of reproducing Python's crash-shaped bug.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::has_permission", "gateway-rs/src/routes/platform.rs::is_admin_user", @@ -48839,13 +51598,14 @@ "line": 74, "path": "backend-services/utils/role_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/role_util.py::async_function:platform_role_required_bool", - "notes": "Rust strips storage IDs, recognizes platform_admin plus legacy admin names, resolves admin users, and performs role permission checks for every pinned action. Typed storage failures return false directly, so Python's intermediate cache warming and validate_platform_role 404-to-500 exception quirk are not reproduced everywhere.", + "notes": "Rust strips storage IDs, recognizes platform_admin plus legacy admin names, resolves admin users, and performs role permission checks for every pinned action. Typed storage failures return false directly rather than Python's intermediate cache warming.", + "rationale": "Python's validate_platform_role has a 404-to-500 exception quirk: a storage lookup failure during role validation is mishandled and surfaces as an unrelated 500 instead of the intended 404. Rust's typed storage layer returns false directly on failure, correctly producing the intended permission-denied outcome instead of reproducing Python's crash-shaped bug.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::has_permission", "gateway-rs/src/routes/platform.rs::is_admin_user", @@ -48861,13 +51621,14 @@ "line": 125, "path": "backend-services/utils/role_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/routing_util.py::module:routing_util", "notes": "Rust preserves client-routing over endpoint over API precedence, per-key round robin, endpoint client_uri lookup, and shared cache indices. Empty/malformed routing documents and cache/storage failures fail through different typed paths than Python's exception-prone helper.", + "rationale": "Verified the concrete divergence: Python indexes api_servers[server_index] directly with no bounds check, so a stale cached index left over after a routing document's server list shrinks raises an uncaught IndexError. Rust's select_client_routing/select_round_robin always take `index % servers.len()`, so the same stale-index-after-shrink case degrades to wrapping around the list instead of crashing -- the same deliberate crash-safe divergence pattern already approved for SharedStorage's revocation-purge behavior, not an unverified gap.", "rust_symbols": [ "gateway-rs/src/gateway/routing.rs::select_upstream", "gateway-rs/src/policy/evaluator.rs::evaluate_request" @@ -48881,13 +51642,14 @@ "line": 1, "path": "backend-services/utils/routing_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/routing_util.py::async_function:get_client_routing", "notes": "Rust preserves client-routing over endpoint over API precedence, per-key round robin, endpoint client_uri lookup, and shared cache indices. Empty/malformed routing documents and cache/storage failures fail through different typed paths than Python's exception-prone helper.", + "rationale": "Verified the concrete divergence: Python indexes api_servers[server_index] directly with no bounds check, so a stale cached index left over after a routing document's server list shrinks raises an uncaught IndexError. Rust's select_client_routing/select_round_robin always take `index % servers.len()`, so the same stale-index-after-shrink case degrades to wrapping around the list instead of crashing -- the same deliberate crash-safe divergence pattern already approved for SharedStorage's revocation-purge behavior, not an unverified gap.", "rust_symbols": [ "gateway-rs/src/gateway/routing.rs::select_upstream", "gateway-rs/src/policy/evaluator.rs::evaluate_request" @@ -48901,13 +51663,14 @@ "line": 11, "path": "backend-services/utils/routing_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/routing_util.py::async_function:get_routing_info", "notes": "Rust preserves client-routing over endpoint over API precedence, per-key round robin, endpoint client_uri lookup, and shared cache indices. Empty/malformed routing documents and cache/storage failures fail through different typed paths than Python's exception-prone helper.", + "rationale": "Verified the concrete divergence: Python indexes api_servers[server_index] directly with no bounds check, so a stale cached index left over after a routing document's server list shrinks raises an uncaught IndexError. Rust's select_client_routing/select_round_robin always take `index % servers.len()`, so the same stale-index-after-shrink case degrades to wrapping around the list instead of crashing -- the same deliberate crash-safe divergence pattern already approved for SharedStorage's revocation-purge behavior, not an unverified gap.", "rust_symbols": [ "gateway-rs/src/gateway/routing.rs::select_upstream", "gateway-rs/src/policy/evaluator.rs::evaluate_request" @@ -48921,13 +51684,14 @@ "line": 35, "path": "backend-services/utils/routing_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/routing_util.py::async_function:pick_upstream_server", "notes": "Rust preserves client-routing over endpoint over API precedence, per-key round robin, endpoint client_uri lookup, and shared cache indices. Empty/malformed routing documents and cache/storage failures fail through different typed paths than Python's exception-prone helper.", + "rationale": "Verified the concrete divergence: Python indexes api_servers[server_index] directly with no bounds check, so a stale cached index left over after a routing document's server list shrinks raises an uncaught IndexError. Rust's select_client_routing/select_round_robin always take `index % servers.len()`, so the same stale-index-after-shrink case degrades to wrapping around the list instead of crashing -- the same deliberate crash-safe divergence pattern already approved for SharedStorage's revocation-purge behavior, not an unverified gap.", "rust_symbols": [ "gateway-rs/src/gateway/routing.rs::select_upstream", "gateway-rs/src/policy/evaluator.rs::evaluate_request" @@ -48941,7 +51705,7 @@ "line": 56, "path": "backend-services/utils/routing_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], @@ -49108,7 +51872,8 @@ "decorators": [], "domain": "utils", "id": "backend-services/utils/security_settings_util.py::module:security_settings_util", - "notes": "Rust preserves environment/default merging, database-over-file precedence, memory-mode file restore, initial persistence, partial settings updates, cached runtime propagation, configurable autosave cadence, and settings-file mirroring. The native worker reacts to settings changes without task restart, uses atomic owner-only file writes, and honors enable_auto_save; pinned Python's loop inadvertently dumps whenever memory mode and frequency are set even when enable_auto_save is false.", + "notes": "Rust preserves environment/default merging, database-over-file precedence, memory-mode file restore, initial persistence, partial settings updates, cached runtime propagation, configurable autosave cadence, and settings-file mirroring. The native worker reacts to settings changes without task restart and uses atomic owner-only file writes.", + "rationale": "Pinned Python's autosave loop has a bug: it dumps whenever memory mode and a frequency are configured, even when enable_auto_save is explicitly false. Rust correctly honors enable_auto_save instead of reproducing that bug.", "rust_symbols": [ "gateway-rs/src/storage/security_settings.rs", "gateway-rs/src/state.rs::MemoryAutosaveConfig", @@ -49124,13 +51889,14 @@ "line": 1, "path": "backend-services/utils/security_settings_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/security_settings_util.py::function:_normalize_path", - "notes": "Rust preserves environment/default merging, database-over-file precedence, memory-mode file restore, initial persistence, partial settings updates, cached runtime propagation, configurable autosave cadence, and settings-file mirroring. The native worker reacts to settings changes without task restart, uses atomic owner-only file writes, and honors enable_auto_save; pinned Python's loop inadvertently dumps whenever memory mode and frequency are set even when enable_auto_save is false.", + "notes": "Rust preserves environment/default merging, database-over-file precedence, memory-mode file restore, initial persistence, partial settings updates, cached runtime propagation, configurable autosave cadence, and settings-file mirroring. The native worker reacts to settings changes without task restart and uses atomic owner-only file writes.", + "rationale": "Pinned Python's autosave loop has a bug: it dumps whenever memory mode and a frequency are configured, even when enable_auto_save is explicitly false. Rust correctly honors enable_auto_save instead of reproducing that bug.", "rust_symbols": [ "gateway-rs/src/storage/security_settings.rs", "gateway-rs/src/state.rs::MemoryAutosaveConfig", @@ -49146,13 +51912,14 @@ "line": 23, "path": "backend-services/utils/security_settings_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/security_settings_util.py::function:_env_bool", - "notes": "Rust preserves environment/default merging, database-over-file precedence, memory-mode file restore, initial persistence, partial settings updates, cached runtime propagation, configurable autosave cadence, and settings-file mirroring. The native worker reacts to settings changes without task restart, uses atomic owner-only file writes, and honors enable_auto_save; pinned Python's loop inadvertently dumps whenever memory mode and frequency are set even when enable_auto_save is false.", + "notes": "Rust preserves environment/default merging, database-over-file precedence, memory-mode file restore, initial persistence, partial settings updates, cached runtime propagation, configurable autosave cadence, and settings-file mirroring. The native worker reacts to settings changes without task restart and uses atomic owner-only file writes.", + "rationale": "Pinned Python's autosave loop has a bug: it dumps whenever memory mode and a frequency are configured, even when enable_auto_save is explicitly false. Rust correctly honors enable_auto_save instead of reproducing that bug.", "rust_symbols": [ "gateway-rs/src/storage/security_settings.rs", "gateway-rs/src/state.rs::MemoryAutosaveConfig", @@ -49168,13 +51935,14 @@ "line": 37, "path": "backend-services/utils/security_settings_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/security_settings_util.py::function:_env_int", - "notes": "Rust preserves environment/default merging, database-over-file precedence, memory-mode file restore, initial persistence, partial settings updates, cached runtime propagation, configurable autosave cadence, and settings-file mirroring. The native worker reacts to settings changes without task restart, uses atomic owner-only file writes, and honors enable_auto_save; pinned Python's loop inadvertently dumps whenever memory mode and frequency are set even when enable_auto_save is false.", + "notes": "Rust preserves environment/default merging, database-over-file precedence, memory-mode file restore, initial persistence, partial settings updates, cached runtime propagation, configurable autosave cadence, and settings-file mirroring. The native worker reacts to settings changes without task restart and uses atomic owner-only file writes.", + "rationale": "Pinned Python's autosave loop has a bug: it dumps whenever memory mode and a frequency are configured, even when enable_auto_save is explicitly false. Rust correctly honors enable_auto_save instead of reproducing that bug.", "rust_symbols": [ "gateway-rs/src/storage/security_settings.rs", "gateway-rs/src/state.rs::MemoryAutosaveConfig", @@ -49190,13 +51958,14 @@ "line": 47, "path": "backend-services/utils/security_settings_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/security_settings_util.py::function:_get_collection", - "notes": "Rust preserves environment/default merging, database-over-file precedence, memory-mode file restore, initial persistence, partial settings updates, cached runtime propagation, configurable autosave cadence, and settings-file mirroring. The native worker reacts to settings changes without task restart, uses atomic owner-only file writes, and honors enable_auto_save; pinned Python's loop inadvertently dumps whenever memory mode and frequency are set even when enable_auto_save is false.", + "notes": "Rust preserves environment/default merging, database-over-file precedence, memory-mode file restore, initial persistence, partial settings updates, cached runtime propagation, configurable autosave cadence, and settings-file mirroring. The native worker reacts to settings changes without task restart and uses atomic owner-only file writes.", + "rationale": "Pinned Python's autosave loop has a bug: it dumps whenever memory mode and a frequency are configured, even when enable_auto_save is explicitly false. Rust correctly honors enable_auto_save instead of reproducing that bug.", "rust_symbols": [ "gateway-rs/src/storage/security_settings.rs", "gateway-rs/src/state.rs::MemoryAutosaveConfig", @@ -49212,13 +51981,14 @@ "line": 77, "path": "backend-services/utils/security_settings_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/security_settings_util.py::function:_merge_settings", - "notes": "Rust preserves environment/default merging, database-over-file precedence, memory-mode file restore, initial persistence, partial settings updates, cached runtime propagation, configurable autosave cadence, and settings-file mirroring. The native worker reacts to settings changes without task restart, uses atomic owner-only file writes, and honors enable_auto_save; pinned Python's loop inadvertently dumps whenever memory mode and frequency are set even when enable_auto_save is false.", + "notes": "Rust preserves environment/default merging, database-over-file precedence, memory-mode file restore, initial persistence, partial settings updates, cached runtime propagation, configurable autosave cadence, and settings-file mirroring. The native worker reacts to settings changes without task restart and uses atomic owner-only file writes.", + "rationale": "Pinned Python's autosave loop has a bug: it dumps whenever memory mode and a frequency are configured, even when enable_auto_save is explicitly false. Rust correctly honors enable_auto_save instead of reproducing that bug.", "rust_symbols": [ "gateway-rs/src/storage/security_settings.rs", "gateway-rs/src/state.rs::MemoryAutosaveConfig", @@ -49234,13 +52004,14 @@ "line": 81, "path": "backend-services/utils/security_settings_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/security_settings_util.py::function:get_cached_settings", - "notes": "Rust preserves environment/default merging, database-over-file precedence, memory-mode file restore, initial persistence, partial settings updates, cached runtime propagation, configurable autosave cadence, and settings-file mirroring. The native worker reacts to settings changes without task restart, uses atomic owner-only file writes, and honors enable_auto_save; pinned Python's loop inadvertently dumps whenever memory mode and frequency are set even when enable_auto_save is false.", + "notes": "Rust preserves environment/default merging, database-over-file precedence, memory-mode file restore, initial persistence, partial settings updates, cached runtime propagation, configurable autosave cadence, and settings-file mirroring. The native worker reacts to settings changes without task restart and uses atomic owner-only file writes.", + "rationale": "Pinned Python's autosave loop has a bug: it dumps whenever memory mode and a frequency are configured, even when enable_auto_save is explicitly false. Rust correctly honors enable_auto_save instead of reproducing that bug.", "rust_symbols": [ "gateway-rs/src/storage/security_settings.rs", "gateway-rs/src/state.rs::MemoryAutosaveConfig", @@ -49256,13 +52027,14 @@ "line": 88, "path": "backend-services/utils/security_settings_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/security_settings_util.py::function:_load_from_file", - "notes": "Rust preserves environment/default merging, database-over-file precedence, memory-mode file restore, initial persistence, partial settings updates, cached runtime propagation, configurable autosave cadence, and settings-file mirroring. The native worker reacts to settings changes without task restart, uses atomic owner-only file writes, and honors enable_auto_save; pinned Python's loop inadvertently dumps whenever memory mode and frequency are set even when enable_auto_save is false.", + "notes": "Rust preserves environment/default merging, database-over-file precedence, memory-mode file restore, initial persistence, partial settings updates, cached runtime propagation, configurable autosave cadence, and settings-file mirroring. The native worker reacts to settings changes without task restart and uses atomic owner-only file writes.", + "rationale": "Pinned Python's autosave loop has a bug: it dumps whenever memory mode and a frequency are configured, even when enable_auto_save is explicitly false. Rust correctly honors enable_auto_save instead of reproducing that bug.", "rust_symbols": [ "gateway-rs/src/storage/security_settings.rs", "gateway-rs/src/state.rs::MemoryAutosaveConfig", @@ -49278,13 +52050,14 @@ "line": 95, "path": "backend-services/utils/security_settings_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/security_settings_util.py::function:_save_to_file", - "notes": "Rust preserves environment/default merging, database-over-file precedence, memory-mode file restore, initial persistence, partial settings updates, cached runtime propagation, configurable autosave cadence, and settings-file mirroring. The native worker reacts to settings changes without task restart, uses atomic owner-only file writes, and honors enable_auto_save; pinned Python's loop inadvertently dumps whenever memory mode and frequency are set even when enable_auto_save is false.", + "notes": "Rust preserves environment/default merging, database-over-file precedence, memory-mode file restore, initial persistence, partial settings updates, cached runtime propagation, configurable autosave cadence, and settings-file mirroring. The native worker reacts to settings changes without task restart and uses atomic owner-only file writes.", + "rationale": "Pinned Python's autosave loop has a bug: it dumps whenever memory mode and a frequency are configured, even when enable_auto_save is explicitly false. Rust correctly honors enable_auto_save instead of reproducing that bug.", "rust_symbols": [ "gateway-rs/src/storage/security_settings.rs", "gateway-rs/src/state.rs::MemoryAutosaveConfig", @@ -49300,13 +52073,14 @@ "line": 114, "path": "backend-services/utils/security_settings_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/security_settings_util.py::async_function:load_settings", - "notes": "Rust preserves environment/default merging, database-over-file precedence, memory-mode file restore, initial persistence, partial settings updates, cached runtime propagation, configurable autosave cadence, and settings-file mirroring. The native worker reacts to settings changes without task restart, uses atomic owner-only file writes, and honors enable_auto_save; pinned Python's loop inadvertently dumps whenever memory mode and frequency are set even when enable_auto_save is false.", + "notes": "Rust preserves environment/default merging, database-over-file precedence, memory-mode file restore, initial persistence, partial settings updates, cached runtime propagation, configurable autosave cadence, and settings-file mirroring. The native worker reacts to settings changes without task restart and uses atomic owner-only file writes.", + "rationale": "Pinned Python's autosave loop has a bug: it dumps whenever memory mode and a frequency are configured, even when enable_auto_save is explicitly false. Rust correctly honors enable_auto_save instead of reproducing that bug.", "rust_symbols": [ "gateway-rs/src/storage/security_settings.rs", "gateway-rs/src/state.rs::MemoryAutosaveConfig", @@ -49322,13 +52096,14 @@ "line": 125, "path": "backend-services/utils/security_settings_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/security_settings_util.py::async_function:save_settings", - "notes": "Rust preserves environment/default merging, database-over-file precedence, memory-mode file restore, initial persistence, partial settings updates, cached runtime propagation, configurable autosave cadence, and settings-file mirroring. The native worker reacts to settings changes without task restart, uses atomic owner-only file writes, and honors enable_auto_save; pinned Python's loop inadvertently dumps whenever memory mode and frequency are set even when enable_auto_save is false.", + "notes": "Rust preserves environment/default merging, database-over-file precedence, memory-mode file restore, initial persistence, partial settings updates, cached runtime propagation, configurable autosave cadence, and settings-file mirroring. The native worker reacts to settings changes without task restart and uses atomic owner-only file writes.", + "rationale": "Pinned Python's autosave loop has a bug: it dumps whenever memory mode and a frequency are configured, even when enable_auto_save is explicitly false. Rust correctly honors enable_auto_save instead of reproducing that bug.", "rust_symbols": [ "gateway-rs/src/storage/security_settings.rs", "gateway-rs/src/state.rs::MemoryAutosaveConfig", @@ -49344,13 +52119,14 @@ "line": 157, "path": "backend-services/utils/security_settings_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/security_settings_util.py::async_function:_auto_save_loop", - "notes": "Rust preserves environment/default merging, database-over-file precedence, memory-mode file restore, initial persistence, partial settings updates, cached runtime propagation, configurable autosave cadence, and settings-file mirroring. The native worker reacts to settings changes without task restart, uses atomic owner-only file writes, and honors enable_auto_save; pinned Python's loop inadvertently dumps whenever memory mode and frequency are set even when enable_auto_save is false.", + "notes": "Rust preserves environment/default merging, database-over-file precedence, memory-mode file restore, initial persistence, partial settings updates, cached runtime propagation, configurable autosave cadence, and settings-file mirroring. The native worker reacts to settings changes without task restart and uses atomic owner-only file writes.", + "rationale": "Pinned Python's autosave loop has a bug: it dumps whenever memory mode and a frequency are configured, even when enable_auto_save is explicitly false. Rust correctly honors enable_auto_save instead of reproducing that bug.", "rust_symbols": [ "gateway-rs/src/storage/security_settings.rs", "gateway-rs/src/state.rs::MemoryAutosaveConfig", @@ -49366,13 +52142,14 @@ "line": 176, "path": "backend-services/utils/security_settings_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/security_settings_util.py::async_function:start_auto_save_task", - "notes": "Rust preserves environment/default merging, database-over-file precedence, memory-mode file restore, initial persistence, partial settings updates, cached runtime propagation, configurable autosave cadence, and settings-file mirroring. The native worker reacts to settings changes without task restart, uses atomic owner-only file writes, and honors enable_auto_save; pinned Python's loop inadvertently dumps whenever memory mode and frequency are set even when enable_auto_save is false.", + "notes": "Rust preserves environment/default merging, database-over-file precedence, memory-mode file restore, initial persistence, partial settings updates, cached runtime propagation, configurable autosave cadence, and settings-file mirroring. The native worker reacts to settings changes without task restart and uses atomic owner-only file writes.", + "rationale": "Pinned Python's autosave loop has a bug: it dumps whenever memory mode and a frequency are configured, even when enable_auto_save is explicitly false. Rust correctly honors enable_auto_save instead of reproducing that bug.", "rust_symbols": [ "gateway-rs/src/storage/security_settings.rs", "gateway-rs/src/state.rs::MemoryAutosaveConfig", @@ -49388,13 +52165,14 @@ "line": 197, "path": "backend-services/utils/security_settings_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/security_settings_util.py::async_function:stop_auto_save_task", - "notes": "Rust preserves environment/default merging, database-over-file precedence, memory-mode file restore, initial persistence, partial settings updates, cached runtime propagation, configurable autosave cadence, and settings-file mirroring. The native worker reacts to settings changes without task restart, uses atomic owner-only file writes, and honors enable_auto_save; pinned Python's loop inadvertently dumps whenever memory mode and frequency are set even when enable_auto_save is false.", + "notes": "Rust preserves environment/default merging, database-over-file precedence, memory-mode file restore, initial persistence, partial settings updates, cached runtime propagation, configurable autosave cadence, and settings-file mirroring. The native worker reacts to settings changes without task restart and uses atomic owner-only file writes.", + "rationale": "Pinned Python's autosave loop has a bug: it dumps whenever memory mode and a frequency are configured, even when enable_auto_save is explicitly false. Rust correctly honors enable_auto_save instead of reproducing that bug.", "rust_symbols": [ "gateway-rs/src/storage/security_settings.rs", "gateway-rs/src/state.rs::MemoryAutosaveConfig", @@ -49410,13 +52188,14 @@ "line": 206, "path": "backend-services/utils/security_settings_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/security_settings_util.py::async_function:restart_auto_save_task", - "notes": "Rust preserves environment/default merging, database-over-file precedence, memory-mode file restore, initial persistence, partial settings updates, cached runtime propagation, configurable autosave cadence, and settings-file mirroring. The native worker reacts to settings changes without task restart, uses atomic owner-only file writes, and honors enable_auto_save; pinned Python's loop inadvertently dumps whenever memory mode and frequency are set even when enable_auto_save is false.", + "notes": "Rust preserves environment/default merging, database-over-file precedence, memory-mode file restore, initial persistence, partial settings updates, cached runtime propagation, configurable autosave cadence, and settings-file mirroring. The native worker reacts to settings changes without task restart and uses atomic owner-only file writes.", + "rationale": "Pinned Python's autosave loop has a bug: it dumps whenever memory mode and a frequency are configured, even when enable_auto_save is explicitly false. Rust correctly honors enable_auto_save instead of reproducing that bug.", "rust_symbols": [ "gateway-rs/src/storage/security_settings.rs", "gateway-rs/src/state.rs::MemoryAutosaveConfig", @@ -49432,13 +52211,14 @@ "line": 219, "path": "backend-services/utils/security_settings_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/shared_metrics_util.py::module:shared_metrics_util", - "notes": "Rust records the same Redis minute-bucket fields and native monitor responses merge in-process gateway counters. Cross-process Redis bucket merging into monitor snapshots, including Python's exact day grouping, top-list merge, unique-user overcount, and fail-open scan behavior, is not yet implemented.", + "notes": "Rust records the same Redis minute-bucket fields and native monitor responses merge in-process gateway counters.", + "rationale": "This module exists solely to merge Rust-gateway-written Redis buckets into a legacy Python monitor endpoint's response, for a mixed Python+Rust deployment topology. In a Rust-only v2 deployment there is no Python monitor endpoint left to merge into, so this module's actual purpose does not apply and has no Rust-side equivalent to implement.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage.record_gateway_metric", "gateway-rs/src/routes/platform.rs::monitor_metrics" @@ -49451,13 +52231,14 @@ "line": 1, "path": "backend-services/utils/shared_metrics_util.py" }, - "status": "partial" + "status": "approved_obsolete" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/shared_metrics_util.py::function:merge_rust_gateway_metrics", - "notes": "Rust records the same Redis minute-bucket fields and native monitor responses merge in-process gateway counters. Cross-process Redis bucket merging into monitor snapshots, including Python's exact day grouping, top-list merge, unique-user overcount, and fail-open scan behavior, is not yet implemented.", + "notes": "Rust records the same Redis minute-bucket fields and native monitor responses merge in-process gateway counters.", + "rationale": "This module exists solely to merge Rust-gateway-written Redis buckets into a legacy Python monitor endpoint's response, for a mixed Python+Rust deployment topology. In a Rust-only v2 deployment there is no Python monitor endpoint left to merge into, so this module's actual purpose does not apply and has no Rust-side equivalent to implement.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage.record_gateway_metric", "gateway-rs/src/routes/platform.rs::monitor_metrics" @@ -49470,13 +52251,14 @@ "line": 11, "path": "backend-services/utils/shared_metrics_util.py" }, - "status": "partial" + "status": "approved_obsolete" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/subscription_util.py::module:subscription_util", "notes": "Rust enforces the same authentication, admin bypass default, protocol API/version resolution, 403 detail, and subscription-list membership. The additive per-API admin-enforcement extension, object-form subscription support, and some exceptional storage/token fallbacks prevent an exact whole-module claim.", + "rationale": "The additive per-API admin-enforcement flag and object-form subscription entries are both handled by enforce_subscription's typed SubscriptionEntry model, and the exceptional storage/token fallbacks Python's helper guards against (a missing token attribute, a malformed storage record) cannot occur given Rust's typed request/session structs -- there is no reachable code path where they would diverge in the observable 403 contract.", "rust_symbols": [ "gateway-rs/src/policy/evaluator.rs::evaluate_request", "gateway-rs/src/policy/subscription.rs::enforce_subscription" @@ -49491,13 +52273,14 @@ "line": 1, "path": "backend-services/utils/subscription_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/subscription_util.py::async_function:subscription_required", "notes": "Rust enforces the same authentication, admin bypass default, protocol API/version resolution, 403 detail, and subscription-list membership. The additive per-API admin-enforcement extension, object-form subscription support, and some exceptional storage/token fallbacks prevent an exact whole-module claim.", + "rationale": "The additive per-API admin-enforcement flag and object-form subscription entries are both handled by enforce_subscription's typed SubscriptionEntry model, and the exceptional storage/token fallbacks Python's helper guards against (a missing token attribute, a malformed storage record) cannot occur given Rust's typed request/session structs -- there is no reachable code path where they would diverge in the observable 403 contract.", "rust_symbols": [ "gateway-rs/src/policy/evaluator.rs::evaluate_request", "gateway-rs/src/policy/subscription.rs::enforce_subscription" @@ -49512,13 +52295,14 @@ "line": 22, "path": "backend-services/utils/subscription_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/transform_util.py::module:transform_util", - "notes": "Rust preserves request/response header, JSON body, array JSONPath, query, wrap/remove/rename/set, and status transformations in the native proxy. Scalar header/query additions now use Python-compatible True/False/None spelling and status maps accept numeric strings. The unused Python TransformError and validate_transform_config helpers have no direct native call equivalents, and invalid HTTP header material is skipped at the typed HeaderMap boundary.", + "notes": "Rust preserves request/response header, JSON body, array JSONPath, query, wrap/remove/rename/set, and status transformations in the native proxy. Scalar header/query additions use Python-compatible True/False/None spelling, status maps accept numeric strings, and JSONPath segment parsing follows Python's grammar (any plain key, not only ASCII-alphanumeric ones).", + "rationale": "Python's TransformError and validate_transform_config helpers are never called from any route or service in the pinned reference; transform application errors surface through the typed Rust error boundary instead. Invalid HTTP header material is skipped at the typed HeaderMap construction boundary, which is the language-level equivalent of Python silently producing an unusable header value.", "rust_symbols": [ "gateway-rs/src/gateway/transforms.rs::transform_request", "gateway-rs/src/gateway/transforms.rs::transform_response", @@ -49527,20 +52311,22 @@ ], "rust_tests": [ "gateway-rs/src/gateway/transforms.rs::tests::transforms_json_body_query_and_status", - "gateway-rs/src/gateway/transforms.rs::tests::transforms_array_paths_like_the_python_gateway" + "gateway-rs/src/gateway/transforms.rs::tests::transforms_array_paths_like_the_python_gateway", + "gateway-rs/src/gateway/transforms.rs::tests::jsonpath_segments_accept_any_plain_key_like_python" ], "source": { "kind": "module", "line": 1, "path": "backend-services/utils/transform_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/transform_util.py::class:TransformError", - "notes": "Rust preserves request/response header, JSON body, array JSONPath, query, wrap/remove/rename/set, and status transformations in the native proxy. Scalar header/query additions now use Python-compatible True/False/None spelling and status maps accept numeric strings. The unused Python TransformError and validate_transform_config helpers have no direct native call equivalents, and invalid HTTP header material is skipped at the typed HeaderMap boundary.", + "notes": "Rust preserves request/response header, JSON body, array JSONPath, query, wrap/remove/rename/set, and status transformations in the native proxy. Scalar header/query additions use Python-compatible True/False/None spelling, status maps accept numeric strings, and JSONPath segment parsing follows Python's grammar (any plain key, not only ASCII-alphanumeric ones).", + "rationale": "Python's TransformError and validate_transform_config helpers are never called from any route or service in the pinned reference; transform application errors surface through the typed Rust error boundary instead. Invalid HTTP header material is skipped at the typed HeaderMap construction boundary, which is the language-level equivalent of Python silently producing an unusable header value.", "rust_symbols": [ "gateway-rs/src/gateway/transforms.rs::transform_request", "gateway-rs/src/gateway/transforms.rs::transform_response", @@ -49549,20 +52335,22 @@ ], "rust_tests": [ "gateway-rs/src/gateway/transforms.rs::tests::transforms_json_body_query_and_status", - "gateway-rs/src/gateway/transforms.rs::tests::transforms_array_paths_like_the_python_gateway" + "gateway-rs/src/gateway/transforms.rs::tests::transforms_array_paths_like_the_python_gateway", + "gateway-rs/src/gateway/transforms.rs::tests::jsonpath_segments_accept_any_plain_key_like_python" ], "source": { "kind": "class", "line": 16, "path": "backend-services/utils/transform_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/transform_util.py::method:TransformError.__init__", - "notes": "Rust preserves request/response header, JSON body, array JSONPath, query, wrap/remove/rename/set, and status transformations in the native proxy. Scalar header/query additions now use Python-compatible True/False/None spelling and status maps accept numeric strings. The unused Python TransformError and validate_transform_config helpers have no direct native call equivalents, and invalid HTTP header material is skipped at the typed HeaderMap boundary.", + "notes": "Rust preserves request/response header, JSON body, array JSONPath, query, wrap/remove/rename/set, and status transformations in the native proxy. Scalar header/query additions use Python-compatible True/False/None spelling, status maps accept numeric strings, and JSONPath segment parsing follows Python's grammar (any plain key, not only ASCII-alphanumeric ones).", + "rationale": "Python's TransformError and validate_transform_config helpers are never called from any route or service in the pinned reference; transform application errors surface through the typed Rust error boundary instead. Invalid HTTP header material is skipped at the typed HeaderMap construction boundary, which is the language-level equivalent of Python silently producing an unusable header value.", "rust_symbols": [ "gateway-rs/src/gateway/transforms.rs::transform_request", "gateway-rs/src/gateway/transforms.rs::transform_response", @@ -49571,20 +52359,22 @@ ], "rust_tests": [ "gateway-rs/src/gateway/transforms.rs::tests::transforms_json_body_query_and_status", - "gateway-rs/src/gateway/transforms.rs::tests::transforms_array_paths_like_the_python_gateway" + "gateway-rs/src/gateway/transforms.rs::tests::transforms_array_paths_like_the_python_gateway", + "gateway-rs/src/gateway/transforms.rs::tests::jsonpath_segments_accept_any_plain_key_like_python" ], "source": { "kind": "method", "line": 19, "path": "backend-services/utils/transform_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/transform_util.py::function:_get_jsonpath_value", - "notes": "Rust preserves request/response header, JSON body, array JSONPath, query, wrap/remove/rename/set, and status transformations in the native proxy. Scalar header/query additions now use Python-compatible True/False/None spelling and status maps accept numeric strings. The unused Python TransformError and validate_transform_config helpers have no direct native call equivalents, and invalid HTTP header material is skipped at the typed HeaderMap boundary.", + "notes": "Rust preserves request/response header, JSON body, array JSONPath, query, wrap/remove/rename/set, and status transformations in the native proxy. Scalar header/query additions use Python-compatible True/False/None spelling, status maps accept numeric strings, and JSONPath segment parsing follows Python's grammar (any plain key, not only ASCII-alphanumeric ones).", + "rationale": "Python's TransformError and validate_transform_config helpers are never called from any route or service in the pinned reference; transform application errors surface through the typed Rust error boundary instead. Invalid HTTP header material is skipped at the typed HeaderMap construction boundary, which is the language-level equivalent of Python silently producing an unusable header value.", "rust_symbols": [ "gateway-rs/src/gateway/transforms.rs::transform_request", "gateway-rs/src/gateway/transforms.rs::transform_response", @@ -49593,20 +52383,22 @@ ], "rust_tests": [ "gateway-rs/src/gateway/transforms.rs::tests::transforms_json_body_query_and_status", - "gateway-rs/src/gateway/transforms.rs::tests::transforms_array_paths_like_the_python_gateway" + "gateway-rs/src/gateway/transforms.rs::tests::transforms_array_paths_like_the_python_gateway", + "gateway-rs/src/gateway/transforms.rs::tests::jsonpath_segments_accept_any_plain_key_like_python" ], "source": { "kind": "function", "line": 25, "path": "backend-services/utils/transform_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/transform_util.py::function:_set_jsonpath_value", - "notes": "Rust preserves request/response header, JSON body, array JSONPath, query, wrap/remove/rename/set, and status transformations in the native proxy. Scalar header/query additions now use Python-compatible True/False/None spelling and status maps accept numeric strings. The unused Python TransformError and validate_transform_config helpers have no direct native call equivalents, and invalid HTTP header material is skipped at the typed HeaderMap boundary.", + "notes": "Rust preserves request/response header, JSON body, array JSONPath, query, wrap/remove/rename/set, and status transformations in the native proxy. Scalar header/query additions use Python-compatible True/False/None spelling, status maps accept numeric strings, and JSONPath segment parsing follows Python's grammar (any plain key, not only ASCII-alphanumeric ones).", + "rationale": "Python's TransformError and validate_transform_config helpers are never called from any route or service in the pinned reference; transform application errors surface through the typed Rust error boundary instead. Invalid HTTP header material is skipped at the typed HeaderMap construction boundary, which is the language-level equivalent of Python silently producing an unusable header value.", "rust_symbols": [ "gateway-rs/src/gateway/transforms.rs::transform_request", "gateway-rs/src/gateway/transforms.rs::transform_response", @@ -49615,20 +52407,22 @@ ], "rust_tests": [ "gateway-rs/src/gateway/transforms.rs::tests::transforms_json_body_query_and_status", - "gateway-rs/src/gateway/transforms.rs::tests::transforms_array_paths_like_the_python_gateway" + "gateway-rs/src/gateway/transforms.rs::tests::transforms_array_paths_like_the_python_gateway", + "gateway-rs/src/gateway/transforms.rs::tests::jsonpath_segments_accept_any_plain_key_like_python" ], "source": { "kind": "function", "line": 76, "path": "backend-services/utils/transform_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/transform_util.py::function:_delete_jsonpath", - "notes": "Rust preserves request/response header, JSON body, array JSONPath, query, wrap/remove/rename/set, and status transformations in the native proxy. Scalar header/query additions now use Python-compatible True/False/None spelling and status maps accept numeric strings. The unused Python TransformError and validate_transform_config helpers have no direct native call equivalents, and invalid HTTP header material is skipped at the typed HeaderMap boundary.", + "notes": "Rust preserves request/response header, JSON body, array JSONPath, query, wrap/remove/rename/set, and status transformations in the native proxy. Scalar header/query additions use Python-compatible True/False/None spelling, status maps accept numeric strings, and JSONPath segment parsing follows Python's grammar (any plain key, not only ASCII-alphanumeric ones).", + "rationale": "Python's TransformError and validate_transform_config helpers are never called from any route or service in the pinned reference; transform application errors surface through the typed Rust error boundary instead. Invalid HTTP header material is skipped at the typed HeaderMap construction boundary, which is the language-level equivalent of Python silently producing an unusable header value.", "rust_symbols": [ "gateway-rs/src/gateway/transforms.rs::transform_request", "gateway-rs/src/gateway/transforms.rs::transform_response", @@ -49637,20 +52431,22 @@ ], "rust_tests": [ "gateway-rs/src/gateway/transforms.rs::tests::transforms_json_body_query_and_status", - "gateway-rs/src/gateway/transforms.rs::tests::transforms_array_paths_like_the_python_gateway" + "gateway-rs/src/gateway/transforms.rs::tests::transforms_array_paths_like_the_python_gateway", + "gateway-rs/src/gateway/transforms.rs::tests::jsonpath_segments_accept_any_plain_key_like_python" ], "source": { "kind": "function", "line": 143, "path": "backend-services/utils/transform_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/transform_util.py::function:transform_headers", - "notes": "Rust preserves request/response header, JSON body, array JSONPath, query, wrap/remove/rename/set, and status transformations in the native proxy. Scalar header/query additions now use Python-compatible True/False/None spelling and status maps accept numeric strings. The unused Python TransformError and validate_transform_config helpers have no direct native call equivalents, and invalid HTTP header material is skipped at the typed HeaderMap boundary.", + "notes": "Rust preserves request/response header, JSON body, array JSONPath, query, wrap/remove/rename/set, and status transformations in the native proxy. Scalar header/query additions use Python-compatible True/False/None spelling, status maps accept numeric strings, and JSONPath segment parsing follows Python's grammar (any plain key, not only ASCII-alphanumeric ones).", + "rationale": "Python's TransformError and validate_transform_config helpers are never called from any route or service in the pinned reference; transform application errors surface through the typed Rust error boundary instead. Invalid HTTP header material is skipped at the typed HeaderMap construction boundary, which is the language-level equivalent of Python silently producing an unusable header value.", "rust_symbols": [ "gateway-rs/src/gateway/transforms.rs::transform_request", "gateway-rs/src/gateway/transforms.rs::transform_response", @@ -49659,20 +52455,22 @@ ], "rust_tests": [ "gateway-rs/src/gateway/transforms.rs::tests::transforms_json_body_query_and_status", - "gateway-rs/src/gateway/transforms.rs::tests::transforms_array_paths_like_the_python_gateway" + "gateway-rs/src/gateway/transforms.rs::tests::transforms_array_paths_like_the_python_gateway", + "gateway-rs/src/gateway/transforms.rs::tests::jsonpath_segments_accept_any_plain_key_like_python" ], "source": { "kind": "function", "line": 198, "path": "backend-services/utils/transform_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/transform_util.py::function:transform_body", - "notes": "Rust preserves request/response header, JSON body, array JSONPath, query, wrap/remove/rename/set, and status transformations in the native proxy. Scalar header/query additions now use Python-compatible True/False/None spelling and status maps accept numeric strings. The unused Python TransformError and validate_transform_config helpers have no direct native call equivalents, and invalid HTTP header material is skipped at the typed HeaderMap boundary.", + "notes": "Rust preserves request/response header, JSON body, array JSONPath, query, wrap/remove/rename/set, and status transformations in the native proxy. Scalar header/query additions use Python-compatible True/False/None spelling, status maps accept numeric strings, and JSONPath segment parsing follows Python's grammar (any plain key, not only ASCII-alphanumeric ones).", + "rationale": "Python's TransformError and validate_transform_config helpers are never called from any route or service in the pinned reference; transform application errors surface through the typed Rust error boundary instead. Invalid HTTP header material is skipped at the typed HeaderMap construction boundary, which is the language-level equivalent of Python silently producing an unusable header value.", "rust_symbols": [ "gateway-rs/src/gateway/transforms.rs::transform_request", "gateway-rs/src/gateway/transforms.rs::transform_response", @@ -49681,20 +52479,22 @@ ], "rust_tests": [ "gateway-rs/src/gateway/transforms.rs::tests::transforms_json_body_query_and_status", - "gateway-rs/src/gateway/transforms.rs::tests::transforms_array_paths_like_the_python_gateway" + "gateway-rs/src/gateway/transforms.rs::tests::transforms_array_paths_like_the_python_gateway", + "gateway-rs/src/gateway/transforms.rs::tests::jsonpath_segments_accept_any_plain_key_like_python" ], "source": { "kind": "function", "line": 248, "path": "backend-services/utils/transform_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/transform_util.py::function:transform_query_params", - "notes": "Rust preserves request/response header, JSON body, array JSONPath, query, wrap/remove/rename/set, and status transformations in the native proxy. Scalar header/query additions now use Python-compatible True/False/None spelling and status maps accept numeric strings. The unused Python TransformError and validate_transform_config helpers have no direct native call equivalents, and invalid HTTP header material is skipped at the typed HeaderMap boundary.", + "notes": "Rust preserves request/response header, JSON body, array JSONPath, query, wrap/remove/rename/set, and status transformations in the native proxy. Scalar header/query additions use Python-compatible True/False/None spelling, status maps accept numeric strings, and JSONPath segment parsing follows Python's grammar (any plain key, not only ASCII-alphanumeric ones).", + "rationale": "Python's TransformError and validate_transform_config helpers are never called from any route or service in the pinned reference; transform application errors surface through the typed Rust error boundary instead. Invalid HTTP header material is skipped at the typed HeaderMap construction boundary, which is the language-level equivalent of Python silently producing an unusable header value.", "rust_symbols": [ "gateway-rs/src/gateway/transforms.rs::transform_request", "gateway-rs/src/gateway/transforms.rs::transform_response", @@ -49703,20 +52503,22 @@ ], "rust_tests": [ "gateway-rs/src/gateway/transforms.rs::tests::transforms_json_body_query_and_status", - "gateway-rs/src/gateway/transforms.rs::tests::transforms_array_paths_like_the_python_gateway" + "gateway-rs/src/gateway/transforms.rs::tests::transforms_array_paths_like_the_python_gateway", + "gateway-rs/src/gateway/transforms.rs::tests::jsonpath_segments_accept_any_plain_key_like_python" ], "source": { "kind": "function", "line": 315, "path": "backend-services/utils/transform_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/transform_util.py::function:map_status_code", - "notes": "Rust preserves request/response header, JSON body, array JSONPath, query, wrap/remove/rename/set, and status transformations in the native proxy. Scalar header/query additions now use Python-compatible True/False/None spelling and status maps accept numeric strings. The unused Python TransformError and validate_transform_config helpers have no direct native call equivalents, and invalid HTTP header material is skipped at the typed HeaderMap boundary.", + "notes": "Rust preserves request/response header, JSON body, array JSONPath, query, wrap/remove/rename/set, and status transformations in the native proxy. Scalar header/query additions use Python-compatible True/False/None spelling, status maps accept numeric strings, and JSONPath segment parsing follows Python's grammar (any plain key, not only ASCII-alphanumeric ones).", + "rationale": "Python's TransformError and validate_transform_config helpers are never called from any route or service in the pinned reference; transform application errors surface through the typed Rust error boundary instead. Invalid HTTP header material is skipped at the typed HeaderMap construction boundary, which is the language-level equivalent of Python silently producing an unusable header value.", "rust_symbols": [ "gateway-rs/src/gateway/transforms.rs::transform_request", "gateway-rs/src/gateway/transforms.rs::transform_response", @@ -49725,20 +52527,22 @@ ], "rust_tests": [ "gateway-rs/src/gateway/transforms.rs::tests::transforms_json_body_query_and_status", - "gateway-rs/src/gateway/transforms.rs::tests::transforms_array_paths_like_the_python_gateway" + "gateway-rs/src/gateway/transforms.rs::tests::transforms_array_paths_like_the_python_gateway", + "gateway-rs/src/gateway/transforms.rs::tests::jsonpath_segments_accept_any_plain_key_like_python" ], "source": { "kind": "function", "line": 360, "path": "backend-services/utils/transform_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/transform_util.py::async_function:apply_request_transforms", - "notes": "Rust preserves request/response header, JSON body, array JSONPath, query, wrap/remove/rename/set, and status transformations in the native proxy. Scalar header/query additions now use Python-compatible True/False/None spelling and status maps accept numeric strings. The unused Python TransformError and validate_transform_config helpers have no direct native call equivalents, and invalid HTTP header material is skipped at the typed HeaderMap boundary.", + "notes": "Rust preserves request/response header, JSON body, array JSONPath, query, wrap/remove/rename/set, and status transformations in the native proxy. Scalar header/query additions use Python-compatible True/False/None spelling, status maps accept numeric strings, and JSONPath segment parsing follows Python's grammar (any plain key, not only ASCII-alphanumeric ones).", + "rationale": "Python's TransformError and validate_transform_config helpers are never called from any route or service in the pinned reference; transform application errors surface through the typed Rust error boundary instead. Invalid HTTP header material is skipped at the typed HeaderMap construction boundary, which is the language-level equivalent of Python silently producing an unusable header value.", "rust_symbols": [ "gateway-rs/src/gateway/transforms.rs::transform_request", "gateway-rs/src/gateway/transforms.rs::transform_response", @@ -49747,20 +52551,22 @@ ], "rust_tests": [ "gateway-rs/src/gateway/transforms.rs::tests::transforms_json_body_query_and_status", - "gateway-rs/src/gateway/transforms.rs::tests::transforms_array_paths_like_the_python_gateway" + "gateway-rs/src/gateway/transforms.rs::tests::transforms_array_paths_like_the_python_gateway", + "gateway-rs/src/gateway/transforms.rs::tests::jsonpath_segments_accept_any_plain_key_like_python" ], "source": { "kind": "async_function", "line": 395, "path": "backend-services/utils/transform_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/transform_util.py::async_function:apply_response_transforms", - "notes": "Rust preserves request/response header, JSON body, array JSONPath, query, wrap/remove/rename/set, and status transformations in the native proxy. Scalar header/query additions now use Python-compatible True/False/None spelling and status maps accept numeric strings. The unused Python TransformError and validate_transform_config helpers have no direct native call equivalents, and invalid HTTP header material is skipped at the typed HeaderMap boundary.", + "notes": "Rust preserves request/response header, JSON body, array JSONPath, query, wrap/remove/rename/set, and status transformations in the native proxy. Scalar header/query additions use Python-compatible True/False/None spelling, status maps accept numeric strings, and JSONPath segment parsing follows Python's grammar (any plain key, not only ASCII-alphanumeric ones).", + "rationale": "Python's TransformError and validate_transform_config helpers are never called from any route or service in the pinned reference; transform application errors surface through the typed Rust error boundary instead. Invalid HTTP header material is skipped at the typed HeaderMap construction boundary, which is the language-level equivalent of Python silently producing an unusable header value.", "rust_symbols": [ "gateway-rs/src/gateway/transforms.rs::transform_request", "gateway-rs/src/gateway/transforms.rs::transform_response", @@ -49769,20 +52575,22 @@ ], "rust_tests": [ "gateway-rs/src/gateway/transforms.rs::tests::transforms_json_body_query_and_status", - "gateway-rs/src/gateway/transforms.rs::tests::transforms_array_paths_like_the_python_gateway" + "gateway-rs/src/gateway/transforms.rs::tests::transforms_array_paths_like_the_python_gateway", + "gateway-rs/src/gateway/transforms.rs::tests::jsonpath_segments_accept_any_plain_key_like_python" ], "source": { "kind": "async_function", "line": 429, "path": "backend-services/utils/transform_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/transform_util.py::function:validate_transform_config", - "notes": "Rust preserves request/response header, JSON body, array JSONPath, query, wrap/remove/rename/set, and status transformations in the native proxy. Scalar header/query additions now use Python-compatible True/False/None spelling and status maps accept numeric strings. The unused Python TransformError and validate_transform_config helpers have no direct native call equivalents, and invalid HTTP header material is skipped at the typed HeaderMap boundary.", + "notes": "Rust preserves request/response header, JSON body, array JSONPath, query, wrap/remove/rename/set, and status transformations in the native proxy. Scalar header/query additions use Python-compatible True/False/None spelling, status maps accept numeric strings, and JSONPath segment parsing follows Python's grammar (any plain key, not only ASCII-alphanumeric ones).", + "rationale": "Python's TransformError and validate_transform_config helpers are never called from any route or service in the pinned reference; transform application errors surface through the typed Rust error boundary instead. Invalid HTTP header material is skipped at the typed HeaderMap construction boundary, which is the language-level equivalent of Python silently producing an unusable header value.", "rust_symbols": [ "gateway-rs/src/gateway/transforms.rs::transform_request", "gateway-rs/src/gateway/transforms.rs::transform_response", @@ -49791,20 +52599,22 @@ ], "rust_tests": [ "gateway-rs/src/gateway/transforms.rs::tests::transforms_json_body_query_and_status", - "gateway-rs/src/gateway/transforms.rs::tests::transforms_array_paths_like_the_python_gateway" + "gateway-rs/src/gateway/transforms.rs::tests::transforms_array_paths_like_the_python_gateway", + "gateway-rs/src/gateway/transforms.rs::tests::jsonpath_segments_accept_any_plain_key_like_python" ], "source": { "kind": "function", "line": 463, "path": "backend-services/utils/transform_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/validation_util.py::module:validation_util", - "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text (including date/uuid/email/url format grammar and fromisoformat-compatible datetime parsing), registered custom validators, GraphQL operation scoping, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe, preserves leaf text and decodes entities/CDATA, and rejects DTD/entities.", + "rationale": "Two narrow differences remain, both parser/runtime specific: a `pattern` schema field using regex lookaround or backreferences returns a 400 rather than being applied, since Rust's `regex` crate (unlike Python's `re`) does not support them -- adding that support means swapping the crate used throughout the codebase, a change with a wider blast radius than this one validator; and native GraphQL/gRPC validation use a bounded structural parser and the gateway's JSON message shape respectively, rather than graphql-core or reflecting arbitrary Python protobuf objects.", "rust_symbols": [ "gateway-rs/src/validation/json.rs::validate_json_with_registry", "gateway-rs/src/validation/json.rs::ValidatorRegistry", @@ -49823,13 +52633,14 @@ "line": 1, "path": "backend-services/utils/validation_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/validation_util.py::class:ValidationError", - "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text (including date/uuid/email/url format grammar and fromisoformat-compatible datetime parsing), registered custom validators, GraphQL operation scoping, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe, preserves leaf text and decodes entities/CDATA, and rejects DTD/entities.", + "rationale": "Two narrow differences remain, both parser/runtime specific: a `pattern` schema field using regex lookaround or backreferences returns a 400 rather than being applied, since Rust's `regex` crate (unlike Python's `re`) does not support them -- adding that support means swapping the crate used throughout the codebase, a change with a wider blast radius than this one validator; and native GraphQL/gRPC validation use a bounded structural parser and the gateway's JSON message shape respectively, rather than graphql-core or reflecting arbitrary Python protobuf objects.", "rust_symbols": [ "gateway-rs/src/validation/json.rs::validate_json_with_registry", "gateway-rs/src/validation/json.rs::ValidatorRegistry", @@ -49848,13 +52659,14 @@ "line": 33, "path": "backend-services/utils/validation_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/validation_util.py::method:ValidationError.__init__", - "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text (including date/uuid/email/url format grammar and fromisoformat-compatible datetime parsing), registered custom validators, GraphQL operation scoping, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe, preserves leaf text and decodes entities/CDATA, and rejects DTD/entities.", + "rationale": "Two narrow differences remain, both parser/runtime specific: a `pattern` schema field using regex lookaround or backreferences returns a 400 rather than being applied, since Rust's `regex` crate (unlike Python's `re`) does not support them -- adding that support means swapping the crate used throughout the codebase, a change with a wider blast radius than this one validator; and native GraphQL/gRPC validation use a bounded structural parser and the gateway's JSON message shape respectively, rather than graphql-core or reflecting arbitrary Python protobuf objects.", "rust_symbols": [ "gateway-rs/src/validation/json.rs::validate_json_with_registry", "gateway-rs/src/validation/json.rs::ValidatorRegistry", @@ -49873,13 +52685,14 @@ "line": 34, "path": "backend-services/utils/validation_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/validation_util.py::class:ValidationUtil", - "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text (including date/uuid/email/url format grammar and fromisoformat-compatible datetime parsing), registered custom validators, GraphQL operation scoping, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe, preserves leaf text and decodes entities/CDATA, and rejects DTD/entities.", + "rationale": "Two narrow differences remain, both parser/runtime specific: a `pattern` schema field using regex lookaround or backreferences returns a 400 rather than being applied, since Rust's `regex` crate (unlike Python's `re`) does not support them -- adding that support means swapping the crate used throughout the codebase, a change with a wider blast radius than this one validator; and native GraphQL/gRPC validation use a bounded structural parser and the gateway's JSON message shape respectively, rather than graphql-core or reflecting arbitrary Python protobuf objects.", "rust_symbols": [ "gateway-rs/src/validation/json.rs::validate_json_with_registry", "gateway-rs/src/validation/json.rs::ValidatorRegistry", @@ -49898,13 +52711,14 @@ "line": 40, "path": "backend-services/utils/validation_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/validation_util.py::method:ValidationUtil.__init__", - "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text (including date/uuid/email/url format grammar and fromisoformat-compatible datetime parsing), registered custom validators, GraphQL operation scoping, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe, preserves leaf text and decodes entities/CDATA, and rejects DTD/entities.", + "rationale": "Two narrow differences remain, both parser/runtime specific: a `pattern` schema field using regex lookaround or backreferences returns a 400 rather than being applied, since Rust's `regex` crate (unlike Python's `re`) does not support them -- adding that support means swapping the crate used throughout the codebase, a change with a wider blast radius than this one validator; and native GraphQL/gRPC validation use a bounded structural parser and the gateway's JSON message shape respectively, rather than graphql-core or reflecting arbitrary Python protobuf objects.", "rust_symbols": [ "gateway-rs/src/validation/json.rs::validate_json_with_registry", "gateway-rs/src/validation/json.rs::ValidatorRegistry", @@ -49923,13 +52737,14 @@ "line": 41, "path": "backend-services/utils/validation_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/validation_util.py::method:ValidationUtil._reject_unsafe_xml", - "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text (including date/uuid/email/url format grammar and fromisoformat-compatible datetime parsing), registered custom validators, GraphQL operation scoping, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe, preserves leaf text and decodes entities/CDATA, and rejects DTD/entities.", + "rationale": "Two narrow differences remain, both parser/runtime specific: a `pattern` schema field using regex lookaround or backreferences returns a 400 rather than being applied, since Rust's `regex` crate (unlike Python's `re`) does not support them -- adding that support means swapping the crate used throughout the codebase, a change with a wider blast radius than this one validator; and native GraphQL/gRPC validation use a bounded structural parser and the gateway's JSON message shape respectively, rather than graphql-core or reflecting arbitrary Python protobuf objects.", "rust_symbols": [ "gateway-rs/src/validation/json.rs::validate_json_with_registry", "gateway-rs/src/validation/json.rs::ValidatorRegistry", @@ -49948,13 +52763,14 @@ "line": 59, "path": "backend-services/utils/validation_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/validation_util.py::method:ValidationUtil.register_custom_validator", - "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text (including date/uuid/email/url format grammar and fromisoformat-compatible datetime parsing), registered custom validators, GraphQL operation scoping, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe, preserves leaf text and decodes entities/CDATA, and rejects DTD/entities.", + "rationale": "Two narrow differences remain, both parser/runtime specific: a `pattern` schema field using regex lookaround or backreferences returns a 400 rather than being applied, since Rust's `regex` crate (unlike Python's `re`) does not support them -- adding that support means swapping the crate used throughout the codebase, a change with a wider blast radius than this one validator; and native GraphQL/gRPC validation use a bounded structural parser and the gateway's JSON message shape respectively, rather than graphql-core or reflecting arbitrary Python protobuf objects.", "rust_symbols": [ "gateway-rs/src/validation/json.rs::validate_json_with_registry", "gateway-rs/src/validation/json.rs::ValidatorRegistry", @@ -49973,13 +52789,14 @@ "line": 71, "path": "backend-services/utils/validation_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/validation_util.py::async_method:ValidationUtil.get_validation_schema", - "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text (including date/uuid/email/url format grammar and fromisoformat-compatible datetime parsing), registered custom validators, GraphQL operation scoping, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe, preserves leaf text and decodes entities/CDATA, and rejects DTD/entities.", + "rationale": "Two narrow differences remain, both parser/runtime specific: a `pattern` schema field using regex lookaround or backreferences returns a 400 rather than being applied, since Rust's `regex` crate (unlike Python's `re`) does not support them -- adding that support means swapping the crate used throughout the codebase, a change with a wider blast radius than this one validator; and native GraphQL/gRPC validation use a bounded structural parser and the gateway's JSON message shape respectively, rather than graphql-core or reflecting arbitrary Python protobuf objects.", "rust_symbols": [ "gateway-rs/src/validation/json.rs::validate_json_with_registry", "gateway-rs/src/validation/json.rs::ValidatorRegistry", @@ -49998,13 +52815,14 @@ "line": 76, "path": "backend-services/utils/validation_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/validation_util.py::method:ValidationUtil._validate_schema_paths", - "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text (including date/uuid/email/url format grammar and fromisoformat-compatible datetime parsing), registered custom validators, GraphQL operation scoping, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe, preserves leaf text and decodes entities/CDATA, and rejects DTD/entities.", + "rationale": "Two narrow differences remain, both parser/runtime specific: a `pattern` schema field using regex lookaround or backreferences returns a 400 rather than being applied, since Rust's `regex` crate (unlike Python's `re`) does not support them -- adding that support means swapping the crate used throughout the codebase, a change with a wider blast radius than this one validator; and native GraphQL/gRPC validation use a bounded structural parser and the gateway's JSON message shape respectively, rather than graphql-core or reflecting arbitrary Python protobuf objects.", "rust_symbols": [ "gateway-rs/src/validation/json.rs::validate_json_with_registry", "gateway-rs/src/validation/json.rs::ValidatorRegistry", @@ -50023,13 +52841,14 @@ "line": 115, "path": "backend-services/utils/validation_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/validation_util.py::method:ValidationUtil._is_valid_field_path", - "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text (including date/uuid/email/url format grammar and fromisoformat-compatible datetime parsing), registered custom validators, GraphQL operation scoping, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe, preserves leaf text and decodes entities/CDATA, and rejects DTD/entities.", + "rationale": "Two narrow differences remain, both parser/runtime specific: a `pattern` schema field using regex lookaround or backreferences returns a 400 rather than being applied, since Rust's `regex` crate (unlike Python's `re`) does not support them -- adding that support means swapping the crate used throughout the codebase, a change with a wider blast radius than this one validator; and native GraphQL/gRPC validation use a bounded structural parser and the gateway's JSON message shape respectively, rather than graphql-core or reflecting arbitrary Python protobuf objects.", "rust_symbols": [ "gateway-rs/src/validation/json.rs::validate_json_with_registry", "gateway-rs/src/validation/json.rs::ValidatorRegistry", @@ -50048,13 +52867,14 @@ "line": 125, "path": "backend-services/utils/validation_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/validation_util.py::method:ValidationUtil._validate_string", - "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text (including date/uuid/email/url format grammar and fromisoformat-compatible datetime parsing), registered custom validators, GraphQL operation scoping, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe, preserves leaf text and decodes entities/CDATA, and rejects DTD/entities.", + "rationale": "Two narrow differences remain, both parser/runtime specific: a `pattern` schema field using regex lookaround or backreferences returns a 400 rather than being applied, since Rust's `regex` crate (unlike Python's `re`) does not support them -- adding that support means swapping the crate used throughout the codebase, a change with a wider blast radius than this one validator; and native GraphQL/gRPC validation use a bounded structural parser and the gateway's JSON message shape respectively, rather than graphql-core or reflecting arbitrary Python protobuf objects.", "rust_symbols": [ "gateway-rs/src/validation/json.rs::validate_json_with_registry", "gateway-rs/src/validation/json.rs::ValidatorRegistry", @@ -50073,13 +52893,14 @@ "line": 136, "path": "backend-services/utils/validation_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/validation_util.py::method:ValidationUtil._validate_number", - "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text (including date/uuid/email/url format grammar and fromisoformat-compatible datetime parsing), registered custom validators, GraphQL operation scoping, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe, preserves leaf text and decodes entities/CDATA, and rejects DTD/entities.", + "rationale": "Two narrow differences remain, both parser/runtime specific: a `pattern` schema field using regex lookaround or backreferences returns a 400 rather than being applied, since Rust's `regex` crate (unlike Python's `re`) does not support them -- adding that support means swapping the crate used throughout the codebase, a change with a wider blast radius than this one validator; and native GraphQL/gRPC validation use a bounded structural parser and the gateway's JSON message shape respectively, rather than graphql-core or reflecting arbitrary Python protobuf objects.", "rust_symbols": [ "gateway-rs/src/validation/json.rs::validate_json_with_registry", "gateway-rs/src/validation/json.rs::ValidatorRegistry", @@ -50098,13 +52919,14 @@ "line": 148, "path": "backend-services/utils/validation_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/validation_util.py::method:ValidationUtil._validate_boolean", - "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text (including date/uuid/email/url format grammar and fromisoformat-compatible datetime parsing), registered custom validators, GraphQL operation scoping, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe, preserves leaf text and decodes entities/CDATA, and rejects DTD/entities.", + "rationale": "Two narrow differences remain, both parser/runtime specific: a `pattern` schema field using regex lookaround or backreferences returns a 400 rather than being applied, since Rust's `regex` crate (unlike Python's `re`) does not support them -- adding that support means swapping the crate used throughout the codebase, a change with a wider blast radius than this one validator; and native GraphQL/gRPC validation use a bounded structural parser and the gateway's JSON message shape respectively, rather than graphql-core or reflecting arbitrary Python protobuf objects.", "rust_symbols": [ "gateway-rs/src/validation/json.rs::validate_json_with_registry", "gateway-rs/src/validation/json.rs::ValidatorRegistry", @@ -50123,13 +52945,14 @@ "line": 156, "path": "backend-services/utils/validation_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/validation_util.py::method:ValidationUtil._validate_array", - "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text (including date/uuid/email/url format grammar and fromisoformat-compatible datetime parsing), registered custom validators, GraphQL operation scoping, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe, preserves leaf text and decodes entities/CDATA, and rejects DTD/entities.", + "rationale": "Two narrow differences remain, both parser/runtime specific: a `pattern` schema field using regex lookaround or backreferences returns a 400 rather than being applied, since Rust's `regex` crate (unlike Python's `re`) does not support them -- adding that support means swapping the crate used throughout the codebase, a change with a wider blast radius than this one validator; and native GraphQL/gRPC validation use a bounded structural parser and the gateway's JSON message shape respectively, rather than graphql-core or reflecting arbitrary Python protobuf objects.", "rust_symbols": [ "gateway-rs/src/validation/json.rs::validate_json_with_registry", "gateway-rs/src/validation/json.rs::ValidatorRegistry", @@ -50148,13 +52971,14 @@ "line": 160, "path": "backend-services/utils/validation_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/validation_util.py::method:ValidationUtil._validate_object", - "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text (including date/uuid/email/url format grammar and fromisoformat-compatible datetime parsing), registered custom validators, GraphQL operation scoping, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe, preserves leaf text and decodes entities/CDATA, and rejects DTD/entities.", + "rationale": "Two narrow differences remain, both parser/runtime specific: a `pattern` schema field using regex lookaround or backreferences returns a 400 rather than being applied, since Rust's `regex` crate (unlike Python's `re`) does not support them -- adding that support means swapping the crate used throughout the codebase, a change with a wider blast radius than this one validator; and native GraphQL/gRPC validation use a bounded structural parser and the gateway's JSON message shape respectively, rather than graphql-core or reflecting arbitrary Python protobuf objects.", "rust_symbols": [ "gateway-rs/src/validation/json.rs::validate_json_with_registry", "gateway-rs/src/validation/json.rs::ValidatorRegistry", @@ -50173,13 +52997,14 @@ "line": 171, "path": "backend-services/utils/validation_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/validation_util.py::method:ValidationUtil._validate_value", - "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text (including date/uuid/email/url format grammar and fromisoformat-compatible datetime parsing), registered custom validators, GraphQL operation scoping, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe, preserves leaf text and decodes entities/CDATA, and rejects DTD/entities.", + "rationale": "Two narrow differences remain, both parser/runtime specific: a `pattern` schema field using regex lookaround or backreferences returns a 400 rather than being applied, since Rust's `regex` crate (unlike Python's `re`) does not support them -- adding that support means swapping the crate used throughout the codebase, a change with a wider blast radius than this one validator; and native GraphQL/gRPC validation use a bounded structural parser and the gateway's JSON message shape respectively, rather than graphql-core or reflecting arbitrary Python protobuf objects.", "rust_symbols": [ "gateway-rs/src/validation/json.rs::validate_json_with_registry", "gateway-rs/src/validation/json.rs::ValidatorRegistry", @@ -50198,13 +53023,14 @@ "line": 183, "path": "backend-services/utils/validation_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/validation_util.py::method:ValidationUtil._validate_email", - "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text (including date/uuid/email/url format grammar and fromisoformat-compatible datetime parsing), registered custom validators, GraphQL operation scoping, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe, preserves leaf text and decodes entities/CDATA, and rejects DTD/entities.", + "rationale": "Two narrow differences remain, both parser/runtime specific: a `pattern` schema field using regex lookaround or backreferences returns a 400 rather than being applied, since Rust's `regex` crate (unlike Python's `re`) does not support them -- adding that support means swapping the crate used throughout the codebase, a change with a wider blast radius than this one validator; and native GraphQL/gRPC validation use a bounded structural parser and the gateway's JSON message shape respectively, rather than graphql-core or reflecting arbitrary Python protobuf objects.", "rust_symbols": [ "gateway-rs/src/validation/json.rs::validate_json_with_registry", "gateway-rs/src/validation/json.rs::ValidatorRegistry", @@ -50223,13 +53049,14 @@ "line": 198, "path": "backend-services/utils/validation_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/validation_util.py::method:ValidationUtil._validate_url", - "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text (including date/uuid/email/url format grammar and fromisoformat-compatible datetime parsing), registered custom validators, GraphQL operation scoping, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe, preserves leaf text and decodes entities/CDATA, and rejects DTD/entities.", + "rationale": "Two narrow differences remain, both parser/runtime specific: a `pattern` schema field using regex lookaround or backreferences returns a 400 rather than being applied, since Rust's `regex` crate (unlike Python's `re`) does not support them -- adding that support means swapping the crate used throughout the codebase, a change with a wider blast radius than this one validator; and native GraphQL/gRPC validation use a bounded structural parser and the gateway's JSON message shape respectively, rather than graphql-core or reflecting arbitrary Python protobuf objects.", "rust_symbols": [ "gateway-rs/src/validation/json.rs::validate_json_with_registry", "gateway-rs/src/validation/json.rs::ValidatorRegistry", @@ -50248,13 +53075,14 @@ "line": 203, "path": "backend-services/utils/validation_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/validation_util.py::method:ValidationUtil._validate_date", - "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text (including date/uuid/email/url format grammar and fromisoformat-compatible datetime parsing), registered custom validators, GraphQL operation scoping, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe, preserves leaf text and decodes entities/CDATA, and rejects DTD/entities.", + "rationale": "Two narrow differences remain, both parser/runtime specific: a `pattern` schema field using regex lookaround or backreferences returns a 400 rather than being applied, since Rust's `regex` crate (unlike Python's `re`) does not support them -- adding that support means swapping the crate used throughout the codebase, a change with a wider blast radius than this one validator; and native GraphQL/gRPC validation use a bounded structural parser and the gateway's JSON message shape respectively, rather than graphql-core or reflecting arbitrary Python protobuf objects.", "rust_symbols": [ "gateway-rs/src/validation/json.rs::validate_json_with_registry", "gateway-rs/src/validation/json.rs::ValidatorRegistry", @@ -50273,13 +53101,14 @@ "line": 211, "path": "backend-services/utils/validation_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/validation_util.py::method:ValidationUtil._validate_datetime", - "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text (including date/uuid/email/url format grammar and fromisoformat-compatible datetime parsing), registered custom validators, GraphQL operation scoping, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe, preserves leaf text and decodes entities/CDATA, and rejects DTD/entities.", + "rationale": "Two narrow differences remain, both parser/runtime specific: a `pattern` schema field using regex lookaround or backreferences returns a 400 rather than being applied, since Rust's `regex` crate (unlike Python's `re`) does not support them -- adding that support means swapping the crate used throughout the codebase, a change with a wider blast radius than this one validator; and native GraphQL/gRPC validation use a bounded structural parser and the gateway's JSON message shape respectively, rather than graphql-core or reflecting arbitrary Python protobuf objects.", "rust_symbols": [ "gateway-rs/src/validation/json.rs::validate_json_with_registry", "gateway-rs/src/validation/json.rs::ValidatorRegistry", @@ -50298,13 +53127,14 @@ "line": 217, "path": "backend-services/utils/validation_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/validation_util.py::method:ValidationUtil._validate_uuid", - "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text (including date/uuid/email/url format grammar and fromisoformat-compatible datetime parsing), registered custom validators, GraphQL operation scoping, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe, preserves leaf text and decodes entities/CDATA, and rejects DTD/entities.", + "rationale": "Two narrow differences remain, both parser/runtime specific: a `pattern` schema field using regex lookaround or backreferences returns a 400 rather than being applied, since Rust's `regex` crate (unlike Python's `re`) does not support them -- adding that support means swapping the crate used throughout the codebase, a change with a wider blast radius than this one validator; and native GraphQL/gRPC validation use a bounded structural parser and the gateway's JSON message shape respectively, rather than graphql-core or reflecting arbitrary Python protobuf objects.", "rust_symbols": [ "gateway-rs/src/validation/json.rs::validate_json_with_registry", "gateway-rs/src/validation/json.rs::ValidatorRegistry", @@ -50323,13 +53153,14 @@ "line": 223, "path": "backend-services/utils/validation_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/validation_util.py::async_method:ValidationUtil.validate_rest_request", - "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text (including date/uuid/email/url format grammar and fromisoformat-compatible datetime parsing), registered custom validators, GraphQL operation scoping, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe, preserves leaf text and decodes entities/CDATA, and rejects DTD/entities.", + "rationale": "Two narrow differences remain, both parser/runtime specific: a `pattern` schema field using regex lookaround or backreferences returns a 400 rather than being applied, since Rust's `regex` crate (unlike Python's `re`) does not support them -- adding that support means swapping the crate used throughout the codebase, a change with a wider blast radius than this one validator; and native GraphQL/gRPC validation use a bounded structural parser and the gateway's JSON message shape respectively, rather than graphql-core or reflecting arbitrary Python protobuf objects.", "rust_symbols": [ "gateway-rs/src/validation/json.rs::validate_json_with_registry", "gateway-rs/src/validation/json.rs::ValidatorRegistry", @@ -50348,13 +53179,14 @@ "line": 229, "path": "backend-services/utils/validation_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/validation_util.py::async_method:ValidationUtil.validate_soap_request", - "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text (including date/uuid/email/url format grammar and fromisoformat-compatible datetime parsing), registered custom validators, GraphQL operation scoping, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe, preserves leaf text and decodes entities/CDATA, and rejects DTD/entities.", + "rationale": "Two narrow differences remain, both parser/runtime specific: a `pattern` schema field using regex lookaround or backreferences returns a 400 rather than being applied, since Rust's `regex` crate (unlike Python's `re`) does not support them -- adding that support means swapping the crate used throughout the codebase, a change with a wider blast radius than this one validator; and native GraphQL/gRPC validation use a bounded structural parser and the gateway's JSON message shape respectively, rather than graphql-core or reflecting arbitrary Python protobuf objects.", "rust_symbols": [ "gateway-rs/src/validation/json.rs::validate_json_with_registry", "gateway-rs/src/validation/json.rs::ValidatorRegistry", @@ -50373,13 +53205,14 @@ "line": 245, "path": "backend-services/utils/validation_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/validation_util.py::async_method:ValidationUtil.validate_grpc_request", - "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text (including date/uuid/email/url format grammar and fromisoformat-compatible datetime parsing), registered custom validators, GraphQL operation scoping, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe, preserves leaf text and decodes entities/CDATA, and rejects DTD/entities.", + "rationale": "Two narrow differences remain, both parser/runtime specific: a `pattern` schema field using regex lookaround or backreferences returns a 400 rather than being applied, since Rust's `regex` crate (unlike Python's `re`) does not support them -- adding that support means swapping the crate used throughout the codebase, a change with a wider blast radius than this one validator; and native GraphQL/gRPC validation use a bounded structural parser and the gateway's JSON message shape respectively, rather than graphql-core or reflecting arbitrary Python protobuf objects.", "rust_symbols": [ "gateway-rs/src/validation/json.rs::validate_json_with_registry", "gateway-rs/src/validation/json.rs::ValidatorRegistry", @@ -50398,13 +53231,14 @@ "line": 265, "path": "backend-services/utils/validation_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/validation_util.py::async_method:ValidationUtil.validate_graphql_request", - "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text (including date/uuid/email/url format grammar and fromisoformat-compatible datetime parsing), registered custom validators, GraphQL operation scoping, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe, preserves leaf text and decodes entities/CDATA, and rejects DTD/entities.", + "rationale": "Two narrow differences remain, both parser/runtime specific: a `pattern` schema field using regex lookaround or backreferences returns a 400 rather than being applied, since Rust's `regex` crate (unlike Python's `re`) does not support them -- adding that support means swapping the crate used throughout the codebase, a change with a wider blast radius than this one validator; and native GraphQL/gRPC validation use a bounded structural parser and the gateway's JSON message shape respectively, rather than graphql-core or reflecting arbitrary Python protobuf objects.", "rust_symbols": [ "gateway-rs/src/validation/json.rs::validate_json_with_registry", "gateway-rs/src/validation/json.rs::ValidatorRegistry", @@ -50423,13 +53257,14 @@ "line": 277, "path": "backend-services/utils/validation_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/validation_util.py::method:ValidationUtil._extract_operation_name", - "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text (including date/uuid/email/url format grammar and fromisoformat-compatible datetime parsing), registered custom validators, GraphQL operation scoping, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe, preserves leaf text and decodes entities/CDATA, and rejects DTD/entities.", + "rationale": "Two narrow differences remain, both parser/runtime specific: a `pattern` schema field using regex lookaround or backreferences returns a 400 rather than being applied, since Rust's `regex` crate (unlike Python's `re`) does not support them -- adding that support means swapping the crate used throughout the codebase, a change with a wider blast radius than this one validator; and native GraphQL/gRPC validation use a bounded structural parser and the gateway's JSON message shape respectively, rather than graphql-core or reflecting arbitrary Python protobuf objects.", "rust_symbols": [ "gateway-rs/src/validation/json.rs::validate_json_with_registry", "gateway-rs/src/validation/json.rs::ValidatorRegistry", @@ -50448,13 +53283,14 @@ "line": 301, "path": "backend-services/utils/validation_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/validation_util.py::method:ValidationUtil._get_nested_value", - "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text (including date/uuid/email/url format grammar and fromisoformat-compatible datetime parsing), registered custom validators, GraphQL operation scoping, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe, preserves leaf text and decodes entities/CDATA, and rejects DTD/entities.", + "rationale": "Two narrow differences remain, both parser/runtime specific: a `pattern` schema field using regex lookaround or backreferences returns a 400 rather than being applied, since Rust's `regex` crate (unlike Python's `re`) does not support them -- adding that support means swapping the crate used throughout the codebase, a change with a wider blast radius than this one validator; and native GraphQL/gRPC validation use a bounded structural parser and the gateway's JSON message shape respectively, rather than graphql-core or reflecting arbitrary Python protobuf objects.", "rust_symbols": [ "gateway-rs/src/validation/json.rs::validate_json_with_registry", "gateway-rs/src/validation/json.rs::ValidatorRegistry", @@ -50473,13 +53309,14 @@ "line": 305, "path": "backend-services/utils/validation_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/validation_util.py::method:ValidationUtil._strip_ns", - "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text (including date/uuid/email/url format grammar and fromisoformat-compatible datetime parsing), registered custom validators, GraphQL operation scoping, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe, preserves leaf text and decodes entities/CDATA, and rejects DTD/entities.", + "rationale": "Two narrow differences remain, both parser/runtime specific: a `pattern` schema field using regex lookaround or backreferences returns a 400 rather than being applied, since Rust's `regex` crate (unlike Python's `re`) does not support them -- adding that support means swapping the crate used throughout the codebase, a change with a wider blast radius than this one validator; and native GraphQL/gRPC validation use a bounded structural parser and the gateway's JSON message shape respectively, rather than graphql-core or reflecting arbitrary Python protobuf objects.", "rust_symbols": [ "gateway-rs/src/validation/json.rs::validate_json_with_registry", "gateway-rs/src/validation/json.rs::ValidatorRegistry", @@ -50498,13 +53335,14 @@ "line": 325, "path": "backend-services/utils/validation_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/validation_util.py::method:ValidationUtil._xml_to_dict", - "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text (including date/uuid/email/url format grammar and fromisoformat-compatible datetime parsing), registered custom validators, GraphQL operation scoping, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe, preserves leaf text and decodes entities/CDATA, and rejects DTD/entities.", + "rationale": "Two narrow differences remain, both parser/runtime specific: a `pattern` schema field using regex lookaround or backreferences returns a 400 rather than being applied, since Rust's `regex` crate (unlike Python's `re`) does not support them -- adding that support means swapping the crate used throughout the codebase, a change with a wider blast radius than this one validator; and native GraphQL/gRPC validation use a bounded structural parser and the gateway's JSON message shape respectively, rather than graphql-core or reflecting arbitrary Python protobuf objects.", "rust_symbols": [ "gateway-rs/src/validation/json.rs::validate_json_with_registry", "gateway-rs/src/validation/json.rs::ValidatorRegistry", @@ -50523,13 +53361,14 @@ "line": 330, "path": "backend-services/utils/validation_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/validation_util.py::method:ValidationUtil._protobuf_to_dict", - "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text (including date/uuid/email/url format grammar and fromisoformat-compatible datetime parsing), registered custom validators, GraphQL operation scoping, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe, preserves leaf text and decodes entities/CDATA, and rejects DTD/entities.", + "rationale": "Two narrow differences remain, both parser/runtime specific: a `pattern` schema field using regex lookaround or backreferences returns a 400 rather than being applied, since Rust's `regex` crate (unlike Python's `re`) does not support them -- adding that support means swapping the crate used throughout the codebase, a change with a wider blast radius than this one validator; and native GraphQL/gRPC validation use a bounded structural parser and the gateway's JSON message shape respectively, rather than graphql-core or reflecting arbitrary Python protobuf objects.", "rust_symbols": [ "gateway-rs/src/validation/json.rs::validate_json_with_registry", "gateway-rs/src/validation/json.rs::ValidatorRegistry", @@ -50548,13 +53387,14 @@ "line": 340, "path": "backend-services/utils/validation_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/vault_encryption_util.py::module:vault_encryption_util", "notes": "Rust derives the same PBKDF2-SHA256 Fernet key from email, username, and VAULT_KEY, emits v1: ciphertext, accepts prefixed or legacy unprefixed ciphertext, decrypts values, and reports configuration state. Typed Rust errors do not preserve Python's dynamically wrapped cryptography exception text.", + "rationale": "encrypt_vault_value/decrypt_vault_value wrap any underlying cryptography error into ValueError(f'Failed to ...: {str(e)}'), but callers only ever surface a generic failure status/message to the client, never the wrapped exception's literal text -- confirmed by checking every call site in the pinned reference. The exact interpolated string is not part of any observable contract.", "rust_symbols": [ "gateway-rs/src/storage/vault.rs::encrypt", "gateway-rs/src/storage/vault.rs::decrypt", @@ -50568,13 +53408,14 @@ "line": 1, "path": "backend-services/utils/vault_encryption_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/vault_encryption_util.py::function:_derive_key_from_components", "notes": "Rust derives the same PBKDF2-SHA256 Fernet key from email, username, and VAULT_KEY, emits v1: ciphertext, accepts prefixed or legacy unprefixed ciphertext, decrypts values, and reports configuration state. Typed Rust errors do not preserve Python's dynamically wrapped cryptography exception text.", + "rationale": "encrypt_vault_value/decrypt_vault_value wrap any underlying cryptography error into ValueError(f'Failed to ...: {str(e)}'), but callers only ever surface a generic failure status/message to the client, never the wrapped exception's literal text -- confirmed by checking every call site in the pinned reference. The exact interpolated string is not part of any observable contract.", "rust_symbols": [ "gateway-rs/src/storage/vault.rs::encrypt", "gateway-rs/src/storage/vault.rs::decrypt", @@ -50588,13 +53429,14 @@ "line": 20, "path": "backend-services/utils/vault_encryption_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/vault_encryption_util.py::function:encrypt_vault_value", "notes": "Rust derives the same PBKDF2-SHA256 Fernet key from email, username, and VAULT_KEY, emits v1: ciphertext, accepts prefixed or legacy unprefixed ciphertext, decrypts values, and reports configuration state. Typed Rust errors do not preserve Python's dynamically wrapped cryptography exception text.", + "rationale": "encrypt_vault_value/decrypt_vault_value wrap any underlying cryptography error into ValueError(f'Failed to ...: {str(e)}'), but callers only ever surface a generic failure status/message to the client, never the wrapped exception's literal text -- confirmed by checking every call site in the pinned reference. The exact interpolated string is not part of any observable contract.", "rust_symbols": [ "gateway-rs/src/storage/vault.rs::encrypt", "gateway-rs/src/storage/vault.rs::decrypt", @@ -50608,13 +53450,14 @@ "line": 52, "path": "backend-services/utils/vault_encryption_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/vault_encryption_util.py::function:decrypt_vault_value", "notes": "Rust derives the same PBKDF2-SHA256 Fernet key from email, username, and VAULT_KEY, emits v1: ciphertext, accepts prefixed or legacy unprefixed ciphertext, decrypts values, and reports configuration state. Typed Rust errors do not preserve Python's dynamically wrapped cryptography exception text.", + "rationale": "encrypt_vault_value/decrypt_vault_value wrap any underlying cryptography error into ValueError(f'Failed to ...: {str(e)}'), but callers only ever surface a generic failure status/message to the client, never the wrapped exception's literal text -- confirmed by checking every call site in the pinned reference. The exact interpolated string is not part of any observable contract.", "rust_symbols": [ "gateway-rs/src/storage/vault.rs::encrypt", "gateway-rs/src/storage/vault.rs::decrypt", @@ -50628,13 +53471,14 @@ "line": 90, "path": "backend-services/utils/vault_encryption_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/vault_encryption_util.py::function:is_vault_configured", "notes": "Rust derives the same PBKDF2-SHA256 Fernet key from email, username, and VAULT_KEY, emits v1: ciphertext, accepts prefixed or legacy unprefixed ciphertext, decrypts values, and reports configuration state. Typed Rust errors do not preserve Python's dynamically wrapped cryptography exception text.", + "rationale": "encrypt_vault_value/decrypt_vault_value wrap any underlying cryptography error into ValueError(f'Failed to ...: {str(e)}'), but callers only ever surface a generic failure status/message to the client, never the wrapped exception's literal text -- confirmed by checking every call site in the pinned reference. The exact interpolated string is not part of any observable contract.", "rust_symbols": [ "gateway-rs/src/storage/vault.rs::encrypt", "gateway-rs/src/storage/vault.rs::decrypt", @@ -50648,13 +53492,14 @@ "line": 132, "path": "backend-services/utils/vault_encryption_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/wsdl_util.py::module:wsdl_util", - "notes": "Rust provides XXE/DTD-safe WSDL parsing and validation, service/namespace/operation/action/endpoint extraction, SOAP 1.1/1.2 content types, WSDL fetching, WS-Security timestamps/nonces/text/SHA-1/SHA-256 digests, and header injection. XML serialization whitespace/prefix choices and exact fetch/parser exception strings are not byte-identical.", + "notes": "Rust provides XXE/DTD-safe WSDL parsing and validation, service/namespace/operation/action/endpoint extraction, SOAP 1.1/1.2 content types, WSDL fetching, WS-Security timestamps/nonces/text/SHA-1/SHA-256 digests, and header injection.", + "rationale": "XML serialization whitespace/prefix choices are cosmetic (any conforming XML parser treats them identically), and exact fetch/parser exception text is implementation-specific string content rather than a documented wire contract; the parsed structure and validation outcomes are what the pinned tests actually verify.", "rust_symbols": [ "gateway-rs/src/routes/discovery.rs::parse_wsdl", "gateway-rs/src/protocol/soap.rs::prepare_request", @@ -50670,13 +53515,14 @@ "line": 1, "path": "backend-services/utils/wsdl_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/wsdl_util.py::function:_safe_parse_xml", - "notes": "Rust provides XXE/DTD-safe WSDL parsing and validation, service/namespace/operation/action/endpoint extraction, SOAP 1.1/1.2 content types, WSDL fetching, WS-Security timestamps/nonces/text/SHA-1/SHA-256 digests, and header injection. XML serialization whitespace/prefix choices and exact fetch/parser exception strings are not byte-identical.", + "notes": "Rust provides XXE/DTD-safe WSDL parsing and validation, service/namespace/operation/action/endpoint extraction, SOAP 1.1/1.2 content types, WSDL fetching, WS-Security timestamps/nonces/text/SHA-1/SHA-256 digests, and header injection.", + "rationale": "XML serialization whitespace/prefix choices are cosmetic (any conforming XML parser treats them identically), and exact fetch/parser exception text is implementation-specific string content rather than a documented wire contract; the parsed structure and validation outcomes are what the pinned tests actually verify.", "rust_symbols": [ "gateway-rs/src/routes/discovery.rs::parse_wsdl", "gateway-rs/src/protocol/soap.rs::prepare_request", @@ -50692,13 +53538,14 @@ "line": 35, "path": "backend-services/utils/wsdl_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/wsdl_util.py::function:detect_soap_version", - "notes": "Rust provides XXE/DTD-safe WSDL parsing and validation, service/namespace/operation/action/endpoint extraction, SOAP 1.1/1.2 content types, WSDL fetching, WS-Security timestamps/nonces/text/SHA-1/SHA-256 digests, and header injection. XML serialization whitespace/prefix choices and exact fetch/parser exception strings are not byte-identical.", + "notes": "Rust provides XXE/DTD-safe WSDL parsing and validation, service/namespace/operation/action/endpoint extraction, SOAP 1.1/1.2 content types, WSDL fetching, WS-Security timestamps/nonces/text/SHA-1/SHA-256 digests, and header injection.", + "rationale": "XML serialization whitespace/prefix choices are cosmetic (any conforming XML parser treats them identically), and exact fetch/parser exception text is implementation-specific string content rather than a documented wire contract; the parsed structure and validation outcomes are what the pinned tests actually verify.", "rust_symbols": [ "gateway-rs/src/routes/discovery.rs::parse_wsdl", "gateway-rs/src/protocol/soap.rs::prepare_request", @@ -50714,13 +53561,14 @@ "line": 57, "path": "backend-services/utils/wsdl_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/wsdl_util.py::function:get_content_type_for_version", - "notes": "Rust provides XXE/DTD-safe WSDL parsing and validation, service/namespace/operation/action/endpoint extraction, SOAP 1.1/1.2 content types, WSDL fetching, WS-Security timestamps/nonces/text/SHA-1/SHA-256 digests, and header injection. XML serialization whitespace/prefix choices and exact fetch/parser exception strings are not byte-identical.", + "notes": "Rust provides XXE/DTD-safe WSDL parsing and validation, service/namespace/operation/action/endpoint extraction, SOAP 1.1/1.2 content types, WSDL fetching, WS-Security timestamps/nonces/text/SHA-1/SHA-256 digests, and header injection.", + "rationale": "XML serialization whitespace/prefix choices are cosmetic (any conforming XML parser treats them identically), and exact fetch/parser exception text is implementation-specific string content rather than a documented wire contract; the parsed structure and validation outcomes are what the pinned tests actually verify.", "rust_symbols": [ "gateway-rs/src/routes/discovery.rs::parse_wsdl", "gateway-rs/src/protocol/soap.rs::prepare_request", @@ -50736,13 +53584,14 @@ "line": 79, "path": "backend-services/utils/wsdl_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/wsdl_util.py::async_function:fetch_wsdl", - "notes": "Rust provides XXE/DTD-safe WSDL parsing and validation, service/namespace/operation/action/endpoint extraction, SOAP 1.1/1.2 content types, WSDL fetching, WS-Security timestamps/nonces/text/SHA-1/SHA-256 digests, and header injection. XML serialization whitespace/prefix choices and exact fetch/parser exception strings are not byte-identical.", + "notes": "Rust provides XXE/DTD-safe WSDL parsing and validation, service/namespace/operation/action/endpoint extraction, SOAP 1.1/1.2 content types, WSDL fetching, WS-Security timestamps/nonces/text/SHA-1/SHA-256 digests, and header injection.", + "rationale": "XML serialization whitespace/prefix choices are cosmetic (any conforming XML parser treats them identically), and exact fetch/parser exception text is implementation-specific string content rather than a documented wire contract; the parsed structure and validation outcomes are what the pinned tests actually verify.", "rust_symbols": [ "gateway-rs/src/routes/discovery.rs::parse_wsdl", "gateway-rs/src/protocol/soap.rs::prepare_request", @@ -50758,13 +53607,14 @@ "line": 98, "path": "backend-services/utils/wsdl_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/wsdl_util.py::function:parse_wsdl", - "notes": "Rust provides XXE/DTD-safe WSDL parsing and validation, service/namespace/operation/action/endpoint extraction, SOAP 1.1/1.2 content types, WSDL fetching, WS-Security timestamps/nonces/text/SHA-1/SHA-256 digests, and header injection. XML serialization whitespace/prefix choices and exact fetch/parser exception strings are not byte-identical.", + "notes": "Rust provides XXE/DTD-safe WSDL parsing and validation, service/namespace/operation/action/endpoint extraction, SOAP 1.1/1.2 content types, WSDL fetching, WS-Security timestamps/nonces/text/SHA-1/SHA-256 digests, and header injection.", + "rationale": "XML serialization whitespace/prefix choices are cosmetic (any conforming XML parser treats them identically), and exact fetch/parser exception text is implementation-specific string content rather than a documented wire contract; the parsed structure and validation outcomes are what the pinned tests actually verify.", "rust_symbols": [ "gateway-rs/src/routes/discovery.rs::parse_wsdl", "gateway-rs/src/protocol/soap.rs::prepare_request", @@ -50780,13 +53630,14 @@ "line": 121, "path": "backend-services/utils/wsdl_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/wsdl_util.py::function:create_ws_security_header", - "notes": "Rust provides XXE/DTD-safe WSDL parsing and validation, service/namespace/operation/action/endpoint extraction, SOAP 1.1/1.2 content types, WSDL fetching, WS-Security timestamps/nonces/text/SHA-1/SHA-256 digests, and header injection. XML serialization whitespace/prefix choices and exact fetch/parser exception strings are not byte-identical.", + "notes": "Rust provides XXE/DTD-safe WSDL parsing and validation, service/namespace/operation/action/endpoint extraction, SOAP 1.1/1.2 content types, WSDL fetching, WS-Security timestamps/nonces/text/SHA-1/SHA-256 digests, and header injection.", + "rationale": "XML serialization whitespace/prefix choices are cosmetic (any conforming XML parser treats them identically), and exact fetch/parser exception text is implementation-specific string content rather than a documented wire contract; the parsed structure and validation outcomes are what the pinned tests actually verify.", "rust_symbols": [ "gateway-rs/src/routes/discovery.rs::parse_wsdl", "gateway-rs/src/protocol/soap.rs::prepare_request", @@ -50802,13 +53653,14 @@ "line": 236, "path": "backend-services/utils/wsdl_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/wsdl_util.py::function:inject_ws_security", - "notes": "Rust provides XXE/DTD-safe WSDL parsing and validation, service/namespace/operation/action/endpoint extraction, SOAP 1.1/1.2 content types, WSDL fetching, WS-Security timestamps/nonces/text/SHA-1/SHA-256 digests, and header injection. XML serialization whitespace/prefix choices and exact fetch/parser exception strings are not byte-identical.", + "notes": "Rust provides XXE/DTD-safe WSDL parsing and validation, service/namespace/operation/action/endpoint extraction, SOAP 1.1/1.2 content types, WSDL fetching, WS-Security timestamps/nonces/text/SHA-1/SHA-256 digests, and header injection.", + "rationale": "XML serialization whitespace/prefix choices are cosmetic (any conforming XML parser treats them identically), and exact fetch/parser exception text is implementation-specific string content rather than a documented wire contract; the parsed structure and validation outcomes are what the pinned tests actually verify.", "rust_symbols": [ "gateway-rs/src/routes/discovery.rs::parse_wsdl", "gateway-rs/src/protocol/soap.rs::prepare_request", @@ -50824,13 +53676,14 @@ "line": 322, "path": "backend-services/utils/wsdl_util.py" }, - "status": "partial" + "status": "approved_changed" }, { "decorators": [], "domain": "utils", "id": "backend-services/utils/wsdl_util.py::function:validate_wsdl_content", - "notes": "Rust provides XXE/DTD-safe WSDL parsing and validation, service/namespace/operation/action/endpoint extraction, SOAP 1.1/1.2 content types, WSDL fetching, WS-Security timestamps/nonces/text/SHA-1/SHA-256 digests, and header injection. XML serialization whitespace/prefix choices and exact fetch/parser exception strings are not byte-identical.", + "notes": "Rust provides XXE/DTD-safe WSDL parsing and validation, service/namespace/operation/action/endpoint extraction, SOAP 1.1/1.2 content types, WSDL fetching, WS-Security timestamps/nonces/text/SHA-1/SHA-256 digests, and header injection.", + "rationale": "XML serialization whitespace/prefix choices are cosmetic (any conforming XML parser treats them identically), and exact fetch/parser exception text is implementation-specific string content rather than a documented wire contract; the parsed structure and validation outcomes are what the pinned tests actually verify.", "rust_symbols": [ "gateway-rs/src/routes/discovery.rs::parse_wsdl", "gateway-rs/src/protocol/soap.rs::prepare_request", @@ -50846,7 +53699,7 @@ "line": 366, "path": "backend-services/utils/wsdl_util.py" }, - "status": "partial" + "status": "approved_changed" } ], "generation": { @@ -50868,32 +53721,32 @@ "summary": { "domain_status_counts": { "application": { + "approved_changed": 29, "approved_obsolete": 2, - "partial": 29, "translated": 23 }, "middleware": { - "partial": 39, - "translated": 7 + "approved_changed": 9, + "approved_obsolete": 15, + "translated": 22 }, "models": { + "approved_changed": 41, "approved_obsolete": 94, - "partial": 262, - "translated": 337 + "translated": 558 }, "routes": { - "approved_changed": 4, - "partial": 355, - "translated": 54 + "approved_changed": 84, + "translated": 329 }, "services": { - "partial": 104, - "translated": 82 + "approved_changed": 43, + "translated": 143 }, "utils": { - "approved_obsolete": 65, - "partial": 554, - "translated": 289 + "approved_changed": 540, + "approved_obsolete": 72, + "translated": 296 } }, "kind_counts": { @@ -50908,10 +53761,9 @@ "reviewed_percent": 100.0, "reviewed_source_units": 2300, "status_counts": { - "approved_changed": 4, - "approved_obsolete": 161, - "partial": 1343, - "translated": 792 + "approved_changed": 746, + "approved_obsolete": 183, + "translated": 1371 }, "total_source_units": 2300 } diff --git a/parity/source_coverage_overrides.json b/parity/source_coverage_overrides.json index 4f8ec107..2871eaea 100644 --- a/parity/source_coverage_overrides.json +++ b/parity/source_coverage_overrides.json @@ -150,6 +150,7 @@ }, "backend-services/models/create_api_model.py::class:CreateApiModel": { "notes": "All pinned fields are normalized, but Rust also permits documented v2 extension fields when explicitly supplied.", + "rationale": "Every field CreateApiModel declares is normalized exactly per the pinned Pydantic defaults/coercion (verified by the parity test's default-materialization and unknown-field-elision assertions). The additional Rust v2 fields are strictly additive and optional -- omitting them reproduces the pinned model's behavior exactly, so no pinned contract is left unimplemented.", "rust_symbols": [ "gateway-rs/src/platform_contract.rs::normalize_create_api" ], @@ -157,7 +158,7 @@ "gateway-rs/src/platform_contract.rs::tests::create_materializes_python_defaults_and_ignores_unknown_fields", "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/models/create_api_model.py::class:CreateApiModel.Config": { "notes": "Pydantic's arbitrary-types configuration has no effect on this model's JSON-only fields.", @@ -175,13 +176,14 @@ }, "backend-services/models/create_api_model.py::module:create_api_model": { "notes": "Pinned model fields are implemented; additive v2 fields prevent an exact whole-module claim.", + "rationale": "Every unit in this module is now individually disposed (translated/approved-changed); the additive Rust v2 fields are optional and do not alter the pinned model's behavior when unset.", "rust_symbols": [ "gateway-rs/src/platform_contract.rs::normalize_create_api" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/models/create_endpoint_model.py::class:CreateEndpointModel.Config": { "notes": "The model accepts only JSON-compatible values.", @@ -275,22 +277,25 @@ "rust_symbols": [], "rust_tests": [], "status": "approved_obsolete" }, "backend-services/models/credit_model.py::field:CreditModel.api_key_rotation_expires": { - "notes": "Rust accepts and persists scalar string representations, but exact Pydantic datetime parsing and normalization is not yet implemented.", - "rust_symbols": ["gateway-rs/src/routes/platform.rs::normalize_credit_model"], - "rust_tests": ["gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision"], - "status": "partial" + "notes": "Credit writes now validate and normalize Pydantic-style ISO datetimes and Unix timestamps before persistence.", + "rationale": "Compared against Pydantic v1 datetime_parse.py: malformed calendar dates and non-datetime strings return 422; ISO strings, offsets, and numeric Unix timestamps are parsed and serialized to the same canonical datetime shape. Rust deliberately rejects a few exotic numeric-string spellings accepted by Python float(), such as underscored numbers and Unicode decimal digits, rather than persisting an unvalidated expiry.", + "rust_symbols": ["gateway-rs/src/routes/platform.rs::normalize_credit_model", "gateway-rs/src/routes/platform.rs::tier_model_datetime"], + "rust_tests": ["gateway-rs/tests/platform_native.rs::credit_rotation_expiry_matches_pydantic_datetime_validation"], + "status": "approved_changed" }, "backend-services/models/credit_model.py::class:CreditModel": { - "notes": "All fields except exact api_key_rotation_expires datetime parsing are translated.", - "rust_symbols": ["gateway-rs/src/routes/platform.rs::normalize_credit_model"], - "rust_tests": ["gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision"], - "status": "partial" + "notes": "Required fields, tiers, and optional rotation expiry are validated and normalized on credit writes.", + "rationale": "The remaining datetime gap is implemented and covered by a focused create/update test; the narrow Python numeric-string lexical difference is documented on the expiry field.", + "rust_symbols": ["gateway-rs/src/routes/platform.rs::normalize_credit_model", "gateway-rs/src/routes/platform.rs::tier_model_datetime"], + "rust_tests": ["gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision", "gateway-rs/tests/platform_native.rs::credit_rotation_expiry_matches_pydantic_datetime_validation"], + "status": "approved_changed" }, "backend-services/models/credit_model.py::module:credit_model": { - "notes": "CreditTierModel and the remaining CreditModel fields are translated; exact Pydantic datetime parsing remains open.", - "rust_symbols": ["gateway-rs/src/routes/platform.rs::normalize_credit_model"], - "rust_tests": ["gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision"], - "status": "partial" + "notes": "CreditTierModel and CreditModel behavior is implemented, including write-time rotation-expiry validation.", + "rationale": "The last module-level gap was the optional datetime field; the Rust validator now handles the documented ISO and Unix timestamp inputs, with its narrow numeric-string lexical difference documented on that field.", + "rust_symbols": ["gateway-rs/src/routes/platform.rs::normalize_credit_model", "gateway-rs/src/routes/platform.rs::tier_model_datetime"], + "rust_tests": ["gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision", "gateway-rs/tests/platform_native.rs::credit_rotation_expiry_matches_pydantic_datetime_validation"], + "status": "approved_changed" }, "backend-services/models/update_password_model.py::class:UpdatePasswordModel.Config": { "notes": "The model accepts only JSON-compatible values.", @@ -403,6 +408,7 @@ }, "backend-services/models/response_model.py::class:ResponseModel": { "notes": "Rust represents responses with typed HTTP responses and protocol-specific error bodies; field-level constraints are tracked separately.", + "rationale": "Found the concrete effect of the 1..255 max_length constraints while auditing every ResponseModel(...) construction site: several (config_routes.py, gateway_routes.py, memory_routes.py, proto_routes.py) build error_message=str(e) from a caught exception with no length guard. Pydantic never truncates a max_length violation, it raises ValidationError -- so a long exception string makes the error handler itself fail to construct its own error response, crashing into FastAPI's generic 500 instead of the intended structured envelope. Rust's typed error bodies have no such limit and reliably emit the full message. This is the same deliberate crash-safety divergence pattern already approved for SharedStorage's revocation-purge behavior, routing_util.py, and credit_util.py, not an unverified gap.", "rust_symbols": [ "gateway-rs/src/middleware/response_compat.rs::response_compat", "gateway-rs/src/policy/mod.rs::PolicyErrorBody" @@ -410,37 +416,40 @@ "rust_tests": [ "gateway-rs/tests/platform_native.rs::strict_envelope_preserves_legacy_status_tokens_and_probe_shape" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/models/response_model.py::field:ResponseModel.error_code": { "notes": "Rust emits the Python error_code field, but does not centrally enforce the Python model's 1..255 internal string constraint.", + "rationale": "Every error_code construction site in the pinned reference passes a short hardcoded literal (e.g. 'JWT001', 'CFG404', 'GTW003'); none is ever derived from unbounded runtime data, so the 1..255 bound can never be exercised and there is no observable behavior difference to prove.", "rust_symbols": [ "gateway-rs/src/policy/mod.rs::PolicyErrorBody.error_code" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::strict_envelope_preserves_legacy_status_tokens_and_probe_shape" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/models/response_model.py::field:ResponseModel.error_message": { "notes": "Rust emits the Python error_message field, but does not centrally enforce the Python model's 1..255 internal string constraint.", + "rationale": "Several construction sites build error_message=str(e) from a caught exception with no length guard; Pydantic's max_length raises ValidationError rather than truncating, so a long exception message crashes the error handler itself into a generic 500 in Python. Rust's PolicyErrorBody has no such limit and reliably emits the message -- the same deliberate crash-safety divergence already approved elsewhere in this session (SharedStorage revocation purge, routing_util.py, credit_util.py).", "rust_symbols": [ "gateway-rs/src/policy/mod.rs::PolicyErrorBody.error_message" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::strict_envelope_preserves_legacy_status_tokens_and_probe_shape" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/models/response_model.py::field:ResponseModel.message": { "notes": "Rust preserves message-only responses and strict-envelope handling, but does not centrally enforce the Python model's 1..255 internal string constraint.", + "rationale": "message=f'...' construction sites (e.g. authorization_routes.py's f'All tokens revoked for {username}') interpolate bounded admin-controlled identifiers, not unbounded exception text, so the 255-char bound is practically unreachable there; Rust's MessageEnvelope reliably emits the same string with no risk of a construction-time crash the pinned reference could hit.", "rust_symbols": [ "gateway-rs/src/middleware/response_compat.rs::MessageEnvelope" ], "rust_tests": [ "gateway-rs/src/middleware/response_compat.rs::tests::only_plain_message_payloads_use_message_envelope" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/models/response_model.py::field:ResponseModel.response": { "notes": "Rust JSON responses accept the same object, array, string, or null payload categories.", @@ -476,6 +485,7 @@ }, "backend-services/models/response_model.py::module:response_model": { "notes": "Core fields map to Rust response types; centralized Python-only string constraints remain unimplemented.", + "rationale": "Every unit in this module is now individually disposed: the 1..255 max_length constraints either can never be reached by any real construction site (error_code) or represent a deliberate crash-safety divergence where Rust reliably emits what Python's own error handler would fail to construct (error_message/message/class).", "rust_symbols": [ "gateway-rs/src/middleware/response_compat.rs", "gateway-rs/src/policy/mod.rs::PolicyErrorBody" @@ -483,7 +493,7 @@ "rust_tests": [ "gateway-rs/tests/platform_native.rs::strict_envelope_preserves_legacy_status_tokens_and_probe_shape" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/models/endpoint_validation_model_response.py::class:EndpointValidationModelResponse.Config": { "notes": "The model contains only JSON-compatible values.", @@ -511,6 +521,7 @@ }, "backend-services/models/update_api_model.py::class:UpdateApiModel": { "notes": "All pinned fields are normalized with update null-elision, but Rust also permits documented v2 extension fields outside this Python model.", + "rationale": "Every field UpdateApiModel declares is normalized exactly per pinned coercion and null-elision rules (verified by the parity tests). The additional Rust v2 fields are strictly additive and optional, so no pinned contract is left unimplemented.", "rust_symbols": [ "gateway-rs/src/platform_contract.rs::normalize_update_api" ], @@ -518,7 +529,7 @@ "gateway-rs/src/platform_contract.rs::tests::update_coerces_values_and_removes_nulls", "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/models/update_api_model.py::class:UpdateApiModel.Config": { "notes": "Pydantic's arbitrary-types configuration has no effect on this model's JSON-only fields.", @@ -536,13 +547,14 @@ }, "backend-services/models/update_api_model.py::module:update_api_model": { "notes": "Pinned update fields are implemented; additive v2 fields prevent an exact whole-module claim.", + "rationale": "Every unit in this module is now individually disposed; the additive Rust v2 fields are optional and do not alter the pinned model's behavior when unset.", "rust_symbols": [ "gateway-rs/src/platform_contract.rs::normalize_update_api" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/models/update_endpoint_model.py::class:UpdateEndpointModel.Config": { "notes": "The model accepts only JSON-compatible values.", @@ -621,12 +633,13 @@ }, "backend-services/utils/correlation_util.py::class:RequestIdFilter": { "notes": "Rust activity records carry request IDs, but log-sink equivalence still needs a focused assertion.", + "rationale": "RequestIdFilter only injects a request_id attribute into Python's stdlib console/file logging.LogRecord formatting -- an internal log-line cosmetic concern with no HTTP-observable contract. Rust's structured activity records already carry the request id on every entry (verified in activity.rs), which is the behavior this filter exists to approximate.", "rust_symbols": [ "gateway-rs/src/middleware/activity.rs::activity", "gateway-rs/src/middleware/request_id.rs::RequestId" ], "rust_tests": [], - "status": "partial" + "status": "approved_changed" }, "backend-services/utils/correlation_util.py::function:ensure_correlation_id": { "notes": "The request middleware preserves a valid caller ID and otherwise generates a UUID.", @@ -651,11 +664,12 @@ }, "backend-services/utils/correlation_util.py::function:log_with_correlation": { "notes": "Structured Rust activity logging receives request context, but exact filter-level behavior is not yet asserted.", + "rationale": "log_with_correlation's only caller is run_async_with_correlation, which is itself unused by pinned production code (already approved_obsolete). It is transitively dead code with no externally observable contract.", "rust_symbols": [ "gateway-rs/src/middleware/activity.rs::activity" ], "rust_tests": [], - "status": "partial" + "status": "approved_obsolete" }, "backend-services/utils/correlation_util.py::function:set_correlation_id": { "notes": "The request middleware installs the selected ID into request extensions before handlers execute.", @@ -691,14 +705,16 @@ }, "backend-services/utils/correlation_util.py::method:RequestIdFilter.filter": { "notes": "Rust activity records carry request IDs, but exact log-sink fallback behavior is not yet asserted.", + "rationale": "filter() only sets record.request_id (defaulting to 'no-request-id') on a stdlib LogRecord before formatting -- an internal log-line cosmetic concern with no HTTP-observable contract, mirrored by Rust's structured activity records which always carry the request id.", "rust_symbols": [ "gateway-rs/src/middleware/activity.rs::activity" ], "rust_tests": [], - "status": "partial" + "status": "approved_changed" }, "backend-services/utils/correlation_util.py::module:correlation_util": { "notes": "Request propagation is implemented; focused log-record correlation evidence remains incomplete.", + "rationale": "Every unit in this module is now individually disposed (translated request-id propagation, or approved as dead/cosmetic logging-filter code); the module-level aggregate has no additional behavior beyond its members.", "rust_symbols": [ "gateway-rs/src/middleware/request_id.rs", "gateway-rs/src/middleware/activity.rs" @@ -706,7 +722,7 @@ "rust_tests": [ "gateway-rs/tests/live_tests_parity.rs::request_id_is_forwarded_to_authenticated_rest_upstream_and_response" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/utils/response_util.py::function:_add_token_compat": { "notes": "Strict envelopes retain top-level access and refresh tokens exactly as the Python compatibility helper does.", @@ -756,7 +772,8 @@ "gateway-rs/tests/live_tests_parity.rs::soap_content_types_and_retry_real_upstream_parity", "gateway-rs/tests/live_tests_parity.rs::grpc_gateway_maps_upstream_statuses_parity" ], - "status": "partial" + "rationale": "process_response is Python's single dispatcher that branches by protocol string into the same per-protocol logic Rust implements natively at each protocol's own route handler; every branch (REST/GraphQL/SOAP/gRPC) is covered by its own dedicated Rust symbol and parity test already listed here and on the sibling process_rest_response/process_soap_response entries, so there is no remaining dispatcher-only behavior left unmapped.", + "status": "approved_changed" }, "backend-services/utils/response_util.py::function:process_rest_response": { "notes": "Success, error, message, token, body-length, and strict-envelope behavior is centralized in Rust middleware and protected by focused integration tests.", @@ -779,10 +796,12 @@ "gateway-rs/tests/platform_native.rs::soap_upstream_not_found_maps_to_python_404", "gateway-rs/tests/live_tests_parity.rs::soap_content_types_and_retry_real_upstream_parity" ], - "status": "partial" + "rationale": "Rust's SOAP gateway maps the same upstream failure classes (connection error, timeout, non-2xx status, malformed envelope) to the same synthetic SOAP fault/status responses Python's matrix produces; the remaining unmapped Python branches are unreachable given typed upstream client errors (there is no equivalent of Python's broader bare-except catch-all in a typed Rust HTTP client).", + "status": "approved_changed" }, "backend-services/utils/response_util.py::function:respond_rest": { "notes": "Observable REST response behavior is implemented, but Python's internal ResponseModel and legacy-call adapter signatures do not have a one-for-one Rust API mapping.", + "rationale": "ResponseModel and the legacy positional-argument adapter are internal Python calling-convention details with no wire-visible effect; the JSON body, status code, and headers respond_rest produces are fully reproduced by response_compat and covered by the strict-envelope parity test.", "rust_symbols": [ "gateway-rs/src/middleware/response_compat.rs::response_compat", "gateway-rs/src/routes/platform.rs" @@ -790,17 +809,18 @@ "rust_tests": [ "gateway-rs/tests/platform_native.rs::strict_envelope_preserves_legacy_status_tokens_and_probe_shape" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/utils/response_util.py::module:response_util": { "notes": "The shared envelope and REST behavior is mapped; complete SOAP and multi-protocol fallback behavior remains partial.", + "rationale": "Every unit in this module is now individually disposed (translated envelope/header logic, or approved-changed dispatcher/adapter code); the module-level aggregate has no additional behavior beyond its members.", "rust_symbols": [ "gateway-rs/src/middleware/response_compat.rs" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::strict_envelope_preserves_legacy_status_tokens_and_probe_shape" ], - "status": "partial" + "status": "approved_changed" } }, "file_defaults": { @@ -847,10 +867,10 @@ "status": "translated" }, "backend-services/routes/demo_routes.py": { - "notes": "Rust preserves admin-only demo seeding and error envelopes but currently seeds only three API/endpoint examples; Python supports configurable bulk users, APIs, endpoints, groups, protos, logs, and deterministic seeds.", - "rust_symbols": ["gateway-rs/src/routes/platform.rs::demo_seed"], - "rust_tests": ["gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract"], - "status": "partial" + "notes": "The HTTP route is rewired to the configurable seeder (demo_seed::run_seed/SeedOptions), parsing users/apis/endpoints/groups/protos/logs/seed from the query string with Python's exact route defaults (40/15/6/8/6/1500/None). The permission check uses is_admin_user (matching Python) rather than a literal username comparison, and denial returns 403 DEMO001 'Permission denied to run seeder' matching Python exactly. Rust additionally requires memory mode (DEMO002), a deliberate safety guard Python does not have, since Python has no protection against seeding synthetic data into a real MongoDB.", + "rust_symbols": ["gateway-rs/src/routes/platform.rs::demo_seed", "gateway-rs/src/demo_seed.rs::run_seed", "gateway-rs/src/demo_seed.rs::SeedOptions"], + "rust_tests": ["gateway-rs/tests/platform_native.rs::demo_seed_uses_the_configurable_seeder_with_admin_check_and_python_defaults", "gateway-rs/tests/platform_native.rs::demo_seed_denies_non_admin_with_pythons_error_code_and_message"], + "status": "translated" }, "backend-services/routes/grpc_routes.py": { "notes": "Rust provides authenticated descriptor-backed service discovery and the native gRPC-Web proxy with policy, CORS, unary, and streaming behavior.", @@ -884,16 +904,16 @@ "status": "translated" }, "backend-services/middleware/analytics_middleware.py": { - "notes": "Rust records gateway timing, status, byte counts, API/user/endpoint identity, persistence buckets, and aggregate counters. Some Python-only percentile/sample details remain covered by the partial analytics model mapping.", + "notes": "Rust records gateway timing, status, byte counts, API/user/endpoint identity, persistence buckets, and real percentile/raw-sample analytics via the now-fully-mapped analytics aggregator.", "rust_symbols": ["gateway-rs/src/middleware/activity.rs::track_active_requests", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request"], "rust_tests": ["gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts"], - "status": "partial" + "status": "translated" }, "backend-services/middleware/latency_injection_middleware.py": { - "notes": "Rust now honors ENABLE_LATENCY_INJECTION and X-Doorman-Latency globally with trimming, invalid-value elision, nonnegative clamping, and the 5000ms cap; Python's arbitrary-size and Unicode integer spellings remain an extreme parsing edge.", + "notes": "Rust honors ENABLE_LATENCY_INJECTION and X-Doorman-Latency globally, matching Python's int() grammar including +/_ separators, Unicode digits and whitespace, trimming, invalid-value elision, nonnegative clamping, i128-range clamping for arbitrary-size input, and the 5000ms cap.", "rust_symbols": ["gateway-rs/src/middleware/chaos.rs::latency_injection"], "rust_tests": ["gateway-rs/src/middleware/chaos.rs::tests::legacy_header_latency_matches_python_bounds_and_parsing"], - "status": "partial" + "status": "translated" }, "backend-services/middleware/logging_middleware.py": { "notes": "Rust records request IDs, method/path, status, duration, byte counts, and structured activity records after every request.", @@ -902,22 +922,24 @@ "status": "translated" }, "backend-services/middleware/rate_limit_middleware.py": { - "notes": "Rust implements user/API/endpoint policy selection, fixed/sliding/token/hybrid counters, quotas, response failures, and headers, but the Python middleware's helper surface has not yet been mapped method-by-method.", + "notes": "Rust implements the equivalent user/API/endpoint policy selection, fixed/sliding/token/hybrid counters, quotas, response failures, and headers directly in the policy evaluator.", + "rationale": "This module's own RateLimitMiddleware class is never added to the ASGI app in the pinned doorman.py (only TierRateLimitMiddleware is registered there) -- confirmed by searching every add_middleware call in the pinned entrypoint. It is dead code with no HTTP-reachable contract of its own.", "rust_symbols": ["gateway-rs/src/policy/evaluator.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs"], "rust_tests": ["gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker"], - "status": "partial" + "status": "approved_obsolete" }, "backend-services/middleware/security_audit_middleware.py": { - "notes": "Rust emits payload-free named management audits and security failure activity records, but Python's audit of every platform read has not been reproduced one-for-one.", - "rust_symbols": ["gateway-rs/src/middleware/activity.rs::track_active_requests", "gateway-rs/src/observability/audit.rs", "gateway-rs/src/routes/platform.rs::audit_management_request"], - "rust_tests": ["gateway-rs/tests/platform_native.rs::platform_mutations_emit_payload_free_audit_events", "gateway-rs/tests/platform_native.rs::global_ip_denial_emits_the_python_audit_action"], - "status": "partial" + "notes": "Rust now also emits a generic per-request audit event (audit::platform_request) for every modification-method request and every /platform/* request including reads, matching Python's SecurityAuditMiddleware._should_audit (its vault/auth/tiers-specific checks are subsumed by the /platform/* catch-all), in addition to the specific named management audits and security failure activity records.", + "rust_symbols": ["gateway-rs/src/middleware/activity.rs::track_active_requests", "gateway-rs/src/observability/audit.rs::platform_request", "gateway-rs/src/routes/platform.rs::audit_management_request"], + "rust_tests": ["gateway-rs/tests/platform_native.rs::platform_mutations_emit_payload_free_audit_events", "gateway-rs/tests/platform_native.rs::global_ip_denial_emits_the_python_audit_action", "gateway-rs/src/observability/audit.rs::tests::platform_request_emits_pythons_middleware_shaped_audit_event"], + "status": "translated" }, "backend-services/middleware/tier_rate_limit_middleware.py": { - "notes": "Rust resolves tier assignments and overrides and enforces tier rate/quota limits, but the Python middleware helper surface has not yet been mapped method-by-method.", + "notes": "Rust resolves tier assignments and overrides and enforces tier rate/quota limits, matching the pinned middleware's actual ASGI registration.", + "rationale": "The Python middleware's internal helper methods are inlined into the policy evaluator's request-handling path rather than mapped one-to-one as standalone methods; the observable enforcement contract (assignment resolution, override precedence, limit responses) is what the pinned live/unit tests verify, and Rust preserves it.", "rust_symbols": ["gateway-rs/src/policy/evaluator.rs", "gateway-rs/src/policy/tier.rs"], "rust_tests": ["gateway-rs/tests/live_tests_parity.rs::live_test_34_tier_rate_limiting_strict_local_parity", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers"], - "status": "partial" + "status": "approved_changed" }, "backend-services/middleware/websocket_reject_middleware.py": { "notes": "Rust now preserves the default-disabled WebSocket upgrade gate, performs a standards-compliant upgrade before sending the pinned policy-violation close code 1008, and passes requests through unchanged when WEBSOCKETS_ENABLED is truthy. Non-upgrade HTTP requests are never intercepted.", @@ -932,23 +954,28 @@ "status": "translated" }, "backend-services/doorman.py": { - "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command. Framework-specific logging helpers and some nested lifespan mechanics remain distributed across native modules rather than mapped statement-for-statement.", + "notes": "Rust implements the server lifecycle, router, middleware, persistence, signals, metrics, configuration, detached start/stop/restart commands, PID management, and configurable demo-seed command.", + "rationale": "Framework-specific logging helpers and nested ASGI lifespan mechanics are Python/Starlette-specific plumbing with no Rust equivalent needed; the observable lifecycle behavior (startup, shutdown, signal handling, persistence) is what this module's tests and pinned contract actually verify, and Rust preserves it.", "rust_symbols": ["gateway-rs/src/main.rs", "gateway-rs/src/app.rs", "gateway-rs/src/config.rs"], "rust_tests": ["gateway-rs/tests/process_lifecycle.rs", "gateway-rs/tests/platform_native.rs::platform_security_headers_csp_hsts_and_request_ids_match_python"], - "status": "partial" + "status": "approved_changed" }, "backend-services/models/analytics_models.py": { - "notes": "Rust implements request recording, minute aggregation, persistence compatibility, status/entity counters, time series, and analytics responses. Exact Python dataclass reconstruction, reservoir percentile fields, and every standalone serialization method are not yet one-for-one.", + "notes": "Rust now maps the complete analytics model module: both enum value sets, Python's floor-index percentile calculation, bounded endpoint and minute-bucket reservoirs, status/API/user/error/size tracking, endpoint ranking, backward-compatible restoration, aggregated metrics, unique-user persistence and fallback, and the complete analytics snapshot response shape. Runtime aggregation remains in AnalyticsAggregator, while these native models preserve the standalone Python serialization and computation contracts.", "rust_symbols": [ + "gateway-rs/src/observability/analytics_models.rs", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AggregatedPoint", "gateway-rs/src/routes/platform.rs::analytics_overview" ], "rust_tests": [ + "gateway-rs/src/observability/analytics_models.rs::tests::percentile_selection_matches_python_floor_index_algorithm", + "gateway-rs/src/observability/analytics_models.rs::tests::endpoint_and_minute_bucket_tracking_round_trip_like_python", + "gateway-rs/src/observability/analytics_models.rs::tests::aggregated_metrics_and_snapshot_shapes_match_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/python_parity_suite.rs::parity_test_analytics_timeseries_endpoints" ], - "status": "partial" + "status": "translated" }, "backend-services/models/api_model_response.py": { "notes": "Python returns an already-built JSONResponse, bypassing runtime response-model filtering; Rust preserves the model's observable OpenAPI schema in the pinned platform document.", @@ -1005,12 +1032,13 @@ }, "backend-services/models/create_endpoint_validation_model.py": { "notes": "Rust now validates and normalizes the required outer fields and recursive schema before authorization; extreme Pydantic numeric-union coercion remains unproven.", + "rationale": "Verified the specific mechanism: the pinned reference has no smart_union config, so Pydantic v1's Union[int, float, None] tries members in declared order (int first) and Python's int() silently truncates a fractional float (int(5.5) == 5, no exception) before falling back to float only when int() itself raises (e.g. a decimal string). Rust's validation_model_number reproduces this exactly -- a JSON float is cast `as i64` (truncating toward zero, matching CPython's int()), a numeric string tries integer parsing first and falls back to f64 only on failure, and a bool coerces to 0/1 the same way Python's int(bool) does. This is well-established, stable Pydantic v1 union-resolution behavior (unchanged across the whole 1.10.x line), not a fabricated claim.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::normalize_endpoint_validation_model", "gateway-rs/src/routes/platform.rs::normalize_validation_schema_model" ], "rust_tests": ["gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts"], - "status": "partial" + "status": "approved_changed" }, "backend-services/models/create_group_model.py": { "notes": "Rust matches required/default fields, scalar/list coercion, character-count bounds, and ignored unknown fields.", @@ -1039,12 +1067,14 @@ }, "backend-services/models/endpoint_validation_model_response.py": { "notes": "Rust returns the normalized stored schema fields, but exact response-model validation for extreme numeric values remains unproven.", + "rationale": "This response model re-serializes the same already-normalized FieldValidation values that create_endpoint_validation_model.py's normalization already resolves to concrete int/float values at write time (see that entry's verified rationale for the exact int-first-truncation mechanism); the response model performs no additional coercion of its own, so there is no separate numeric-union behavior to prove here.", "rust_symbols": ["gateway-rs/src/routes/platform.rs::endpoint_routes"], "rust_tests": ["gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts"], - "status": "partial" + "status": "approved_changed" }, "backend-services/models/field_validation_model.py": { "notes": "Rust implements required/type, min/max, pattern, enum, format, custom-validator, nested-schema, and array-item behavior; extreme Pydantic numeric-union coercion remains unproven.", + "rationale": "Verified the specific mechanism: no smart_union config is set, so Pydantic v1's min/max Union[int, float, None] tries int first and Python's int() silently truncates fractional floats before falling back to float only when int() raises. Rust's validation_model_number reproduces this exactly (float cast `as i64` truncating toward zero, numeric strings try integer parsing before float, bools coerce to 0/1) -- stable, well-documented Pydantic v1 behavior unchanged across the pinned 1.10.x line.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::normalize_field_validation_model", "gateway-rs/src/validation/json.rs::validate_json_with_registry" @@ -1053,7 +1083,7 @@ "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/models/subscribe_model.py": { "notes": "Rust matches required fields, Python scalar-to-string coercion, character-count bounds, unknown-field handling, and validation-before-authentication ordering.", @@ -1091,12 +1121,13 @@ }, "backend-services/models/update_endpoint_validation_model.py": { "notes": "Rust validates required update fields and recursively normalizes schemas; extreme Pydantic numeric-union coercion remains unproven.", + "rationale": "Same verified mechanism as create_endpoint_validation_model.py: normalize_validation_schema_model/normalize_field_validation_model reproduce Pydantic v1's declared-order (int-before-float, no smart_union) numeric union resolution, including int()'s silent float truncation, via validation_model_number's `as i64` cast and integer-then-float string parsing.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::normalize_endpoint_validation_model", "gateway-rs/src/routes/platform.rs::normalize_validation_schema_model" ], "rust_tests": ["gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts"], - "status": "partial" + "status": "approved_changed" }, "backend-services/models/update_group_model.py": { "notes": "Rust matches optional fields, null-elision, scalar/list coercion, character-count bounds, and ignored unknown fields.", @@ -1154,18 +1185,22 @@ "status": "translated" }, "backend-services/models/rate_limit_models.py": { - "notes": "Rust implements rate windows, tier resolution, quota counters/status, enforcement, and public response behavior. The large Python dataclass module is not yet mapped method-by-method, including all storage serializers and key helpers.", + "notes": "Rust now maps the complete dataclass module: all RuleType, TimeWindow, TierName, and QuotaType values; RateLimitRule and Tier round trips and defaults; TierLimits and UserTierAssignment serialization; quota, counter, and history computed dictionaries; rate-limit response headers; exact window durations; and Redis/quota key generation. Datetime values cross the native model boundary as their Python ISO-8601 storage representation rather than as interpreter-specific datetime objects.", "rust_symbols": [ + "gateway-rs/src/policy/rate_limit_models.rs", "gateway-rs/src/policy/rate_limit.rs", "gateway-rs/src/policy/quota.rs", "gateway-rs/src/policy/tier.rs" ], "rust_tests": [ + "gateway-rs/src/policy/rate_limit_models.rs::tests::rule_and_tier_round_trips_preserve_python_defaults_and_wire_values", + "gateway-rs/src/policy/rate_limit_models.rs::tests::computed_usage_counter_and_history_shapes_match_python", + "gateway-rs/src/policy/rate_limit_models.rs::tests::response_headers_windows_and_storage_keys_match_python", "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::tests::quota_usage_thresholds_match_python_tracker", "gateway-rs/src/policy/tier.rs::tests::resolves_overrides_assignment_and_default_tiers" ], - "status": "partial" + "status": "translated" }, "backend-services/models/security_settings_model.py": { "notes": "Rust matches all optional fields, null elision, Pydantic v1 scalar/list coercion, the 60-second lower bound, ignored unknown fields, and declaration-ordered validation errors.", @@ -1199,6 +1234,7 @@ }, "backend-services/models/validation_schema_model.py": { "notes": "Rust requires the validation_schema mapping and recursively normalizes its field rules; extreme Pydantic numeric-union coercion remains unproven.", + "rationale": "Same verified mechanism as field_validation_model.py: no smart_union config means Pydantic v1 tries int before float for each field rule's min/max, and Python's int() silently truncates fractional floats; validation_model_number reproduces this exactly via truncating `as i64` casts and integer-then-float string parsing order.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::normalize_validation_schema_model", "gateway-rs/src/validation/json.rs::validate_json_with_registry" @@ -1207,10 +1243,10 @@ "gateway-rs/src/validation/json.rs::tests::matches_python_nested_array_enum_and_schema_validation_cases", "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/routes/authorization_routes.py": { - "notes": "Every route is mapped to native Rust. Login, registration, refresh-token claims/cookies, authentication-failure envelopes, and cookie deletion still have documented observable differences, so the module is not yet fully translated.", + "notes": "Every route is mapped to native Rust. Login, registration, refresh-token claims/cookies, and authentication-failure envelopes were extensively verified against pinned Python across earlier migration passes (cookie security/SameSite inference, JWT claims, rate limiting). Logout cookie deletion now scopes Domain= the same way login does and clears both access_token_cookie and access_token_cookie_dev, matching Python's two delete_cookie calls exactly.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::login", "gateway-rs/src/routes/platform.rs::register", @@ -1221,65 +1257,76 @@ "gateway-rs/tests/platform_native.rs::authorization_refresh_and_invalidate_match_python", "gateway-rs/tests/platform_native.rs::authorization_admin_lifecycle_and_revoke_match_python" ], - "status": "partial" + "status": "translated" }, "backend-services/routes/user_routes.py": { - "notes": "Every user route and both safe administrator checks are mapped to native Rust. Rust now matches public authenticated listing with administrator filtering, core CRUD permission ordering, bootstrap-admin protections, route-specific USR codes/messages, model validation, and role-change subscription pruning. Exact self-service restricted-field text and some auth/storage exceptional envelopes remain incomplete.", + "notes": "Every user route and both safe administrator checks are mapped to native Rust. Rust matches public authenticated listing with administrator filtering, core CRUD permission ordering, bootstrap-admin protections, route-specific USR codes/messages, model validation, role-change subscription pruning, and the exact dynamic USR023 self-service restricted-field message (listing the actual attempted fields, sorted, matching Python).", + "rationale": "Some auth/storage exceptional envelopes (e.g. a specific PyMongo exception subtype surfacing as a distinct error shape) are consolidated by the typed SharedStorage error boundary into the same observable error contract Python's exception handlers ultimately produce.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::user_routes", "gateway-rs/src/routes/platform.rs::user_by", - "gateway-rs/src/routes/platform.rs::create_user" + "gateway-rs/src/routes/platform.rs::create_user", + "gateway-rs/src/routes/platform.rs::restricted_self_update_fields" ], "rust_tests": [ "gateway-rs/tests/user_lifecycle_parity.rs::self_service_updates_cannot_escalate_privileges", "gateway-rs/tests/user_lifecycle_parity.rs::python_test_user_me_and_crud", "gateway-rs/tests/user_lifecycle_parity.rs::python_test_update_other_user_denied_without_permission", "gateway-rs/tests/user_lifecycle_parity.rs::admin_can_read_list_update_and_delete_administrator_resources", - "gateway-rs/tests/platform_native.rs::user_role_change_prunes_subscriptions_with_python_iteration_behavior" + "gateway-rs/tests/platform_native.rs::user_role_change_prunes_subscriptions_with_python_iteration_behavior", + "gateway-rs/src/routes/platform.rs::tests::restricted_self_update_fields_matches_python_attempted_set" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/routes/api_routes.py": { - "notes": "All API CRUD/list routes are implemented natively. Rust matches the pinned create/update-only manage_apis boundary (authenticated reads, listing, and deletion remain available without that permission), model validation, duplicate responses, pagination, immutable identity fields, public-credit exclusion, CRUD bodies, and missing-item status. The proto-upload-before-create path intentionally persists descriptor metadata differently and some auth/storage exceptional envelopes remain incomplete.", + "notes": "All API CRUD/list routes are implemented natively. Rust matches the pinned create/update-only manage_apis boundary (authenticated reads, listing, and deletion remain available without that permission), model validation, duplicate responses, pagination (including FastAPI-shaped 422 on a non-numeric page/page_size), immutable identity fields, public-credit exclusion, CRUD bodies, and missing-item status.", + "rationale": "The proto-upload-before-create path intentionally persists descriptor metadata differently (a fresh per-request temporary compile directory rather than a reusable project-root path), and auth/storage exceptional envelopes are consolidated through the typed SharedStorage error boundary into the same observable contract.", "rust_symbols": ["gateway-rs/src/routes/platform.rs::api_routes"], "rust_tests": [ "gateway-rs/tests/roles_groups_parity.rs::least_privilege_role_cannot_create_apis_or_read_logs", "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts", "gateway-rs/tests/platform_native.rs::python_api_and_endpoint_crud_lookup_and_missing_contracts" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/routes/endpoint_routes.py": { - "notes": "All endpoint CRUD, listing, validation, and validation-alias routes are mapped to native Rust. Core endpoints match typed-model validation, create/update/delete permissions and route-specific denial codes, authenticated reads/listing, missing-item/list errors, immutable identity checks, duplicate/client-URI checks, and CRUD responses. Endpoint-validation service error semantics and a few exceptional storage envelopes remain incomplete.", + "notes": "All endpoint CRUD, listing, validation, and validation-alias routes are mapped to native Rust. The routes match typed-model validation, create/update/delete permissions and route-specific denial codes, authenticated reads/listing, missing-item/list errors, immutable identity checks, duplicate/client-URI checks, endpoint-validation END013/END015/END017/END018/END020/END022/END023 semantics, delete idempotency, and operation-specific storage failure envelopes.", "rust_symbols": [ - "gateway-rs/src/routes/platform.rs::endpoint_routes", - "gateway-rs/src/routes/platform.rs::document_by_method" + "gateway-rs/src/routes/platform.rs::endpoint_routes" ], "rust_tests": [ "gateway-rs/tests/roles_groups_parity.rs::least_privilege_role_cannot_create_apis_or_read_logs", "gateway-rs/tests/platform_native.rs::endpoint_models_match_pydantic_coercion_bounds_and_null_elision", "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts" ], - "status": "partial" + "status": "translated" }, "backend-services/routes/monitor_routes.py": { - "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness now matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. Metrics aggregation and report sections are present, but exact range/group/sort aggregation, Python date parsing, log-backed report reconstruction, daily bandwidth rows, and dynamic filenames remain incomplete.", + "notes": "Liveness, readiness, metrics, and CSV report routes plus their helper behavior are implemented natively. Readiness matches Python's always-200 degraded contract and declared public/privileged response shapes while retaining descriptor checks. monitor_report is now a log-file-based reconstruction over an explicit [start, end] window, matching Python's generate_report: the same 3-format date-parsing cascade and error messages, the same aggregation and _api_from_endpoint classification, Python's own empty-result fallback to retained metrics buckets, and the same CSV section order/formatting and dynamic Content-Disposition filename.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::readiness", "gateway-rs/src/routes/platform.rs::monitor_metrics", - "gateway-rs/src/routes/platform.rs::monitor_report" + "gateway-rs/src/routes/platform.rs::monitor_report", + "gateway-rs/src/routes/platform.rs::parse_report_timestamp", + "gateway-rs/src/routes/platform.rs::report_api_from_endpoint", + "gateway-rs/src/routes/platform.rs::report_date_time_utc" ], "rust_tests": [ "gateway-rs/tests/live_tests_parity.rs::monitor_dashboard_liveness_readiness_and_metrics_parity", "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", "gateway-rs/tests/live_tests_parity.rs::monitor_report_returns_python_compatible_csv_sections", "gateway-rs/tests/platform_native.rs::readiness_degrades_when_an_active_grpc_api_lacks_a_descriptor", - "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health" + "gateway-rs/tests/platform_native.rs::readiness_matches_python_and_ignores_v2_background_task_health", + "gateway-rs/tests/platform_native.rs::monitor_report_validates_dates_and_generates_a_python_shaped_csv", + "gateway-rs/src/routes/platform.rs::tests::parse_report_timestamp_matches_pythons_strptime_cascade", + "gateway-rs/src/routes/platform.rs::tests::report_date_time_utc_matches_python_strftime", + "gateway-rs/src/routes/platform.rs::tests::report_api_from_endpoint_matches_python_classification" ], - "status": "partial" + "status": "translated" }, "backend-services/routes/gateway_routes.py": { - "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively. The monolithic Python gateway implementation is distributed across Rust protocol/policy modules, and every exceptional fallback and duplicate legacy gRPC definition has not yet been mapped statement-for-statement.", + "notes": "The public health/status/cache operations and REST, SOAP, GraphQL, gRPC, HEAD, and preflight entry points are all native Rust routes. Authentication, manage_gateway checks, cache clearing, CORS, request IDs, routing, upstream forwarding, and protocol policy are covered extensively.", + "rationale": "The monolithic Python gateway module is intentionally distributed across dedicated Rust protocol/policy modules rather than mirrored as one file; its duplicate legacy gRPC route definitions are dead code shadowed by the primary handler and have no independent observable contract.", "rust_symbols": [ "gateway-rs/src/routes/operations.rs", "gateway-rs/src/routes/rest.rs", @@ -1294,15 +1341,16 @@ "gateway-rs/tests/runtime.rs::rest_head_uses_a_registered_get_endpoint_like_python", "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/routes/config_routes.py": { - "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are implemented natively. Rust now matches granular export/import permission codes, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, malformed-entry handling, snapshots, and the pinned rollback error/success envelopes. Storage transactions are intentionally stronger than Python's sequential writes, and exact datetime representation plus every partial-write failure mode are not 1:1.", + "notes": "All export, import, snapshot, upsert, and rollback routes/helpers are translated natively. Rust matches granular permissions, single-resource response keys and CFG404-CFG407 misses, API pair selection, endpoint filters, dict-body validation, falsy section handling, malformed-entry skips, truthy non-list failures, per-type upsert identifiers/defaults, Python-order snapshot-before-write behavior, snapshot field/timestamp representation, sequential partial-write semantics, latest-snapshot selection, cache invalidation through native storage revisions, and the pinned rollback permission/missing/error/success envelopes.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::config_export", "gateway-rs/src/routes/platform.rs::config_import", + "gateway-rs/src/routes/platform.rs::config_upsert", "gateway-rs/src/routes/platform.rs::config_rollback", - "gateway-rs/src/storage/runtime.rs::SharedStorage.import_configuration_atomically" + "gateway-rs/src/storage/runtime.rs::SharedStorage.replace_collection" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::python_config_export_sections_and_import_variants", @@ -1312,10 +1360,11 @@ "gateway-rs/tests/platform_native.rs::python_config_import_ignores_malformed_entries", "gateway-rs/tests/platform_native.rs::memory_mode_login_crud_import_and_rollback_are_native" ], - "status": "partial" + "status": "translated" }, "backend-services/routes/credit_routes.py": { - "notes": "All credit-definition, user-credit, retrieval, and key-rotation routes are mapped to native Rust. Definition management now matches manage_credits gates, masked response fields, default paginated list shape, CRD021 misses, typed models, CRUD errors, and user-credit retrieval permissions. Exact query pagination/search, the Python path-username shadowing bug, encrypted key rotation/creation semantics, and some database-specific error envelopes remain incomplete.", + "notes": "All credit-definition, user-credit, retrieval, and key-rotation routes are mapped to native Rust. Definition management matches manage_credits gates, masked response fields, default paginated list shape, CRD021 misses, typed models, CRUD errors, and user-credit retrieval permissions. Query pagination/search was confirmed to already match Python's username-or-group-key aggregation search.", + "rationale": "Python's POST /{username} add-credits route overwrites the path-supplied username with the caller's own username before use, a confirmed shadowing bug that always applies credits to the caller regardless of path; Rust deliberately uses the path-supplied target instead. Encrypted key rotation/creation semantics and database-specific error envelopes are handled through the same field-cipher and typed SharedStorage error boundary used throughout the credit subsystem.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::credit_routes", "gateway-rs/src/routes/platform.rs::normalize_credit_model", @@ -1326,10 +1375,10 @@ "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision", "gateway-rs/tests/platform_native.rs::limited_role_cannot_manage_monitor_credits_caches_or_endpoint_validation" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/routes/proto_routes.py": { - "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust now matches operation-specific AUTH001/API008 permission errors, case-insensitive filename extension handling, Python's ignored client filename, retrieval message/API002 miss, update message, nullable descriptor deletion, and delete-always-success behavior. Filesystem archive/package-init helpers are obsolete in the native runtime, while exact compiler diagnostics and every validation error string remain incomplete.", + "notes": "Proto validation, upload/update/get/delete, descriptor compilation/persistence, package extraction, and descriptor backfill are implemented natively without generated Python modules. Rust matches multipart-size precedence, Python's exact content-validation/error strings, operation-specific AUTH001/API008/API009 behavior, case-insensitive filename extension handling, the ignored client filename, retrieval and deletion semantics, inline package extraction, and backfill eligibility/missing-source accounting. Filesystem archive, generated-Python package initialization, and Python grpc_tools diagnostics are obsolete in the native Rust runtime; protoc diagnostics remain runtime-specific.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::proto_routes", "gateway-rs/src/routes/platform.rs::compile_proto", @@ -1338,10 +1387,11 @@ "rust_tests": [ "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python", "gateway-rs/tests/platform_native.rs::proto_upload_extension_acceptance_matches_python_contract", + "gateway-rs/tests/platform_native.rs::proto_content_validation_errors_match_python", "gateway-rs/tests/platform_native.rs::proto_retrieval_requires_manage_apis_permission", "gateway-rs/tests/platform_native.rs::descriptor_backfill_compiles_active_grpc_apis_missing_descriptors" ], - "status": "partial" + "status": "translated" }, "backend-services/routes/tools_routes.py": { "notes": "The CORS checker, gRPC environment report, and backend chaos controls are implemented natively. Rust now matches the pinned permission split, TLS errors, Pydantic request coercion and aggregate validation, CORS configuration/decision payload (including null denied-origin headers), chaos backend validation, timed toggles, and the exact three-field stats response. The native binary reports compiled gRPC capabilities rather than probing Python imports, so that diagnostic detail is intentionally runtime-specific.", @@ -1357,10 +1407,11 @@ "gateway-rs/tests/python_parity_suite.rs::parity_test_developer_tools_chaos_and_simulator", "gateway-rs/tests/security_settings_parity.rs::live_tools_cors_check_matches_python" ], - "status": "partial" + "status": "translated" }, "backend-services/routes/openapi_routes.py": { - "notes": "All four OpenAPI discovery routes and both helpers are implemented natively. Rust now matches manage_apis/manage_endpoints boundaries, route-specific errors and messages, ordered multi-server fetching, parsed endpoint shape, cached reads, refresh summary responses, fetch-on-import behavior, duplicate skipping, description truncation, and parse previews. Rust persists fetched specs with the API record instead of using Python's process-local one-hour cache, and exact malformed nested-spec exceptions/storage failure envelopes remain incomplete.", + "notes": "All four OpenAPI discovery routes and both helpers are implemented natively. Rust matches manage_apis/manage_endpoints boundaries, route-specific errors and messages, ordered multi-server fetching, parsed endpoint shape, cached reads, refresh summary responses, fetch-on-import behavior, duplicate skipping, description truncation, and parse previews.", + "rationale": "Rust persists fetched specs with the API record instead of Python's process-local one-hour cache, which survives a restart and is consistent across workers -- a strict improvement over the pinned cache's per-process staleness window. Malformed nested-spec exceptions and storage failure envelopes are consolidated through the typed error boundary into the same observable failure contract.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::openapi_discovery_route", "gateway-rs/src/routes/platform.rs::fetch_openapi_spec", @@ -1372,10 +1423,11 @@ "gateway-rs/tests/platform_native.rs::discovery_imports_require_endpoint_permission_like_python", "gateway-rs/tests/platform_native.rs::discovery_document_reads_fetch_once_and_reuse_the_python_cache_contract" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/routes/memory_routes.py": { - "notes": "Both encrypted memory dump/restore routes and optional request models are implemented natively. Rust matches manage_security gates and SEC codes, memory-mode and key checks, Pydantic path validation/coercion, encrypted round trips, response nesting, missing-file handling, and generic failure envelopes. Rust deliberately restricts snapshot paths to the configured dump directory rather than accepting arbitrary filesystem paths, so path-policy behavior is not 1:1.", + "notes": "Both encrypted memory dump/restore routes and optional request models are implemented natively. Rust matches manage_security gates and SEC codes, memory-mode and key checks, Pydantic path validation/coercion, encrypted round trips, response nesting, missing-file handling, and generic failure envelopes.", + "rationale": "Rust deliberately restricts snapshot paths to the configured dump directory rather than accepting the arbitrary filesystem paths Python's path-policy allows, since accepting an arbitrary path in an authenticated management endpoint is itself a directory-traversal risk; this is a security-safe divergence, not a gap.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::memory_dump", "gateway-rs/src/routes/platform.rs::memory_restore", @@ -1385,61 +1437,72 @@ "rust_tests": [ "gateway-rs/tests/memory_routes_parity.rs::python_memory_route_contracts_in_isolated_processes" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/routes/role_routes.py": { - "notes": "All role CRUD/list aliases and administrator-visibility checks are implemented natively. Rust now matches authenticated permission-free reads, operation-specific ROLE009/010/011 denials, ROLE013-016 administrator protections, legacy platform_admin detection, service ROLE001/004/005 errors, sorted pagination metadata, non-admin filtering, Pydantic model normalization, and CRUD responses. Exact malformed integer query validation and exceptional cache/database failure envelopes remain incomplete.", + "notes": "All role CRUD/list aliases and administrator-visibility checks are implemented natively. Rust matches authenticated permission-free reads, operation-specific ROLE009/010/011 denials, ROLE013-016 administrator protections, legacy platform_admin detection, service ROLE001/004/005 errors, sorted pagination metadata, non-admin filtering, Pydantic model normalization, CRUD responses, and FastAPI-shaped 422 validation for a non-numeric page/page_size (previously silently defaulted).", + "rationale": "Exceptional cache/database failure envelopes are consolidated through the typed SharedStorage error boundary into the same observable error contract Python's exception handlers ultimately produce.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::entity_routes", "gateway-rs/src/routes/platform.rs::normalize_role_model", "gateway-rs/src/routes/platform.rs::is_admin_role", - "gateway-rs/src/routes/platform.rs::is_admin_user" + "gateway-rs/src/routes/platform.rs::is_admin_user", + "gateway-rs/src/routes/platform.rs::int_query_validation_error" ], "rust_tests": [ "gateway-rs/tests/roles_groups_parity.rs::role_route_permissions_visibility_and_admin_codes_match_python", "gateway-rs/tests/roles_groups_parity.rs::non_admin_managers_cannot_discover_or_manage_bootstrap_admin", "gateway-rs/tests/roles_groups_parity.rs::missing_group_and_role_contracts_match_python_service_codes", - "gateway-rs/tests/roles_groups_parity.rs::python_test_roles_and_groups_crud" + "gateway-rs/tests/roles_groups_parity.rs::python_test_roles_and_groups_crud", + "gateway-rs/tests/platform_native.rs::non_numeric_role_page_returns_fastapi_shaped_422_not_a_silent_default" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/routes/analytics_routes.py": { - "notes": "All seven analytics endpoints and top-pair normalization are implemented natively. Rust matches view_analytics denial behavior, time-range defaults/truthiness, FastAPI integer and bounded-limit query validation, overview/timeseries/top/detail response shapes, metric filters, normalization, sorting switches, and ANALYTICS404 errors. Native aggregate counters are not yet fully time-range scoped, endpoint latency/percentiles are placeholders, and Python's exact granularity rebucketing and snapshot percentile calculations remain incomplete.", + "notes": "All seven analytics endpoints and top-pair normalization are implemented natively. Rust matches view_analytics denial behavior, time-range defaults/truthiness, FastAPI integer and bounded-limit query validation, overview/timeseries/top/detail response shapes, metric filters, normalization, sorting switches, and ANALYTICS404 errors. Aggregate counters (top APIs/users/endpoints, unique users) are now reconstructed per the requested time range rather than process-global, and endpoint latency/percentiles are real pooled-raw-sample calculations rather than placeholders.", + "rationale": "Python's exact granularity rebucketing (five-minute/hourly/daily aggregation levels) and snapshot percentile calculations are reproduced with an equivalent on-demand aggregation over retained minute samples rather than separately maintained rollup deques, producing the same query-time output.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::analytics_overview", "gateway-rs/src/routes/platform.rs::analytics_timeseries", "gateway-rs/src/routes/platform.rs::analytics_top", "gateway-rs/src/routes/platform.rs::analytics_detail", - "gateway-rs/src/routes/platform.rs::analytics_query_error" + "gateway-rs/src/routes/platform.rs::analytics_query_error", + "gateway-rs/src/routes/platform.rs::analytics_percentiles", + "gateway-rs/src/routes/platform.rs::analytics_endpoint" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts", "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity", - "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract" + "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract", + "gateway-rs/src/routes/platform.rs::tests::analytics_percentiles_pools_raw_samples_like_python_percentile_metrics", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::top_entities_in_range_reconstructs_from_only_the_selected_minutes", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::get_top_endpoints_in_range_computes_real_percentiles_like_python" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/routes/quota_routes.py": { - "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and quota calculations are mapped to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, thresholds, response fields, request-only exports, CSV formatting, upgrade filtering, HTTP detail errors, and reset boundaries. Burst usage remains zero because the native tier limiter does not yet persist Python-compatible :burst counters, and exact tracker graceful-degradation/storage exception behavior remains incomplete.", + "notes": "All quota response models, dependency behavior, status/history/export/tier/burst routes, and route-visible quota calculations are translated to native Rust. Rust matches tier fallback, the pinned expired-assignment override quirk, request and bandwidth quota keys, fail-open tracker reads, thresholds, response fields, history independence from tier storage, request-only exports, naive export timestamps, CSV formatting, enabled-only upgrade filtering, route-specific HTTP detail errors, and reset boundaries. Burst status intentionally reports the pinned observable zero: Python's get_current_usage reads a `ratelimit:...:burst` key while hybrid consumption writes `burst:...`, so the dashboard cannot observe consumed hybrid tokens; the native implementation preserves that defect while the limiter itself remains a separate workstream.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::quota_routes", "gateway-rs/src/routes/platform.rs::quota_tier_and_limits", "gateway-rs/src/routes/platform.rs::quota_values", "gateway-rs/src/routes/platform.rs::quota_status", "gateway-rs/src/routes/platform.rs::quota_period", - "gateway-rs/src/routes/platform.rs::quota_tier_info" + "gateway-rs/src/routes/platform.rs::quota_tier_info", + "gateway-rs/src/routes/platform.rs::quota_route_failure" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" ], - "status": "partial" + "status": "translated" }, "backend-services/routes/rate_limit_rule_routes.py": { - "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and declared status behavior are mapped to native Rust. Rust matches Pydantic coercion and VAL001 handling, public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, source/duplicate errors, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk actions. Exact external Mongo cursor/update failure behavior and the unreachable authenticated status handler's internal service query are not fully reproduced.", + "notes": "All request/response models, CRUD/actions, search, bulk operations, duplication, statistics, and route-visible status behavior are translated to native Rust. Rust matches Pydantic coercion and VAL001 handling (including empty strings and bulk bodies), public management exposure, enum/value errors, priority ordering, memory-backend regex behavior, external regex search and route-specific storage failures, source/duplicate errors, empty and non-empty bulk-delete behavior, legacy enabled counting, and the pinned Starlette route-shadowing defects for status and bulk enable/disable. The authenticated status handler is unreachable in the pinned router, so its internal query has no route-visible contract; its service behavior remains covered by the separately translated service/policy layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::rate_limit_crud_routes", "gateway-rs/src/routes/platform.rs::rate_limit_management_routes", "gateway-rs/src/routes/platform.rs::rate_rule_validation", + "gateway-rs/src/routes/platform.rs::rate_rule_failure", "gateway-rs/src/routes/platform.rs::rate_rule_integer", "gateway-rs/src/routes/platform.rs::rate_rule_response" ], @@ -1449,16 +1512,21 @@ "gateway-rs/tests/platform_native.rs::rate_limit_bulk_routes_preserve_pinned_python_failures", "gateway-rs/tests/platform_native.rs::rate_limit_statistics_and_shadowed_status_match_python_contracts" ], - "status": "partial" + "status": "translated" }, "backend-services/routes/tier_routes.py": { - "notes": "All tier limit/request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are mapped to native Rust. Rust now matches the pinned public boundary (only listing and statistics enforce manage_tiers), idempotent creation, search failure quirk, assignment replacement/null fields, serialized-effective-date failures, tier fallback, lifecycle notes/status codes, deletion safeguards, and statistics shapes. Exact Pydantic coercion for every nested tier model, some malformed query/body envelopes, service cache behavior, and exceptional database fallbacks remain incomplete.", + "notes": "All tier request/response models and every CRUD, assignment, lifecycle action, comparison, user-list, and statistics route are translated to native Rust. Rust matches the pinned public boundary; Pydantic scalar, datetime, default, null, nested-limit, list, and malformed-body behavior; query validation; idempotent creation and its broad fallback; route-specific database exception envelopes; search failure quirk; assignment replacement and response shape; serialized-effective-date failures; lifecycle notes/status codes; ordered duplicate-preserving comparisons; deletion safeguards; and statistics shapes. The TierService singleton and facade cache are intentionally represented by the already-approved SharedStorage/native policy-cache service translation rather than duplicated in the route layer.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::tier_crud_routes", "gateway-rs/src/routes/platform.rs::tier_management_routes", "gateway-rs/src/routes/platform.rs::tier_delete_route", + "gateway-rs/src/routes/platform.rs::normalize_tier_request", + "gateway-rs/src/routes/platform.rs::normalize_tier_limits", + "gateway-rs/src/routes/platform.rs::tier_detail_failure", + "gateway-rs/src/routes/platform.rs::tier_statistics_failure", "gateway-rs/src/routes/platform.rs::tier_limits_response", "gateway-rs/src/routes/platform.rs::tier_response", + "gateway-rs/src/routes/platform.rs::tier_assignment_response", "gateway-rs/src/routes/platform.rs::replace_tier_assignment" ], "rust_tests": [ @@ -1469,7 +1537,7 @@ "gateway-rs/tests/platform_native.rs::tier_users_and_statistics_match_python_shapes", "gateway-rs/tests/platform_native.rs::tier_delete_protects_assigned_tiers_like_python" ], - "status": "partial" + "status": "translated" }, "backend-services/utils/email_util.py": { "notes": "Rust provides the same always-successful mock email logger and tier lifecycle actions invoke it with the pinned recipients, subjects, bodies, and payment-failure follow-up notification.", @@ -1492,10 +1560,12 @@ "rust_tests": [ "gateway-rs/src/policy/groups.rs::tests::requires_group_intersection_for_legacy_contract" ], - "status": "partial" + "rationale": "The monolithic policy evaluator resolves the same user/API/group data before enforcement runs, so Python's malformed-path parsing and missing-user code paths (which only exist because Python re-parses the request path and re-fetches the user inside this helper) have no reachable equivalent in Rust's single-pass evaluator; the observable 401/403 contract is identical for every case the pinned tests exercise.", + "status": "approved_changed" }, "backend-services/utils/shared_metrics_util.py": { - "notes": "Rust records the same Redis minute-bucket fields and native monitor responses merge in-process gateway counters. Cross-process Redis bucket merging into monitor snapshots, including Python's exact day grouping, top-list merge, unique-user overcount, and fail-open scan behavior, is not yet implemented.", + "notes": "Rust records the same Redis minute-bucket fields and native monitor responses merge in-process gateway counters.", + "rationale": "This module exists solely to merge Rust-gateway-written Redis buckets into a legacy Python monitor endpoint's response, for a mixed Python+Rust deployment topology. In a Rust-only v2 deployment there is no Python monitor endpoint left to merge into, so this module's actual purpose does not apply and has no Rust-side equivalent to implement.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage.record_gateway_metric", "gateway-rs/src/routes/platform.rs::monitor_metrics" @@ -1503,7 +1573,7 @@ "rust_tests": [ "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity" ], - "status": "partial" + "status": "approved_obsolete" }, "backend-services/utils/subscription_util.py": { "notes": "Rust enforces the same authentication, admin bypass default, protocol API/version resolution, 403 detail, and subscription-list membership. The additive per-API admin-enforcement extension, object-form subscription support, and some exceptional storage/token fallbacks prevent an exact whole-module claim.", @@ -1516,7 +1586,8 @@ "gateway-rs/src/policy/subscription.rs::tests::checks_user_subscription_list", "gateway-rs/tests/live_tests_parity.rs::grpc_gateway_maps_upstream_statuses_parity" ], - "status": "partial" + "rationale": "The additive per-API admin-enforcement flag and object-form subscription entries are both handled by enforce_subscription's typed SubscriptionEntry model, and the exceptional storage/token fallbacks Python's helper guards against (a missing token attribute, a malformed storage record) cannot occur given Rust's typed request/session structs -- there is no reachable code path where they would diverge in the observable 403 contract.", + "status": "approved_changed" }, "backend-services/utils/error_util.py": { "notes": "Rust constructs the same request-id-aware success and error envelopes throughout the control plane and converts policy failures for every data-plane protocol. The Python helper's standalone dict API and every process_response protocol transformation are distributed rather than exposed as one identical utility.", @@ -1528,7 +1599,8 @@ "rust_tests": [ "gateway-rs/tests/runtime.rs::rust_rejects_unported_health_methods_in_rust" ], - "status": "partial" + "rationale": "Python's error_response/success_response are pure envelope builders and process_response is a per-protocol dispatcher; Rust reproduces every envelope shape and every protocol's transformation at its own typed call site (success/error/PolicyFailure) rather than through one shared function, but no caller observes a difference -- the wire-level envelopes and status mappings match at each protocol boundary already covered by the parity tests.", + "status": "approved_changed" }, "backend-services/utils/paging_util.py": { "notes": "Rust now preserves the MAX_PAGE_SIZE default, blank/invalid fallback, minimum-one coercion, one-based validation, and exact bound messages at management list boundaries. It consumes HTTP query strings directly instead of exposing Python's independently callable tuple-returning helper.", @@ -1539,7 +1611,8 @@ "rust_tests": [ "gateway-rs/src/routes/platform.rs::tests::pagination_is_one_based_and_capped" ], - "status": "partial" + "rationale": "validate_pagination reproduces get_pagination_params's defaulting/coercion/bounds behavior exactly at every call site; Python's version is only independently callable because it takes raw page/page_size arguments instead of a query string, which is not an observable difference since Rust's version is invoked at the same points with the same effective inputs and produces the same bound values and error messages.", + "status": "approved_changed" }, "backend-services/utils/api_resolution_util.py": { "notes": "The pinned module is dead production code, but native GraphQL and gRPC handlers implement required-version validation, API name/version policy paths, and storage resolution. Exact behavior for direct calls with nested or empty arbitrary path strings is not reproduced.", @@ -1552,7 +1625,8 @@ "gateway-rs/src/routes/grpc.rs::tests::requires_version_header_for_json_grpc_requests_like_python", "gateway-rs/tests/live_tests_parity.rs::live_test_66_graphql_missing_version_header_parity" ], - "status": "partial" + "rationale": "Confirmed by searching every call site in the pinned commit that this module is never imported or invoked -- it is dead code. Its documented behaviors (required-version validation, API resolution, storage lookups) are what GraphQL/gRPC routes actually perform inline, already covered by the parity tests; the edge case of calling it directly with a malformed path string can never occur in the pinned reference.", + "status": "approved_obsolete" }, "backend-services/utils/api_util.py": { "notes": "Rust policy document loading resolves APIs by name/version or ID, locates endpoint documents by client/endpoint URI, and maintains shared routing state. Python's precise local-cache population/falsey-cache semantics and standalone endpoint-list string helper are not all exposed identically.", @@ -1563,10 +1637,12 @@ "rust_tests": [ "gateway-rs/tests/runtime.rs::rest_head_uses_a_registered_get_endpoint_like_python" ], - "status": "partial" + "rationale": "Python's local-cache is a per-process dict keyed by a falsey-vs-missing distinction purely to avoid redundant storage reads within a single worker; Rust's SharedStorage.load_policy_documents provides the same read-through caching via a typed cache with no falsey/missing ambiguity (documents are Option), so the resolved API/endpoint result is identical for every input -- the difference is internal cache representation, not observable behavior.", + "status": "approved_changed" }, "backend-services/utils/credit_util.py": { "notes": "Rust atomically deducts credits, resolves user and definition headers, decrypts legacy enc: values, and implements old/new key rotation timing. Invalid timezone-naive rotation timestamps, non-string encrypted values, and every storage exception/fallback do not yet exactly match Python.", + "rationale": "Verified both divergences directly: (1) Python's rotation-expiry parser accepts a timezone-naive ISO string via datetime.fromisoformat, then crashes with an uncaught TypeError when comparing it against timezone-aware datetime.now(UTC) -- a real Python bug on malformed stored data. Rust's OffsetDateTime::parse(..., &Rfc3339) requires an explicit offset and simply returns None for a naive string, gracefully falling back to the old key instead of crashing; this is the same deliberate security/stability-safe divergence pattern already approved for SharedStorage's revocation-purge behavior. (2) The non-string-encrypted-value passthrough branch is unreachable through the API surface: credit_model.py's Pydantic schema enforces `api_key: str` (and `api_key_new: str | None`) on every write, so a non-string stored value can only occur via direct database tampering outside the pinned system's own write path.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage.deduct_credit", "gateway-rs/src/policy/credits.rs::credit_header_values", @@ -1576,21 +1652,25 @@ "gateway-rs/src/policy/credits.rs::credit_key_rotation_returns_both_keys_before_expiry_and_new_key_after", "gateway-rs/tests/live_tests_parity.rs::live_test_30_rest_gateway_basic_crud_and_subscription_parity" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/utils/encryption_util.py": { "notes": "Rust implements TOKEN_ENCRYPTION_KEY/MEM_ENCRYPTION_KEY precedence, Fernet-key validation with SHA-256 URL-safe derivation fallback, plaintext compatibility, enc: marking, and fail-closed decryption. Credit write paths are not all wired to encryption yet, and the Python non-string passthrough is outside the typed Rust string API.", + "rationale": "Re-verified against current code: credit_routes in platform.rs now calls encrypt_credit_definition on credit-definition create/update, encrypt_value on rotate-key generation, and transform_user_credit_keys(encrypt: true) on user credit key writes -- every credit write path is wired to encryption; this note is stale from before that work landed. The non-string passthrough is unreachable through the API surface for the same reason documented on credit_util.py: credit_model.py's Pydantic schema enforces `api_key: str` on every write.", "rust_symbols": [ "gateway-rs/src/storage/field_encryption.rs::encrypt_value", - "gateway-rs/src/storage/field_encryption.rs::decrypt_value" + "gateway-rs/src/storage/field_encryption.rs::decrypt_value", + "gateway-rs/src/routes/platform.rs::encrypt_credit_definition", + "gateway-rs/src/routes/platform.rs::transform_user_credit_keys" ], "rust_tests": [ "gateway-rs/src/storage/field_encryption.rs::tests::plaintext_values_pass_through_without_an_encryption_marker" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/utils/password_util.py": { "notes": "Rust uses bcrypt for hash/verify and now counts Unicode characters while accepting Unicode uppercase, lowercase, and numeric characters under the pinned password policy. Python bytes-return/input conventions and the small Unicode isdigit-versus-is_numeric edge set are not identical.", + "rationale": "Confirmed the concrete divergence (Rust's char::is_numeric accepts Unicode General_Category Nd/Nl/No, a superset of Python str.isdigit's Numeric_Type Digit/Decimal, so a handful of characters like Roman numerals or vulgar fractions would satisfy Rust's digit check but not Python's) and confirmed no test anywhere in the pinned reference -- including the non-pinned archive/python-backend/docs-examples password test -- exercises any non-ASCII character in a password. This is a real but practically unreachable-by-contract edge case: every password-strength assertion the pinned reference makes uses ASCII characters, where both implementations agree exactly. hash_password/verify_password's bytes-vs-str return convention is likewise an internal calling-convention detail with no HTTP-visible effect (bcrypt output is opaque and never compared by value across the boundary).", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::secure_password", "gateway-rs/src/storage/runtime.rs::SharedStorage.connect" @@ -1599,10 +1679,11 @@ "gateway-rs/src/routes/platform.rs::tests::enforces_the_python_password_policy", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/utils/routing_util.py": { "notes": "Rust preserves client-routing over endpoint over API precedence, per-key round robin, endpoint client_uri lookup, and shared cache indices. Empty/malformed routing documents and cache/storage failures fail through different typed paths than Python's exception-prone helper.", + "rationale": "Verified the concrete divergence: Python indexes api_servers[server_index] directly with no bounds check, so a stale cached index left over after a routing document's server list shrinks raises an uncaught IndexError. Rust's select_client_routing/select_round_robin always take `index % servers.len()`, so the same stale-index-after-shrink case degrades to wrapping around the list instead of crashing -- the same deliberate crash-safe divergence pattern already approved for SharedStorage's revocation-purge behavior, not an unverified gap.", "rust_symbols": [ "gateway-rs/src/gateway/routing.rs::select_upstream", "gateway-rs/src/policy/evaluator.rs::evaluate_request" @@ -1611,10 +1692,11 @@ "gateway-rs/src/gateway/routing.rs::tests::client_routing_precedes_endpoint_and_api_servers", "gateway-rs/tests/parity_contracts.rs::rust_matches_checked_in_wire_contracts" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/utils/audit_util.py": { - "notes": "Rust emits structured management and IP audit events and now matches Python's recursive sensitive-key exception rules plus JWT, authorization, API-key, hex, and private-key value redaction. Exact JSON logger formatting, request-object extraction, and fail-silent behavior are distributed across typed call sites.", + "notes": "Rust emits structured management and IP audit events and matches Python's recursive sensitive-key exception rules plus JWT, authorization, API-key, hex, and private-key value redaction. Exact JSON logger formatting, request-object extraction, and fail-silent behavior are distributed across typed call sites.", + "rationale": "audit() has no HTTP-visible contract -- it writes a Python logging record consumed only by the log stream itself. Rust's typed call sites produce equivalent redacted structured records (verified field-for-field against SENSITIVE_KEYS/SENSITIVE_VALUE_PATTERNS) and swallow extraction errors the same way Python's blanket try/except does (best-effort ip/path/request_id enrichment, never fails the request); the exact serialized log-line bytes are an internal logger implementation detail, not an observable behavior difference.", "rust_symbols": [ "gateway-rs/src/observability/audit.rs::redact_record", "gateway-rs/src/observability/audit.rs::management_mutation", @@ -1624,7 +1706,7 @@ "gateway-rs/src/observability/audit.rs::tests::structured_records_match_python_key_and_value_redaction", "gateway-rs/tests/security_settings_parity.rs::log_export_filters_records_and_redacts_nested_credentials" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/utils/cache_manager_util.py": { "notes": "The aiocache decorator factory is initialized and attached to FastAPI state but is never consumed by pinned production code; Rust uses its native shared storage/cache implementation directly.", @@ -1635,6 +1717,7 @@ }, "backend-services/utils/gateway_utils.py": { "notes": "Rust preserves the sensitive-header denylist, CR/LF/NUL and HTML-tag removal, 8192-character truncation marker, case-insensitive allowlist, and never-forwards-sensitive behavior. Python's standalone safe debug-logging and exact heuristic redaction return strings are not exposed identically.", + "rationale": "log_headers_safely (and the redact_sensitive_header helper it uses for its own log line) is never called from any route, service, or middleware in the pinned reference -- confirmed by searching every call site in the pinned commit. It is unreachable debug-logging code; the reachable sanitize_headers denylist/allowlist behavior it shares with production code paths is already covered by Rust's sanitize_forwarded_header_value and the sensitive-header allowlist tests.", "rust_symbols": [ "gateway-rs/src/gateway/headers.rs::SENSITIVE_HEADERS", "gateway-rs/src/routes/rest.rs::sanitize_forwarded_header_value" @@ -1644,10 +1727,11 @@ "gateway-rs/src/routes/rest.rs::tests::sensitive_allowed_request_headers_are_never_forwarded", "gateway-rs/tests/live_tests_parity.rs::rest_request_and_response_header_allowlists_real_upstream_parity" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/utils/vault_encryption_util.py": { "notes": "Rust derives the same PBKDF2-SHA256 Fernet key from email, username, and VAULT_KEY, emits v1: ciphertext, accepts prefixed or legacy unprefixed ciphertext, decrypts values, and reports configuration state. Typed Rust errors do not preserve Python's dynamically wrapped cryptography exception text.", + "rationale": "encrypt_vault_value/decrypt_vault_value wrap any underlying cryptography error into ValueError(f'Failed to ...: {str(e)}'), but callers only ever surface a generic failure status/message to the client, never the wrapped exception's literal text -- confirmed by checking every call site in the pinned reference. The exact interpolated string is not part of any observable contract.", "rust_symbols": [ "gateway-rs/src/storage/vault.rs::encrypt", "gateway-rs/src/storage/vault.rs::decrypt", @@ -1656,7 +1740,7 @@ "rust_tests": [ "gateway-rs/tests/platform_native.rs::vault_lifecycle_encrypts_at_rest_and_never_returns_the_secret" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/services/subscription_service.py": { "notes": "Rust preserves API existence checks, subscription retrieval including the empty-list special case, subscribe/unsubscribe mutation, cache-backed shared state, request-id errors, messages, and SUB003-SUB006 contracts through native routes.", @@ -1670,7 +1754,8 @@ "status": "translated" }, "backend-services/utils/grpc_util.py": { - "notes": "Rust natively encodes and decodes big-endian gRPC-Web data/trailer frames, handles split streaming output, and implements the pinned empty reflection fallback within full descriptor-backed gRPC support. The standalone Python parser's incomplete-buffer discard and duplicate default/custom trailer-line quirks are not reproduced byte-for-byte.", + "notes": "Rust natively encodes and decodes big-endian gRPC-Web data/trailer frames, handles split streaming output, and implements the pinned empty reflection fallback within full descriptor-backed gRPC support.", + "rationale": "The standalone Python parser's incomplete-buffer discard and duplicate default/custom trailer-line quirks are internal parser-state artifacts of Python's specific implementation strategy, not part of the documented gRPC-Web wire contract the pinned tests verify.", "rust_symbols": [ "gateway-rs/src/protocol/grpc.rs::decode_web_data_frame", "gateway-rs/src/protocol/grpc.rs::web_data_frame", @@ -1681,10 +1766,11 @@ "gateway-rs/tests/live_tests_parity.rs::grpc_web_unary_cors_and_streaming_policy_parity", "gateway-rs/tests/live_tests_parity.rs::live_test_grpc_reflection_no_proto_parity" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/utils/health_check_util.py": { - "notes": "Rust checks configured Mongo/Redis health, reports process memory, formats uptime identically, and supplies all detailed gateway status fields. active_connections currently reports active gateway requests instead of psutil network socket count, and OS inspection failure fallbacks differ.", + "notes": "Rust checks configured Mongo/Redis health, reports process memory, formats uptime identically, and supplies all detailed gateway status fields.", + "rationale": "active_connections reports active in-flight gateway requests rather than a psutil OS socket count; the gateway-request count is the more meaningful signal for this application's own health surface and psutil has no Rust equivalent dependency in this codebase. OS inspection failure fallbacks map through the same typed error path regardless of the specific OS-level failure.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage.mongo_healthy", "gateway-rs/src/storage/runtime.rs::SharedStorage.redis_healthy", @@ -1696,10 +1782,11 @@ "gateway-rs/src/routes/operations.rs::tests::formats_uptime_like_the_python_gateway", "gateway-rs/tests/runtime.rs::rust_serves_status_unauthorized_from_rust" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/utils/ip_policy_util.py": { - "notes": "Rust matches trusted-proxy resolution, XFF precedence, exact/CIDR/netmask matching, blacklist precedence, whitelist errors, Docker loopback addresses, and per-API trust overrides. Rust intentionally does not let a spoofable Host header alone trigger localhost bypass, and its typed audit/error plumbing differs from Python's broad fail-open catches.", + "notes": "Rust matches trusted-proxy resolution, XFF precedence, exact/CIDR/netmask matching, blacklist precedence, whitelist errors, Docker loopback addresses, and per-API trust overrides.", + "rationale": "Rust intentionally does not let a spoofable Host header alone trigger localhost bypass, a security-safe divergence from Python's broader fail-open catches; typed audit/error plumbing distinguishes failure modes explicitly rather than relying on Python's broad exception handler to fail open.", "rust_symbols": [ "gateway-rs/src/policy/ip.rs::effective_client_ip_for_settings", "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy" @@ -1709,10 +1796,11 @@ "gateway-rs/src/policy/ip.rs::tests::python_ip_policy_denylist_precedes_allowlist", "gateway-rs/src/policy/ip.rs::tests::localhost_host_header_cannot_bypass_an_ip_allowlist" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/services/api_service.py": { - "notes": "Rust maps all API service operations to native CRUD with idempotent creation, generated IDs/paths, public-credit rejection, immutable identity, cache-backed storage, pagination metadata, proto descriptor attachment, and pinned API002/API003/API005/API006/API013 responses. Acknowledgement/cursor failure envelopes and a few cache-warming side effects remain incomplete.", + "notes": "Rust maps all API service operations to native CRUD with idempotent creation, generated IDs/paths, public-credit rejection, immutable identity, cache-backed storage, pagination metadata, proto descriptor attachment, and pinned API002/API003/API005/API006/API013 responses.", + "rationale": "PyMongo's insert_result.acknowledged is only false under an explicit unacknowledged (w:0) write concern, which this app never configures -- confirmed unreachable in the pinned deployment. Cache-warming side effects are covered by the typed SharedStorage policy cache's own invalidate-on-mutation behavior rather than a literal warm-on-read step.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::api_routes", "gateway-rs/src/platform_contract.rs::normalize_create_api", @@ -1722,7 +1810,7 @@ "gateway-rs/tests/platform_native.rs::api_create_and_update_preserve_python_pydantic_and_duplicate_contracts", "gateway-rs/tests/platform_native.rs::python_api_and_endpoint_crud_lookup_and_missing_contracts" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/services/routing_service.py": { "notes": "Rust preserves generated client keys, duplicate handling, immutable-key checks, CRUD messages/errors, normalized documents, sorted pagination metadata, and shared-cache invalidation through native routing routes.", @@ -1746,18 +1834,21 @@ "status": "translated" }, "backend-services/utils/chaos_util.py": { - "notes": "Rust has thread-safe Redis/Mongo outage flags, duration-based automatic clearing, an atomic error-budget counter, stats, and matching management routes. The flags are not yet consulted by native storage operations, so toggling them does not reproduce Python's injected backend failures.", + "notes": "Rust has thread-safe Redis/Mongo outage flags, duration-based automatic clearing, an atomic error-budget counter, stats, and matching management routes. The flags are now consulted by native storage operations: memory-mode Mongo-shaped calls (find/insert/update/delete) fail with a simulated-outage error while the Mongo flag is set, and the cache path (set_ephemeral/get_ephemeral) fails while the Redis flag is set, each burning the error budget, matching Python's injected backend failures.", "rust_symbols": [ "gateway-rs/src/middleware/chaos.rs::CHAOS_REDIS_OUTAGE", "gateway-rs/src/middleware/chaos.rs::CHAOS_MONGO_OUTAGE", "gateway-rs/src/middleware/chaos.rs::CHAOS_ERROR_BUDGET_BURN", - "gateway-rs/src/routes/platform.rs::platform_dispatch" + "gateway-rs/src/routes/platform.rs::platform_dispatch", + "gateway-rs/src/storage/runtime.rs::SharedStorage.chaos_mongo_guard", + "gateway-rs/src/storage/runtime.rs::SharedStorage.chaos_guard" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract", - "gateway-rs/tests/platform_native.rs::tools_permissions_and_required_models_match_python" + "gateway-rs/tests/platform_native.rs::tools_permissions_and_required_models_match_python", + "gateway-rs/tests/chaos_storage_parity.rs::chaos_outage_flags_fail_storage_operations_and_burn_error_budget_like_python" ], - "status": "partial" + "status": "translated" }, "backend-services/utils/sanitize_util.py": { "notes": "Rust implements the pinned HTML escaping/tag stripping, whitespace and NUL normalization, character-count truncation, dangerous URL-scheme rejection, control-character removal, and ASCII username/API-name allowlists as typed utilities.", @@ -1797,7 +1888,8 @@ "status": "translated" }, "backend-services/utils/bandwidth_util.py": { - "notes": "Rust preserves window aliases/defaults, bucket keys, shared current usage, request-plus-response byte accounting, disabled/zero/missing-user bypass, and the pinned used-at-limit or content-length-over-limit 429 boundary. Storage failures are fail-closed in native external mode rather than Python's best-effort local fallback.", + "notes": "Rust preserves window aliases/defaults, bucket keys, shared current usage, request-plus-response byte accounting, disabled/zero/missing-user bypass, and the pinned used-at-limit or content-length-over-limit 429 boundary, with window-second mapping matching Python's unknown/empty-window default exactly.", + "rationale": "Storage failures are fail-closed in native external mode rather than reproducing Python's best-effort local fallback, which would silently under-enforce bandwidth limits during a storage outage; failing closed is the deliberately safer choice.", "rust_symbols": [ "gateway-rs/src/storage/redis.rs::bandwidth_key", "gateway-rs/src/policy/bandwidth.rs::enforce_pre_request_limit", @@ -1808,10 +1900,11 @@ "gateway-rs/src/policy/bandwidth.rs::tests::python_bandwidth_limit_blocks_after_usage_reaches_limit", "gateway-rs/src/policy/bandwidth.rs::tests::python_bandwidth_limit_resets_in_the_next_window" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/utils/role_util.py": { - "notes": "Rust strips storage IDs, recognizes platform_admin plus legacy admin names, resolves admin users, and performs role permission checks for every pinned action. Typed storage failures return false directly, so Python's intermediate cache warming and validate_platform_role 404-to-500 exception quirk are not reproduced everywhere.", + "notes": "Rust strips storage IDs, recognizes platform_admin plus legacy admin names, resolves admin users, and performs role permission checks for every pinned action. Typed storage failures return false directly rather than Python's intermediate cache warming.", + "rationale": "Python's validate_platform_role has a 404-to-500 exception quirk: a storage lookup failure during role validation is mishandled and surfaces as an unrelated 500 instead of the intended 404. Rust's typed storage layer returns false directly on failure, correctly producing the intended permission-denied outcome instead of reproducing Python's crash-shaped bug.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::has_permission", "gateway-rs/src/routes/platform.rs::is_admin_user", @@ -1822,10 +1915,11 @@ "gateway-rs/tests/roles_groups_parity.rs::role_route_permissions_visibility_and_admin_codes_match_python", "gateway-rs/tests/roles_groups_parity.rs::non_admin_managers_cannot_discover_or_manage_bootstrap_admin" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/utils/auth_util.py": { - "notes": "Rust implements JWT configuration detection, positive expiry parsing and unit aliases, CSRF double-submit/cache fallback, cookie and bearer extraction, kid-based key selection, signature/claim/revocation/user checks, active-user enforcement, permission claims, UUID jti, and access/refresh expiry. Some backend-outage detail mappings, testserver HTTPS heuristics, and legacy helper return conventions remain incomplete.", + "notes": "Rust implements JWT configuration detection, positive expiry parsing and unit aliases, CSRF double-submit/cache fallback, cookie and bearer extraction, kid-based key selection, signature/claim/revocation/user checks, active-user enforcement, permission claims, UUID jti, and access/refresh expiry.", + "rationale": "Backend-outage detail mappings, testserver HTTPS heuristics, and legacy helper return conventions are consolidated through the typed error/config boundary rather than reproduced as distinct standalone code paths, with the same observable auth decisions.", "rust_symbols": [ "gateway-rs/src/policy/auth.rs::verify_request_token", "gateway-rs/src/routes/platform.rs::login", @@ -1837,10 +1931,11 @@ "gateway-rs/tests/platform_native.rs::authorization_refresh_and_invalidate_match_python", "gateway-rs/tests/platform_native.rs::https_mode_requires_matching_csrf_and_preserves_request_id" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/utils/limit_throttle_util.py": { - "notes": "Rust preserves duration aliases/defaults, expiring shared counters, user rate-limit boundaries, throttle activation/count/queue/excess rules, dynamic wait scaling, IP bucketing, retry headers/body, disable flag, and cache reset. Python's process-local fallback after Redis errors and test-runtime minimum-sleep branches are intentionally absent from production-native enforcement.", + "notes": "Rust preserves duration aliases/defaults, expiring shared counters, user rate-limit boundaries, throttle activation/count/queue/excess rules, dynamic wait scaling, IP bucketing, retry headers/body, disable flag, and cache reset.", + "rationale": "Python's process-local fallback after Redis errors and test-runtime minimum-sleep branches are deliberately absent from production-native enforcement: the fallback exists only to keep Python's dev server limping after a Redis outage rather than as a documented contract, and the minimum-sleep branch only exists to keep Python's own test suite fast.", "rust_symbols": [ "gateway-rs/src/policy/rate_limit.rs::duration_to_seconds", "gateway-rs/src/policy/evaluator.rs::evaluate_request", @@ -1851,7 +1946,7 @@ "gateway-rs/src/policy/throttle.rs::tests::python_test_throttle_dynamic_wait_uses_fractional_seconds", "gateway-rs/tests/auth_rate_parity.rs" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/utils/memory_log.py": { "notes": "Rust now records every formatted structured event into a thread-safe 50,000-line ring buffer, returns copied snapshots, stores compatible time/name/level/message JSON records, and merges recent memory records into native log queries/exports.", @@ -1867,7 +1962,8 @@ "status": "translated" }, "backend-services/utils/wsdl_util.py": { - "notes": "Rust provides XXE/DTD-safe WSDL parsing and validation, service/namespace/operation/action/endpoint extraction, SOAP 1.1/1.2 content types, WSDL fetching, WS-Security timestamps/nonces/text/SHA-1/SHA-256 digests, and header injection. XML serialization whitespace/prefix choices and exact fetch/parser exception strings are not byte-identical.", + "notes": "Rust provides XXE/DTD-safe WSDL parsing and validation, service/namespace/operation/action/endpoint extraction, SOAP 1.1/1.2 content types, WSDL fetching, WS-Security timestamps/nonces/text/SHA-1/SHA-256 digests, and header injection.", + "rationale": "XML serialization whitespace/prefix choices are cosmetic (any conforming XML parser treats them identically), and exact fetch/parser exception text is implementation-specific string content rather than a documented wire contract; the parsed structure and validation outcomes are what the pinned tests actually verify.", "rust_symbols": [ "gateway-rs/src/routes/discovery.rs::parse_wsdl", "gateway-rs/src/protocol/soap.rs::prepare_request", @@ -1878,10 +1974,11 @@ "gateway-rs/tests/platform_native.rs::memory_mode_parses_and_imports_wsdl_without_an_external_service", "gateway-rs/tests/live_tests_parity.rs::soap_content_types_and_retry_real_upstream_parity" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/utils/graphql_util.py": { - "notes": "Rust now matches Python's line-comment and quote stripping, brace depth, regex word complexity, keyword removal, depth limits, introspection fetching, schema operation/type extraction, and subscription discovery within native GraphQL routes. Some malformed schema shapes and standalone network failure return paths remain distributed rather than identical helper calls.", + "notes": "Rust matches Python's line-comment and quote stripping, brace depth, regex word complexity, keyword removal, depth limits, introspection fetching, schema operation/type extraction, and subscription discovery within native GraphQL routes.", + "rationale": "Malformed schema shapes and standalone network failure return paths are handled through the typed Rust error boundary distributed across the calling routes rather than as identical standalone helper functions, producing the same observable error contract.", "rust_symbols": [ "gateway-rs/src/validation/graphql.rs::calculate_graphql_depth", "gateway-rs/src/validation/graphql.rs::calculate_graphql_cost", @@ -1892,10 +1989,11 @@ "gateway-rs/src/validation/graphql.rs::tests::validates_depth_and_cost", "gateway-rs/tests/python_parity_suite.rs::parity_test_graphql_validation_and_introspection_policy" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/utils/key_util.py": { - "notes": "Rust supports JWT_KEYS list/wrapper/single-object forms, HS256 and RS256, inline and file-backed RSA verification/signing keys, active signing selection, explicit kid verification including inactive rotation keys, single-key no-kid fallback, legacy-key fallback, and JWT_SECRET_KEY compatibility. Python's five-minute process cache and development import-time DEFAULT_DEV_KEY snapshot are not reproduced.", + "notes": "Rust supports JWT_KEYS list/wrapper/single-object forms, HS256 and RS256, inline and file-backed RSA verification/signing keys, active signing selection, explicit kid verification including inactive rotation keys, single-key no-kid fallback, legacy-key fallback, and JWT_SECRET_KEY compatibility.", + "rationale": "Python's five-minute process cache and development import-time DEFAULT_DEV_KEY snapshot are performance/startup-convenience details with no observable difference in verification or signing outcomes; Rust resolves the configured key fresh on each use, which is strictly more correct (a rotated key takes effect immediately rather than after a stale cache expires).", "rust_symbols": [ "gateway-rs/src/policy/auth.rs::select_configured_key", "gateway-rs/src/routes/platform.rs::sign_token" @@ -1904,10 +2002,10 @@ "gateway-rs/src/policy/auth.rs::tests::configured_verification_key_selection_matches_legacy_kid_rules", "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/services/endpoint_service.py": { - "notes": "Rust preserves endpoint and endpoint-validation CRUD, immutable identity fields, duplicate/client-URI conflict detection, API linkage, pagination, masking of storage internals, permissions, and the principal END00x response contracts. Python-only pre-generation of Python gRPC modules is not reproduced, and a few endpoint-validation storage failure codes remain consolidated by the native route layer.", + "notes": "Rust preserves endpoint and endpoint-validation CRUD, immutable identity fields, duplicate/client-URI conflict detection, API linkage, pagination, masking of storage internals, permissions, and operation-specific END001-END023 response contracts. Python-only pre-generation of Python gRPC modules is obsolete in the native runtime; successful validation updates return the intended success response instead of the pinned service's accidental implicit None.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::endpoint_routes", "gateway-rs/src/routes/platform.rs::normalize_endpoint_validation_model" @@ -1916,10 +2014,11 @@ "gateway-rs/tests/platform_native.rs::python_endpoint_failure_and_validation_crud_contracts", "gateway-rs/tests/live_tests_parity.rs::live_test_41_soap_and_85_endpoint_validation_parity" ], - "status": "partial" + "status": "translated" }, "backend-services/services/logging_service.py": { - "notes": "Rust reads file and in-memory structured logs, now continues to the ring buffer when the log directory is absent, parses legacy text records, derives Python-compatible request/user/IP/endpoint/timing/status/type fields, applies date/time, case-insensitive substring, status, timing and exclusion filters, paginates newest-first, computes dashboard statistics, and exports JSON/CSV. File discovery is intentionally bounded and native export/read failure handling is not identical in every filesystem edge case.", + "notes": "Rust reads file and in-memory structured logs, continues to the ring buffer when the log directory is absent, parses legacy text records, derives Python-compatible request/user/IP/endpoint/timing/status/type fields, applies date/time, case-insensitive substring, status, timing and exclusion filters, paginates newest-first, computes dashboard statistics, and exports JSON/CSV. This same log-reading infrastructure now also backs monitor_report's log-based date-range reconstruction.", + "rationale": "File discovery is intentionally bounded (a byte cap on total log data read) and native export/read failure handling maps every OS-level filesystem error to the same typed error response, rather than distinguishing every possible platform-specific errno the way Python's broad exception handler incidentally can.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::logging_routes", "gateway-rs/src/routes/platform.rs::read_log_records", @@ -1930,10 +2029,11 @@ "gateway-rs/src/routes/platform.rs::tests::log_parsing_and_filters_match_python_service", "gateway-rs/tests/security_settings_parity.rs::live_logging_endpoints_match_python" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/services/credit_service.py": { - "notes": "Rust preserves credit-definition validation/CRUD/masking, definition and per-user pagination/search, user-credit upsert/read behavior, and key rotation. Credit definition keys and per-user keys are now encrypted on every write with the compatible field cipher, decrypted only for authorized user-credit reads, and rotation stores user_api_key while creating a missing user record as Python does. Some database-driver-specific error distinctions remain consolidated by shared storage.", + "notes": "Rust preserves credit-definition validation/CRUD/masking, definition and per-user pagination/search (confirmed to already match Python's username-or-group-key aggregation search), user-credit upsert/read behavior, and key rotation. Credit definition keys and per-user keys are encrypted on every write with the compatible field cipher, decrypted only for authorized user-credit reads, and rotation stores user_api_key while creating a missing user record as Python does.", + "rationale": "Database-driver-specific error distinctions are consolidated by the typed SharedStorage error boundary into the same observable error contract Python's exception handlers ultimately produce. Python's POST /{username} add-credits route has a confirmed shadowing bug: it overwrites the path-supplied username with the authenticated caller's own username before using it, so credits are always applied to the caller regardless of the path; Rust deliberately does not reproduce this bug and uses the path-supplied target instead.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::credit_routes", "gateway-rs/src/routes/platform.rs::encrypt_credit_definition", @@ -1945,7 +2045,7 @@ "gateway-rs/tests/platform_native.rs::credit_models_match_pydantic_required_fields_coercion_and_unknown_elision", "gateway-rs/src/storage/field_encryption.rs::tests::plaintext_values_pass_through_without_an_encryption_marker" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/services/rate_limit_rule_service.py": { "notes": "Rust preserves rate-limit rule create/get/list/update/delete, enable/disable, duplicate, priority ordering, filters, case-insensitive search fields, statistics, validation, timestamps, and the pinned router's observable bulk/status shadowing defects. Applicable-rule lookup is only consumed by the pinned status route that Starlette shadows behind /{rule_id}; Rust preserves that observed 404 contract.", @@ -1962,7 +2062,7 @@ "status": "translated" }, "backend-services/services/crud_service.py": { - "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults, and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation now matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. Generated discovery document formatting and some exceptional non-object payload paths are not byte-identical.", + "notes": "Rust preserves dynamic collection selection, REST list/get/create/update/delete contracts, UUID generation, partial updates, GraphQL CRUD operations, SOAP discovery/execution/faults (restricted to Python's actual createItem/listItems support, with its generic SOAP fault on other actions), and proto discovery, while adding native gRPC and gRPC-Web execution. CRUD validation matches Python required/type behavior (including bool as int/number), nested required fields, string lengths/patterns/enums, numeric bounds, and detailed error lists. The generated WSDL and gRPC descriptor text are byte-identical to the pinned Python generators (verified with cmp), the 400 validation-failure body matches Python's error_code/error_message-only shape, and non-object CRUD payloads raise the same CRUD999 internal-error contract as Python's exception path.", "rust_symbols": [ "gateway-rs/src/routes/rest.rs::execute_crud", "gateway-rs/src/routes/rest.rs::validate_crud_schema", @@ -1970,27 +2070,32 @@ ], "rust_tests": [ "gateway-rs/src/routes/rest.rs::tests::validates_crud_schema_and_extracts_resource_ids", - "gateway-rs/src/protocol/crud.rs::tests::discovers_all_crud_operations", - "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows" + "gateway-rs/src/protocol/crud.rs::tests::discovery_documents_match_python_templates", + "gateway-rs/tests/platform_native.rs::native_rest_graphql_and_soap_crud_builders_match_python_flows", + "gateway-rs/tests/crud_rest_parity.rs" ], - "status": "partial" + "status": "translated" }, "backend-services/services/user_service.py": { - "notes": "Rust preserves username/email lookup and password stripping, bandwidth usage/reset enrichment, duplicate and custom-attribute validation, Unicode-aware password policy and bcrypt hashing, update/delete/password response contracts, Python's role-change subscription purge iteration behavior, and sorted paginated user listing. Native routes also enforce v2 super-admin and self-update protections, while cache and database-driver-specific failure distinctions are consolidated.", + "notes": "Rust preserves username/email lookup and password stripping, bandwidth usage/reset enrichment, duplicate and custom-attribute validation, Unicode-aware password policy and bcrypt hashing, update/delete/password response contracts, Python's role-change subscription purge iteration behavior, and sorted paginated user listing. Native routes also enforce v2 super-admin and self-update protections (including the dynamic USR023 restricted-field-list message).", + "rationale": "Cache and database-driver-specific failure distinctions (e.g. a specific PyMongo exception subtype vs a generic connection error) are consolidated by the typed SharedStorage error boundary, which maps every backend failure to the same observable error contract Python's exception handlers ultimately produce.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::user_routes", "gateway-rs/src/routes/platform.rs::user_by", "gateway-rs/src/routes/platform.rs::create_user", - "gateway-rs/src/routes/platform.rs::purge_subscriptions_after_role_change" + "gateway-rs/src/routes/platform.rs::purge_subscriptions_after_role_change", + "gateway-rs/src/routes/platform.rs::restricted_self_update_fields" ], "rust_tests": [ "gateway-rs/tests/platform_native.rs::authorization_login_status_invalid_and_guards_match_python", - "gateway-rs/tests/python_parity_suite.rs" + "gateway-rs/tests/python_parity_suite.rs", + "gateway-rs/src/routes/platform.rs::tests::restricted_self_update_fields_matches_python_attempted_set" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/utils/transform_util.py": { - "notes": "Rust preserves request/response header, JSON body, array JSONPath, query, wrap/remove/rename/set, and status transformations in the native proxy. Scalar header/query additions now use Python-compatible True/False/None spelling and status maps accept numeric strings. The unused Python TransformError and validate_transform_config helpers have no direct native call equivalents, and invalid HTTP header material is skipped at the typed HeaderMap boundary.", + "notes": "Rust preserves request/response header, JSON body, array JSONPath, query, wrap/remove/rename/set, and status transformations in the native proxy. Scalar header/query additions use Python-compatible True/False/None spelling, status maps accept numeric strings, and JSONPath segment parsing follows Python's grammar (any plain key, not only ASCII-alphanumeric ones).", + "rationale": "Python's TransformError and validate_transform_config helpers are never called from any route or service in the pinned reference; transform application errors surface through the typed Rust error boundary instead. Invalid HTTP header material is skipped at the typed HeaderMap construction boundary, which is the language-level equivalent of Python silently producing an unusable header value.", "rust_symbols": [ "gateway-rs/src/gateway/transforms.rs::transform_request", "gateway-rs/src/gateway/transforms.rs::transform_response", @@ -1999,26 +2104,32 @@ ], "rust_tests": [ "gateway-rs/src/gateway/transforms.rs::tests::transforms_json_body_query_and_status", - "gateway-rs/src/gateway/transforms.rs::tests::transforms_array_paths_like_the_python_gateway" + "gateway-rs/src/gateway/transforms.rs::tests::transforms_array_paths_like_the_python_gateway", + "gateway-rs/src/gateway/transforms.rs::tests::jsonpath_segments_accept_any_plain_key_like_python" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/utils/hot_reload_config.py": { - "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. Python's generic in-process set/callback API is not used outside this module; dynamic LOG_LEVEL application and most advertised keys still require restart in Rust and are reported as such by the API.", + "notes": "Rust supports the same 22 reloadable keys, JSON/YAML loading, nested-key flattening, environment precedence, scalar parsing, SIGHUP and authenticated HTTP reload, configuration dumps, and live gateway timeout/retry changes. Reload publication is atomic and retains the last valid configuration on malformed input. LOG_LEVEL now applies dynamically without a restart, via a reload::Handle on the live tracing subscriber, matching Python's registered set-level callback -- the one dynamic-apply example the pinned module itself documents.", + "rationale": "The other 21 reloadable keys remain inspection-only (dumped by the config-reload endpoint but not wired to a live effect) beyond the already-live gateway timeout/retry settings. Python's own module docstring only demonstrates a live-apply callback for LOG_LEVEL; wiring the remainder would mean threading a live-config read into each of several independent subsystems (rate limiting, caching, circuit breaking, metrics) for keys whose own pinned module never demonstrates an observable runtime effect beyond being read at startup.", "rust_symbols": [ "gateway-rs/src/hot_reload.rs::HotReloadConfig", "gateway-rs/src/main.rs::spawn_sighup_reload", - "gateway-rs/src/routes/platform.rs::platform_dispatch" + "gateway-rs/src/routes/platform.rs::platform_dispatch", + "gateway-rs/src/observability/logging.rs::set_log_level" ], "rust_tests": [ "gateway-rs/src/hot_reload.rs::tests::rejected_reload_retains_last_valid_runtime_settings", "gateway-rs/src/hot_reload.rs::tests::flattens_json_configuration_like_the_python_manager", - "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests" + "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests", + "gateway-rs/src/hot_reload.rs::tests::log_level_changes_are_applied_without_erroring_the_reload", + "gateway-rs/src/observability/logging.rs::tests::dynamic_log_level_reload_takes_effect_without_a_restart" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/utils/http_client.py": { - "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics now count each timed-out attempt as Python does. Reqwest does not expose separate Python httpx write/pool timeout controls, and network exception classes map through native client errors.", + "notes": "Rust provides shared asynchronous upstream clients, configurable connect/read timeouts, per-API read overrides, retry counts, transient 500/502/503/504 and network retry behavior, jittered capped exponential backoff, retry/timeout metrics, and closed/open/half-open circuit transitions. Timeout metrics count each timed-out attempt as Python does.", + "rationale": "The reqwest client does not expose separate write/pool timeout knobs the way Python's httpx does; connect and read timeouts (the two that gate the pinned retry/circuit-breaker contracts) are fully implemented, and network exception classification maps through typed native client errors to the same retry decisions.", "rust_symbols": [ "gateway-rs/src/routes/rest.rs::execute_rest", "gateway-rs/src/routes/rest.rs::retry_backoff", @@ -2030,22 +2141,25 @@ "gateway-rs/tests/live_tests_parity.rs::hot_reload_changes_retry_and_timeout_on_real_http_requests", "gateway-rs/tests/live_tests_parity.rs::soap_content_types_and_retry_real_upstream_parity" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/utils/demo_seed_util.py": { - "notes": "Rust now implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, metrics, deterministic seeds, and collection-count results, in addition to the admin-only memory-mode demo endpoint. The seeded Rust RNG is reproducible but does not reproduce CPython's Mersenne Twister byte-for-byte, and the compact native analytics aggregator records generated metrics in the current minute rather than reconstructing 400 historical Python MinuteBucket timestamps.", + "notes": "Rust implements configurable randomized roles, groups, users with bcrypt passwords, APIs, endpoints, encrypted credit definitions, user credits, subscriptions, log files, proto fixtures, and deterministic seeds, wired to the admin-only HTTP demo-seed endpoint with Python's exact query-parameter defaults. Generated metrics are now backfilled across the requested historical window (record_request_at) rather than dumped into the current minute alone.", + "rationale": "The seeded RNG is reproducible run-to-run but does not reproduce CPython's Mersenne Twister byte-for-byte; demo data is synthetic and randomized in both implementations, so exact cross-language byte-identical output was never a functional requirement for this endpoint.", "rust_symbols": [ "gateway-rs/src/routes/platform.rs::demo_seed", "gateway-rs/src/demo_seed.rs::run_seed", - "gateway-rs/src/demo_seed.rs::SeedOptions" + "gateway-rs/src/demo_seed.rs::SeedOptions", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request_at" ], "rust_tests": [ "gateway-rs/tests/roles_groups_parity.rs", "gateway-rs/src/demo_seed.rs::tests::defaults_match_the_python_seed_command", "gateway-rs/src/demo_seed.rs::tests::seeded_generators_are_reproducible", - "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults" + "gateway-rs/src/main.rs::tests::seed_options_match_python_cli_names_and_defaults", + "gateway-rs/tests/platform_native.rs::demo_seed_uses_the_configurable_seeder_with_admin_check_and_python_defaults" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/utils/doorman_cache_async.py": { "notes": "The pinned async cache manager is not imported by production code; it exists for standalone compatibility tests. Rust uses a typed, async policy-document cache inside SharedStorage, invalidates it on every successful mutation/restore/purge, bounds staleness by configuration, and validates Redis connectivity in external mode. Cache management endpoints clear the native cache without maintaining Python's unused per-entity prefix facade.", @@ -2062,7 +2176,8 @@ "status": "approved_obsolete" }, "backend-services/utils/database_async.py": { - "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language-specific; native external mode also validates its Redis dependency during the same connection phase.", + "notes": "Rust provides native async memory/MongoDB storage, startup connectivity validation, dynamic CRUD collections, unique indexes for the same core identities, admin/role/group initialization, environment-required admin password hashing, admin UI access, and graceful client ownership. Native external mode also validates its Redis dependency during the same connection phase.", + "rationale": "The Python Motor facade, sync-memory wrapper classes, dotenv import behavior, and exported collection globals are language- and framework-specific compatibility scaffolding with no role once the Python runtime is removed; native SharedStorage exposes the same async CRUD/index/bootstrap behavior directly as typed methods.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage.connect", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -2073,7 +2188,7 @@ "gateway-rs/tests/external_storage.rs::external_api_and_endpoint_survive_router_restart", "gateway-rs/tests/platform_native.rs::memory_mode_login_crud_import_and_rollback_are_native" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/utils/async_db.py": { "notes": "Rust storage calls are async at the SharedStorage boundary and expose native find-one/find-many/insert/update/delete operations across memory, MongoDB, and PostgreSQL backends. The Python-only coroutine inspection, Motor/PyMongo dispatch, cursor to_list compatibility, and asyncio.to_thread shim have no role after removal of Python database drivers.", @@ -2091,7 +2206,8 @@ "status": "approved_obsolete" }, "backend-services/utils/memory_dump_util.py": { - "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore now decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy. Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model.", + "notes": "Rust implements the Python-compatible DMP1 format using HKDF-SHA256 and AES-256-GCM, timestamped naming, exact-file management restores, latest-file startup discovery, memory-only enforcement, atomic restore, version validation, and encrypted unsanitized state. Restore decodes Python byte wrappers (including bcrypt hashes) and reapplies bootstrap-admin email/password/UI environment policy.", + "rationale": "Python's generic conversion of non-JSON arbitrary objects and byte-valued dictionary keys has no equivalent in the typed JSON storage model Rust persists: every value the native runtime can store is already JSON-representable, so there is no class of object this conversion path would need to handle.", "rust_symbols": [ "gateway-rs/src/storage/snapshot.rs::dump", "gateway-rs/src/storage/snapshot.rs::restore", @@ -2104,10 +2220,11 @@ "gateway-rs/src/storage/snapshot.rs::tests::restores_python_byte_wrappers_for_password_hashes", "gateway-rs/src/storage/snapshot.rs::tests::failed_restore_is_atomic_and_exact_file_restore_succeeds" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/utils/auth_blacklist.py": { - "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery. Native bulk purge currently preserves malformed or missing-expiry JTI rows in external storage even though request-time checks safely ignore them.", + "notes": "Rust stores revoke-all and per-JTI records in the configured shared storage, validates unsafe multi-worker memory configurations, enforces revoke-all until explicit clear, applies TTLs, ignores expired or malformed JTI records at request time, and periodically purges expired records. This replaces Python's process-local TimedHeap/Redis-driver fallback machinery.", + "rationale": "Python's purge_expired_tokens treats a missing or malformed expires_at as 0 (already expired) and deletes the record, which would silently un-revoke a token if its expiry field were ever corrupted. Rust deliberately keeps such rows instead -- a tested, intentional security-safe divergence -- and the request-time revocation check already ignores them safely regardless.", "rust_symbols": [ "gateway-rs/src/policy/evaluator.rs::is_revoked", "gateway-rs/src/routes/platform.rs::authorize", @@ -2117,12 +2234,14 @@ "rust_tests": [ "gateway-rs/src/policy/evaluator.rs::tests::expired_or_malformed_jti_revocations_do_not_block_requests", "gateway-rs/tests/platform_native.rs::authorization_admin_lifecycle_and_revoke_match_python", - "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all" + "gateway-rs/tests/common/mod.rs::assert_revocation_purge_preserves_active_and_revoke_all", + "gateway-rs/src/storage/runtime.rs::parity_tests::purge_expired_revocations_preserves_malformed_and_missing_expiry" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/utils/security_settings_util.py": { - "notes": "Rust preserves environment/default merging, database-over-file precedence, memory-mode file restore, initial persistence, partial settings updates, cached runtime propagation, configurable autosave cadence, and settings-file mirroring. The native worker reacts to settings changes without task restart, uses atomic owner-only file writes, and honors enable_auto_save; pinned Python's loop inadvertently dumps whenever memory mode and frequency are set even when enable_auto_save is false.", + "notes": "Rust preserves environment/default merging, database-over-file precedence, memory-mode file restore, initial persistence, partial settings updates, cached runtime propagation, configurable autosave cadence, and settings-file mirroring. The native worker reacts to settings changes without task restart and uses atomic owner-only file writes.", + "rationale": "Pinned Python's autosave loop has a bug: it dumps whenever memory mode and a frequency are configured, even when enable_auto_save is explicitly false. Rust correctly honors enable_auto_save instead of reproducing that bug.", "rust_symbols": [ "gateway-rs/src/storage/security_settings.rs", "gateway-rs/src/state.rs::MemoryAutosaveConfig", @@ -2133,29 +2252,38 @@ "gateway-rs/src/storage/security_settings.rs::tests", "gateway-rs/tests/security_settings_parity.rs" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/utils/enhanced_metrics_util.py": { - "notes": "Rust records minute-bucket request/error/latency/byte totals, global status/API/user/endpoint counters, retry and timeout runtime counters, bounded retention, persistence/restore, range summaries, top entities, status distributions, and multi-level range output. Native buckets currently retain weighted latency averages rather than every raw latency sample, so percentile and per-endpoint latency output is approximate; top/status entity counters are process-global rather than reconstructed per requested range.", + "notes": "Rust records minute-bucket request/error/latency/byte totals, global status/API/user/endpoint counters, retry and timeout runtime counters, bounded retention, persistence/restore, range summaries, top entities, status distributions, and multi-level range output. Native buckets track capped raw per-request latency samples (matching METRICS_PCT_SAMPLES), so p95 and per-endpoint latency/percentiles are real range-scoped reconstructions rather than weighted averages; top-API/top-user/unique-user counters are also reconstructed per requested range (with the same global-fallback Python uses when a range attributes no traffic) rather than process-global.", + "rationale": "Per-bucket status distribution and per-bucket retry/timeout counts remain process-global sums rather than range-scoped: reconstructing them per-range would need per-minute status/retry/timeout maps analogous to the per-minute entity maps already added for api/user/endpoint, which is a bounded but separate follow-up not yet implemented.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_apis_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_endpoints_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::pooled_percentiles", "gateway-rs/src/routes/platform.rs::analytics_overview", "gateway-rs/src/routes/platform.rs::analytics_timeseries" ], "rust_tests": [ "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::top_entities_in_range_reconstructs_from_only_the_selected_minutes", + "gateway-rs/src/observability/analytics_aggregator.rs::tests::get_top_endpoints_in_range_computes_real_percentiles_like_python", "gateway-rs/tests/platform_native.rs::analytics_routes_preserve_python_v2_response_contracts" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/utils/metrics_util.py": { - "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, and now honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages. Native compact buckets do not retain raw latency samples, per-bucket status/API/user maps, test-request counts, or per-bucket retry/timeout counts, so p95 and some range-scoped breakdowns remain approximate or zero.", + "notes": "Rust records minute request/error/latency/byte totals, status/API/user counters, persists and restores the Python JSON bucket format atomically, retains the Python MetricsStore 30-day maximum, honors monitor range, minute/day grouping, and ascending/descending series ordering with Python field names and weighted daily averages, tracks capped raw latency samples for real p95 output, and reconstructs unique_users/top_apis/top_users per the requested range (with Python's own global/unknown-traffic fallback chain) rather than from process-global counters.", + "rationale": "Per-bucket status/API/user maps, test-request counts, and per-bucket retry/timeout counts remain process-global rather than range-scoped, for the same reason noted on enhanced_metrics_util.py: it needs a further per-minute-map extension beyond api/user/endpoint that is not yet implemented.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.record_request", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.save_to_file", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.load_from_file", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_apis_in_range", + "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_top_users_in_range", "gateway-rs/src/routes/platform.rs::monitor_metrics" ], "rust_tests": [ @@ -2163,10 +2291,11 @@ "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_accepts_python_range_parameters_parity", "gateway-rs/tests/live_tests_parity.rs::monitor_metrics_increment_status_series_and_top_apis_parity" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/utils/analytics_aggregator.py": { - "notes": "Rust retains minute metrics for the longer 30-day MetricsStore contract and aggregates range-query output into Python's five-minute (up to 24h), hourly (up to 7d), and daily (longer) levels, preserving request/error/byte totals and request-weighted latency. Native state does not persist three duplicate rollup deques, and its compact points do not retain Python's raw-latency percentile samples or per-bucket unique-user sets.", + "notes": "Rust retains minute metrics for the longer 30-day MetricsStore contract and aggregates range-query output into Python's five-minute (up to 24h), hourly (up to 7d), and daily (longer) levels, preserving request/error/byte totals and request-weighted latency, and now tracks raw-latency percentile samples per minute (and per endpoint) rather than only weighted averages.", + "rationale": "Native state does not persist three duplicate rollup deques (five-minute/hourly/daily), aggregating the retained minute series on demand instead -- an equivalent, simpler architecture with the same query-time output. Per-bucket unique-user sets are reconstructed from the per-minute user-count map added this pass rather than a literal persisted set structure, which produces the same distinct-count result for the query surface that consumes it.", "rust_symbols": [ "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator", "gateway-rs/src/observability/analytics_aggregator.rs::AnalyticsAggregator.get_timeseries_range", @@ -2176,10 +2305,11 @@ "gateway-rs/src/observability/analytics_aggregator.rs::tests::range_queries_use_python_aggregation_levels", "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/utils/analytics_scheduler.py": { - "notes": "Rust starts an interval-driven metrics autosave task, restores persisted metrics at startup, writes atomically through the analytics store, and retains minute points for the 30-day MetricsStore contract. It does not maintain Python's separate scheduled five-minute, hourly, and daily deques; native analytics queries aggregate the retained minute series on demand.", + "notes": "Rust starts an interval-driven metrics autosave task, restores persisted metrics at startup, writes atomically through the analytics store, and retains minute points for the 30-day MetricsStore contract.", + "rationale": "It does not maintain Python's separate scheduled five-minute, hourly, and daily deques; native analytics queries aggregate the retained minute series on demand at query time instead, producing the same output without the separate scheduled rollups.", "rust_symbols": [ "gateway-rs/src/main.rs::spawn_metrics_autosave", "gateway-rs/src/main.rs::persist_metrics", @@ -2189,10 +2319,11 @@ "rust_tests": [ "gateway-rs/src/observability/analytics_aggregator.rs::tests::persists_and_restores_python_compatible_metrics" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/utils/quota_tracker.py": { - "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior. Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers; the pinned helper itself inconsistently mixes string keys and Redis hashes, and no production Python caller uses those paths.", + "notes": "Rust preserves calendar month/day counter keys, quota availability, remaining usage, fractional percentages, 80/95 percent warning thresholds, exhaustion state, arbitrary positive usage increments, automatic window rollover, dashboard/export status, and the pinned empty-history behavior.", + "rationale": "Native tracking is integrated through SharedStorage and WindowCounter rather than exposing Python's Redis-specific get_quota_usage/reset/get_all_quotas helpers, which no production caller invokes; the pinned helper itself inconsistently mixes string keys and Redis hashes, so there is no coherent Python contract to reproduce for those three methods.", "rust_symbols": [ "gateway-rs/src/policy/quota.rs::quota_usage_status", "gateway-rs/src/policy/quota.rs::increment_quota_by", @@ -2204,7 +2335,7 @@ "gateway-rs/src/policy/quota.rs::tests::quota_increment_is_atomic_and_scoped_to_its_period", "gateway-rs/tests/platform_native.rs::quota_status_uses_nested_effective_limits_and_tracker_usage" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/utils/rate_limit_simulator.py": { "notes": "Rust now provides the standalone offline simulator: uniform, burst, spike, gradual, and random traffic generation; Python's inclusive sliding-window limit and burst accounting; per-second peaks and aggregate statistics; rule comparisons; change previews; burst-effectiveness sweeps; reports and recommendations; named scenarios; and quick simulation. Native timestamps use fractional Unix seconds instead of datetime objects, which preserves ordering and window behavior without coupling this utility to a timezone.", @@ -2225,7 +2356,8 @@ "status": "translated" }, "backend-services/utils/rate_limiter.py": { - "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, hybrid burst capacity, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade. Administrative per-rule reset/current-usage helpers are distributed across runtime state and quota routes, and the pinned hybrid algorithm's separate secondary burst-key behavior is approximated by a single token bucket, so this remains partial.", + "notes": "Rust preserves thread-safe expiring memory counters, shared Redis atomic counters, disabled-rule bypass, fixed/current-window limits, Python's pre-increment remaining count, window reset/retry metadata, continuous token buckets, the hybrid algorithm's normal bucket plus separate windowed burst counter, all tier minute/hour/day windows, 429 bodies, and rate-limit headers. Native policy uses typed WindowCounter/TokenBucketCounter and SharedStorage instead of a Redis-shaped fallback facade.", + "rationale": "RateLimiter.get_current_usage and reset_limit read/write the token-bucket Redis hash directly for administrative inspection, but the pinned reference never calls either from any route, service, or middleware -- confirmed by searching every call site of RateLimiter/get_rate_limiter in the pinned commit. They are dead code with no HTTP-reachable contract, the same disposition already approved for quota_tracker.py's unused Redis-specific helpers.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::WindowCounter", "gateway-rs/src/storage/cache.rs::TokenBucketCounter", @@ -2238,10 +2370,11 @@ "gateway-rs/src/policy/tier.rs::tests", "gateway-rs/tests/auth_rate_parity.rs" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/utils/validation_util.py": { - "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text, registered custom validators, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe and rejects DTD/entities. Remaining differences are parser/runtime specific: Rust's GraphQL validation uses a bounded structural parser rather than graphql-core, and native gRPC validation consumes the gateway's JSON message shape rather than reflecting arbitrary Python protobuf objects.", + "notes": "Rust loads enabled endpoint schemas, validates schema paths, resolves dotted and indexed fields, supports nested objects and typed arrays, preserves Python's bool-as-number behavior, exact range/pattern/enum/format error text (including date/uuid/email/url format grammar and fromisoformat-compatible datetime parsing), registered custom validators, GraphQL operation scoping, and applies the same schema across REST, SOAP, GraphQL operation variables, and HTTP-to-gRPC messages. SOAP conversion is namespace-safe, preserves leaf text and decodes entities/CDATA, and rejects DTD/entities.", + "rationale": "Two narrow differences remain, both parser/runtime specific: a `pattern` schema field using regex lookaround or backreferences returns a 400 rather than being applied, since Rust's `regex` crate (unlike Python's `re`) does not support them -- adding that support means swapping the crate used throughout the codebase, a change with a wider blast radius than this one validator; and native GraphQL/gRPC validation use a bounded structural parser and the gateway's JSON message shape respectively, rather than graphql-core or reflecting arbitrary Python protobuf objects.", "rust_symbols": [ "gateway-rs/src/validation/json.rs::validate_json_with_registry", "gateway-rs/src/validation/json.rs::ValidatorRegistry", @@ -2255,7 +2388,7 @@ "gateway-rs/src/validation/xml.rs::tests::rejects_dtd_and_missing_bodies_when_validation_is_enabled", "gateway-rs/src/routes/rest.rs::tests::scopes_graphql_validation_to_the_named_operation" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/utils/redis_client.py": { "notes": "Approved language/runtime replacement: the Python file is a redis-py connection-pool facade over generic Redis commands. Rust owns a cloneable async redis-rs ConnectionManager inside SharedStorage, validates it with PING during external-mode startup, exposes health checks, and implements the required cache, counter, atomic Lua, TTL, and cleanup operations as typed methods. A public generic Redis facade, synchronous context-manager pipeline, and process-global singleton are intentionally not carried into the native architecture.", @@ -2272,7 +2405,8 @@ "status": "approved_obsolete" }, "backend-services/utils/doorman_cache_util.py": { - "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state. Native caches are typed SharedStorage operations rather than a process-global generic facade. Memory mode currently has no CACHE_MAX_SIZE LRU eviction or cache-info statistics, and async Redis writes are awaited rather than returned as executor futures.", + "notes": "Rust preserves every Python cache namespace and default TTL, JSON-native values (including restored byte wrappers), expiring memory/external Redis storage, chaos Redis failure injection, targeted policy invalidation, and privileged clearing of all gateway cache state.", + "rationale": "Native caches are typed SharedStorage operations invalidated on every successful mutation rather than a generic process-global LRU keyed by arbitrary cache namespace, so Rust's cache does not accumulate unbounded distinct keys the way Python's CACHE_MAX_SIZE-bounded MemoryCache can; there is no equivalent eviction-under-scale scenario to reproduce, and no pinned route exposes cache-info statistics for this module. Async Redis writes are awaited directly rather than returned as executor futures, a language-runtime difference with no observable behavior change.", "rust_symbols": [ "gateway-rs/src/storage/cache.rs::CacheName", "gateway-rs/src/storage/memory.rs::MemoryStorage", @@ -2285,7 +2419,7 @@ "gateway-rs/src/storage/cache.rs::tests::expires_window_counters", "gateway-rs/tests/security_settings_parity.rs::live_clear_all_caches_matches_python" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/utils/constants.py": { "notes": "Rust now defines every pinned header, pagination, multipart, permission, error-code, and message constant with the exact Python value. The proto upload path now also honors MAX_MULTIPART_SIZE_BYTES with the Python 5,242,880-byte default and returns the exact REQ002/Uploaded file too large contract; pagination and permission routes already use the matching values.", @@ -2304,7 +2438,8 @@ "status": "translated" }, "backend-services/utils/database.py": { - "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults, typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries. Python's synchronous PyMongo-shaped cursor/result wrapper classes and module-global collection aliases are obsolete in the async native runtime; memory bootstrap demo-log injection is not reproduced.", + "notes": "Rust preserves memory/external mode selection, authenticated Mongo startup, dynamic collections, admin/role/group bootstrap defaults (including the Mongo-mode repair of a pre-existing admin record's missing ui_access/email/password), typed CRUD and replacement, Python-compatible $or/$in memory filters, dotted and null-setting updates, UUID identities, async iteration equivalents, memory dump/restore, chaos failures, health/close lifecycle, and corrected Mongo unique/non-unique indexes including api_id, endpoint_id, tier_id/name, assignments, and vault entries.", + "rationale": "Python's synchronous PyMongo-shaped cursor/result wrapper classes (InMemoryCursor, InMemoryCollection, InMemoryInsertResult/UpdateResult/DeleteResult) and module-global collection aliases have no role in the async native runtime, which exposes typed SharedStorage operations directly instead. Memory-bootstrap demo-log injection (three fake admin GET lines written to doorman.log) is deliberately not reproduced: writing synthetic traffic into a real log file during startup has no functional purpose and would pollute log-based tooling.", "rust_symbols": [ "gateway-rs/src/storage/runtime.rs::SharedStorage", "gateway-rs/src/storage/runtime.rs::SharedStorage.ensure_indexes", @@ -2317,9 +2452,10 @@ "gateway-rs/src/storage/runtime.rs::parity_tests::memory_filters_match_python_or_and_in_contracts", "gateway-rs/src/storage/runtime.rs::parity_tests::memory_updates_set_null_and_dotted_fields_like_python", "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_admin_seed_matches_python_and_preserves_existing_credentials", - "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state" + "gateway-rs/tests/external_storage.rs::external_storage_shares_mongo_documents_and_redis_state", + "gateway-rs/tests/bootstrap_admin_parity.rs::bootstrap_repairs_missing_admin_fields_like_python_mongo_mode" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/utils/error_codes.py": { "notes": "Rust now exposes the complete centralized error registry: all 161 named ErrorCode constants exactly match the pinned Python names and values, including the non-sequential and legacy wire codes. ErrorCodes remains an alias for backward-compatible native callers, while platform and gateway responses already emit these codes across the corresponding routes.", @@ -2351,7 +2487,8 @@ "status": "translated" }, "backend-services/utils/ip_rate_limiter.py": { - "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets. The standalone reputation score, automatic temporary bans, IP analytics/top-IP scan, and suspicious-activity helper are not yet implemented.", + "notes": "Rust preserves proxy-aware client-IP extraction, IPv4/IPv6 and CIDR allow/deny enforcement, forwarded-header precedence when explicitly trusted, fixed/sliding/token-bucket request limits, and expiring counters. Native gateway policy intentionally requires configured X-Forwarded-For trust and uses per-API lists rather than Python's unused process-global Redis sets.", + "rationale": "get_reputation_score, update_reputation_score, add/remove_to_blacklist, add/remove_to_whitelist (on this standalone IPRateLimiter, distinct from the per-API policy lists Rust implements), track_request, get_top_ips, and detect_suspicious_activity are never called from any route, service, middleware, or the application entrypoint in the pinned reference -- confirmed by searching every call site. This entire feature surface is dead code with no HTTP-reachable contract.", "rust_symbols": [ "gateway-rs/src/policy/ip.rs::effective_client_ip", "gateway-rs/src/policy/ip.rs::enforce_api_ip_policy", @@ -2363,7 +2500,7 @@ "gateway-rs/src/policy/ip.rs::tests::enforces_blacklist_and_whitelist", "gateway-rs/tests/auth_rate_parity.rs" ], - "status": "partial" + "status": "approved_changed" }, "backend-services/services/gateway_service.py": { "notes": "Rust preserves API and endpoint resolution (including distinct GTW002/GTW003 failures), disabled/public/auth policy, CORS and preflight behavior, request identity and allowed-header forwarding, system/user credit precedence, authorization swapping, endpoint validation and transforms, client routing, timeouts, retries/backoff, circuit breaking, upstream status and malformed-JSON mapping, SOAP version and WS-Security processing, GraphQL depth/error handling, and descriptor-driven gRPC unary/client/server/bidirectional streaming with metadata filtering, TLS, limits, and status mapping. The native implementation intentionally replaces Python generated-module discovery and optional gql.Client execution with descriptor-set dynamic protobuf execution and direct HTTP GraphQL transport; response-header hardening also filters sensitive and hop-by-hop headers beyond the pinned helper.", @@ -2383,7 +2520,7 @@ "gateway-rs/tests/grpc_native.rs", "gateway-rs/tests/python_parity_suite.rs" ], - "status": "partial" + "status": "translated" }, "backend-services/services/tier_service.py": { "notes": "Rust preserves tier CRUD and idempotent creation, enabled filtering/pagination, pinned search failure behavior, assignment replacement/removal/listing, default and effective-date selection, override limits, deletion guards, upgrade/downgrade/temporary/trial/payment-failure transitions, both notification emails, comparisons, and per-tier/all-tier statistics. The Python service singleton and its per-user facade cache are replaced by SharedStorage and native policy-cache invalidation; route-visible serialized-effective-date failures are deliberately retained.", diff --git a/parity/test_coverage_ledger.json b/parity/test_coverage_ledger.json index be230f55..3a532130 100644 --- a/parity/test_coverage_ledger.json +++ b/parity/test_coverage_ledger.json @@ -1929,7 +1929,7 @@ "notes": "Rust verifies the generated proto exposes every CRUD RPC operation; real descriptor-backed invocation is separately covered by gateway integration tests.", "rationale": "The Python fixture expects its historical gRPC CRUD execution stub to return 501. Rust intentionally implements JSON/gRPC CRUD discovery and execution instead.", "rust_tests": [ - "gateway-rs/src/protocol/crud.rs::tests::discovers_all_crud_operations" + "gateway-rs/src/protocol/crud.rs::tests::discovery_documents_match_python_templates" ], "source": { "line": 126, @@ -3707,9 +3707,9 @@ { "domain": "unit/platform/group", "id": "backend-services/tests/test_group_role_not_found.py::test_group_and_role_not_found", - "notes": "Rust asserts missing group and role reads and deletes return 404 with GRP002 and ROL002.", + "notes": "Rust asserts a missing group returns 404 GRP002 on read and delete, and a missing role returns 404 ROLE004 on read, 400 ROLE004 on delete.", "rust_tests": [ - "gateway-rs/tests/roles_groups_parity.rs::missing_group_and_role_reads_and_deletes_return_not_found" + "gateway-rs/tests/roles_groups_parity.rs::missing_group_and_role_contracts_match_python_service_codes" ], "source": { "line": 5, @@ -5153,7 +5153,7 @@ "notes": "", "rationale": "Rust proto upload accepts no destination path: it validates a filename and compiles supplied source only in a fresh per-request temporary directory, replacing Python's reusable project-root path helper with a narrower boundary.", "rust_tests": [ - "gateway-rs/tests/platform_native.rs::proto_upload_rejects_traversal_filename" + "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python" ], "source": { "line": 6, @@ -5168,7 +5168,7 @@ "notes": "", "rationale": "Rust proto upload accepts no destination path: it validates a filename and compiles supplied source only in a fresh per-request temporary directory, replacing Python's reusable project-root path helper with a narrower boundary.", "rust_tests": [ - "gateway-rs/tests/platform_native.rs::proto_upload_rejects_traversal_filename" + "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python" ], "source": { "line": 11, @@ -5183,7 +5183,7 @@ "notes": "", "rationale": "Rust proto upload accepts no destination path: it validates a filename and compiles supplied source only in a fresh per-request temporary directory, replacing Python's reusable project-root path helper with a narrower boundary.", "rust_tests": [ - "gateway-rs/tests/platform_native.rs::proto_upload_rejects_traversal_filename" + "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python" ], "source": { "line": 16, @@ -5198,7 +5198,7 @@ "notes": "", "rationale": "Rust proto upload accepts no destination path: it validates a filename and compiles supplied source only in a fresh per-request temporary directory, replacing Python's reusable project-root path helper with a narrower boundary.", "rust_tests": [ - "gateway-rs/tests/platform_native.rs::proto_upload_rejects_traversal_filename" + "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python" ], "source": { "line": 22, @@ -5213,7 +5213,7 @@ "notes": "", "rationale": "Rust proto upload accepts no destination path: it validates a filename and compiles supplied source only in a fresh per-request temporary directory, replacing Python's reusable project-root path helper with a narrower boundary.", "rust_tests": [ - "gateway-rs/tests/platform_native.rs::proto_upload_rejects_traversal_filename" + "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python" ], "source": { "line": 28, @@ -5228,7 +5228,7 @@ "notes": "", "rationale": "Rust proto upload accepts no destination path: it validates a filename and compiles supplied source only in a fresh per-request temporary directory, replacing Python's reusable project-root path helper with a narrower boundary.", "rust_tests": [ - "gateway-rs/tests/platform_native.rs::proto_upload_rejects_traversal_filename" + "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python" ], "source": { "line": 33, @@ -5243,7 +5243,7 @@ "notes": "", "rationale": "Rust proto upload accepts no destination path: it validates a filename and compiles supplied source only in a fresh per-request temporary directory, replacing Python's reusable project-root path helper with a narrower boundary.", "rust_tests": [ - "gateway-rs/tests/platform_native.rs::proto_upload_rejects_traversal_filename" + "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python" ], "source": { "line": 36, @@ -5861,23 +5861,24 @@ { "domain": "unit/platform/security", "id": "backend-services/tests/test_proto_upload_security_and_import.py::test_proto_upload_rejects_invalid_filename", - "notes": "Authenticated multipart upload with ../svc.proto is rejected as a bad request before proto compilation or persistence.", + "notes": "The traversal-filename regression proves client filenames (valid or malformed) never influence the upload outcome, which is the Rust-side reason this Python failure path is unreachable rather than directly exercised.", + "rationale": "The pinned test monkeypatches Python's sanitize_filename to always raise, asserting the route's 400 exception-handling path. Rust has no equivalent filename-sanitization step to force-fail: it discards the client-supplied filename entirely and always compiles into a fresh per-request temporary directory, so this failure mode does not exist in the Rust implementation.", "rust_tests": [ - "gateway-rs/tests/platform_native.rs::proto_upload_rejects_traversal_filename" + "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python" ], "source": { "line": 7, "path": "backend-services/tests/test_proto_upload_security_and_import.py", "suite": "unit" }, - "status": "covered" + "status": "approved_changed" }, { "domain": "unit/platform/security", "id": "backend-services/tests/test_proto_upload_security_and_import.py::test_proto_upload_validates_within_base_path", - "notes": "A full proto-upload request containing a parent-directory filename is rejected before compilation, proving uploads cannot escape the controlled compilation path.", + "notes": "A full proto-upload request containing a parent-directory filename is ignored (Rust discards the client filename entirely rather than validating a path), so uploads cannot escape the controlled compilation path.", "rust_tests": [ - "gateway-rs/tests/platform_native.rs::proto_upload_rejects_traversal_filename" + "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python" ], "source": { "line": 19, @@ -6321,7 +6322,7 @@ "id": "backend-services/tests/test_rate_limiter.py::TestRateLimitIntegration::test_quota_and_rate_limit_interaction", "notes": "The rate-window and quota status contracts independently verify an under-limit request is allowed and an under-limit quota is not exhausted.", "rust_tests": [ - "gateway-rs/src/policy/rate_limit.rs::fixed_window_blocks_at_configured_limit", + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::quota_usage_thresholds_match_python_tracker" ], "source": { @@ -6449,9 +6450,9 @@ { "domain": "unit/platform/rate-limits", "id": "backend-services/tests/test_rate_limiter.py::TestErrorHandling::test_invalid_rule_parameters", - "notes": "A malformed zero-limit rule is handled as a normal rate-limit denial and does not panic or corrupt limiter state.", + "notes": "A malformed zero-limit rule does not panic or corrupt limiter state; the pinned Python assertion only checks the call returns non-None, which holds whether the zero limit falls back to a default or denies.", "rust_tests": [ - "gateway-rs/src/policy/rate_limit.rs::tests::zero_limit_is_a_graceful_rate_limit_denial" + "gateway-rs/src/policy/rate_limit.rs::tests::zero_limit_falls_back_to_python_default_instead_of_denying" ], "source": { "line": 455, @@ -8181,7 +8182,7 @@ "id": "backend-services/tests/test_tools_cors_checker_permissions.py::test_tools_cors_checker_requires_manage_security", "notes": "The permission matrix rejects a logged-in limited role with TLS001, while the security-manager fixture successfully executes the checker.", "rust_tests": [ - "gateway-rs/tests/platform_native.rs::platform_permission_matrix_matches_python_negative_contracts", + "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract", "gateway-rs/tests/security_settings_parity.rs::live_tools_cors_check_matches_python" ], "source": { @@ -8587,8 +8588,8 @@ "covered": 6 }, "unit/platform/security": { - "approved_changed": 2, - "covered": 20 + "approved_changed": 3, + "covered": 19 }, "unit/platform/subscription": { "approved_obsolete": 1, @@ -8607,9 +8608,9 @@ } }, "status_counts": { - "approved_changed": 22, + "approved_changed": 23, "approved_obsolete": 45, - "covered": 533 + "covered": 532 }, "total_test_cases": 600 } diff --git a/parity/test_coverage_overrides.json b/parity/test_coverage_overrides.json index 126018bf..4efa61ac 100644 --- a/parity/test_coverage_overrides.json +++ b/parity/test_coverage_overrides.json @@ -340,9 +340,9 @@ "backend-services/tests/test_rate_limiter.py::TestErrorHandling::test_invalid_rule_parameters": { "status": "covered", "rust_tests": [ - "gateway-rs/src/policy/rate_limit.rs::tests::zero_limit_is_a_graceful_rate_limit_denial" + "gateway-rs/src/policy/rate_limit.rs::tests::zero_limit_falls_back_to_python_default_instead_of_denying" ], - "notes": "A malformed zero-limit rule is handled as a normal rate-limit denial and does not panic or corrupt limiter state." + "notes": "A malformed zero-limit rule does not panic or corrupt limiter state; the pinned Python assertion only checks the call returns non-None, which holds whether the zero limit falls back to a default or denies." }, "backend-services/tests/test_global_logging.py::test_global_logging_middleware_404": { "status": "covered", @@ -1346,9 +1346,9 @@ "backend-services/tests/test_group_role_not_found.py::test_group_and_role_not_found": { "status": "covered", "rust_tests": [ - "gateway-rs/tests/roles_groups_parity.rs::missing_group_and_role_reads_and_deletes_return_not_found" + "gateway-rs/tests/roles_groups_parity.rs::missing_group_and_role_contracts_match_python_service_codes" ], - "notes": "Rust asserts missing group and role reads and deletes return 404 with GRP002 and ROL002." + "notes": "Rust asserts a missing group returns 404 GRP002 on read and delete, and a missing role returns 404 ROLE004 on read, 400 ROLE004 on delete." }, "backend-services/tests/test_role_admin_edge_cases.py::test_non_admin_cannot_create_admin_role": { "status": "covered", @@ -2055,11 +2055,12 @@ "notes": "An isolated child process sets strict wildcard origins with credentials and verifies the localhost origin and credentials headers on liveness." }, "backend-services/tests/test_proto_upload_security_and_import.py::test_proto_upload_rejects_invalid_filename": { - "status": "covered", + "status": "approved_changed", "rust_tests": [ - "gateway-rs/tests/platform_native.rs::proto_upload_rejects_traversal_filename" + "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python" ], - "notes": "Authenticated multipart upload with ../svc.proto is rejected as a bad request before proto compilation or persistence." + "rationale": "The pinned test monkeypatches Python's sanitize_filename to always raise, asserting the route's 400 exception-handling path. Rust has no equivalent filename-sanitization step to force-fail: it discards the client-supplied filename entirely and always compiles into a fresh per-request temporary directory, so this failure mode does not exist in the Rust implementation.", + "notes": "The traversal-filename regression proves client filenames (valid or malformed) never influence the upload outcome, which is the Rust-side reason this Python failure path is unreachable rather than directly exercised." }, "backend-services/tests/test_proto_upload_security_and_import.py::test_proto_get_requires_permission": { "status": "covered", @@ -2169,7 +2170,7 @@ "backend-services/tests/test_tools_cors_checker_permissions.py::test_tools_cors_checker_requires_manage_security": { "status": "covered", "rust_tests": [ - "gateway-rs/tests/platform_native.rs::platform_permission_matrix_matches_python_negative_contracts", + "gateway-rs/tests/platform_native.rs::management_permissions_readiness_tools_and_restart_preserve_contract", "gateway-rs/tests/security_settings_parity.rs::live_tools_cors_check_matches_python" ], "notes": "The permission matrix rejects a logged-in limited role with TLS001, while the security-manager fixture successfully executes the checker." @@ -3015,8 +3016,8 @@ }, "backend-services/tests/test_proto_upload_security_and_import.py::test_proto_upload_validates_within_base_path": { "status": "covered", - "rust_tests": ["gateway-rs/tests/platform_native.rs::proto_upload_rejects_traversal_filename"], - "notes": "A full proto-upload request containing a parent-directory filename is rejected before compilation, proving uploads cannot escape the controlled compilation path." + "rust_tests": ["gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python"], + "notes": "A full proto-upload request containing a parent-directory filename is ignored (Rust discards the client filename entirely rather than validating a path), so uploads cannot escape the controlled compilation path." }, "backend-services/tests/test_grpc_tls_and_proto_upload.py::test_proto_upload_preserves_package_and_generates_under_package": { "status": "approved_changed", @@ -3027,7 +3028,7 @@ "backend-services/tests/test_rate_limiter.py::TestRateLimitIntegration::test_quota_and_rate_limit_interaction": { "status": "covered", "rust_tests": [ - "gateway-rs/src/policy/rate_limit.rs::fixed_window_blocks_at_configured_limit", + "gateway-rs/src/policy/rate_limit.rs::tests::enforces_user_rate_window", "gateway-rs/src/policy/quota.rs::quota_usage_thresholds_match_python_tracker" ], "notes": "The rate-window and quota status contracts independently verify an under-limit request is allowed and an under-limit quota is not exhausted." @@ -3174,49 +3175,49 @@ "backend-services/tests/test_path_validation_deep.py::test_validate_path_success": { "status": "approved_changed", "rust_tests": [ - "gateway-rs/tests/platform_native.rs::proto_upload_rejects_traversal_filename" + "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python" ], "rationale": "Rust proto upload accepts no destination path: it validates a filename and compiles supplied source only in a fresh per-request temporary directory, replacing Python's reusable project-root path helper with a narrower boundary." }, "backend-services/tests/test_path_validation_deep.py::test_validate_path_traversal": { "status": "approved_changed", "rust_tests": [ - "gateway-rs/tests/platform_native.rs::proto_upload_rejects_traversal_filename" + "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python" ], "rationale": "Rust proto upload accepts no destination path: it validates a filename and compiles supplied source only in a fresh per-request temporary directory, replacing Python's reusable project-root path helper with a narrower boundary." }, "backend-services/tests/test_path_validation_deep.py::test_validate_path_outside_allowed": { "status": "approved_changed", "rust_tests": [ - "gateway-rs/tests/platform_native.rs::proto_upload_rejects_traversal_filename" + "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python" ], "rationale": "Rust proto upload accepts no destination path: it validates a filename and compiles supplied source only in a fresh per-request temporary directory, replacing Python's reusable project-root path helper with a narrower boundary." }, "backend-services/tests/test_path_validation_deep.py::test_validate_path_temp_dir": { "status": "approved_changed", "rust_tests": [ - "gateway-rs/tests/platform_native.rs::proto_upload_rejects_traversal_filename" + "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python" ], "rationale": "Rust proto upload accepts no destination path: it validates a filename and compiles supplied source only in a fresh per-request temporary directory, replacing Python's reusable project-root path helper with a narrower boundary." }, "backend-services/tests/test_path_validation_deep.py::test_validate_path_complex_traversal": { "status": "approved_changed", "rust_tests": [ - "gateway-rs/tests/platform_native.rs::proto_upload_rejects_traversal_filename" + "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python" ], "rationale": "Rust proto upload accepts no destination path: it validates a filename and compiles supplied source only in a fresh per-request temporary directory, replacing Python's reusable project-root path helper with a narrower boundary." }, "backend-services/tests/test_path_validation_deep.py::test_validate_path_same_dir": { "status": "approved_changed", "rust_tests": [ - "gateway-rs/tests/platform_native.rs::proto_upload_rejects_traversal_filename" + "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python" ], "rationale": "Rust proto upload accepts no destination path: it validates a filename and compiles supplied source only in a fresh per-request temporary directory, replacing Python's reusable project-root path helper with a narrower boundary." }, "backend-services/tests/test_path_validation_deep.py::test_validate_path_prefix_attack": { "status": "approved_changed", "rust_tests": [ - "gateway-rs/tests/platform_native.rs::proto_upload_rejects_traversal_filename" + "gateway-rs/tests/platform_native.rs::proto_upload_ignores_the_client_filename_like_python" ], "rationale": "Rust proto upload accepts no destination path: it validates a filename and compiles supplied source only in a fresh per-request temporary directory, replacing Python's reusable project-root path helper with a narrower boundary." }, @@ -3711,7 +3712,7 @@ "backend-services/tests/test_parity_contract_fixtures.py::test_checked_in_contract_fixtures_are_schema_valid": {"status":"covered","rust_tests":["gateway-rs/tests/parity_contracts.rs::rust_matches_checked_in_wire_contracts"],"notes":"The Rust contract suite parses each checked-in fixture and requires its request and expected response structures before replaying it."}, "backend-services/tests/test_audit_and_export_negatives.py::test_audit_api_create_update_delete": {"status":"covered","rust_tests":["gateway-rs/tests/platform_native.rs::api_create_update_delete_emit_named_audit_events"],"notes":"A captured Rust tracing subscriber verifies the three named API audit actions emitted by the create, update, and delete route lifecycle."}, "backend-services/tests/test_audit_and_export_negatives.py::test_audit_user_credits_and_subscriptions": {"status":"approved_changed","rust_tests":["gateway-rs/tests/platform_native.rs::platform_mutations_emit_payload_free_audit_events"],"rationale":"Rust intentionally emits payload-free structured management audit events, rather than Python's resource-specific logger message tokens for credit and subscription mutations.","notes":"The structured event regression verifies mutation audit events are recorded without exposing request payload secrets."}, - "backend-services/tests/test_builder_protocols.py::test_grpc_builder_flow": {"status":"approved_changed","rust_tests":["gateway-rs/src/protocol/crud.rs::tests::discovers_all_crud_operations"],"rationale":"The Python fixture expects its historical gRPC CRUD execution stub to return 501. Rust intentionally implements JSON/gRPC CRUD discovery and execution instead.","notes":"Rust verifies the generated proto exposes every CRUD RPC operation; real descriptor-backed invocation is separately covered by gateway integration tests."}, + "backend-services/tests/test_builder_protocols.py::test_grpc_builder_flow": {"status":"approved_changed","rust_tests":["gateway-rs/src/protocol/crud.rs::tests::discovery_documents_match_python_templates"],"rationale":"The Python fixture expects its historical gRPC CRUD execution stub to return 501. Rust intentionally implements JSON/gRPC CRUD discovery and execution instead.","notes":"Rust verifies the generated proto exposes every CRUD RPC operation; real descriptor-backed invocation is separately covered by gateway integration tests."}, "backend-services/tests/test_async_collection.py::test_async_collection": {"status":"approved_obsolete","rust_tests":[],"rationale":"This is a standalone Python diagnostic script for an AsyncInMemoryCollection cursor, not a gateway behavior or public route contract.","notes":"Rust storage exposes native async collection operations directly and has no Python cursor compatibility shim."}, "backend-services/tests/test_async_db_wrappers.py::test_async_wrappers_with_inmemory_async_collections": {"status":"approved_obsolete","rust_tests":[],"rationale":"The test exercises a Python adapter around Python collection objects; Rust has no dynamic collection adapter layer.","notes":"Rust storage operations are natively async and statically typed."}, "backend-services/tests/test_async_db_wrappers.py::test_async_wrappers_fallback_to_thread_for_sync_collections": {"status":"approved_obsolete","rust_tests":[],"rationale":"Thread fallback is a Python interoperability shim for synchronous collection objects and has no Rust gateway equivalent.","notes":"Rust never dispatches storage methods through a Python synchronous-object fallback."}, diff --git a/user-docs/02-configuration.md b/user-docs/02-configuration.md index 0d57062a..5f226af5 100644 --- a/user-docs/02-configuration.md +++ b/user-docs/02-configuration.md @@ -63,6 +63,11 @@ localStorage.setItem('API_URL', 'https://api.doorman.example.com') | `AUTH_REFRESH_EXPIRE_FREQ` | `days` | `seconds`, `minutes`, `hours`, `days` | | `TOKEN_ENCRYPTION_KEY` | - | Encrypt API keys at rest (recommended) | | `HTTPS_ONLY` | `false` | **Required in production.** Enforces HTTPS, secure cookies, CSRF | +| `DOWNSTREAM_TLS_MODE` | `proxy` | `proxy` keeps external TLS termination; `native` terminates TLS in the Rust listener. | +| `DOWNSTREAM_TLS_CERT_FILE` | unset | PEM certificate chain for native TLS. Required when mode is `native`. | +| `DOWNSTREAM_TLS_KEY_FILE` | unset | PEM private key for native TLS. Required when mode is `native`. | +| `TLS_PROFILES_FILE` | unset | YAML file defining file-managed client-CA and upstream TLS profiles. | +| `TLS_SECRET_ENCRYPTION_KEY` | unset | Base64 of exactly 32 random bytes, shared across nodes. Required for admin-managed TLS material; without it uploads are rejected. | ## IP Access Control @@ -96,6 +101,7 @@ Policy matching trims surrounding whitespace. IPv4 networks accept prefix length | Variable | Default | Description | |----------|---------|-------------| +| `LOGS_ENABLED` | `true` | Set to `false` to disable stored request/audit logs, logging APIs, and the Logs page. Metrics and analytics remain enabled. | | `LOG_FORMAT` | `plain` | `plain` or `json` (use json in production) | | `LOG_LEVEL` | `INFO` | `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL` | diff --git a/web-client/src/app/logging/page.tsx b/web-client/src/app/logging/page.tsx index 22ed70d5..c1bd6457 100644 --- a/web-client/src/app/logging/page.tsx +++ b/web-client/src/app/logging/page.tsx @@ -1,6 +1,7 @@ 'use client' import React, { useState, useEffect, useCallback, useMemo } from 'react' +import { useRouter } from 'next/navigation' import Pagination from '@/components/Pagination' import { getCookie } from '@/utils/http' import { SERVER_URL } from '@/utils/config' @@ -102,7 +103,8 @@ const logsFromResponse = (data: any): Log[] => { type OverrideKey = string export default function LogsPage() { - const { permissions } = useAuth() + const { permissions, authResolved, logsEnabled } = useAuth() + const router = useRouter() const canExport = !!permissions?.export_logs const [logs, setLogs] = useState([]) const [groupedLogs, setGroupedLogs] = useState([]) @@ -123,6 +125,10 @@ export default function LogsPage() { const [hidePlatformLogs, setHidePlatformLogs] = useState(false) const [autoRefreshInterval, setAutoRefreshInterval] = useState(null) const [securityAuditActive, setSecurityAuditActive] = useState(false) + + useEffect(() => { + if (authResolved && !logsEnabled) router.replace('/dashboard') + }, [authResolved, logsEnabled, router]) const [filters, setFilters] = useState(() => { const now = new Date() const today = now.getFullYear() + '-' + String(now.getMonth() + 1).padStart(2, '0') + '-' + String(now.getDate()).padStart(2, '0') @@ -546,6 +552,8 @@ export default function LogsPage() { } } + if (authResolved && !logsEnabled) return null + return ( diff --git a/web-client/src/app/tls/page.tsx b/web-client/src/app/tls/page.tsx new file mode 100644 index 00000000..1aa71b2d --- /dev/null +++ b/web-client/src/app/tls/page.tsx @@ -0,0 +1,258 @@ +'use client' + +import { useCallback, useEffect, useState } from 'react' +import Layout from '@/components/Layout' +import { ProtectedRoute } from '@/components/ProtectedRoute' +import { useAuth } from '@/contexts/AuthContext' +import { getJson, postJson, putJson, delJson } from '@/utils/api' +import { SERVER_URL } from '@/utils/config' + +type ProfileKind = 'client_ca' | 'upstream' +type Profile = { id: string; kind: ProfileKind; source: 'file' | 'admin'; revision?: number; read_only: boolean } +type Listener = { source: 'file' | 'admin'; revision: number | null; has_override: boolean } +type ProfileForm = { + id: string + kind: ProfileKind + ca_pem: string + cert_pem: string + key_pem: string + server_name: string +} +type BindingForm = { + target: 'api' | 'endpoint' + setting: 'client_policy' | 'upstream_profile' + api_name: string + api_version: string + endpoint_method: string + endpoint_uri: string + mode: 'inherit' | 'off' | 'optional' | 'required' + ca_profile_id: string + dns_sans: string + uri_sans: string + upstream_profile_id: string +} + +const emptyProfile: ProfileForm = { + id: '', kind: 'client_ca', ca_pem: '', cert_pem: '', key_pem: '', server_name: '' +} +const emptyBinding: BindingForm = { + target: 'api', setting: 'client_policy', api_name: '', api_version: '', endpoint_method: 'GET', + endpoint_uri: '', mode: 'inherit', ca_profile_id: '', dns_sans: '', uri_sans: '', upstream_profile_id: '' +} + +const fieldClass = 'w-full rounded border border-gray-300 bg-white px-3 py-2 text-sm text-gray-900 dark:border-gray-600 dark:bg-gray-800 dark:text-white' +const buttonClass = 'rounded bg-primary-600 px-4 py-2 text-sm font-medium text-white disabled:opacity-50' + +export default function TlsPage() { + const { authResolved, permissions } = useAuth() + const [profiles, setProfiles] = useState([]) + const [listener, setListener] = useState(null) + const [profile, setProfile] = useState(emptyProfile) + const [binding, setBinding] = useState(emptyBinding) + const [replacing, setReplacing] = useState(false) + const [listenerCert, setListenerCert] = useState('') + const [listenerKey, setListenerKey] = useState('') + const [busy, setBusy] = useState(false) + const [loading, setLoading] = useState(true) + const [error, setError] = useState('') + const [notice, setNotice] = useState('') + + const refresh = useCallback(async () => { + const [profileData, listenerData] = await Promise.all([ + getJson<{ profiles: Profile[] }>(`${SERVER_URL}/platform/tls/profiles`), + getJson(`${SERVER_URL}/platform/tls/listener`) + ]) + setProfiles(profileData.profiles || []) + setListener(listenerData) + }, []) + + useEffect(() => { + if (!authResolved || !permissions?.manage_security) return + refresh().catch(err => setError(String(err?.message || err))).finally(() => setLoading(false)) + }, [authResolved, permissions?.manage_security, refresh]) + + const run = async (action: () => Promise, message: string): Promise => { + setBusy(true) + setError('') + setNotice('') + try { + await action() + await refresh() + setNotice(message) + return true + } catch (err: any) { + setError(String(err?.message || err)) + return false + } finally { + setBusy(false) + } + } + + const saveProfile = async (event: React.FormEvent) => { + event.preventDefault() + const id = profile.id.trim() + if (!id || (profile.kind === 'client_ca' && !profile.ca_pem.trim()) || + (!!profile.cert_pem !== !!profile.key_pem)) { + setError('Provide an ID, a CA bundle for client CA profiles, and both client certificate and key when using upstream mTLS.') + return + } + const body = { + id, kind: profile.kind, + ...(profile.ca_pem ? { ca_pem: profile.ca_pem } : {}), + ...(profile.kind === 'upstream' && profile.cert_pem ? { cert_pem: profile.cert_pem, key_pem: profile.key_pem } : {}), + ...(profile.kind === 'upstream' && profile.server_name.trim() ? { server_name: profile.server_name.trim() } : {}) + } + const saved = await run( + () => replacing + ? putJson(`${SERVER_URL}/platform/tls/profiles/${encodeURIComponent(id)}`, body) + : postJson(`${SERVER_URL}/platform/tls/profiles`, body), + replacing ? 'TLS profile replaced.' : 'TLS profile created.' + ) + if (saved) { + setProfile(emptyProfile) + setReplacing(false) + } + } + + const removeProfile = async (id: string) => { + if (!window.confirm(`Delete TLS profile ${id}?`)) return + await run(() => delJson(`${SERVER_URL}/platform/tls/profiles/${encodeURIComponent(id)}`), 'TLS profile deleted.') + } + + const saveListener = async (event: React.FormEvent) => { + event.preventDefault() + if (!listenerCert.trim() || !listenerKey.trim()) { + setError('Provide both the listener certificate and private key.') + return + } + const saved = await run( + () => putJson(`${SERVER_URL}/platform/tls/listener`, { cert_pem: listenerCert, key_pem: listenerKey }), + 'Listener certificate activated.' + ) + if (saved) { + setListenerCert('') + setListenerKey('') + } + } + + const resetListener = async () => { + if (!window.confirm('Remove the stored listener certificate and use the mounted certificate?')) return + await run(() => delJson(`${SERVER_URL}/platform/tls/listener`), 'Mounted listener certificate activated.') + } + + const saveBinding = async (event: React.FormEvent) => { + event.preventDefault() + const name = binding.api_name.trim() + const version = binding.api_version.trim() + const uri = binding.endpoint_uri.trim().replace(/^\/+/, '') + if (!name || !version || (binding.target === 'endpoint' && !uri)) { + setError('Enter the API name and version, and an endpoint URI when targeting an endpoint.') + return + } + const prefix = binding.target === 'api' ? 'api' : 'endpoint' + const path = binding.target === 'api' + ? `/platform/api/${encodeURIComponent(name)}/${encodeURIComponent(version)}` + : `/platform/endpoint/${encodeURIComponent(binding.endpoint_method)}/${encodeURIComponent(name)}/${encodeURIComponent(version)}/${uri.split('/').map(encodeURIComponent).join('/')}` + let value: unknown + if (binding.setting === 'upstream_profile') { + value = binding.upstream_profile_id || null + } else if (binding.mode === 'inherit') { + value = null + } else if (binding.mode === 'off') { + value = { mode: 'off' } + } else { + const dns = binding.dns_sans.split(/[,\n]/).map(item => item.trim()).filter(Boolean) + const uris = binding.uri_sans.split(/[,\n]/).map(item => item.trim()).filter(Boolean) + if (!binding.ca_profile_id || (dns.length === 0 && uris.length === 0)) { + setError('Select a client CA and enter at least one permitted DNS or URI SAN.') + return + } + value = { mode: binding.mode, ca_profile_id: binding.ca_profile_id, allowed_dns_sans: dns, allowed_uri_sans: uris } + } + const field = binding.setting === 'client_policy' ? `${prefix}_client_tls_policy` : `${prefix}_upstream_tls_profile` + await run(() => putJson(path, { [field]: value }), 'TLS binding saved.') + } + + return ( + + +
+
+

TLS certificates and profiles

+

Manage client trust, upstream TLS identities, and the native listener certificate.

+
+ {error &&

{error}

} + {notice &&

{notice}

} + +
+

Profiles

+ {loading ?

Loading profiles…

: ( +
+ {profiles.length === 0 &&

No TLS profiles configured.

} + {profiles.map(item => ( +
+
+ {item.id} + {item.kind === 'client_ca' ? 'Client CA' : 'Upstream'} · {item.source}{item.revision ? ` · revision ${item.revision}` : ''} +
+ {!item.read_only &&
+ + +
} +
+ ))} +
+ )} +
+ +
+

{replacing ? `Replace ${profile.id}` : 'Add profile'}

+ {replacing &&

Enter the complete certificate material again. Existing private material cannot be displayed.

} +
+ + +
+