|
1 | 1 | # Contributing to Fortress |
2 | 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 | | -- **`tools/verify_release.py <tag>`** — checks a published release is internally consistent: |
37 | | - every expected bundle asset is present and `SHA256SUMS` matches the SDK tables. Runs |
38 | | - automatically when a release is published; run it locally with `--full` to re-hash assets. |
39 | | - |
40 | | -Full build instructions: [docs/BUILD_NATIVE.md](docs/BUILD_NATIVE.md). Expect a multi-hour first |
41 | | -compile; incremental rebuilds after a one-line patch are minutes. |
42 | | - |
43 | | -### The de-branded switch prefix — do not rename it |
44 | | - |
45 | | -Runtime overrides are exposed as `--uxr-*` flags read through `base::UxrConfig`. That prefix is |
46 | | -intentional and **must stay `uxr`** — a neutral token so the binary carries no product string a |
47 | | -detector could match. A new surface means a new `--uxr-<surface>` flag; never a `--fortress-*` / |
48 | | -`--tilion-*` flag, and never a brand string literal baked into the binary. |
49 | | - |
50 | | -## Before you open a PR — run the checks |
51 | | - |
52 | | -CI runs these on every PR; run them locally first (`make check`): |
53 | | - |
54 | | -```bash |
55 | | -python tools/check_patches.py # patch-set integrity (series, numbering, single-surface, uxr-only) |
56 | | -python -m pytest sdk/python/tests -q |
57 | | -``` |
58 | | - |
59 | | -Optionally install the git hooks so they run automatically: |
60 | | - |
61 | | -```bash |
62 | | -pip install pre-commit && pre-commit install |
63 | | -``` |
64 | | - |
65 | | -Markdown links and badges in `README.md` and `docs/` are verified by the **links** workflow |
66 | | -([lychee](https://github.com/lycheeverse/lychee-action)) — on PRs that touch a `*.md` file and on |
67 | | -a weekly schedule. A hard 404 fails the job. If an external host merely rate-limits the CI crawler, |
68 | | -add it to [`.lycheeignore`](.lycheeignore) rather than leaving the check red. |
69 | | - |
70 | | -## Submitting a change |
71 | | - |
72 | | -1. **Open an issue first** for anything beyond a typo, so we can agree on the surface and approach. |
73 | | -2. **Branch** from `main`, focused on one surface / one fix. |
74 | | -3. **One patch per file, single-surface**, and add it to `patches/series`. |
75 | | -4. **Verify** with `tools/gauntlet.py`; paste the before/after into the PR. |
76 | | -5. **Rebase, don't merge** — `git fetch && git rebase origin/main` before pushing. The patch set is |
77 | | - rebased monthly onto new Chromium; a linear history keeps that sane. |
78 | | - |
79 | | -Docs, examples, the gauntlet, packaging, and the SDKs do **not** require a Chromium build — a great |
80 | | -place to start. |
81 | | - |
82 | | -## Security |
83 | | - |
84 | | -A page that *fingerprints* Fortress is not a security issue — file it in the open. A crash, sandbox |
85 | | -escape, or host leak **is** — report it privately per [SECURITY.md](SECURITY.md). |
86 | | - |
87 | | -## Licensing |
88 | | - |
89 | | -Fortress is BSD-3-Clause (a Chromium derivative — see [LICENSE](LICENSE) and [NOTICE](NOTICE)). By |
90 | | -contributing, you agree your contribution is licensed under the same terms. |
| 3 | +Fortress is built and maintained by its **core team**. To protect the stealth |
| 4 | +engine's invariants and keep the supply chain trustworthy, contributions are |
| 5 | +accepted **only from authorized core-team members**. |
| 6 | + |
| 7 | +## Policy |
| 8 | + |
| 9 | +- **Unsolicited external pull requests are not accepted and will be closed.** |
| 10 | + This explicitly includes branding / attribution / "brand refresh" PRs, |
| 11 | + dependency-bump PRs, and CI / GitHub Actions workflow PRs from non-team accounts. |
| 12 | +- **No third-party attribution, badges, or brand strings** may be added to this |
| 13 | + repository. Fortress is not affiliated with, and is not "built" or "maintained |
| 14 | + by," any outside party. |
| 15 | +- **CI / GitHub Actions from forks is never approved to run**, and workflow files |
| 16 | + are only added by the core team. |
| 17 | +- **Core-team members** coordinate with the maintainer before opening a PR. Any |
| 18 | + test change needing elevated permissions (CI secrets, publishing, infra) must be |
| 19 | + authorized in advance. |
| 20 | +- Changes to `patches/`, the SDK, packaging, and `.github/workflows/` require |
| 21 | + maintainer review — see [.github/CODEOWNERS](.github/CODEOWNERS). |
| 22 | + |
| 23 | +## Bug reports |
| 24 | + |
| 25 | +Anyone may open an **issue** for a genuine bug or question. Code, however, lands |
| 26 | +only through the core team. |
0 commit comments