5.9 KiB
Contributing to Obscura
Thanks for your interest in Obscura. This guide covers how to build, test, and submit changes. For the deeper, non-obvious engine details (architecture, gotchas, robustness invariants), read AGENTS.md first; this file does not repeat it.
Code of conduct
Be respectful and constructive. We want Obscura to be a welcoming project, so keep discussion focused on the work and assume good faith. Harassment or abuse is not tolerated.
Before you start
For anything beyond a minor documentation fix, please open an issue first (or comment on an existing one) and say you intend to work on it. This lets us give early feedback and avoids two people building the same thing or a PR that does not fit the project's direction.
A few notes to keep the project maintainable:
- Link an issue. PRs without a linked issue or prior discussion may be closed, except for small doc fixes.
- Human oversight required. AI-assisted contributions are fine, but low-quality or unreviewed agent output will be closed. Understand and test what you submit.
- New to the codebase? Look for issues labeled
good first issue.
Building
cargo build --release # binary at ./target/release/obscura
- The first build compiles V8 from source: roughly 5 minutes and a few GB of disk. Incremental builds are seconds.
- Iterating on one crate? Scope it:
cargo build -p obscura-cli. - Stealth (
--features stealth) pulls in BoringSSL through CMake, socmakemust be installed. The default build uses rustls and needs neither CMake nor OpenSSL. - If the vendored OpenSSL build hits an AVX-512 assembler error on your host,
build with
OPENSSL_NO_VENDOR=1.
Testing
Run tests with cargo nextest, not cargo test:
cargo nextest run --workspace # or -p <crate> while iterating
cargo test runs the whole test binary in one process, but the engine holds a
single V8 isolate per process, so the runtime tests fail under it. nextest
runs each test in its own process, which is the only supported way.
The authoritative behavioral gate is the obstacle course in the companion
repo obscura-benchmark
(33 capability and speed stages, must stay 33/33):
OBSCURA_BIN=./target/release/obscura python3 obstacle-course/run.py --runs 1 --warmup 0
It serves local fixtures, so it is deterministic and offline.
Before you open a PR
For any code change:
cargo build --release(or-p <crate>) compiles clean.cargo nextest runpasses for the crates you touched.- The obstacle course still reports 33/33.
- Performance is a hard constraint. Obscura is roughly 12x faster and uses about 6x less memory than headless Chrome on framework pages. Keep the native Rust fast paths and add a JS fallback only for real spec edge cases. If your change could affect performance, benchmark old vs new interleaved, min-of-N (the noise floor is about plus or minus 10%).
- For stealth changes, re-test with
--stealth. A non-stealth binary does not exercise thewreqpath.
Keep ops panic-safe: a panic in an op must degrade to a null result, never
unwind into V8's FFI frame. Do not remove the robustness guards described in
AGENTS.md (the V8 watchdog, the tree.rs reparenting guards, the CLI deadline).
Do not bulk-run cargo fmt. The tree is not rustfmt-clean, so a blanket format
produces a large unrelated diff. Match the surrounding style in the files you
edit. Comments should explain non-obvious "why", not restate the code.
Commit messages
Keep them short and factual: what changed and why. We use a lightweight
type(scope): summary style, matching the existing history:
fix(cdp): honor text selection on Backspace and typing
Backspace trimmed the last character and typing always appended, ignoring
any selection. Both now respect a non-collapsed selection.
Fixes #316.
typeis one offix,feat,docs,test,perf,chore. Thescopeis optional and lowercase (for examplecdp,js,net,stealth,cli).- No em dashes. Use commas, periods, or restructure the sentence.
- No AI-generated filler ("This commit improves...", "As an AI...").
- Do not add
Co-Authored-Bylines or list yourself as a co-author.
Pull requests
- All submissions are reviewed; a maintainer merges after approval.
- Keep the diff small and readable. One logical change per PR. Split large contributions into several PRs.
- Reference the issue the PR closes, and say how you verified it (the test or repro that now passes).
Reporting bugs
Open an issue with enough detail to reproduce:
- The obscura version or commit, plus OS and architecture.
- A repro: a URL, an
--evalsnippet, or a short CDP sequence. - What you expected and what actually happened.
- If it is a rendering or compatibility issue, whether headless Chrome behaves the same. Anti-bot, CAPTCHA, and login walls block headless Chrome too from a datacenter IP, so those are not engine bugs.
Multi-statement --eval that starts with const returns null (V8 gives
const an empty completion value). Wrap repro snippets in an IIFE:
(function(){ ...; return result; })().
Security issues: do not open a public issue. See SECURITY.md for private reporting.
Scope and direction
Obscura targets web scraping and AI-agent automation, and is heading toward a hosted cloud scraping service. The priorities are real-world render success and robustness (no crashes or hangs). Conformance and new Web APIs are welcome when they do not regress performance or stability.
The stealth features are privacy-first anti-fingerprinting: they present a normal, consistent browser identity so ordinary automation is not singled out. Contributions that add detection-evasion for abusive purposes are out of scope.
License
By contributing, you agree that your contributions are licensed under the Apache License 2.0, the same license as the project.