|
| 1 | +# Contributing to Fortress |
| 2 | + |
| 3 | +Fortress is a stealth Chromium engine that corrects fingerprint surfaces in the browser's **C++**, |
| 4 | +then exposes raw CDP on `http://localhost:9222` as a drop-in for Playwright and Puppeteer. This |
| 5 | +guide covers how to report a detection and how to get a change merged. |
| 6 | + |
| 7 | +## The single most valuable contribution |
| 8 | + |
| 9 | +**A page that reliably flags Fortress.** A minimal, reproducible detector — a URL or short script |
| 10 | +that separates Fortress from real Chrome — is worth more than any feature. Open an issue with the |
| 11 | +**Detection vector** template. |
| 12 | + |
| 13 | +Before filing, sanity-check it is a **fingerprint** issue and not an **IP** one: roughly 90% of |
| 14 | +"it got blocked" reports are the datacenter IP getting flagged before any page script runs. Re-run |
| 15 | +through a residential or mobile proxy first — if it clears, the fingerprint was fine. See rule 4 in |
| 16 | +[AGENTS.md](AGENTS.md). |
| 17 | + |
| 18 | +## Two house rules |
| 19 | + |
| 20 | +1. **Every claim ships with a way to reproduce it.** A patch that changes a surface comes with the |
| 21 | + command or test page that shows the before/after. |
| 22 | +2. **Every limitation is written down.** If a patch is partial, say so in the patch header and the |
| 23 | + docs. The word *undetectable* stays out of this project — we correct specific, named surfaces. |
| 24 | + |
| 25 | +## How the patch set is organized |
| 26 | + |
| 27 | +Fortress is a set of source patches applied to a pinned Chromium checkout (`CHROMIUM_VERSION`), not |
| 28 | +a runtime library. |
| 29 | + |
| 30 | +- **`patches/`** — one patch per file, numbered, **single-surface**. `0002`/`0003` are the |
| 31 | + `base::UxrConfig` singleton every override reads from; the rest each touch one place. |
| 32 | +- **`patches/series`** — the apply order. **A patch not listed here is silently skipped** by |
| 33 | + `build/apply-patches.sh`, so always add your patch to `series`. |
| 34 | +- **`build/apply-patches.sh`** applies the series onto a Chromium `src/`. |
| 35 | +- **`tools/gauntlet.py`** — the live detection harness (CreepJS / Sannysoft / BrowserScan). |
| 36 | + |
| 37 | +Full build instructions: [docs/BUILD_NATIVE.md](docs/BUILD_NATIVE.md). Expect a multi-hour first |
| 38 | +compile; incremental rebuilds after a one-line patch are minutes. |
| 39 | + |
| 40 | +### The de-branded switch prefix — do not rename it |
| 41 | + |
| 42 | +Runtime overrides are exposed as `--uxr-*` flags read through `base::UxrConfig`. That prefix is |
| 43 | +intentional and **must stay `uxr`** — a neutral token so the binary carries no product string a |
| 44 | +detector could match. A new surface means a new `--uxr-<surface>` flag; never a `--fortress-*` / |
| 45 | +`--tilion-*` flag, and never a brand string literal baked into the binary. |
| 46 | + |
| 47 | +## Before you open a PR — run the checks |
| 48 | + |
| 49 | +CI runs these on every PR; run them locally first (`make check`): |
| 50 | + |
| 51 | +```bash |
| 52 | +python tools/check_patches.py # patch-set integrity (series, numbering, single-surface, uxr-only) |
| 53 | +python -m pytest sdk/python/tests -q |
| 54 | +``` |
| 55 | + |
| 56 | +Optionally install the git hooks so they run automatically: |
| 57 | + |
| 58 | +```bash |
| 59 | +pip install pre-commit && pre-commit install |
| 60 | +``` |
| 61 | + |
| 62 | +## Submitting a change |
| 63 | + |
| 64 | +1. **Open an issue first** for anything beyond a typo, so we can agree on the surface and approach. |
| 65 | +2. **Branch** from `main`, focused on one surface / one fix. |
| 66 | +3. **One patch per file, single-surface**, and add it to `patches/series`. |
| 67 | +4. **Verify** with `tools/gauntlet.py`; paste the before/after into the PR. |
| 68 | +5. **Rebase, don't merge** — `git fetch && git rebase origin/main` before pushing. The patch set is |
| 69 | + rebased monthly onto new Chromium; a linear history keeps that sane. |
| 70 | + |
| 71 | +Docs, examples, the gauntlet, packaging, and the SDKs do **not** require a Chromium build — a great |
| 72 | +place to start. |
| 73 | + |
| 74 | +## Security |
| 75 | + |
| 76 | +A page that *fingerprints* Fortress is not a security issue — file it in the open. A crash, sandbox |
| 77 | +escape, or host leak **is** — report it privately per [SECURITY.md](SECURITY.md). |
| 78 | + |
| 79 | +## Licensing |
| 80 | + |
| 81 | +Fortress is BSD-3-Clause (a Chromium derivative — see [LICENSE](LICENSE) and [NOTICE](NOTICE)). By |
| 82 | +contributing, you agree your contribution is licensed under the same terms. |
0 commit comments