#!/usr/bin/env python3 """Static regression checks for bounded-memory/background-worker contracts. This is intentionally Rust-toolchain independent. It does not replace runtime RSS/ heap profiling; it prevents the source-level bounds audited for this release from silently disappearing before compiler-enabled acceptance runs. """ from __future__ import annotations from pathlib import Path ROOT = Path(__file__).resolve().parents[1] def read(path: str) -> str: return (ROOT / path).read_text(encoding="utf-8") def require(path: str, *markers: str) -> None: text = read(path) for marker in markers: assert marker in text, f"{path}: missing memory contract: {marker}" def forbid(path: str, *markers: str) -> None: text = read(path) for marker in markers: assert marker not in text, f"{path}: forbidden memory pattern returned: {marker}" # Transform path: hard aggregate/decode/concurrency budgets and no JSON DOM tree. require( "src/transform/mod.rs", "DEFAULT_MEMORY_BUDGET_BYTES: usize = 128 * 1024 * 1024", "pub memory_budget_bytes: usize", "pub max_inflight: usize", "try_reserve_transform_memory(required_memory, settings.memory_budget_bytes)", "try_reserve_transform_slot(settings.max_inflight)", "TRANSFORM_MEMORY_IN_USE_BYTES: AtomicUsize", "TRANSFORM_INFLIGHT: AtomicUsize", "pub struct ResourceUsage", "pub fn resource_usage(settings: &Settings)", "memory_reserved_bytes: TRANSFORM_MEMORY_IN_USE_BYTES.load", "Limited::new(body, settings.max_body_bytes)", ".try_reserve_exact(read)", '"memory_pressure"', '"concurrency_pressure"', "aggregation_is_bounded_even_when_content_length_is_false", "transform_memory_reservation_obeys_runtime_budget", "transform_inflight_reservation_obeys_runtime_limit", ) require("src/transform/json.rs", "IgnoredAny::deserialize", "Vec::with_capacity(body.len())") forbid("src/transform/json.rs", "use serde_json::Value", "from_slice::") require("src/transform/css.rs", "let mut last_char: Option = None") require("src/transform/html.rs", "enum RawElement", "fn raw_tag(tag: &str)") # Cache background work: all previously high-retention paths have hard bounds. require( "src/cache/model.rs", "COLD_DELETE_FALLBACKS: usize = 2", "COLD_CLEANUP_SLOTS: usize = 1", "BACKGROUND_REVALIDATION_LIMIT: usize = 8", "pub cold_limit_bytes: u64", "pub cold_limit_entries: usize", "pub hot_auto_trim_enabled: bool", "pub hot_auto_trim_after_seconds: u64", "pub hot_auto_trim_target_percent: u8", ) require( "src/admin/mod.rs", 'payload["transform_resources"]', 'payload["memory_accounting"]', '"non_cache_rss_includes_transform": true', ) require( "src/cache/cold.rs", "BinaryHeap::with_capacity(requested_limit.saturating_add(1))", "self.cold_delete_fallbacks.clone().try_acquire_owned()", "self.cleanup_slots.clone().try_acquire_owned()", "std::mem::take(&mut delete)", ) require( "src/cache/tickets.rs", "active.len() >= BACKGROUND_REVALIDATION_LIMIT", ) require( "src/cache/collapse.rs", ".saturating_mul(64)", ".clamp(64, 256)", "settings.proactive_refresh_max_inflight as u64", ) require( "src/cache/lifecycle.rs", "mpsc::channel(COLD_QUEUE)", "cold_delete_fallbacks: Arc::new(Semaphore::new(COLD_DELETE_FALLBACKS))", "cleanup_slots: Arc::new(Semaphore::new(COLD_CLEANUP_SLOTS))", "cache.trim_hot_idle();", "fn trim_hot_idle(&self)", ) # Other long-lived/background facilities: queue/task/worker cardinality is bounded # or owned by a cancellation-aware supervisor/TaskTracker. require( "src/logging.rs", "HISTORY_CAPACITY: usize = 4096", "LIVE_STREAM_CAPACITY: usize = 4096", "mpsc::channel(SINK_QUEUE)", "self.sink.try_send(entry)", "pub capture_user_agent: bool", "pub capture_country: bool", ) require( "src/traffic.rs", "QUEUE_CAPACITY: usize = 2048", "TOP_CAPACITY: usize = 32", "MAX_VHOSTS: usize = 64", "self.tx.try_send(sample)", "client_ips: TopTable", ) require( "src/diagnostics.rs", "tokio::task::spawn_blocking(move || system_stats::sample(previous)).await", "stop.cancelled()", "pub fn trim_allocator() -> bool", ) require( "src/runtime.rs", "Duration::from_secs(60)", "spawn_blocking(crate::diagnostics::trim_allocator)", ) require( "src/upstream.rs", "Semaphore::new(16)", ".try_acquire_owned()", "tokio::time::timeout(DNS_TIMEOUT, lookup)", ) require( "src/balance.rs", "if checks.len() >= 16 { break; }", "checks.abort_all()", ) require( "src/stream.rs", "Semaphore::new(host.max_connections)", "mpsc::channel(64)", "JoinSet::new()", ) require( "src/server.rs", "Semaphore::new(max_connections)", "let mut tasks = JoinSet::new()", ) require( "src/runtime.rs", "tokio_util::task::TaskTracker::new()", "update_slots: Arc::new(Semaphore::new(8))", "inflight: Arc::new(Semaphore::new(max_inflight))", ) require("src/acme.rs", "slot: Arc::new(Semaphore::new(1))", ".try_acquire_owned()") require("src/docker.rs", "shutdown.cancelled()", "Duration::from_secs(5)") require("src/update_check.rs", "shutdown.cancelled()", "tokio::time::sleep(interval)") print("PASS: bounded-memory transform/cache contracts and background-worker limits are present.")