Register all seven public Speedrun cohorts with verifiable boundaries
This commit is contained in:
@@ -184,7 +184,7 @@ async function main() {
|
||||
const research = await researchResponse.json();
|
||||
assert.equal(research.companies.length, 1253);
|
||||
assert.equal(research.categories.length, 11);
|
||||
assert.equal(research.evidence.length, 4894);
|
||||
assert.equal(research.evidence.length, 4909);
|
||||
assert.equal(research.observations.length, 491);
|
||||
assert.equal((await request("/api/research/ai-companies", { method: "POST", headers })).status, 405);
|
||||
const researchPage = await request("/docs/other-research/ai-company-research/overview", { headers });
|
||||
|
||||
@@ -124,7 +124,7 @@ test("research revisions share the authentication database and preserve replay l
|
||||
assert.equal(consumeCode(config, "invalid"), "limited");
|
||||
const initial = readResearchSnapshot();
|
||||
assert.equal(initial.companies.length, 1253);
|
||||
assert.equal(initial.evidence.length, 4894);
|
||||
assert.equal(initial.evidence.length, 4909);
|
||||
assert.equal(initial.observations.length, 491);
|
||||
const businessReviews = initial.reviews.filter((review) => review.type === businessModelReviewType);
|
||||
assert.equal(businessReviews.length, 7);
|
||||
@@ -170,8 +170,8 @@ test("research validation rejects broken evidence and unsafe source links", () =
|
||||
test("reviews link explicit companies without turning global or excluded cases into companies", () => {
|
||||
const snapshot = structuredClone(seed) as ResearchSnapshot;
|
||||
assert.equal(snapshot.reviews.filter((r) => r.scope === "companies").length, 248);
|
||||
assert.equal(snapshot.reviews.filter((r) => r.scope === "dataset").length, 147);
|
||||
assert.equal(snapshot.reviews.filter((r) => r.scope === "excluded-candidate").length, 54);
|
||||
assert.equal(snapshot.reviews.filter((r) => r.scope === "dataset").length, 149);
|
||||
assert.equal(snapshot.reviews.filter((r) => r.scope === "excluded-candidate").length, 55);
|
||||
const review = snapshot.reviews.find((r) => r.id === "R4")!;
|
||||
assert.deepEqual(reviewCompanyIds(snapshot, review), ["AI007", "AI013", "AI021", "AI034"]);
|
||||
assert.deepEqual(reviewCompanyIds(snapshot, snapshot.reviews.find((r) => r.id === "CN-R-PSI")!), []);
|
||||
@@ -630,6 +630,35 @@ test("the public SR007 roster preserves unique entries and Alven's older operato
|
||||
"a current category change must retain the unresolved historical product attribution");
|
||||
});
|
||||
|
||||
test("public Speedrun cohort rosters preserve the finite boundary without inventing founding years", () => {
|
||||
const snapshot = seed as ResearchSnapshot;
|
||||
const rosters = snapshot.candidateBatches!.filter((batch) => /^SR00[1-7]-public-roster-2026-1$/.test(batch.id));
|
||||
assert.equal(rosters.length, 7);
|
||||
for (const [index, count] of [25, 25, 32, 42, 59, 59, 79].entries()) {
|
||||
const batch = rosters.find((item) => item.id.startsWith(`SR${String(index + 1).padStart(3, "0")}-`))!;
|
||||
assert.equal(batch.records.length, count);
|
||||
assert.equal(batch.complete, false, "a complete directory page is not completed company-level research");
|
||||
}
|
||||
const rows = rosters.flatMap((batch) => batch.records);
|
||||
assert.equal(rows.length, 321);
|
||||
assert.equal(new Set(rows.map((row) => row.url)).size, 321);
|
||||
const newlyRegistered = rosters.filter((batch) => !batch.id.startsWith("SR007-")).flatMap((batch) => batch.records);
|
||||
assert.equal(newlyRegistered.length, 242);
|
||||
assert.equal(newlyRegistered.filter((row) => row.status === "pending-year").length, 226);
|
||||
assert.equal(newlyRegistered.filter((row) => row.status === "linked").length, 9);
|
||||
assert.equal(newlyRegistered.filter((row) => row.status === "existing-outside-cohort").length, 1);
|
||||
assert.equal(newlyRegistered.filter((row) => row.status === "outside-cohort").length, 6);
|
||||
assert.ok(newlyRegistered.filter((row) => row.status === "outside-cohort").every((row) =>
|
||||
row.profileStatus === "readable" && row.evidenceIds?.some((id) => id.startsWith("SRALL1-P-"))),
|
||||
"old founding years require independent profile evidence, not cohort age");
|
||||
const variants = newlyRegistered.filter((row) => row.name === "Variant");
|
||||
assert.equal(variants.length, 2);
|
||||
assert.equal(new Set(variants.map((row) => row.url)).size, 2, "same-name profiles must not be merged by name");
|
||||
assert.equal(variants.filter((row) => row.companyId === "AI066").length, 1);
|
||||
assert.ok(!snapshot.observations.some((row) => row.evidence.startsWith("SRALL1-")),
|
||||
"roster discovery and outside-cohort claims do not create financial observations");
|
||||
});
|
||||
|
||||
test("annual launch archives exclude older companies only with evidence and reuse existing records", () => {
|
||||
const snapshot = structuredClone(seed) as ResearchSnapshot;
|
||||
const batch = snapshot.candidateBatches!.find((b) => b.id === "PH-2025-visible-1")!;
|
||||
@@ -657,7 +686,7 @@ test("unreconciled directory financials remain source reviews instead of income
|
||||
assert.ok(review.evidenceIds.includes("PH-TANA-DR"));
|
||||
assert.equal(reviewCompanyIds(snapshot, review).length, 0);
|
||||
assert.ok(!snapshot.observations.some((o) => o.evidence === "PH-TANA-DR"));
|
||||
assert.equal(snapshot.candidateBatches!.flatMap((b) => b.records).filter((r) => r.status === "pending-year").length, 131);
|
||||
assert.equal(snapshot.candidateBatches!.flatMap((b) => b.records).filter((r) => r.status === "pending-year").length, 357);
|
||||
});
|
||||
|
||||
test("product pivots and founder histories do not become new company years or current revenue", () => {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "2026-11-01-sr007-followup-10",
|
||||
"version": "2026-11-01-sr-public-rosters-1",
|
||||
"scopeConfirmedAt": "2026-10-30",
|
||||
"acceptance": "以确认的公开来源清单为边界,逐条核对并标明缺项。",
|
||||
"provenance": "S01—S12恢复自已提交用户的《AI公司研究_来源与分类模板》来源清单;S13—S16单列后续已使用的补充证据渠道,不将使用次数当作全量覆盖。",
|
||||
@@ -3040,8 +3040,8 @@
|
||||
"speedrun.a16z.com"
|
||||
],
|
||||
"initialAccess": "见具体证据访问记录",
|
||||
"boundary": "原有定向个案保留。2026-11-01匿名普通HTML默认SR007载荷79条唯一ID/slug、75普通UUID链接,count79且next/previous空。当前71关联(17复用、54本系列新增)、Alven1年份/主体冲突、6AI主营待核、scaledrive2024超年1;本系列已读79独立档案(62补读+17复用重读),全部位置有对应档案证据;复用原ID/观测,不新增重复公司。未执行站点脚本/私有接口;SR005/SR006参数仍返回SR007,不认其他批次或两年全量。Bric/Coherence/KIRA/Leonidas/Mecone/PhotonSpear当前AI主营未明。签约/cARR/管线/融资、客户资产/回款、旧事业业绩和界面财务不当已实现收入;live ARR、年度合同标签、年化服务和累计收入分别保留,财务日期/币种/净费不补造。软件订阅、额度充值、模型定制/运行、专业/人工托管、云存储、评测、硬件、金融手续费及旅行采购按交付拆开。所有公司交付/技术/收费缺项见关联证据和核查记录;公开说明、未发布功能、公开制品与独立测试分级。Sterling条款法人占位及Zoah的OPACITY残留只作补证,不能据此推造假。 本轮官网复核中Infragrid首页实验室数据/评测与条款Runbooks并列,当前暂C02但旧ARR不迁产品;Abliteration托管/API按C02,标题/正文口径不明仍保留。Codos/Proper明确含嵌入式工程,非纯自助软件假定。",
|
||||
"nextCheck": "已完成17复用独立档案重读;继续核Alven2024主体/2025品牌沿革及6项AI主营。再建立其他批次可验证公开边界,不按请求参数认成功。公司层面补独立登记、真实合同/履约/取消、币种与财务日、经常性净费、模型/人工/资料授权/存储和渠道成本;重点包括Sterling年合同净费与法人、Vene个人/机构实付、Valent年化业务组成、Truli单次/订阅、Zoah训练退出/席位额度/运营者、Foundry公告/制品及Vound具体产品。其余公司核查缺项继续保留,不以本批可读证明全部真实。 Infragrid数据业务/旧Runbooks的产品沿革、合同与数据许可,Abliteration衍生模型权利/预收消费,Alia Prosieve及Proper GAIA/Virgo主体关系,Codos/Proper试点转续费及工程工时需补。",
|
||||
"boundary": "2026-11-01公开前端匿名GET目录已取得SR001–SR007七批,分别25/25/32/42/59/59/79,共321个唯一公司ID/slug,声明/返回数一致且无下一页。只解析公开JSON,不执行JS、不登录、不调用投资者导出/联系或个人资料接口。原HTML默认SR007及其审计保留,公开GET的SR007 slug集合与其一致;此前普通页面?cohort参数无效不代表其他批次不可读。SR007的79独立档案已读:71关联、Alven1年份/主体冲突、6AI主营待核、scaledrive2024超年1。其余六批242位置仅10个已有档案URL精确复用(9两年公司、Rork2024对照),本轮另读Runware/Sloyd/Hedra/FLORA/Intangible/Agent Astra六项均旧年排除,226独立档案未读。当前321位置总80关联、1既有超年对照、7超年不新增、227成立/主体待核、6AI主营待核;不是所有公开档案均完成财务/注册/技术审计,也不含未公开/已移除/未来公司。原公司合同、业务转向、数据许可及技术缺项见逐条核查,不以完整目录充当完整公司研究。",
|
||||
"nextCheck": "逐项读取新增六批226个未读候选档案,分清2025/2026成立、旧公司/品牌沿革及是否AI主营;10个复用档案保留既有证据并检查变化。同名Variant两链接先独立保留,不凭名字合并。继续核SR007的Alven主体/品牌和6项AI主营,以及已关联公司的登记、真实合同/履约/取消、币种/财务日、净经常性定义、人工/模型/硬件/数据成本。公开七批321为当前目录边界,不证明档案都已研究或两年无缺漏。",
|
||||
"limitation": "来源可读不等于声明已独立验证。",
|
||||
"rosterAudit": {
|
||||
"url": "https://speedrun.a16z.com/companies",
|
||||
@@ -3055,7 +3055,121 @@
|
||||
"htmlUuidProfileLinks": 75,
|
||||
"htmlSha256": "32a8e1d9e6c9a2581077aed058767c46f03cdffdab9b0086ee9bd0c86094e152",
|
||||
"candidateBatchId": "SR007-public-roster-2026-1"
|
||||
}
|
||||
},
|
||||
"publicRosterAudits": [
|
||||
{
|
||||
"cohort": "SR001",
|
||||
"url": "https://speedrun.a16z.com/api/companies/companyparams?limit=100&offset=0&cohort=SR001",
|
||||
"accessedAt": "2026-11-01",
|
||||
"method": "公开前端实际使用的匿名GET,无Cookie/Authorization;只解析JSON不执行JS",
|
||||
"httpStatus": 200,
|
||||
"reportedCount": 25,
|
||||
"recordCount": 25,
|
||||
"uniquePublicIds": 25,
|
||||
"uniqueSlugs": 25,
|
||||
"next": null,
|
||||
"previous": null,
|
||||
"responseSha256": "9a4eb2c78fe918e31c88132f2052be26dfd07bddae6ebbe6ef5ea99f73897eea",
|
||||
"candidateBatchId": "SR001-public-roster-2026-1",
|
||||
"evidenceId": "SRALL1-SR001-ROSTER"
|
||||
},
|
||||
{
|
||||
"cohort": "SR002",
|
||||
"url": "https://speedrun.a16z.com/api/companies/companyparams?limit=100&offset=0&cohort=SR002",
|
||||
"accessedAt": "2026-11-01",
|
||||
"method": "公开前端实际使用的匿名GET,无Cookie/Authorization;只解析JSON不执行JS",
|
||||
"httpStatus": 200,
|
||||
"reportedCount": 25,
|
||||
"recordCount": 25,
|
||||
"uniquePublicIds": 25,
|
||||
"uniqueSlugs": 25,
|
||||
"next": null,
|
||||
"previous": null,
|
||||
"responseSha256": "2ac0887cb0d97ee6da4aa3f7b7d2ca4045b2640f0494e3be513c9ed6c05a79f8",
|
||||
"candidateBatchId": "SR002-public-roster-2026-1",
|
||||
"evidenceId": "SRALL1-SR002-ROSTER"
|
||||
},
|
||||
{
|
||||
"cohort": "SR003",
|
||||
"url": "https://speedrun.a16z.com/api/companies/companyparams?limit=100&offset=0&cohort=SR003",
|
||||
"accessedAt": "2026-11-01",
|
||||
"method": "公开前端实际使用的匿名GET,无Cookie/Authorization;只解析JSON不执行JS",
|
||||
"httpStatus": 200,
|
||||
"reportedCount": 32,
|
||||
"recordCount": 32,
|
||||
"uniquePublicIds": 32,
|
||||
"uniqueSlugs": 32,
|
||||
"next": null,
|
||||
"previous": null,
|
||||
"responseSha256": "8b205f1b6e58aec25b5bf0d39ae5bb29d6d0b10cc7144606792ea134cb7a345f",
|
||||
"candidateBatchId": "SR003-public-roster-2026-1",
|
||||
"evidenceId": "SRALL1-SR003-ROSTER"
|
||||
},
|
||||
{
|
||||
"cohort": "SR004",
|
||||
"url": "https://speedrun.a16z.com/api/companies/companyparams?limit=100&offset=0&cohort=SR004",
|
||||
"accessedAt": "2026-11-01",
|
||||
"method": "公开前端实际使用的匿名GET,无Cookie/Authorization;只解析JSON不执行JS",
|
||||
"httpStatus": 200,
|
||||
"reportedCount": 42,
|
||||
"recordCount": 42,
|
||||
"uniquePublicIds": 42,
|
||||
"uniqueSlugs": 42,
|
||||
"next": null,
|
||||
"previous": null,
|
||||
"responseSha256": "eae528acacf9a52bb001b4a2e42c774662849dcb130dfc009488cc86ec8b7475",
|
||||
"candidateBatchId": "SR004-public-roster-2026-1",
|
||||
"evidenceId": "SRALL1-SR004-ROSTER"
|
||||
},
|
||||
{
|
||||
"cohort": "SR005",
|
||||
"url": "https://speedrun.a16z.com/api/companies/companyparams?limit=100&offset=0&cohort=SR005",
|
||||
"accessedAt": "2026-11-01",
|
||||
"method": "公开前端实际使用的匿名GET,无Cookie/Authorization;只解析JSON不执行JS",
|
||||
"httpStatus": 200,
|
||||
"reportedCount": 59,
|
||||
"recordCount": 59,
|
||||
"uniquePublicIds": 59,
|
||||
"uniqueSlugs": 59,
|
||||
"next": null,
|
||||
"previous": null,
|
||||
"responseSha256": "82a94a083f45f8c61d72667f196b8b7afb7a03d25c386cfdb6cc212a21579ac8",
|
||||
"candidateBatchId": "SR005-public-roster-2026-1",
|
||||
"evidenceId": "SRALL1-SR005-ROSTER"
|
||||
},
|
||||
{
|
||||
"cohort": "SR006",
|
||||
"url": "https://speedrun.a16z.com/api/companies/companyparams?limit=100&offset=0&cohort=SR006",
|
||||
"accessedAt": "2026-11-01",
|
||||
"method": "公开前端实际使用的匿名GET,无Cookie/Authorization;只解析JSON不执行JS",
|
||||
"httpStatus": 200,
|
||||
"reportedCount": 59,
|
||||
"recordCount": 59,
|
||||
"uniquePublicIds": 59,
|
||||
"uniqueSlugs": 59,
|
||||
"next": null,
|
||||
"previous": null,
|
||||
"responseSha256": "baa82a040e3a8466241a86fdc3c681ffd114ba55f9a16c3f73448227468726c7",
|
||||
"candidateBatchId": "SR006-public-roster-2026-1",
|
||||
"evidenceId": "SRALL1-SR006-ROSTER"
|
||||
},
|
||||
{
|
||||
"cohort": "SR007",
|
||||
"url": "https://speedrun.a16z.com/api/companies/companyparams?limit=100&offset=0&cohort=SR007",
|
||||
"accessedAt": "2026-11-01",
|
||||
"method": "公开前端实际使用的匿名GET,无Cookie/Authorization;只解析JSON不执行JS",
|
||||
"httpStatus": 200,
|
||||
"reportedCount": 79,
|
||||
"recordCount": 79,
|
||||
"uniquePublicIds": 79,
|
||||
"uniqueSlugs": 79,
|
||||
"next": null,
|
||||
"previous": null,
|
||||
"responseSha256": "9a9d437fbd16ed477f2844b84ac1ad037ad3e0c9215013c7a9a90126569ab915",
|
||||
"candidateBatchId": "SR007-public-roster-2026-1",
|
||||
"evidenceId": "SRALL1-SR007-ROSTER"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "S15",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"sourceVersion": "2026-11-01-sr007-followup-10",
|
||||
"sourceVersion": "2026-11-01-sr-public-rosters-1",
|
||||
"asOf": "2026-11-01",
|
||||
"metric": "platform-mrr-usd",
|
||||
"sampleUnit": "product-or-business",
|
||||
|
||||
@@ -4,7 +4,7 @@ from collections import Counter
|
||||
import json
|
||||
from pathlib import Path
|
||||
import sys
|
||||
from urllib.parse import urlsplit
|
||||
from urllib.parse import parse_qs, urlsplit
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
DATA = json.loads((ROOT / 'content/research/ai-companies.seed.json').read_text())
|
||||
@@ -49,6 +49,27 @@ def source_register():
|
||||
assert roster['defaultCohort'] == 'SR007' and roster['next'] is None
|
||||
assert len(batch['records']) == roster['recordCount'] == roster['reportedCount']
|
||||
assert len({row['url'] for row in batch['records']}) == roster['recordCount']
|
||||
if source['id'] == 'S14' and source.get('publicRosterAudits'):
|
||||
audits = source['publicRosterAudits']
|
||||
assert {a['cohort'] for a in audits} == {f'SR{i:03d}' for i in range(1, 8)}
|
||||
assert len(audits) == 7
|
||||
profile_urls = []
|
||||
for audit in audits:
|
||||
batch = next(b for b in DATA['candidateBatches'] if b['id'] == audit['candidateBatchId'])
|
||||
query = parse_qs(urlsplit(audit['url']).query)
|
||||
assert urlsplit(audit['url']).netloc == 'speedrun.a16z.com'
|
||||
assert query == {'limit': ['100'], 'offset': ['0'], 'cohort': [audit['cohort']]}
|
||||
assert urlsplit(audit['url']).path == '/api/companies/companyparams'
|
||||
assert audit['httpStatus'] == 200 and audit['accessedAt'] <= DATA['asOf']
|
||||
assert audit['next'] is None and audit['previous'] is None
|
||||
assert len(batch['records']) == audit['recordCount'] == audit['reportedCount']
|
||||
assert audit['uniquePublicIds'] == audit['uniqueSlugs'] == audit['recordCount']
|
||||
assert len(audit['responseSha256']) == 64 and all(c in '0123456789abcdef' for c in audit['responseSha256'])
|
||||
assert batch['sourceId'] == 'S14' and not batch['complete']
|
||||
proof = next(e for e in DATA['evidence'] if e['id'] == audit['evidenceId'])
|
||||
assert proof['url'] == audit['url'] and proof['companyId'] is None
|
||||
profile_urls.extend(row['url'] for row in batch['records'])
|
||||
assert len(profile_urls) == len(set(profile_urls)), 'duplicate profiles across public cohorts'
|
||||
if source['url']:
|
||||
assert urlsplit(source['url']).scheme in {'http', 'https'} and urlsplit(source['url']).netloc
|
||||
for host in source['hosts']:
|
||||
|
||||
Reference in New Issue
Block a user