diff --git a/.dockerignore b/.dockerignore index 3217a56..179cc8a 100644 --- a/.dockerignore +++ b/.dockerignore @@ -2,4 +2,31 @@ target/ .git/ .gitignore *.md + +# Lean 4 proofs +lean4/ + +# Paper / docs +docs/ + +# Training data, datasets, artifacts +*.bin +*.jsonl +models/ +.fastembed_cache/ + +# burn training artifacts (checkpoints, experiment logs) +src/ensemble/gen/scanner_artifacts/ +src/ensemble/gen/ddos_artifacts/ + +# Dev / CI files certs/ +.github/ +.vscode/ +.idea/ +.claude/ +scripts/ +infrastructure/ +*.swp +*.swo +*~ diff --git a/Dockerfile b/Dockerfile index 1002c28..0b7d3b6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,3 +1,6 @@ +# Copyright Sunbeam Studios 2026 +# SPDX-License-Identifier: Apache-2.0 + # ── Stage 1: build ────────────────────────────────────────────── FROM rust:slim AS builder @@ -23,6 +26,7 @@ COPY Cargo.toml Cargo.lock ./ RUN mkdir -p src benches && \ echo 'fn main() {}' > src/main.rs && \ echo 'fn main() {}' > benches/scanner_bench.rs && \ + echo 'fn main() {}' > benches/ddos_bench.rs && \ cargo build --release --target "$(cat /rust-target)" ; \ rm -rf src benches @@ -46,7 +50,6 @@ FROM cgr.dev/chainguard/static:latest COPY --from=builder /tini /tini COPY --from=builder /sunbeam-proxy /usr/local/bin/sunbeam-proxy -COPY models/ /models/ EXPOSE 80 443 diff --git a/LICENSE b/LICENSE index e2218ea..3240348 100644 --- a/LICENSE +++ b/LICENSE @@ -184,7 +184,7 @@ comment syntax for the file format. Please also get (or round off) your own UID and put it after the copyright sign. - Copyright 2025-2026 Sunbeam Studios + Copyright 2026 Sunbeam Studios Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/benches/ddos_bench.rs b/benches/ddos_bench.rs index 2cc524f..d829af8 100644 --- a/benches/ddos_bench.rs +++ b/benches/ddos_bench.rs @@ -1,3 +1,6 @@ +// Copyright Sunbeam Studios 2026 +// SPDX-License-Identifier: Apache-2.0 + use criterion::{black_box, criterion_group, criterion_main, Criterion}; use sunbeam_proxy::ensemble::ddos::ddos_ensemble_predict; use sunbeam_proxy::ensemble::gen::ddos_weights; diff --git a/src/acme.rs b/src/acme.rs index afe39c5..0ef4fd0 100644 --- a/src/acme.rs +++ b/src/acme.rs @@ -1,3 +1,6 @@ +// Copyright Sunbeam Studios 2026 +// SPDX-License-Identifier: Apache-2.0 + use futures::StreamExt; use k8s_openapi::api::networking::v1::Ingress; use kube::{runtime::watcher, Api, Client}; diff --git a/src/autotune/gp.rs b/src/autotune/gp.rs index 9bfcdc4..80069e8 100644 --- a/src/autotune/gp.rs +++ b/src/autotune/gp.rs @@ -1,3 +1,6 @@ +// Copyright Sunbeam Studios 2026 +// SPDX-License-Identifier: Apache-2.0 + /// Gaussian Process surrogate with RBF kernel and Cholesky solver. /// Designed for <200 observations in 4-10 dimensions. diff --git a/src/autotune/mod.rs b/src/autotune/mod.rs index 14a54c7..e31464e 100644 --- a/src/autotune/mod.rs +++ b/src/autotune/mod.rs @@ -1,3 +1,6 @@ +// Copyright Sunbeam Studios 2026 +// SPDX-License-Identifier: Apache-2.0 + pub mod ddos; pub mod gp; pub mod optimizer; diff --git a/src/autotune/optimizer.rs b/src/autotune/optimizer.rs index 9f6c7f5..c4232ef 100644 --- a/src/autotune/optimizer.rs +++ b/src/autotune/optimizer.rs @@ -1,3 +1,6 @@ +// Copyright Sunbeam Studios 2026 +// SPDX-License-Identifier: Apache-2.0 + use crate::autotune::gp::GaussianProcess; use crate::autotune::params::ParamSpace; use serde::Serialize; diff --git a/src/autotune/params.rs b/src/autotune/params.rs index d9f1db3..c27addf 100644 --- a/src/autotune/params.rs +++ b/src/autotune/params.rs @@ -1,3 +1,6 @@ +// Copyright Sunbeam Studios 2026 +// SPDX-License-Identifier: Apache-2.0 + use rand::Rng; #[derive(Debug, Clone)] diff --git a/src/cache.rs b/src/cache.rs index 00b2b2f..ddae409 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -1,3 +1,6 @@ +// Copyright Sunbeam Studios 2026 +// SPDX-License-Identifier: Apache-2.0 + use pingora_cache::MemCache; use std::sync::LazyLock; diff --git a/src/cert.rs b/src/cert.rs index 7e212e6..bc775a6 100644 --- a/src/cert.rs +++ b/src/cert.rs @@ -1,3 +1,6 @@ +// Copyright Sunbeam Studios 2026 +// SPDX-License-Identifier: Apache-2.0 + use anyhow::{Context, Result}; use k8s_openapi::api::core::v1::Secret; use kube::{Api, Client}; diff --git a/src/cluster/bandwidth.rs b/src/cluster/bandwidth.rs index 06d32e5..b18c1b3 100644 --- a/src/cluster/bandwidth.rs +++ b/src/cluster/bandwidth.rs @@ -1,3 +1,6 @@ +// Copyright Sunbeam Studios 2026 +// SPDX-License-Identifier: Apache-2.0 + use rustc_hash::FxHashMap; use std::collections::VecDeque; use std::sync::atomic::{AtomicU64, Ordering}; diff --git a/src/cluster/messages.rs b/src/cluster/messages.rs index 62a93f2..ef96d62 100644 --- a/src/cluster/messages.rs +++ b/src/cluster/messages.rs @@ -1,3 +1,6 @@ +// Copyright Sunbeam Studios 2026 +// SPDX-License-Identifier: Apache-2.0 + use serde::{Deserialize, Serialize}; /// Envelope for all cluster gossip messages. diff --git a/src/cluster/mod.rs b/src/cluster/mod.rs index e8cebc7..9e23afa 100644 --- a/src/cluster/mod.rs +++ b/src/cluster/mod.rs @@ -1,3 +1,6 @@ +// Copyright Sunbeam Studios 2026 +// SPDX-License-Identifier: Apache-2.0 + pub mod bandwidth; pub mod messages; pub mod node; diff --git a/src/cluster/node.rs b/src/cluster/node.rs index 93b1c20..7e41320 100644 --- a/src/cluster/node.rs +++ b/src/cluster/node.rs @@ -1,3 +1,6 @@ +// Copyright Sunbeam Studios 2026 +// SPDX-License-Identifier: Apache-2.0 + use std::net::SocketAddr; use std::path::Path; use std::sync::Arc; diff --git a/src/dataset/mod.rs b/src/dataset/mod.rs index 6018c9c..46efc7d 100644 --- a/src/dataset/mod.rs +++ b/src/dataset/mod.rs @@ -1,3 +1,6 @@ +// Copyright Sunbeam Studios 2026 +// SPDX-License-Identifier: Apache-2.0 + pub mod sample; pub mod modsec; pub mod cicids; diff --git a/src/dataset/sample.rs b/src/dataset/sample.rs index 844ad47..d1350b4 100644 --- a/src/dataset/sample.rs +++ b/src/dataset/sample.rs @@ -1,3 +1,6 @@ +// Copyright Sunbeam Studios 2026 +// SPDX-License-Identifier: Apache-2.0 + use serde::{Deserialize, Serialize}; use std::collections::HashMap; use std::path::Path; diff --git a/src/dataset/synthetic.rs b/src/dataset/synthetic.rs index defdf50..5bf354b 100644 --- a/src/dataset/synthetic.rs +++ b/src/dataset/synthetic.rs @@ -1,3 +1,6 @@ +// Copyright Sunbeam Studios 2026 +// SPDX-License-Identifier: Apache-2.0 + //! Synthetic data generation for DDoS and scanner training samples. //! //! DDoS synthetic samples are generated by sampling from CIC-IDS2017 timing diff --git a/src/ddos/features.rs b/src/ddos/features.rs index ecff1bd..cec69e0 100644 --- a/src/ddos/features.rs +++ b/src/ddos/features.rs @@ -1,3 +1,6 @@ +// Copyright Sunbeam Studios 2026 +// SPDX-License-Identifier: Apache-2.0 + use rustc_hash::FxHashSet; use serde::{Deserialize, Serialize}; use std::time::Instant; diff --git a/src/dual_stack.rs b/src/dual_stack.rs index d412fdc..0be8cd6 100644 --- a/src/dual_stack.rs +++ b/src/dual_stack.rs @@ -1,3 +1,6 @@ +// Copyright Sunbeam Studios 2026 +// SPDX-License-Identifier: Apache-2.0 + //! Dual-stack TCP listener implementation inspired by `tokio_dual_stack`. //! //! This module provides a `DualStackTcpListener` that can listen on both IPv4 and IPv6 diff --git a/src/ensemble/gen/mod.rs b/src/ensemble/gen/mod.rs index 6c07054..e742e32 100644 --- a/src/ensemble/gen/mod.rs +++ b/src/ensemble/gen/mod.rs @@ -1,2 +1,5 @@ +// Copyright Sunbeam Studios 2026 +// SPDX-License-Identifier: Apache-2.0 + pub mod ddos_weights; pub mod scanner_weights; diff --git a/src/ensemble/mlp.rs b/src/ensemble/mlp.rs index fa2f096..5226bff 100644 --- a/src/ensemble/mlp.rs +++ b/src/ensemble/mlp.rs @@ -1,3 +1,6 @@ +// Copyright Sunbeam Studios 2026 +// SPDX-License-Identifier: Apache-2.0 + /// Two-layer MLP forward pass with a fixed hidden size of 32: /// /// hidden = ReLU(W1 @ input + b1) diff --git a/src/ensemble/mod.rs b/src/ensemble/mod.rs index 5c02b8b..2bddf3d 100644 --- a/src/ensemble/mod.rs +++ b/src/ensemble/mod.rs @@ -1,3 +1,6 @@ +// Copyright Sunbeam Studios 2026 +// SPDX-License-Identifier: Apache-2.0 + pub mod ddos; pub mod gen; pub mod mlp; diff --git a/src/ensemble/tree.rs b/src/ensemble/tree.rs index ff343cd..032ce03 100644 --- a/src/ensemble/tree.rs +++ b/src/ensemble/tree.rs @@ -1,3 +1,6 @@ +// Copyright Sunbeam Studios 2026 +// SPDX-License-Identifier: Apache-2.0 + /// Decision from a tree leaf node. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum TreeDecision { diff --git a/src/metrics.rs b/src/metrics.rs index d129807..c07ac68 100644 --- a/src/metrics.rs +++ b/src/metrics.rs @@ -1,3 +1,6 @@ +// Copyright Sunbeam Studios 2026 +// SPDX-License-Identifier: Apache-2.0 + use prometheus::{ Encoder, Gauge, Histogram, HistogramOpts, IntCounterVec, Opts, Registry, TextEncoder, }; diff --git a/src/rate_limit/cidr.rs b/src/rate_limit/cidr.rs index 9c0057a..1ee77ab 100644 --- a/src/rate_limit/cidr.rs +++ b/src/rate_limit/cidr.rs @@ -1,3 +1,6 @@ +// Copyright Sunbeam Studios 2026 +// SPDX-License-Identifier: Apache-2.0 + use std::net::IpAddr; /// A parsed CIDR block for allowlist matching. diff --git a/src/rate_limit/key.rs b/src/rate_limit/key.rs index be0514f..eea2f68 100644 --- a/src/rate_limit/key.rs +++ b/src/rate_limit/key.rs @@ -1,3 +1,6 @@ +// Copyright Sunbeam Studios 2026 +// SPDX-License-Identifier: Apache-2.0 + use std::hash::{Hash, Hasher}; use std::net::IpAddr; diff --git a/src/rate_limit/limiter.rs b/src/rate_limit/limiter.rs index 92eb9a3..0128efd 100644 --- a/src/rate_limit/limiter.rs +++ b/src/rate_limit/limiter.rs @@ -1,3 +1,6 @@ +// Copyright Sunbeam Studios 2026 +// SPDX-License-Identifier: Apache-2.0 + use crate::config::{BucketConfig, RateLimitConfig}; use crate::rate_limit::cidr::{self, CidrBlock}; use crate::rate_limit::key::RateLimitKey; diff --git a/src/rate_limit/mod.rs b/src/rate_limit/mod.rs index 8b551c0..6e59bbd 100644 --- a/src/rate_limit/mod.rs +++ b/src/rate_limit/mod.rs @@ -1,3 +1,6 @@ +// Copyright Sunbeam Studios 2026 +// SPDX-License-Identifier: Apache-2.0 + pub mod cidr; pub mod key; pub mod limiter; diff --git a/src/scanner/allowlist.rs b/src/scanner/allowlist.rs index f493700..58caf10 100644 --- a/src/scanner/allowlist.rs +++ b/src/scanner/allowlist.rs @@ -1,3 +1,6 @@ +// Copyright Sunbeam Studios 2026 +// SPDX-License-Identifier: Apache-2.0 + use crate::config::BotAllowlistRule; use crate::rate_limit::cidr::CidrBlock; use rustc_hash::FxHashMap; diff --git a/src/scanner/features.rs b/src/scanner/features.rs index 9f2c9d0..1ca18a7 100644 --- a/src/scanner/features.rs +++ b/src/scanner/features.rs @@ -1,3 +1,6 @@ +// Copyright Sunbeam Studios 2026 +// SPDX-License-Identifier: Apache-2.0 + use rustc_hash::FxHashSet; use serde::{Deserialize, Serialize}; diff --git a/src/ssh.rs b/src/ssh.rs index b23b594..c8e680c 100644 --- a/src/ssh.rs +++ b/src/ssh.rs @@ -1,3 +1,6 @@ +// Copyright Sunbeam Studios 2026 +// SPDX-License-Identifier: Apache-2.0 + use tokio::io::copy_bidirectional; use tokio::net::TcpStream; diff --git a/src/static_files.rs b/src/static_files.rs index 6d2e4a4..b72a4de 100644 --- a/src/static_files.rs +++ b/src/static_files.rs @@ -1,3 +1,6 @@ +// Copyright Sunbeam Studios 2026 +// SPDX-License-Identifier: Apache-2.0 + use pingora_http::ResponseHeader; use pingora_proxy::Session; use std::path::{Path, PathBuf}; diff --git a/src/telemetry.rs b/src/telemetry.rs index b05bb74..e8e6422 100644 --- a/src/telemetry.rs +++ b/src/telemetry.rs @@ -1,3 +1,6 @@ +// Copyright Sunbeam Studios 2026 +// SPDX-License-Identifier: Apache-2.0 + use opentelemetry::trace::TracerProvider as _; use opentelemetry_otlp::WithExportConfig; use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt, EnvFilter}; diff --git a/src/training/tree.rs b/src/training/tree.rs index 8c5d37b..48b60fe 100644 --- a/src/training/tree.rs +++ b/src/training/tree.rs @@ -1,3 +1,6 @@ +// Copyright Sunbeam Studios 2026 +// SPDX-License-Identifier: Apache-2.0 + //! CART decision tree trainer (pure Rust, no burn dependency). //! //! Trains a binary classification tree using Gini impurity and outputs diff --git a/src/watcher.rs b/src/watcher.rs index 3f66fed..2b76311 100644 --- a/src/watcher.rs +++ b/src/watcher.rs @@ -1,3 +1,6 @@ +// Copyright Sunbeam Studios 2026 +// SPDX-License-Identifier: Apache-2.0 + use futures::StreamExt; use k8s_openapi::api::core::v1::{ConfigMap, Secret}; use kube::{runtime::watcher, Api, Client}; diff --git a/tests/cluster_test.rs b/tests/cluster_test.rs index 095f066..95e5163 100644 --- a/tests/cluster_test.rs +++ b/tests/cluster_test.rs @@ -1,3 +1,6 @@ +// Copyright Sunbeam Studios 2026 +// SPDX-License-Identifier: Apache-2.0 + //! Integration test: spin up two gossip nodes with bootstrap discovery //! and verify that bandwidth reports propagate between them. diff --git a/tests/dual_stack_test.rs b/tests/dual_stack_test.rs index 5c6178d..fd20ac5 100644 --- a/tests/dual_stack_test.rs +++ b/tests/dual_stack_test.rs @@ -1,3 +1,6 @@ +// Copyright Sunbeam Studios 2026 +// SPDX-License-Identifier: Apache-2.0 + //! Integration test for dual-stack TCP listener functionality. use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4}; diff --git a/tests/proptest.rs b/tests/proptest.rs index c0dd426..48fccd6 100644 --- a/tests/proptest.rs +++ b/tests/proptest.rs @@ -1,3 +1,6 @@ +// Copyright Sunbeam Studios 2026 +// SPDX-License-Identifier: Apache-2.0 + use bytes::Bytes; use proptest::prelude::*; use std::collections::HashSet; diff --git a/tests/rate_limit_test.rs b/tests/rate_limit_test.rs index 1b517dd..9a8e1e5 100644 --- a/tests/rate_limit_test.rs +++ b/tests/rate_limit_test.rs @@ -1,3 +1,6 @@ +// Copyright Sunbeam Studios 2026 +// SPDX-License-Identifier: Apache-2.0 + use std::net::IpAddr; use sunbeam_proxy::config::{BucketConfig, RateLimitConfig}; use sunbeam_proxy::rate_limit::key::{self, RateLimitKey};