pub mod bench;
pub mod billing;
pub mod capture;
pub mod churn;
pub mod emit;
pub mod mock;
pub mod prefix_shape;
pub mod preflight;
pub mod proxy;
pub mod retention;
pub mod session;
pub mod tokenize;
pub mod transforms;
pub mod wire_format;
use std::net::SocketAddr;
use std::sync::Arc;
use std::time::Duration;
use std::collections::BTreeMap;
use axum::extract::DefaultBodyLimit;
use axum::routing::get;
use axum::Router;
use tokio::net::TcpListener;
use tokio::sync::mpsc::Sender;
use tokio::sync::Semaphore;
use crate::cloud::CloudEvent;
use crate::core::policy::{PolicyHandle, ResidentBundle};
use crate::error::{OlError, ERR_BOUNDARY_SERVE};
use crate::privacy::PrivacyFilter;
use session::SessionRegistry;
use tokenize::Estimator;
use wire_format::{AuthMode, WireFormat};
pub const DEFAULT_BOUNDARY_PORT: u16 = 7600;
pub const DEFAULT_INFLIGHT: usize = 16;
pub const MAX_MATERIALIZE_BYTES: usize = 32 * 1024 * 1024;
pub const HEADER_TIMEOUT: Duration = Duration::from_secs(60);
pub const ANTHROPIC_BASE: &str = "https://api.anthropic.com";
pub struct BoundaryState {
pub client: crate::egress::ClientHandle,
upstream: BTreeMap<&'static str, reqwest::Url>,
openai_chatgpt: Option<reqwest::Url>,
fallback: reqwest::Url,
pub inflight: Arc<Semaphore>,
pub privacy: PrivacyFilter,
pub started_at: std::time::Instant,
pub port: u16,
pub header_timeout: Duration,
pub registry: Arc<SessionRegistry>,
pub cloud_tx: Option<Sender<CloudEvent>>,
pub tokenizer: Estimator,
pub churn: Arc<churn::ChurnTracker>,
pub prefix_shape: Arc<prefix_shape::PrefixTracker>,
pub transforms_act: bool,
pub inject_mutate_panic: bool,
pub policy: Option<PolicyHandle>,
pub wiring: Arc<preflight::WiringState>,
pub egress: crate::egress::EgressReporter,
}
impl BoundaryState {
pub fn new(
upstream_base: reqwest::Url,
port: u16,
inflight: usize,
extra_patterns: &[String],
) -> Self {
Self::new_with_egress(
upstream_base,
port,
inflight,
extra_patterns,
&crate::egress::EgressConfig::direct(),
)
}
pub fn new_with_egress(
upstream_base: reqwest::Url,
port: u16,
inflight: usize,
extra_patterns: &[String],
egress: &crate::egress::EgressConfig,
) -> Self {
Self {
client: crate::egress::ClientHandle::new(build_boundary_client_with(egress)),
upstream: WireFormat::ALL
.iter()
.map(|f| (f.as_str(), upstream_base.clone()))
.collect(),
openai_chatgpt: None,
fallback: upstream_base,
inflight: Arc::new(Semaphore::new(inflight.max(1))),
privacy: PrivacyFilter::new(extra_patterns),
started_at: std::time::Instant::now(),
port,
header_timeout: HEADER_TIMEOUT,
registry: Arc::new(SessionRegistry::default()),
cloud_tx: None,
tokenizer: Estimator,
churn: Arc::new(churn::ChurnTracker::default()),
prefix_shape: Arc::new(prefix_shape::PrefixTracker::default()),
transforms_act: false,
inject_mutate_panic: false,
policy: None,
wiring: Arc::new(preflight::WiringState::default()),
egress: crate::egress::EgressReporter::silent(egress),
}
}
pub fn with_client_handle(mut self, client: crate::egress::ClientHandle) -> Self {
self.client = client;
self
}
pub fn with_egress_reporter(mut self, egress: crate::egress::EgressReporter) -> Self {
self.egress = egress;
self
}
pub fn with_header_timeout(mut self, timeout: Duration) -> Self {
self.header_timeout = timeout;
self
}
pub fn with_measurement(
mut self,
registry: Arc<SessionRegistry>,
cloud_tx: Option<Sender<CloudEvent>>,
) -> Self {
self.registry = registry;
self.cloud_tx = cloud_tx;
self
}
pub fn with_transforms_act(mut self, act: bool) -> Self {
self.transforms_act = act;
self
}
pub fn with_inject_mutate_panic(mut self, inject: bool) -> Self {
self.inject_mutate_panic = inject;
self
}
pub fn with_policy(mut self, policy: Option<PolicyHandle>) -> Self {
self.policy = policy;
self
}
pub fn with_wiring(mut self, wiring: Arc<preflight::WiringState>) -> Self {
self.wiring = wiring;
self
}
pub fn with_upstream_map(mut self, map: BTreeMap<String, String>) -> Self {
for fmt in WireFormat::ALL {
let default = || reqwest::Url::parse(fmt.default_upstream()).ok();
let resolved = match map.get(fmt.as_str()) {
None => default(),
Some(v) => reqwest::Url::parse(v).ok().or_else(|| {
tracing::warn!(
format = fmt.as_str(),
value = %v,
"[boundary.upstream] entry is not a valid URL — forwarding {} to {} instead",
fmt.as_str(),
fmt.default_upstream()
);
default()
}),
};
let Some(url) = resolved else {
tracing::error!(
format = fmt.as_str(),
value = fmt.default_upstream(),
"[boundary.upstream] built-in default is not a valid URL — leaving this \
format unmapped"
);
continue;
};
if url.path() != "/" {
tracing::info!(
format = fmt.as_str(),
upstream = %url,
"[boundary.upstream] entry carries a path — requests are prefixed with {} \
and their own leading /v1 is dropped",
url.path()
);
}
if matches!(fmt, WireFormat::OpenAiResponses) {
let first_party = reqwest::Url::parse(wire_format::OPENAI_BASE)
.ok()
.is_some_and(|builtin| builtin == url);
self.openai_chatgpt = first_party
.then(|| reqwest::Url::parse(wire_format::CHATGPT_BASE).ok())
.flatten();
if first_party && self.openai_chatgpt.is_none() {
tracing::error!(
value = wire_format::CHATGPT_BASE,
"built-in ChatGPT upstream is not a valid URL — a ChatGPT-plan request \
will forward to the openai-responses upstream instead"
);
}
}
self.upstream.insert(fmt.as_str(), url);
}
self
}
pub fn upstream_for(&self, fmt: WireFormat) -> &reqwest::Url {
self.upstream.get(fmt.as_str()).unwrap_or(&self.fallback)
}
pub fn chatgpt_upstream(&self) -> Option<&reqwest::Url> {
self.openai_chatgpt.as_ref()
}
pub fn upstream_for_request(&self, fmt: WireFormat, auth: AuthMode) -> &reqwest::Url {
match (fmt, auth) {
(WireFormat::OpenAiResponses, AuthMode::ChatGptSubscription) => self
.openai_chatgpt
.as_ref()
.unwrap_or_else(|| self.upstream_for(fmt)),
_ => self.upstream_for(fmt),
}
}
pub fn resident_request_rules(&self) -> Option<arc_swap::Guard<Arc<Option<ResidentBundle>>>> {
self.policy.as_ref().map(|handle| handle.load())
}
}
pub fn default_upstream() -> reqwest::Url {
reqwest::Url::parse(ANTHROPIC_BASE).expect("ANTHROPIC_BASE is a valid URL")
}
pub fn resolve_boundary_port() -> u16 {
default_boundary_port()
}
pub fn default_boundary_port() -> u16 {
match std::env::var("OPENLATCH_BOUNDARY_DEFAULT_PORT") {
Ok(v) => v.trim().parse::<u16>().unwrap_or(DEFAULT_BOUNDARY_PORT),
Err(_) => DEFAULT_BOUNDARY_PORT,
}
}
pub fn build_boundary_client() -> Option<reqwest::Client> {
build_boundary_client_with(&crate::egress::EgressConfig::direct())
}
pub fn build_boundary_client_with(cfg: &crate::egress::EgressConfig) -> Option<reqwest::Client> {
match crate::egress::build_client(crate::egress::Consumer::Boundary, cfg) {
Ok(client) => Some(client),
Err(e) if e.code == crate::error::ERR_DIRECT_FORBIDDEN => {
tracing::error!(
code = %e.code,
error = %e.message,
"boundary has no permitted egress route; forwarding is refused rather than falling back to a direct connection"
);
None
}
Err(e) => {
tracing::error!(
code = %e.code,
error = %e.message,
"boundary egress client could not be built from the configured proxy route; forwarding directly instead"
);
crate::egress::client_builder()
.connect_timeout(Duration::from_secs(10))
.pool_max_idle_per_host(8)
.build()
.ok()
.or_else(|| Some(crate::egress::client()))
}
}
}
pub fn router(state: Arc<BoundaryState>) -> Router {
Router::new()
.route("/admin/boundary/status", get(proxy::boundary_status))
.fallback(proxy::proxy_any)
.layer(DefaultBodyLimit::max(MAX_MATERIALIZE_BYTES))
.with_state(state)
}
pub async fn serve_ephemeral(state: Arc<BoundaryState>) -> u16 {
let listener = TcpListener::bind(("127.0.0.1", 0)).await.unwrap();
let port = listener.local_addr().unwrap().port();
let app = router(state);
tokio::spawn(async move {
let _ = axum::serve(listener, app).await;
});
port
}
pub async fn bind_pinned(port: u16) -> Result<TcpListener, OlError> {
let addr = SocketAddr::from(([127, 0, 0, 1], port));
TcpListener::bind(addr)
.await
.map_err(|e| OlError::port_occupied(port, e))
}
pub async fn serve_bound(
listener: TcpListener,
state: Arc<BoundaryState>,
shutdown_rx: tokio::sync::watch::Receiver<bool>,
) -> Result<(), OlError> {
tracing::info!(
port = state.port,
upstream = %state.upstream_for(WireFormat::AnthropicMessages),
"boundary serving (loopback only)"
);
serve_until_shutdown(listener, state, shutdown_rx).await
}
pub async fn serve_attempt(
pre_bound: Arc<tokio::sync::Mutex<Option<TcpListener>>>,
state: Arc<BoundaryState>,
shutdown_rx: tokio::sync::watch::Receiver<bool>,
) -> Result<(), OlError> {
let listener = match pre_bound.lock().await.take() {
Some(l) => l,
None => bind_pinned(state.port).await?,
};
serve_bound(listener, state, shutdown_rx).await
}
async fn serve_until_shutdown(
listener: TcpListener,
state: Arc<BoundaryState>,
mut shutdown_rx: tokio::sync::watch::Receiver<bool>,
) -> Result<(), OlError> {
let app = router(state);
axum::serve(listener, app)
.with_graceful_shutdown(async move {
let _ = shutdown_rx.wait_for(|stop| *stop).await;
})
.await
.map_err(|e| OlError::new(ERR_BOUNDARY_SERVE, format!("boundary serve failed: {e}")))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn default_upstream_parses() {
let u = default_upstream();
assert_eq!(u.as_str(), "https://api.anthropic.com/");
}
#[test]
fn upstream_with_a_path_reports_how_the_prefix_is_applied() {
let mut map = BTreeMap::new();
map.insert(
WireFormat::AnthropicMessages.as_str().to_string(),
"https://gw.example/anthropic".to_string(),
);
let (state, logs) = crate::core::policy::test_support::capture_logs(|| {
BoundaryState::new(default_upstream(), 0, 8, &[]).with_upstream_map(map)
});
assert!(
logs.contains("carries a path"),
"the prefix must be reported, got: {logs}"
);
assert!(
logs.contains("/anthropic"),
"the line must name the prefix requests will carry, got: {logs}"
);
assert_eq!(
state.upstream_for(WireFormat::AnthropicMessages).host_str(),
Some("gw.example")
);
assert_eq!(
state.upstream_for(WireFormat::AnthropicMessages).path(),
"/anthropic",
"the prefix must survive into the installed entry — it is what the \
forward path prepends"
);
}
#[test]
fn a_chatgpt_credential_selects_the_chatgpt_backend() {
let state =
BoundaryState::new(default_upstream(), 0, 8, &[]).with_upstream_map(BTreeMap::new());
assert_eq!(
state
.upstream_for_request(WireFormat::OpenAiResponses, AuthMode::ChatGptSubscription)
.as_str(),
"https://chatgpt.com/backend-api/codex",
);
assert_eq!(
state
.upstream_for_request(WireFormat::OpenAiResponses, AuthMode::Platform)
.host_str(),
Some("api.openai.com"),
);
assert_eq!(
state
.upstream_for_request(WireFormat::AnthropicMessages, AuthMode::ChatGptSubscription)
.host_str(),
Some("api.anthropic.com"),
);
}
#[test]
fn the_pairing_survives_a_fully_materialized_map() {
let cfg = crate::config::BoundaryConfig::default();
let map: BTreeMap<String, String> = WireFormat::ALL
.iter()
.map(|f| (f.as_str().to_string(), cfg.upstream_for(*f)))
.collect();
assert!(
map.contains_key(WireFormat::OpenAiResponses.as_str()),
"the daemon materializes every key — if this ever stops being true \
the pairing's precondition changed"
);
let state = BoundaryState::new(default_upstream(), 0, 8, &[]).with_upstream_map(map);
assert_eq!(
state.chatgpt_upstream().map(reqwest::Url::as_str),
Some("https://chatgpt.com/backend-api/codex"),
"a default host must pair, or no ChatGPT-plan Codex install works"
);
}
#[test]
fn a_configured_openai_upstream_wins_over_the_chatgpt_builtin() {
let mut map = BTreeMap::new();
map.insert(
WireFormat::OpenAiResponses.as_str().to_string(),
"https://gw.example".to_string(),
);
let state = BoundaryState::new(default_upstream(), 0, 8, &[]).with_upstream_map(map);
for auth in [AuthMode::ChatGptSubscription, AuthMode::Platform] {
assert_eq!(
state
.upstream_for_request(WireFormat::OpenAiResponses, auth)
.host_str(),
Some("gw.example"),
"a configured gateway must not be bypassed for {auth:?}"
);
}
}
#[test]
fn unparseable_entry_falls_back_to_its_own_default() {
let mut map = BTreeMap::new();
map.insert(
WireFormat::AnthropicMessages.as_str().to_string(),
"https://gw.example".to_string(),
);
map.insert(
WireFormat::OpenAiResponses.as_str().to_string(),
"bogus".to_string(),
);
let (state, logs) = crate::core::policy::test_support::capture_logs(|| {
BoundaryState::new(
reqwest::Url::parse("https://gw.example").expect("url"),
0,
8,
&[],
)
.with_upstream_map(map)
});
assert_eq!(
state.upstream_for(WireFormat::OpenAiResponses).host_str(),
Some("api.openai.com"),
"a bad Responses entry takes OpenAI's default, never the gateway"
);
assert_eq!(
state.upstream_for(WireFormat::AnthropicMessages).host_str(),
Some("gw.example"),
"the good entry is untouched"
);
assert!(
logs.contains("not a valid URL"),
"a present-but-unparseable value must say so, got: {logs}"
);
assert!(
!logs.contains("format=\"unknown\"") && !logs.contains("format: \"unknown\""),
"an ABSENT key takes its default silently — no spurious warning: {logs}"
);
}
#[test]
fn one_url_populates_every_format() {
let base = reqwest::Url::parse("http://127.0.0.1:1").expect("url");
let state = BoundaryState::new(base.clone(), 0, 8, &[]);
for fmt in WireFormat::ALL {
assert_eq!(state.upstream_for(fmt), &base, "{fmt:?}");
}
}
#[test]
fn resolve_boundary_port_is_deterministic() {
assert_eq!(resolve_boundary_port(), DEFAULT_BOUNDARY_PORT);
assert_eq!(resolve_boundary_port(), DEFAULT_BOUNDARY_PORT);
}
#[tokio::test]
async fn boundary_listener_terminates_on_shutdown_signal() {
let (shutdown_tx, shutdown_rx) = tokio::sync::watch::channel(false);
let listener = TcpListener::bind(("127.0.0.1", 0)).await.unwrap();
let port = listener.local_addr().unwrap().port();
let state = Arc::new(BoundaryState::new(default_upstream(), port, 8, &[]));
let serve = tokio::spawn(serve_bound(listener, state, shutdown_rx));
assert!(
bind_pinned(port).await.is_err(),
"port must be held while the boundary is serving"
);
shutdown_tx.send(true).unwrap();
let joined = tokio::time::timeout(Duration::from_secs(5), serve)
.await
.expect("boundary listener did not terminate after shutdown signal")
.expect("boundary serve task panicked");
assert!(joined.is_ok(), "graceful shutdown should return Ok");
assert!(
bind_pinned(port).await.is_ok(),
"port must be free after graceful shutdown"
);
}
#[tokio::test]
async fn supervised_boundary_retries_a_failed_bind_and_recovers() {
use crate::core::supervision::task::{
spawn_supervised, Backoff, HealthRegistry, RestartPolicy, TaskSpec,
};
let squatter = TcpListener::bind(("127.0.0.1", 0)).await.unwrap();
let port = squatter.local_addr().unwrap().port();
let registry = Arc::new(HealthRegistry::new());
let (shutdown_tx, shutdown_rx) = tokio::sync::watch::channel(false);
let spec = TaskSpec::new("boundary", RestartPolicy::Always).with_backoff(Backoff::new(
Duration::from_millis(20),
Duration::from_millis(60),
));
let pre_bound = Arc::new(tokio::sync::Mutex::new(None));
let task_shutdown_rx = shutdown_rx.clone();
let handle = spawn_supervised(®istry, spec, shutdown_rx, move || {
let state = Arc::new(BoundaryState::new(default_upstream(), port, 4, &[]));
serve_attempt(pre_bound.clone(), state, task_shutdown_rx.clone())
});
let deadline = std::time::Instant::now() + Duration::from_secs(10);
let mut retried_while_degraded = false;
let mut health = None;
while std::time::Instant::now() < deadline {
if let Some(h) = registry.tasks().first().cloned() {
retried_while_degraded = h.restarts() >= 2 && registry.is_degraded();
health = Some(h);
if retried_while_degraded {
break;
}
}
tokio::time::sleep(Duration::from_millis(10)).await;
}
let health = health.expect("the supervised task never registered with the health registry");
assert!(
retried_while_degraded,
"an occupied port must be retried and read as degraded, \
saw {} restarts and degraded={}",
health.restarts(),
registry.is_degraded()
);
let recorded = health.last_error().unwrap_or_default();
assert!(
recorded.contains(&port.to_string()),
"the bind failure must be recorded on the health entry, got {recorded:?}"
);
drop(squatter);
let client = crate::egress::client_builder()
.timeout(Duration::from_secs(2))
.build()
.expect("client");
let url = format!("http://127.0.0.1:{port}/admin/boundary/status");
let deadline = std::time::Instant::now() + Duration::from_secs(10);
let mut served = false;
while std::time::Instant::now() < deadline {
if let Ok(r) = client.get(&url).send().await {
if r.status().is_success() {
served = true;
break;
}
}
tokio::time::sleep(Duration::from_millis(25)).await;
}
assert!(
served,
"the boundary must bind and serve once the port is released"
);
shutdown_tx.send(true).expect("shutdown send");
let _ = tokio::time::timeout(Duration::from_secs(5), handle).await;
}
#[tokio::test]
async fn first_attempt_serves_the_prebound_listener_without_rebinding() {
let listener = TcpListener::bind(("127.0.0.1", 0)).await.unwrap();
let port = listener.local_addr().unwrap().port();
let pre_bound = Arc::new(tokio::sync::Mutex::new(Some(listener)));
let (shutdown_tx, shutdown_rx) = tokio::sync::watch::channel(false);
let state = Arc::new(BoundaryState::new(default_upstream(), port, 4, &[]));
let serve = tokio::spawn(serve_attempt(pre_bound.clone(), state, shutdown_rx));
let client = crate::egress::client_builder()
.timeout(Duration::from_secs(2))
.build()
.expect("client");
let url = format!("http://127.0.0.1:{port}/admin/boundary/status");
let deadline = std::time::Instant::now() + Duration::from_secs(5);
let mut served = false;
while std::time::Instant::now() < deadline {
if let Ok(r) = client.get(&url).send().await {
if r.status().is_success() {
served = true;
break;
}
}
tokio::time::sleep(Duration::from_millis(25)).await;
}
assert!(served, "the pre-bound listener must be served as-is");
assert!(
pre_bound.lock().await.is_none(),
"the pre-bound listener is consumed by the first attempt only"
);
shutdown_tx.send(true).expect("shutdown send");
let _ = tokio::time::timeout(Duration::from_secs(5), serve).await;
}
#[tokio::test]
async fn bind_pinned_is_loud_when_occupied() {
let probe = TcpListener::bind(("127.0.0.1", 0)).await.unwrap();
let port = probe.local_addr().unwrap().port();
drop(probe);
let held = bind_pinned(port).await.expect("first bind succeeds");
let occupied = bind_pinned(port).await;
assert!(occupied.is_err(), "second bind of a held port must fail");
assert_eq!(
occupied.unwrap_err().code,
crate::error::ERR_BOUNDARY_PORT_IN_USE
);
drop(held);
}
}