# AGENTS.md
## Project
stygian-proxy — A high-performance, resilient proxy rotation library for Rust, designed
as a first-class citizen in the Stygian scraping ecosystem. Manages a pool
of HTTP/SOCKS proxies with pluggable rotation strategies, async health
checking, per-proxy circuit breakers, and native integration with
stygian-browser (per-context binding) and stygian-graph (ScrapingService
HTTP adapters). No external database required: the in-memory backend
supports all production workloads; persistence adapters are optional and
unlocked via feature flags.
## Setup commands
- Build: `cargo build -p stygian-proxy --all-features`
- Test: `cargo test -p stygian-proxy --all-features`
- Lint: `cargo clippy -p stygian-proxy --all-features -- -D warnings`
## Architecture: Hexagonal
- Domain layer must have zero I/O dependencies
- All external interactions go through port traits
- Adapters implement port traits and live in `adapters/`
- New capabilities require a new port trait before an adapter
- Depend inward: adapters → ports ← domain
## Code style
- Language: rust
## Rules
- Rust edition 2024, stable toolchain (1.94.0).
- All error types use 'thiserror'; 'anyhow' only in examples/tests/binary entry points.
- No .unwrap() or .expect() in library code; use exhaustive error handling.
- Async runtime: Tokio 1.49 for all I/O; tokio::sync::{RwLock, Mutex} for shared state.
- Use 'async fn' in traits directly (Rust 2024; no async_trait macro needed).
- Hexagonal architecture: ProxyStoragePort and RotationStrategy are pure traits; adapters live in sub-modules.
- All public types must be Send + Sync + 'static so they can be shared across Tokio tasks.
- Per-proxy metrics are tracked via std::sync::atomic (AtomicU64); no external metrics crate in core.
- Circuit breaker state machine uses AtomicU8 + CAS loops; do NOT use Mutex for hot-path state reads.
- Health checker runs as a background Tokio task spawned from ProxyManager::start().
- Proxy validation at ingestion: reject malformed URLs, enforce scheme whitelist (http, https, socks5, socks4).
- SOCKS proxy support is gated behind the 'socks' cargo feature (reqwest socks feature).
- stygian-browser integration (per-context binding) is gated behind the 'browser' cargo feature.
- stygian-graph integration (ProxyManagerPort trait) is gated behind the 'graph' cargo feature.
- All public APIs must have doc comments with a runnable '#[doc(test)]' example.
- Use Rust 1.94.0 features: async closures, LazyLock for static defaults, let chains.
- Performance targets: proxy acquisition < 1 µs in the common (healthy pool) case.
- Thread-contention budget: the hot-path (acquire_proxy) must hold no exclusive locks; prefer Arc + atomic or epoch-based reads.
- Security: treat proxy URLs as untrusted input; sanitize credentials before logging.
## Testing instructions
- Run `cargo test -p stygian-proxy --all-features` before committing
- Every new public function needs at least one test
- Fix all test failures before marking a task complete
## Commit conventions
- Use conventional commits: `feat:`, `fix:`, `refactor:`, `test:`, `docs:`
- Focus commit messages on user impact, not file counts or line numbers
---
_Generated by [wiggum](https://github.com/greysquirr3l/wiggum)._