Catalogue · The data
The registry as data
153 entries · 38 columns · 10 sections
15 columns carry a fetch date
Read at 2026-08-14T09:12:00Z
2ND ED., 1ST PRINTING · CC0-1.0
This catalogue's whole claim is that its states are derived, not asserted. That is only worth anything if you can take the fields the derivation read and run the rule yourself, so the register is published as data before it is published as a page — the same file, the same instant, the same rubric edition. If your recomputation disagrees with what is printed here, the register is wrong, and a correction is issued against a named edition rather than quietly edited.
Three files, one printing
| File | Size | What is in it |
|---|---|---|
|
registry.json
application/json |
225 KB | Header, schema, sections and every entry. The whole printing in one object. |
|
registry.csv
text/csv |
71 KB | One row per entry, 38 columns in the order printed below. Arrays joined with a semicolon. |
|
README.md
text/markdown |
14 KB | The schema and the licence in plain text, generated from the same field list as this page. |
All three are generated from one field list at build, so the CSV cannot drift from the JSON and neither can drift from the schema printed below — a column that is not declared here cannot exist in the payload. The files carry no key, no rate limit and no terms: fetch them from a script, mirror them, or paste them into a spreadsheet. Every payload begins with its own header — edition, printing, corrected-to date and field check — so a copy that has been sitting on a disk for a year can still say exactly what it is.
How to read a column: the four provenance classes
| Class | Columns | What it means, and what it does not |
|---|---|---|
| measured | 16 | Read from the endpoint named beside it, at the field-check instant. Never guessed: a field the sweep did not capture is null. |
| derived | 9 | Computed from measured fields by the rubric in force. Recomputable from this same file; nothing here is stored by hand. |
| transcribed | 4 | Copied from the source itself — its own name, its own URL, its own words condensed to one sentence. Not a claim this register makes. |
| editorial | 9 | The curator's decision: placement, keying, declared relations, flags and the signed annotation. The only opinion in the payload. |
The split that matters is between the first two and the last two. A measured column is a reading from a named endpoint at a named instant, and a derived one is arithmetic on those readings under a printed rule — both are falsifiable against the source. A transcribed column repeats what a project says about itself, and an editorial one is a person's decision. Those last two are not evidence and are not dressed as it: 13 of the 153 entries carry a signed annotation, and it sits in its own column so you can drop it.
Which columns carry a fetch date
15 of the 38 columns are readings taken at one instant and at no other — they are marked dated in the schema below, and every one of them is equal to 2026-08-14T09:12:00Z in this printing. Star counts and push dates are in that group, which is why this register never prints them as live figures. The remaining 23 columns are either derived from the dated ones or are text that does not rot on a clock. A field the sweep did not capture is null; it is never guessed, and 5 entries in this printing have a null pushed_at and are stated through the rubric's printed fallback instead.
The schema, column by column
| Column | Type | Provenance | Source | Note |
|---|---|---|---|---|
| slug | string | editorial | Curator, signed | The key this entry is filed under. Stable across printings; a slug is never reused for a different project. |
| name | string | transcribed | The project, at its own URL | Spelled as the project spells it, including capitalisation the register would otherwise normalise. |
| url | string | transcribed | The project, at its own URL | The exact URL the link check was made against. Where a vendor host refuses automated clients, this is the docs host and the substitution is carried in flags. |
| section | string (01–10) | editorial | Curator, signed | One of ten sections. An entry sits in exactly one; cross-topic entries are placed where a reader would look first, not where they fit best. |
| section_slug | string | editorial | Curator, signed | The section's URL segment, so a row can be joined back to its printed section without a lookup table. |
| kind | repo | page | docs | paper | dataset | community | product | editorial | Curator, signed | What sort of thing this is, which decides which fields can exist at all: only a repo carries pushed_at, only a non-repo is stated by the link check alone. |
| description | string | transcribed | The project's README, docs or abstract | One sentence, condensed from what the source says about itself. It is never a finding, an endorsement or a test result. |
| language | string | null | transcribed | The project, at its own URL | Implementation language as the project states it, not as GitHub's linguist guesses it. |
| repo_path | string | null | measured | GET https://api.github.com/repos/{owner}/{repo} | owner/name as it appears in the API path. Null for every entry with no repository, which is what makes the rest of the repository columns null too. |
|
pushed_at
dated |
date | null | measured | GET https://api.github.com/repos/{owner}/{repo} → pushed_at | The liveness field. Null where the sweep did not capture it, in which case the rubric's fallback clause reads release_published_at instead and says so in derivation. |
|
created_at
dated |
date | null | measured | GET https://api.github.com/repos/{owner}/{repo} → created_at | Used only as the denominator of stars_per_day. It sets no state. |
|
stars
dated |
integer | null | measured | GET https://api.github.com/repos/{owner}/{repo} → stargazers_count | A reading taken at one instant, not a live figure, and it sets no state. It is the least important number in the row. |
|
forks
dated |
integer | null | measured | GET https://api.github.com/repos/{owner}/{repo} → forks_count | Captured where the sweep recorded it. Sets no state. |
|
archived
dated |
boolean | null | measured | GET https://api.github.com/repos/{owner}/{repo} → archived | A maintainer's own statement, and the one measured field that outranks every date rule. |
|
archived_at
dated |
date | null | measured | GET https://api.github.com/repos/{owner}/{repo} → archived_at | Captured where GitHub returned it. Its absence never implies the archive flag is false — read archived for that. |
|
release_tag
dated |
string | null | measured | GET https://api.github.com/repos/{owner}/{repo}/releases/latest → tag_name | The latest tagged release as the project tagged it. Null is ambiguous on its own, which is why no_releases exists. |
|
release_published_at
dated |
date | null | measured | GET https://api.github.com/repos/{owner}/{repo}/releases/latest → published_at | Stands in for pushed_at under the fallback clause. Where it does, derivation names the substitution. |
|
no_releases
dated |
boolean | measured | GET https://api.github.com/repos/{owner}/{repo}/releases/latest → 404 | True means the repository has published no tagged release at all. False with a null release_tag means the sweep did not capture one — a different thing, kept a different field. |
|
http_status
dated |
integer | null | measured | HEAD, then GET on failure, against url — redirects not followed | 0 means the request did not complete at all. Any status of 400 or worse is tested first and produces DEAD, because an unreachable URL cannot be rescued by another field. |
|
http_checked_at
dated |
timestamp | null | measured | HEAD, then GET on failure, against url — redirects not followed | The instant the link check was made. Equal to checked_at in this printing, and carried per row so a later partial re-sweep cannot lie about it. |
|
http_note
dated |
string | null | measured | HEAD, then GET on failure, against url — redirects not followed | What the non-200 was: the response, the redirect target, or the failure mode. Printed verbatim on the field log. |
|
http_redirect_to
dated |
string | null | measured | HEAD, then GET on failure, against url — redirects not followed → Location | Where a 301 pointed. This is the whole evidence for WITHDRAWN: the maintainer said where the work went, and the register did not infer it. |
|
license_spdx
dated |
string | null | measured | GET https://api.github.com/repos/{owner}/{repo} → license.spdx_id | Null means no licence is declared, which is a finding rather than a gap — see license_bucket. NOASSERTION means a licence file exists that SPDX could not identify. |
| license_bucket | permissive | copyleft | custom | none | na | derived | licenseBucket(), from license_spdx | none is the one that matters: an entry you cannot legally reuse. na is for entries with no source to license, such as a test page. |
| state | ACTIVE | SEMI | NRND | WITHDRAWN | ARCHIVED | DEAD | derived | Rubric, second edition, thresholds in force | Never stored, never asserted, never supplied by a submitter. Recompute it from the measured columns and this file must agree with the printed page. |
| state_first_edition | string | derived | Rubric, first edition (superseded) | The same field data put through the superseded rules. Where it differs from state, the difference is a property of the rules and not of the world. |
| state_moved | boolean | derived | state ≠ state_first_edition | True for every row printed on the errata leaf for this printing. |
| derivation | string | derived | Rubric, second edition, the clause that fired | The rule that set the state, in the rubric's own words, with the values it read quoted inside it. This column is the audit trail. |
| age_days | integer | null | derived | checked_at − the liveness field | Whole days between the liveness field and the field check. Measured against the printing's instant, never against the reader's clock, so a page reprints identically in a year. |
| release_bucket | r30 | r180 | r365 | rold | rnone | runknown | derived | release_published_at, bucketed | The recency facet the filter rail counts against. runknown is not rnone: one means unread, the other means none exists. |
| stars_per_day | number | null | derived | stars ÷ age of created_at | Two measured numbers divided. Not a rank, not a score, not a comparison against any population of tools — this register has measured none. |
| verify_independently | boolean | derived | stars_per_day > 25 | The unverified flag, and the only place this register raises an eyebrow in a column. It changes no state and accuses nothing; it says check the contributor graph yourself. |
| flags | string[] | editorial | Curator, signed | Conditions the reader should know before trusting the row: young-repo, vendor-operated, freemium, historical, listed-elsewhere, docs-host-substituted, no-license. |
| supersedes | string[] (slugs) | editorial | Curator, signed | Declared, not inferred. Both directions are stored once and reversed at build, so the graph cannot contradict itself. |
| superseded_by | string[] (slugs) | editorial | Curator, signed | Feeds one rubric clause: a quiet entry whose declared successor reads ACTIVE is marked NRND rather than left looking healthy. |
| alternative_to | string[] (slugs) | editorial | Curator, signed | Symmetric. Substitutes for the same job, with no claim that either is better. |
| annotation | string | null | editorial | Curator, signed | The signed verdict, printed in italic typewriter face and kept separate from every other column precisely so it can be ignored. |
|
checked_at
dated |
timestamp | measured | The sweep's own clock | The instant every dated field in this row was read. It is the same value on every row of this printing, and it is the only claim this file makes about how current it is. |
The derivation column is the one to read first if you are checking this register rather than using it: it carries the rule that fired, in the rubric's own words, with the values it read quoted inside it. The thresholds behind it are printed on the rubric, and the superseded first edition stays in print at /method/1 so any state it set can be audited against the rules that set it rather than against these.
The entries this register does not vouch for
Two columns exist to mark an entry as not independently confirmed: verify_independently, set when a repository's stars divided by its age exceed 25 a day sustained since creation, and the young-repo value in flags. Neither changes a state and neither is an accusation. They are printed because a register that lists a 30k-star repository with six months of history and says nothing about the arithmetic is doing the reader's work badly.
| Entry | State | The two numbers | Why it is marked |
|---|---|---|---|
|
CloakBrowser
Section 01 |
ACTIVE |
30k stars
created 2026-02-22 |
173 stars a day sustained since creation, over the printed 25-a-day threshold. Repository under one year old, so it has no release history to read. Vendor-operated. |
|
ShardBrowser
Section 01 |
ACTIVE |
638 stars
created 2026-05-30 |
Repository under one year old, so it has no release history to read. Vendor-operated. |
|
clearcote-browser
Section 01 |
ACTIVE |
75 stars
created 2026-06-15 |
Repository under one year old, so it has no release history to read. Vendor-operated. |
What is deliberately not in this file
No score, no percentile, no rarity figure, no rating and no comparison of tools against any population: this register has tested no tool, so there is no honest denominator for one. No detection-test results: no entry here has been run against Cloudflare, DataDome, Kasada or anyone else by this register, and where a project's README claims it is undetected, the payload records that the claim was made and does not repeat it as a finding. No traffic figures, no popularity ranking, and no column whose value cannot be re-fetched from the endpoint printed beside it.
Licence, and how to cite a printing
CC0-1.0. To the extent possible under law, the keepers of this register waive all copyright and related rights to the data in these three files. No attribution is required and no permission needs asking — that is the licence the awesome.re manifesto requires of a list, and it is the licence this one is published under. The waiver covers the register's own fields only: the projects listed are under their own licences, recorded in license_spdx, and this says nothing about them.
WHOLE ANTIDETECT CATALOG, 2ND ED., 1ST PRINTING, corrected to 2026-08-14. https://awesomeantidetect.com/data/registry.json
A citation names the printing because the data moves and the rules move separately: a state you quote from this file is a statement about 2026-08-14 under the second edition of the rubric, and it stays true about that date forever. How the two ordinals are counted, and how a correction is issued when one of these rows turns out to be wrong, is printed in the colophon. The criteria a new row has to satisfy before it can appear here are on the submission page.
The keeper's own row
donut-browser is a row in these files with the same columns as everything else, derived by the same rule, and the people who keep this register work on it. That disclosure is printed on the front sheet, in the colophon and here, because the alternative is hoping nobody joins the CSV to the byline. Donut Browser is an open-source anti-detect browser under AGPL-3.0: engine-level fingerprint spoofing through the Wayfern Chromium fork rather than JavaScript patching, a local REST API and MCP server on your own machine, self-hostable sync, and a pre-launch gate that refuses to start a profile when the proxy's exit geography contradicts the profile's fingerprint.
curl -fsSL https://donutbrowser.com/install.sh | sh
macOS · Windows · Linux · Nix. Desktop only. Source, AGPL-3.0
A list that publishes only its verdicts is asking to be trusted. A list that publishes the fields underneath them is asking to be checked, which is a much smaller thing to ask and the only one worth asking. — ED.