# 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)._
