Reconcile current YC coverage accounting with source boundaries
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "2026-11-01-arr-time-basis-1",
|
||||
"version": "2026-11-01-source-accounting-1",
|
||||
"asOf": "2026-10-31",
|
||||
"scope": "全球公开资料研究:保留首批个案,并扩展核查2025—2026八个YC批次候选池;成立年份以官方公司页面字段为依据。",
|
||||
"limitations": [
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"sourceVersion": "2026-11-01-arr-time-basis-1",
|
||||
"sourceVersion": "2026-11-01-source-accounting-1",
|
||||
"asOf": "2026-10-31",
|
||||
"metric": "platform-mrr-usd",
|
||||
"sampleUnit": "product-or-business",
|
||||
|
||||
@@ -16,6 +16,20 @@ SOURCE_SLUG = 'ai-company-research/02-coverage-and-gaps'
|
||||
BASE = '/docs/other-research/ai-company-research/overview'
|
||||
|
||||
|
||||
def yc_coverage_summary():
|
||||
companies = {row['id']: row for row in DATA['companies']}
|
||||
imported = [companies[f"YC{row['ycId']}"] for row in AUDIT['records'] if row['status'] == 'imported']
|
||||
profile_only = sum(bool(row.get('profileOnly')) for row in imported)
|
||||
groups = {}
|
||||
for label, prefix in [('unclearAI', 'YC-AI-UNCLEAR-'), ('missingYear', 'YC-MISSING-YEAR-'),
|
||||
('dateConflict', 'YC-DATE-CONFLICT-')]:
|
||||
rows = [row for batch in DATA.get('candidateBatches', []) if batch['id'].startswith(prefix)
|
||||
for row in batch['records']]
|
||||
groups[label] = {'records': len(rows), 'statuses': dict(sorted(Counter(row['status'] for row in rows).items()))}
|
||||
return {'initialProfiles': len(AUDIT['records']), 'originalImported': len(imported),
|
||||
'profileOnly': profile_only, 'deepenedOriginal': len(imported) - profile_only, **groups}
|
||||
|
||||
|
||||
|
||||
def source_register():
|
||||
sources = SOURCES['sources']
|
||||
@@ -26,6 +40,8 @@ def source_register():
|
||||
for source in sources:
|
||||
assert source['status'] in {'candidate-audit', 'targeted', 'pending', 'context', 'access-limited', 'per-company'}
|
||||
assert source['boundary'] and source['nextCheck']
|
||||
if source['id'] == 'S01':
|
||||
assert source.get('coverageSummary') == yc_coverage_summary(), 'YC source summary is stale'
|
||||
if source['url']:
|
||||
assert urlsplit(source['url']).scheme in {'http', 'https'} and urlsplit(source['url']).netloc
|
||||
for host in source['hosts']:
|
||||
@@ -49,7 +65,18 @@ def source_register():
|
||||
company_ids = {e['companyId'] for e in evidence if e['companyId']}
|
||||
observations = sum(o['evidence'] in evidence_ids for o in DATA['observations'])
|
||||
name = f"[{source['name']}]({source['url']})" if source['url'] else source['name']
|
||||
lines.append(f"| {source['id']} {name} | {statuses[source['status']]} | {len(evidence)} / {len(company_ids)} / {observations} | {source['boundary']} | {source['nextCheck']} |")
|
||||
boundary = source['boundary']
|
||||
if source['id'] == 'S01':
|
||||
summary = source['coverageSummary']
|
||||
boundary += (f" 当前原候选池{summary['initialProfiles']}项,原新增{summary['originalImported']}项中"
|
||||
f"{summary['profileOnly']}项目录基础资料、{summary['deepenedOriginal']}项深化个案。")
|
||||
for key, label in [('unclearAI', '原AI不明'), ('missingYear', '原缺年'), ('dateConflict', '原日期冲突')]:
|
||||
group = summary[key]
|
||||
labels = {'linked': '关联公司', 'pending-ai': 'AI主营待核',
|
||||
'pending-year': '成立/主体待核', 'outside-cohort': '范围外'}
|
||||
counts = '、'.join(f'{labels.get(status, status)} {count}' for status, count in group['statuses'].items())
|
||||
boundary += f" {label}{group['records']}项当前:{counts}。"
|
||||
lines.append(f"| {source['id']} {name} | {statuses[source['status']]} | {len(evidence)} / {len(company_ids)} / {observations} | {boundary} | {source['nextCheck']} |")
|
||||
lines += ['', 'Dealroom、Product Hunt、机器之心与36氪入口于2026-10-30重新访问。官网首页可读不证明已取得完整筛选结果;安全检测页面不作为文章内容。候选池之外的来源边界尚需建立可回查条目,完成前不宣布来源清单已全部覆盖。', '']
|
||||
return lines
|
||||
|
||||
|
||||
Reference in New Issue
Block a user