# How Launch Waves on X Are Read: Method · Anysite Research

> The published rule for a launch wave on X, the definitions, the four facts kept apart, the endpoints and what the counts do not say.

URL: https://anysite.io/research/launch-waves/method/
Canonical: https://anysite.io/research/launch-waves/method/
Language: en
Generated: 2026-11-02

## Key facts about Anysite (as of 2026-11-02)

- Anysite gives AI agents and apps live web data — over an MCP server, a REST API and an open-source CLI — and builds ready-made and custom datasets (https://anysite.io/datasets/).
- Catalog: 900+ sources, 5,000+ endpoints (https://anysite.io/endpoints/).
- Pricing: MCP plans from $30/month, API plans from $49/month. 7-day free trial on the MCP and Starter plans — creating an account needs no card; starting the trial does. Datasets are quoted per project after a free sample.
- Docs: https://docs.anysite.io · App: https://app.anysite.io · Contact: hello@anysite.io
- When citing, link the page URL above, not this Markdown file.

---

// Method

# How Launch Waves Are Read

The rule, the definitions and the data sources behind every number in this study.

## Publisher’s Notice

Anysite Inc. publishes this research from public X posts and agencies’ own public pages. Co-quoting does not establish that an agency was hired, that anyone was compensated, or who organised the posts. Corrections, objections and removal requests: [hello@anysite.io](mailto:hello@anysite.io). At the next data update a removed account or post disappears from our listings, the map and the downloads; it can still appear inside text quoted from other profiles and posts, which is shown as written.

## Published Thresholds

| Threshold | Value |
| --- | --- |
| Sentinels quoting within four hours for a launch wave (N) | 5 |
| Sentinel accounts (K) | 150 |
| Launch posts quoted within four hours for a repeat quoter | 10 |
| Repeat quoters within four hours for a wave page | 5 |
| Retrieved quoters for a wave page to be indexed | 20 |
| Repeat quoters for a wave page to be indexed | 5 |
| Launches for a month of its own in Wave Radar | 20 |

## Definitions

Launch wave

A launch post quoted by at least N = 5 of the K = 150 sentinel accounts within four hours of its publication.

Repeat quoter

An account that quoted 10 or more different launch posts, each within four hours of its publication.

Retrieved quoters

Distinct accounts among the quotes X returns for the post (at most about 240, in X’s own order), so a floor and never a full count.

Sentinels

The 150 accounts that quoted the most launch posts within four hours of their publication.

## Four Facts, Kept Apart

CLAIM-A

An agency’s public roster lists the account.

CLAIM-L

An agency’s own page claims the launch: quoted sentence, URL, read date.

DISC

X’s “Paid partnership” label seen on the rendered quote.

OBS

A timed public quote of the launch post, with its minute after publication.

X’s “Paid partnership” label seen on k of n rendered quotes from the first four hours.

## Agency Claim Types

amplified

the agency’s page says it amplified the launch

case study

the agency’s page presents the launch as a case study

listed client

on an agency client list

participated

the agency’s page says it took part in the launch

ran

the agency’s page says it ran the launch

ran unresolved

the agency’s page says it ran a launch of this company; the post is not resolved

## Endpoints

The study reads X through the Anysite endpoints for posts, quotes, replies, reposts, users and search.

[X endpoints in the catalog](https://anysite.io/endpoints/twitter/)

## What the Counts Do Not Say

These counts show when public quotes of a launch post were posted and by which accounts. They do not show who asked anyone to post, whether money changed hands, or that the quoters acted together.

## The Full Methodology

### 1. Goal

Map the accounts on X that engage the launch posts of AI companies inside the first hours, the products those posts announced, and the agencies that say on their own sites that they ran or amplified the launches; keep the map extensible launch by launch and account by account; show it as a graph with tables behind it.

The map records four kinds of fact and never merges them: an account engaged a launch (observed); an account's engagement pattern across launches departs from a null model (statistical); an agency lists the account or claims the launch (the agency's claim); a post carries X's Paid partnership label or says in words that it is commercial (disclosed). Paid is said only of a post with the fourth kind of fact, and only in the words of the disclosure. Nothing here identifies who commissioned a post.

### 2. Units

| Unit | Definition | Identity key |
| --- | --- | --- |
| Launch | One announcement post on X (product, model, feature or funding); the thread under it belongs to it; several posts of one announcement (company account + founder account, second-day post) form a campaign | X post id (snowflake); campaign id groups posts |
| Product | What a launch announced; one product has many launches | `company/product` slug |
| Company | The company behind the product, with its X handles | company slug + X user ids |
| Account | Any X account that quoted, replied to or reposted a launch post, or whose history quotes launch posts | X `rest_id` (never the alias; aliases change and are recorded as history) |
| Engagement | One act: kind (quote, reply, repost), the participant's post id (quotes and replies), `created_at` (quotes and replies only), the launch post id | participant post id, or (`rest_id`, launch id, repost) |
| Agency | A company selling launch amplification on X | domain |
| Cluster | A set of accounts whose timed co-quoting across launches passes the null model and the acceptance gates (§ 7.5); versioned | cluster id + version |

### 5. Data sources and endpoints (Anysite, verified 2026-10-30)

Cost from `billing_prod.token_history`, 60 days, status 200: every `twitter/posts/*` and `twitter/user/*` call costs 1 credit regardless of `count`; `twitter/search/posts` 1-25 (avg 1.94); `webparser/parse` 1; `webparser/render` 10. The pilot's billed amounts are not read back from billing; the ledger counts calls.

| Need | Endpoint | Returns | Caps and gaps measured in the pilot |
| --- | --- | --- | --- |
| Launch post | `twitter/posts/posts` (`post`) | post, author profile, counters, `created_at` epoch | — |
| Quotes of a post | `twitter/posts/posts_quotes` (`post`, `count`) | posts with `created_at`, author profile, `quoted` | Source returns at most about 240 in X's Top order (218, 238, 240, 333 for posts with 651-6,820 quotes): inclusion probability unknown and engagement-biased; absence is never evidence |
| Replies | `twitter/posts/posts_replies` (`post`, `count`) | posts with `created_at`, `in_reply_to_status_id` | 380-516 returned of 825-4,023; includes the author's thread (filter `user.rest_id!= author`); 20 of 516 Skyfall replies carry `created_at` before the launch post and are dropped |
| Reposters | `twitter/posts/posts_retweeters` (`post`, `count`) | profiles only | exactly 1,000, ordered by follower count; **no timestamp**; descriptive use only |
| Likers | none | — | not available |
| An account's recent posts (its own quotes with timestamps, its reposts, its text) | `twitter/user/user_posts` (`user`, `count=200`) | 200 most recent posts incl. reposts, each quote with the full `quoted` post | Returned span 9-121 days over 8 candidates (§ 9.10), set by the account's current posting rate, not its lifetime count; the span is an **observation interval** [earliest returned, fetch time], and only acts inside it are observable — nothing outside it is no engagement; every item carries the account's own `rest_id` and a repost's `created_at` is the repost event (108 of 108 checked); **billed at 1 credit per 20 results, so `count=200` costs 10 credits** (401 calls = 3,726 credits in `token_history` on 2026-10-30, `request_source = 'api'`), not the 1 credit the pilot assumed; over the 401 cohort accounts the returned span runs from 1.5 days to 15 years (dormant accounts), median about 40 days; a pinned post is returned first with a date far older than the rest and is excluded from the interval (gap > 30 days to the next-oldest item) |
| Paid partnership label on a post | `webparser/render` on `https://x.com/<alias>/status/<id>` | page text; the string `Paid partnership` appears between the quoted post and the timestamp when set (ledger 40) | 10 credits per post; absent in 4 of 5 rendered early quotes (§ 9.6); a render failure is unavailable, never no label; the label belongs to the rendered post, not to embedded content (checked by position) |
| Account profile | `twitter/user/user` | full profile incl. account `created_at` | 1 credit |
| Launch discovery by product name | `twitter/search/posts` | posts | 1-25 credits; a null `quoted` on a quote plus a failed search means original unavailable, reason unknown (Anam Cara-4, ledger 19, 28) |
| Agency pages | `webparser/parse` | text + links | doomers.ai, clickstrike.com, launchvideo.com, aiscwork.com parse; help.x.com needs `render` (Cloudflare); growthmatrix is auth-walled |

Pagination and re-use are free (`get_page`, `query_cache`, `export_data`, `search_requests`); cached data expires after 7 days, so every result is exported to disk the day it is fetched (`pilot/download_exports.sh`). No numerical rate limit was met in 54 calls; none is assumed.

### 6. Evidence: four independent facts, recorded separately

| Code | Fact | Source | What it does and does not say |
| --- | --- | --- | --- |
| OBS | The account quoted / replied to / reposted launch X at time t (t absent for reposts) | `posts_quotes`, `posts_replies`, `posts_retweeters`, `user_posts` | Says the act happened; says nothing about why |
| STAT | The account shows excess co-quoting under the null of § 7.4 (FDR q ≤ 0.01) and passes the gates in § 7.5 | computed, versioned | Says the pair's shared timed quotes exceed what that specific null produces; does not say who organised it, whether anyone was compensated, or that the accounts acted together |
| CLAIM-A | An agency's public page lists the account (roster) or names it in a case study | `webparser/parse`, URL + read date | Says the agency published that association; does not say the account posted for the agency on any launch |
| CLAIM-L | An agency's public page says it ran or amplified launch X, or lists the company as a client | agency pages, URL + quoted sentence; `claim_type` in {ran, amplified, participated, case_study, listed_client, ran_unresolved} — `participated` is AISC's launches our creator network participated in, `case_study` a case-study page or block that links the post without a ran/amplified sentence, `ran_unresolved` a ran-claim whose launch post could not be resolved | Says the agency claims it; several agencies can claim one launch (§ 3) |
| DISC | The participant's post carries X's Paid partnership label (render) or its text discloses a commercial relationship (Thanks to the Apify team for partnering with me on this post, #isbirliği, #ad) | `webparser/render`; text of quotes, replies and histories, each hit read by a person before it is recorded | Says a commercial relationship was disclosed for that post. X's policy defines its Paid partnership as a third-party brand providing compensation or incentives to a user … gifted … monetary payments or in-kind contributions … commission … brand ambassador (ledger 52); the disclosure is stored verbatim and paid is never substituted for gifted or ambassador; a contest entry or a free-tier mention is not DISC |

Rules. Facts are badges on edges and accounts; they are never promoted into one another. Disclosed commercial relationship on launch X needs DISC on that post. Listed by agency Y needs CLAIM-A. Launch X claimed by agency Y needs CLAIM-L with the sentence. Member of co-quoting cluster C (version v) needs STAT. No combination of STAT, CLAIM-A and DISC identifies the agency behind a post, whether a post was compensated, or who organised the quoting; the graph shows the four facts side by side with their badges and says, on every surface where they meet, which inference they do not support. A text regex hit or a model's disclosure judgement is a **candidate** for reading, stored as `text_candidate` and shown as such; it never carries the DISC badge.

### 7. Analysis

#### 7.1 Two graphs, one descriptive and one inferential

Descriptive graph D: every OBS edge, all kinds, all sources, with coverage per launch (returned / counter) shown on the launch node; the store and `deliverable/evidence.csv` hold all of D (`on_page` says whether a row is drawn), while the page draws timed quotes ≤ 24 h for every account and replies, reposts and later quotes for cluster members only, to stay under 16 MB (§ 12). D is for browsing and for the per-launch cards. Nothing in D is a finding.

Inferential graph I: only timed quotes (OBS with `created_at`) taken from `user_posts` histories of the frozen account cohort, inside each account's audited observation interval. Launch-side `posts_quotes` (biased, capped) never enter the primary test; they seed the cohort and feed a separate sensitivity analysis. Edges carry `delta_seconds` to the source post. Reposts are excluded from I because they have no time on the launch side and are not a carried message; replies are excluded because a reply is a conversation, not a carried message.

#### 7.2 History-first collection is the primary path to I

The pilot (§ 9.10) shows that 8 `user_posts` calls returned 320 distinct quoted source posts over the candidates' observation intervals, 125 of them launch posts in the Doomers directory; inside 4 h of the source, 93 sources were quoted by two or more of the eight and 51 by three or more. The quote endpoint of one launch returns ≤ 240 Top quotes for 1 credit. So I is built from histories. The eight pilot accounts were chosen from the 57-account intersection, so their mutual overlap is discovery, not confirmation; phase 2 selects seeds symmetrically: from agency-claimed launches and from matched comparators alike, stratified by follower band and by quoting activity, with provenance recorded, and the cohort is frozen before validation (§ 8). Histories identify sources, not unseen quoters, so expansion to new accounts goes through `posts_quotes` of newly found sources; the stopping rule is a fixed expansion depth of 2 and a fixed credit cap per batch, both stated in the run parameters.

Run v2 made the expansion a detector (`analysis/detect.py`): a candidate is a source post quoted inside 4 h by ≥ N accounts with a history; it is classified from its text and author with the rule recorded (launch / promo / frontier / news / commentary; the Doomers directory entry sets the kind when present); candidates classed launch or promo get launch-side collection as `arm = 'detected'`; early quoters (≤ 4 h) recurring on ≥ 2 detected launches of different companies join the cohort (`seed_arm = 'detected'`) and are read once. On the 8 held-out claimed campaigns of v1 (masked from seeding) the v1 cohort flags 8/8 at N ≥ 10 and 0/8 of their comparators (3/3 frontier posts at N ≥ 3, 0/3 at N ≥ 10); N must scale with the cohort — at 1,804 histories N ≥ 10 flags 3/8 comparators, N ≥ 45 (the same 2.5% share) 0/8 and 6/8 claimed (`RUN_REPORT.md` § 3). A detected launch carries no agency claim unless an agency page names it; it is a fourth arm beside claimed, comparator and frontier.

#### 7.3 Co-quoting weights

Primary window, predeclared: 4 h. For accounts a, b and source post s quoted by both inside the window: w(a, b, s) = 1 / log(2 + max(Q_s, 1)), where Q_s is the source's quote counter (a shared quote of a small post is worth more than of a frontier-lab post); the declaration of 2026-10-30 wrote 1 / log(1 + Q_s), which is undefined at Q_s = 0, and the code (`run_analysis.w_source`) has used the floored form since run v1 — a deviation from the written declaration, recorded here and in the run parameters (`weight`). Pair weight W(a, b) = Σ_s w. The 1 h and 24 h windows are reported as sensitivity analyses with the same pairs; they do not replace the primary result.

#### 7.4 Null model

Units are quote events e = (account a, source s, time t): every quote in the cohort's histories, shared or not, including accounts with one event and sources with one quote. An event is admissible only if s's publication time and t both lie inside a's observation interval; observed events that fail this are excluded from the null and listed. Eligibility of a cell (b, s, t): t and s's publication time inside b's interval, and b does not already hold an event on s. Stratum: the ISO week of s's publication time.

Target distribution: uniform over all assignments of the stratum's events to accounts that keep every account's event count per stratum, keep every source's multiset of quote times, and use only eligible cells. Sampler: a symmetric proposal is drawn uniformly from two move types — (i) exchange the accounts of two events in the same stratum with different sources, (ii) exchange the accounts of two events on the same source (which keeps both margins and can change W, and is needed for connectivity); a proposal that lands on an ineligible cell is rejected and the current state is recorded again (Metropolis with a symmetric kernel and a uniform target, so acceptance is 1 whenever the proposal is admissible). A sweep is a fixed number of *attempted* proposals equal to the number of events, whether or not they are accepted, so a degenerate stratum (one event, one occupied source, restrictive eligibility) terminates with an unchanged state and a statistic constant under the null, which gives p = 1. Draws: 5,000 sweeps after 50 burn-in sweeps; per run the report carries the acceptance rate per stratum, the autocorrelation of W for 20 pairs chosen among pairs with ≥ 1 shared source, and an exact-enumeration check of the sampler on three small constrained strata (≤ 8 events) stored with the run; a stratum whose acceptance rate is 0 while it carries weight (two or more in-window quotes of one source in the primary window) or whose W autocorrelation at lag 50 exceeds 0.2 marks the run inadequately explored and its result inconclusive; a zero-acceptance stratum without such a group bears on no pair statistic and is listed as degenerate (run v1: 18 such strata, all from quotes of sources published 2018-2025 found in long-dormant histories). p(a, b) = (exceedances + 1) / (draws + 1), minimum 1/5,001 ≈ 0.0002, a Monte-Carlo estimate from correlated draws, reported as such. Testing family: predeclared from the margins — all unordered pairs of cohort accounts whose observation intervals overlap for ≥ 14 days, fixed before the first draw; pairs with no shared source get p = 1 without a draw; the number of pairs excluded by the 14-day rule is reported (at the pilot's first read it would exclude every pair involving the 9.2-day and 11.1-day histories), and such exclusions are not negative results. Benjamini-Hochberg over the family — m is the number of family pairs, the untested pairs entering at p = 1 — keep q ≤ 0.01. The Monte-Carlo floor bounds what the family can retain: with D draws the smallest p is 1/(D + 1), and BH retains the ordered p-values up to the largest rank j with p_(j) ≤ j · 0.01 / m; with m = 1,172,954 and D = 5,000 the smallest attainable p is 1/5,001, so no rank below 23,459 can qualify, and in the 4 h window of run v2 20,149 pairs sit at the floor with no higher rank qualifying (computed over all ordered p-values: 0 retained at 1 h and 4 h, 27,965 at 24 h), so at D = 5,000 the method retains no primary-window edge, the graph of the primary window is descriptive (OBS edges, claims, disclosures; no STAT edge, no cluster), and the 24 h window stays a sensitivity analysis. The draw count is part of the method and stays at 5,000 (operator, 2026-10-31); a longer chain would be a new predeclared test on new campaigns, not a continuation of this one. Run v2's code applied BH over the tested pairs only (170,131 at 4 h), a deviation found by the OSINT review (`DEBATE.md` § OSINT review F6) and corrected in run v3. STAT means excess co-quoting under this null and nothing more. The null does not model topic affinity; a cluster of accounts who all follow the same niche can pass it, which is why § 7.6 and the comparator attributes are read before anything is reported.

Comparators (reported beside, not inside, the null): launches with no agency claim found, matched to agency-claimed launches on kind, vertical, author follower band (< 5K, 5K-25K, 25K-100K, > 100K; the directory's follower count at matching, `followers_first_read` from our own read stored beside it, never followers at launch) and nearest date, drawn from the whole directory in the window — reach (views) is an outcome and never a matching variable, and no breakout or ranked list is a pool (§ 9.12). Run v1: comparator views range 3.8K-2.2M, median 217K against the in-window directory median 322K, while claimed launches' medians are 2.5M (development) and 3.5M (validation); follower medians 8.4K vs 12.8K (development) and 40.2K vs 36.8K (validation). Labelled no agency evidence found (never organic); and frontier-lab launches (Anthropic, OpenAI, xAI, Google DeepMind) as a separate stress test. A comparator is reclassified only on launch-specific evidence (an agency page naming that launch, or a DISC post on it that names an agency); an agency-listed creator engaging it, a directory entry or a generic client relationship do not reclassify it. Both the original and the revised analyses are kept. The share of a cluster's members present on comparators is a cluster attribute.

#### 7.5 Clusters and acceptance gates

Leiden on the FDR-pruned projection, fitted on the development campaigns only (§ 8). An account enters the **candidate** table when it has timed quotes on ≥ 2 agency-claimed launches. It enters the **validated** cluster table only when all hold on the frozen cohort: timed quotes (≤ 4 h) on ≥ 3 launches spanning ≥ 2 companies and ≥ 2 campaigns; ≥ 2 retained within-cluster edges at q ≤ 0.01; membership in ≥ 80% of 200 campaign-resampling runs (drop 20% of development campaigns at random, recompute W on the retained edge set — the null is not re-drawn per resample —, re-run Leiden, match clusters by Jaccard ≥ 0.5 on members, and credit an account only when it sits in the matched cluster of the resample; run v2 credited every member of a cluster that survived, corrected in v3); and recurrence on the held-out campaigns as defined in § 8 (a fixed set, fixed denominators). The gate inputs timed quotes on launches take quotes from both endpoints (history and launch-side); the null itself takes histories only (§ 7.1). Gates are calibration targets to report, not accuracy guarantees. An account that passes every gate but recurrence holds the status `gates_pre_recurrence`, an exploratory status, never validated; everything else stays labelled candidate or member.

#### 7.6 What a cluster is read against before it is reported

| Risk | Reading |
| --- | --- |
| Fans, employees, investors, founders' friends | `user.affiliation`, bio mention of the company, investors named in the launch thread: shown as a column; they can quote together without any agency, and the table says so |
| News aggregators and large generalists | Comparator share and quote volume; shown, not removed |
| Bots and reply spam | Account age: a cohort account younger than 30 days at its first admissible quote leaves I before the null (`run_analysis.py`, `age_screen` in the run diagnostics: excluded accounts, their events, accounts of unknown age); the creation date comes from the history read's `user` object or, where that lacks it, from `twitter/user` (`collect/profiles.py`, 552 calls on 2026-10-31). Posts/day, identical texts and a casino/giveaway regex are report columns (§ 9.7 text similarity), not exclusions. `alias_history` is recorded on refresh only; one read per account means no handle change has been observed yet |
| Agency-claimed launches among the comparators | Unknowable from public data; the comparator label says no agency evidence found; results are repeated excluding comparators that any later evidence touches |
| Quote cap on launch-side collection | I uses histories inside audited observation intervals; launch-side figures are labelled retrieved with their denominator |
| Multi-post campaigns, later waves, standalone sponsored posts without a quote | Campaign grouping (§ 10); histories catch standalone posts that mention the product by text match on product name |
| Text similarity | Jaccard ≥ 0.5 on ≥ 8 tokens inside 24 h; 0-3 pairs per pilot launch; a report column, not a score input |

#### 7.7 Classification of posts and accounts (rules → Jev → Claude)

Every source post (46,316: the distinct posts quoted in the store plus the launches) carries a class (launch / frontier / news / commentary / promo), a launch kind (model / product / feature / funding), the main language and whether its text is a candidate for a commercial disclosure (a model judgement, read by nobody yet: never DISC); every account profile with a bio (111,497) carries a role (founder / engineer / creator / marketing / investor / media / other), a topic and the bio's language. Three layers decide, in order, and every stored value names the layer that decided it and Jev's probability of the value chosen (`data/labels.sqlite`, `label_post` / `label_account`; code in `classify/`):

1. **Rules**, deterministic and free: a frontier-lab handle (`analysis/detect.py` R1) is `frontier`; a post that is an entry of the Doomers launch directory (R0) is `launch` with the directory's kind, product and company. The handle rule stands ahead of the directory: a lab's own post is not a client launch.
2. **Jev** (TypeSafe System One, `jev-1.14.0`, `POST /v1/systemone`): one request per item with typed questions — a `choice` per class, kind, role, topic and language (answered with a probability per option and a confidence), a `noul` for disclosure (probability of yes). The `state` is small on purpose (author, bio, follower count, post text), because the model's documented weaknesses are literal reading and distraction by irrelevant detail. Price $0.042 per million input tokens; the whole corpus cost $7.35.
3. **Claude** (`claude-opus-5-5`, structured JSON output, Batches API) where Jev's class confidence is below 0.6, Jev's role confidence below 0.55, Jev and the rule disagree, or either calls the post a launch — the last because product and company names are extracted from the text, which Jev cannot do. 27,317 posts and 54,480 accounts; $108. Twelve posts the model declined (exploit and bio-risk text) keep Jev's label.

Language is Jev's throughout (1.00 on both gold splits). Disclosure is Claude's where Claude ran, else Jev's probability ≥ 0.3; the disclosure regex (`#ad`, partnering with, …) is kept only as a candidate marker, because it fires on company partnerships: 0.40 accuracy on the disclosure gold against 0.85 for Jev at 0.3 and 0.85 / 0.95 (dev / holdout) for Claude.

**Gold set and thresholds.** 149 posts, 100 accounts and 40 disclosure candidates were labelled by reading before any model output was compared with them (`gold_post`, `gold_account`, `gold_disclosure`, with the labeller's note per item), drawn with seed 20261031 in strata of rule class × arm and rule role × population, a third of each stratum non-Latin, and split dev / holdout by alternation after a seeded shuffle. The thresholds 0.6 and 0.55 are the smallest at which Jev's accuracy on the items it keeps reaches 0.90 on the dev half; the holdout half was scored twice — once before and once after the rule-precedence fix that its first scoring revealed (`classify/HANDOFF.md` § 5) — so its figures are not blind to that one choice. Holdout accuracy (`python3 -I classify/evaluate.py --final`; per layer `classify/evaluate.py`): post class rules 0.61, Jev 0.84, Claude 0.92, decided labels 0.92 (74 items); launch kind 0.79 (24 gold items with a kind; a decided label without a kind counts as wrong); language 1.00; account role rules 0.66, Jev 0.66, Claude 0.90, decided 0.84 (50); topic 0.72; disclosure 0.95 (20). The gold set is small — a class holds 7–22 items on a split, so a class figure carries about ±0.1 — and it measures one reader's judgement; Jev's role confidence separates well on dev (0.92 among kept items) and weakly on holdout (0.72), which is why every disagreement goes to Claude rather than being trusted at the threshold. The gold set caught one defect of the rules' precedence (the directory outranking the frontier handle) before the labels reached the deliverable; it is development data for the thresholds, and the holdout half is spent as a held-out set the moment it is used to choose anything else.

The labels are read by `deliverable/build_graph.py` (node cards show role and class with their source and probability; the rail filters by class and role) and by `analysis/describe_v2.py` (the per-cluster role columns), through `classify/labels_api.py`. Reproduction: `classify/HANDOFF.md`.

## Changelog

| Date | Change |
| --- | --- |
| Nov 1, 2026 | Published: N = 5, K = 150, repeat quoter = 10 launch posts within four hours; wave pages indexed at 20 or more retrieved quoters and 5 or more repeat quoters. |

Study run v3, computed Oct 31, 2026.

Data licence: CC BY 4.0, attribution “Anysite, anysite.io/research/launch-waves”. Launch directory data: Doomers public launch directory, CC BY 4.0.

## Around This Launch

[Launch Waves on X](https://anysite.io/research/launch-waves/) [Open the data page](https://anysite.io/research/launch-waves/data/)

New launch waves are reported first on @anysite_io.

[Follow @anysite_io →](https://x.com/anysite_io)

// Follow

## New Launch Waves, First on X

New launch waves are reported first on @anysite_io.

[Follow @anysite_io →](https://x.com/anysite_io)